├── .gitignore ├── .npmrc ├── LICENSE ├── NAMING.md ├── README.md ├── index.html ├── package.json ├── polyfill.js ├── spec.emu └── spec.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | 29 | # Only apps should have lockfiles 30 | npm-shrinkwrap.json 31 | package-lock.json 32 | yarn.lock 33 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Jordan Harband 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /NAMING.md: -------------------------------------------------------------------------------- 1 | # Naming Constraints 2 | 3 | Recently there has been some concern around the naming of the “globalThis” proposal. I would like to address some of the concerns and make transparent the restrictions that the committee had while choosing a name. Hopefully this will help clarify how we got to where we are, and help people think of viable alternatives. 4 | 5 | We don’t have the option of doing nothing. In strict mode code (all Modules, and `class`, and anything in `'use strict'` code), the only reliable cross-environment way to get the global is eval via `Function`. This is unavailable in a CSP context - like Chrome apps. 6 | 7 | One thing that is important to note, is that this name is not something JavaScript developers should be seeing every day - in fact it should be used rarely, if at all. Environment-specific references to the global will almost certainly remain in use to denote browser-only or node-only APIs - this proposal provides a way for polyfills/shims, build tools, and portable code to have a reliable non-eval means to access the global. 8 | 9 | 10 | The constraints listed here use the word “must” to indicate an absolute restriction, and the word “should” indicates a restriction that ideally should be respected, but is not necessarily a blocker for achieving consensus. I’ll use the phrase “the global” to describe the object this proposal is providing access to - known in the spec as “the global _this_ value”. 11 | 12 | ## Constraints: 13 | 1. **Must** be a global identifier, so that it's accessible without previously having access to the global itself. 14 | 15 | #### Names ruled out by this restriction: 16 | - Symbol.global (or any other symbol) 17 | - anything that isn't a valid identifier 18 | 19 | 1. **Must** be a global identifier, so that it can be "deniable" per compartment - meaning, that two conceptual "compartments" in the same realm must be able to be provided two different objects for the global. This means it can't be stored on any object that's accessible via syntax (ie, undeniable) - so it can't be a property on `Object`, or `Function`, or `Error`, etc. This also means that the name can't meaningfully be "realm"-related, nor can it imply that it's some kind of "ultimate top thing". 20 | 21 | #### Names ruled out by this restriction: 22 | - `rootRealm` 23 | - `currentRealm` 24 | - `shadowRealm` 25 | - `topGlobal` 26 | - `rootGlobal` 27 | - `globalRoot` 28 | 29 | 1. **Must** not be related to religion - it wouldn't be appropriate to venture into that arena, and we would not want to risk disrespecting anyone’s spiritual beliefs. 30 | 31 | #### Names ruled out by this restriction: 32 | - `godObject` 33 | - `globalGod` 34 | 35 | 1. **Must** make sense in non-browser environments, like `node` or Moddable or other non-browser engines 36 | 37 | #### Names ruled out by this restriction: 38 | - `browser` 39 | - `browserContext` 40 | 41 | 1. **Must** be web compatible: it turns out that basically anything used for "environment detection" is something that will break sites on the web. 42 | 43 | #### Names ruled out by this restriction: 44 | - `global` (used in node; broke flickr.com, among others) 45 | - `self` (used in browsers; also includes `self.instance`) 46 | - `window` (used in browsers) 47 | - `top` (used in browsers) 48 | - `root` (used in node) 49 | - `GLOBAL` (used in node) 50 | 51 | 1. Names **must** not conflict with related specifications, such as [HTML](https://github.com/tc39/proposal-global#html-and-the-windowproxy). 52 | 53 | #### Names ruled out by this restriction: 54 | - `globalObject` 55 | - `globalObj` 56 | 57 | 1. **Must** not conflict with the mental model around distinctly defined concepts 58 | 59 | 1. Names that imply a reified "scope" object: the object this proposal provides is not the global scope - it doesn't contain properties for global `let`, `const`, or `class` values - only global `function` declarations and global `var`s. It was widely agreed that a name that implied "scope" would cause a large amount of confusion due to these inconsistencies. 60 | 61 | #### Names ruled out by this restriction: 62 | - `globalScope` 63 | - `globalContext` 64 | - `context` 65 | - `browserContext` 66 | - `currentGlobalScope` 67 | - `globalEnv` 68 | 69 | 1. Names that imply that a "reference" is a concrete thing in the language, since the language does not have references. Note that there are [future](https://github.com/sebmarkbage/ecmascript-asset-references) [proposals](https://github.com/tc39/proposal-weakrefs) that may add this concept to the language. 70 | 71 | #### Names ruled out by this restriction: 72 | - `globalRef` 73 | - `globalReference` 74 | 75 | 1. **Should** make sense in relation to how naming is used in the JavaScript community so far. In other words, if a name already has a colloquial meaning that does not make sense for the global, it should not be used. The reason for this restriction is that it would lead to added confusion in the language. This rules out the following: 76 | 77 | 1. Names that don't connote "global" - colloquially the object this proposal provides is more or less the "global object", despite the constraint above. The general consensus, and my personal opinion, is that the name should contain the word "global" so that its meaning is clear. 78 | 79 | #### Names ruled out by this restriction: 80 | - `system` 81 | - `universe` 82 | - `globe` 83 | - `shell` 84 | - `container` 85 | 86 | 1. Names that start with a capital - by overwhelming community convention, names that start with a capital letter (also called “PascalCase”) are typically used only for constructor functions, or for namespaces (like `Math`, `Reflect`, `JSON`, etc) - objects that group related values under one containing object. Since the global is not a function, and is not a container for related objects following a theme, some on the committee felt that these names would not be appropriate. 87 | 88 | #### Names ruled out by this restriction: 89 | - `Global` 90 | - `GlobalObject` 91 | - `Globals` 92 | 93 | 1. Names that already have a conflicting meaning in the JS community. Note that this also drastically increases the likelihood of [web compatibility](#web-compat) issues. 94 | 95 | #### Names ruled out by this restriction: 96 | - `store` 97 | - `globalStore` 98 | - `globalMap` 99 | - `globalExports` 100 | - `globalEnv` 101 | - `common` 102 | - `shared` 103 | 104 | 105 | These are the names that have been suggested (by both committee members and the community) that "survive" all of these constraints, with some notes inline: 106 | - `globalThis` 107 | - `globals` 108 | - `globalInstance` 109 | - `globalValue` 110 | - `theGlobal`: there's no precedent for using a definite article in a name (and it would make things more difficult for non-native-English speakers, many of whom are members of TC39) 111 | - `globalVars`: this isn’t accurate because it includes function declarations and can include properties added without using `var`. 112 | - `__global__`: There exists the pattern of using `__` in other places, most notably `__proto__` - but this was a legacy pattern, and one that the committee did not want to repeat. Node.js uses the double underscore for `__dirname` and `__filename` in CommonJS modules, but this pattern will no longer be used in ES Modules. Python uses the double underscore for built-ins that need to avoid conflicts with userland, such as `__init__`. 113 | 114 | ### How we came to `globalThis`: 115 | 116 | Given that `global` ended up failing due to web compatibility issues, browsers were hesitant to ship another identifier that might break sites - so the next step was to gather usage data. Doing so presents a cost to browsers, and so I was requested to prune the list down to 3 or 4 options - a short list. While I’d hoped to gather as much data as possible, as the proposal champion, I had to make a choice: so I chose these names, with these reasons: 117 | - `global`: as a control, and to provide appropriate scale for the other names 118 | - `globals`: my personal favorite, since my first choice was unavailable 119 | - `globalThis`: while this is not a name in common usage, it matches the spec’s existing terminology, and accurately describes the global. 120 | - `globalObject`: despite the [constraint](#related-specs) noted above, this name seemed closest to common usage in the community, and I wanted to either decisively rule it out, or attempt to persuade the committee that the collision with the HTML spec might be worth it. 121 | 122 | The results confirmed that `global` was out, and that of the remaining three names, `globals` had significantly more usage than the other two (albeit, much less than `global`), and `globalThis` had less usage than `globalObject`. I presented these findings to the committee with a recommendation to go with `globalThis`, and the recommendation received consensus: [notes part 1](https://github.com/rwaldron/tc39-notes/blob/c2aaad7ef4a348b7ab019cca9f19b07f7484478a/es9/2018-07/july-24.md#new-name-for-global) / [notes part 2](https://github.com/rwaldron/tc39-notes/blob/c2aaad7ef4a348b7ab019cca9f19b07f7484478a/es9/2018-07/july-25.md#revisit-global-name). Within a month, V8 had announced its [intent to ship](https://groups.google.com/a/chromium.org/d/msg/blink-dev/6fxzDrO-9Oc/Pm4cGt8qBAAJ). 123 | 124 | ### What we, as a committee, could have done better: 125 | 126 | We should have communicated better and clearer with the community, as otherwise we would not be having a naming discussion so late in the process. Without a doubt, this document should have been written sooner. Although this has been implemented by a browser engine already, that doesn’t mean things are set in stone. If a viable alternative arises, there is certainly wiggle room. 127 | 128 | During the November 2018 meeting, some user feedback was received claiming that `globalThis` was a confusing name due to the overall confusion around `this` in JavaScript, and due to Modules not having a top-level `this` value. While some members of the committee were concerned about this claim, the overall consensus was to proceed with `globalThis`. 129 | 130 | All feedback is welcomed. In particular, if you have a suggestion that meets the above constraints, please [file an issue](https://github.com/tc39/proposal-global/issues/new) - and if you think that any part of this document can be clarified, please [file an issue](https://github.com/tc39/proposal-global/issues/new) or [create a pull request](https://github.com/tc39/proposal-global/compare)! 131 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [globalThis](https://www.npmjs.com/package/globalthis) 2 | ECMAScript Proposal, specs, and reference implementation for `globalThis` 3 | 4 | Spec drafted by [@ljharb](https://github.com/ljharb). 5 | 6 | This proposal is currently [stage 4](https://github.com/tc39/ecma262) of the [process](https://tc39.github.io/process-document/). 7 | 8 | ## Rationale 9 | It is difficult to write portable ECMAScript code which accesses the global object. On the web, it is accessible as `window` or `self` or `this` or `frames`; on node.js, it is `global` or `this`; among those, only `this` is available in a shell like V8's `d8` or JavaScriptCore's `jsc`. In a standalone function call in sloppy mode, `this` works too, but it's `undefined` in modules or in strict mode within a function. In such contexts, the global object can still be accessed by `Function('return this')()`, but that form is inaccessible with some CSP settings, such as within Chrome Apps. Below is some code from the wild to get the global object, passed in as the single argument to an IIFE, which works for most cases but won't actually work in `d8` when in a module or in strict mode inside a function (which could be fixed using the `Function` trick): 10 | ```js 11 | function foo() { 12 | // If we're in a browser, the global namespace is named 'window'. If we're 13 | // in node, it's named 'global'. If we're in a shell, 'this' might work. 14 | (typeof window !== "undefined" 15 | ? window 16 | : (typeof process === 'object' && 17 | typeof require === 'function' && 18 | typeof global === 'object') 19 | ? global 20 | : this); 21 | } 22 | ``` 23 | 24 | In addition, the `es6-shim` had to switch from `Function('return this')()` due to [CSP concerns](https://github.com/paulmillr/es6-shim/issues/301), such that the current [check](https://github.com/paulmillr/es6-shim/commit/2367e0953edd01ae9a5628e1f47cf14b0377a7d6) to handle browsers, node, web workers, and frames is: 25 | ```js 26 | var getGlobal = function () { 27 | // the only reliable means to get the global object is 28 | // `Function('return this')()` 29 | // However, this causes CSP violations in Chrome apps. 30 | if (typeof self !== 'undefined') { return self; } 31 | if (typeof window !== 'undefined') { return window; } 32 | if (typeof global !== 'undefined') { return global; } 33 | throw new Error('unable to locate global object'); 34 | }; 35 | ``` 36 | 37 | ## HTML and the `WindowProxy` 38 | 39 | In HTML, the global object is separated into the `Window` and the `WindowProxy`. New attributes are set on the `Window`, but top-level `this` has the identity of the `WindowProxy`. The `WindowProxy` forwards all object operations to the underlying `Window`, but as the page changes, `globalThis` maintains the same identity while the underlying `Window` is swapped out. 40 | 41 | The distinction is observable in the following scenario, with files `parent.html`, `frame-a.html`, and `frame-b.html`. `frame-a.html` has the following source code: 42 | 43 | ```html 44 | 48 | ``` 49 | 50 | `frame-b.html` has the following source code: 51 | 52 | ```html 53 | 56 | ``` 57 | 58 | `parent.html`’s source code is: 59 | 60 | ```html 61 | 62 | 78 | ``` 79 | 80 | [This demo](https://tc39.es/proposal-global/html-windowproxy/example-1/) shows that the global variable `foo` was being stored on the actual global object, which has changed during navigation, but `globalThis` has not changed during navigation. Therefore, `globalThis` is not the global object. 81 | 82 | Thus, `globalThis` is observably different from “the global object”, which is not directly accessible from JavaScript. [In web browsers, it’s even possible that (even in the global scope), `foo !== globalThis.foo`.](https://tc39.es/proposal-global/html-windowproxy/example-2/) 83 | 84 | ES6/ES2015 does not account for the `Window`/`WindowProxy` structure, and simply refers to ”the global object” directly. This specification does the same. If the ECMAScript specification is changed for top-level `this` to account for `WindowProxy`, then the change should also apply to the definition of this proposal. 85 | 86 | ## SES interaction 87 | 88 | For Secure ECMAScript, it is important that all references to the global object be spoof-able and capable of being locked down, so that each context gets its own shadow global context. Additionally, references to the global object should not be reachable from other ECMAScript intrinsic objects, which SES would like to simply recursively freeze. In this proposal, `globalThis` is a writable and configurable property of the global object, so it should meet SES requirements. 89 | 90 | ## Naming 91 | ~~There is desire to reify one of the existing global property names, particularly `global` or `window`, instead of `System.global`. Further research will be done to determine if either of these two options will or will not break existing code doing runtime environment detection.~~ ~~Further research has determined that using `global` will not break existing code.~~ Attempts were made to ship under the name `global`, but it turns out that this does, in fact, break some existing websites. 92 | 93 | After some data-gathering to determine web compatibility of a short list of choices, we settled on `globalThis`, as this name is both highly likely to be web compatible, and also maps to the concept of being the “global `this` value” (and not the “global object”, per [above](https://github.com/tc39/proposal-global#html-and-the-windowproxy)). 94 | 95 | For a more detailed list of constraints, see [NAMING.md](NAMING.md). 96 | 97 | ## Spec 98 | You can view the spec in [markdown format](spec.md) or rendered as [HTML](http://tc39.github.io/proposal-global/). 99 | 100 | ## Thanks 101 | Originally inspired by https://twitter.com/littledan/status/627284720284372992 / http://littledan.github.io/global.html 102 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 |The initial value of globalThis
is the well-known intrinsic object %GlobalThisValue%.
This property has the attributes { [[Writable]]:
Intrinsic Name | 2169 |Global Name | 2170 |ECMAScript Language Association | 2171 |
---|---|---|
2174 | |
2176 | 2177 | | The initial value of the prototype property of %Generator% |
2178 |
2181 | |
2183 | globalThis |
2184 | The initial value of the globalThis property of the |
2185 |
%Int8Array% | 2188 |Int8Array |
2189 | The Int8Array constructor ( |
2190 |
The abstract operation SetRealmGlobalObject with arguments realmRec, globalObj, and thisValue performs the following steps:
2201 |© 2019 Jordan Harband
2225 | 2226 |All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.
2228 | 2229 |Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
2230 | 2231 |THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2238 | 2239 |7 | title: global 8 | stage: 4 9 | contributors: Jordan Harband 10 |11 |
The initial value of `globalThis` is the well-known intrinsic object %GlobalThisValue%.
16 |This property has the attributes { [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.
17 |Intrinsic Name | 27 |Global Name | 28 |ECMAScript Language Association | 29 |
---|---|---|
%GeneratorPrototype% | 32 |33 | | The initial value of the prototype property of %Generator% |
34 |
%GlobalThisValue% | 37 |globalThis |
38 | The initial value of the globalThis property of the global object |
39 |
%Int8Array% | 42 |Int8Array |
43 | The Int8Array constructor ( |
44 |
The abstract operation SetRealmGlobalObject with arguments _realmRec_, _globalObj_, and _thisValue_ performs the following steps:
54 |Intrinsic Name | 15 |Global Name | 16 |ECMAScript Language Association | 17 |
---|---|---|
%GeneratorPrototype% | 20 |21 | | The initial value of the `prototype` property of %Generator% | 22 |
%GlobalThisValue% | 25 |globalThis |
26 | The initial value of the `globalThis` property of the global object | 27 |
%Int8Array% | 30 |Int8Array |
31 | The `Int8Array` constructor ( |
32 |