Closed rauschma closed 5 years ago
I'm already using global
in webpack. It works in node and browsers. Node's global
and the browser's window
are not a this
. To me, this
suggests a context might change, which isn't the case. I would think globalThis
could be confusing.
I'm gonna vote against this
.
I am 100% in support of @rauschma here. Please, please reconsider.
Also in complete agreement with @rauschma et al.
browserify also maps window
to global
.
Using global
would just be paving the goat-tracks that are proven to work.
EDIT: Just noticed this:
Attempts were made to ship under the name global, but it turns out that this does, in fact, break some existing websites.
And I have to say, as much as I get the "don't break things" attitude, the future is slightly more important than the past.
Is there another name we could have proposed to investigate that doesn't cause enough breakage to be seen as a web compat problem? Several have been investigated already including global
. Note that web compat problems are not purely theoretical nor absolute. JSON
broke Facebook, but that website was able to update in a way that made the problem go away. Large distributed sites that cannot be feasibly updated are a different story.
@bmeck I appreciate how difficult it is to pick a name and how important it is not to break anything! I’m fine with literally anything that doesn’t have the word this
in it. My suggestion would be globalObject
, but I don’t know how web-compatible that is.
globalObject
,globalObj
, system
, context
???
Scott
We should avoid jests if we can here. It takes a huge amount of time to check any given thing and generally means some browser needs to actually roll it out if it seems safe enough, see what breaks and then roll it back.
Has self
been considered? It's already a synonym for window
in the browser.
@bmeck - Maybe some humor might make the language even more fun? 😄 It is already silly in some places. Your reasoning for not kidding around eludes my understanding. I'm certain the silly suggestions would be ignored for the spec. At any rate, I've edited my comment. Scott
This is the option we decided to go with. The only better name imo is global, and breaking the web is unacceptable (the future of the web depends on not breaking the web).
globalThis is the global this value, which applies to sloppy mode Scripts, the Function constructor even in modules, and the upcoming Realms API - it’s not the global object, and being correct (not merely pedantic) is important.
@feross Yes: https://github.com/tc39/proposal-global/issues/11
@ljharb I completely understand how tricky all of this is and how important not breaking the web is!
I wouldn’t be as emotionally invested if I didn’t see almost daily people who are confused about this
. And the many blog posts explaining it, many getting it wrong.
From the readme's rationale (emphasis mine):
It is difficult to write portable ECMAScript code which accesses the global object.
That sounds like that's the main goal here.
@kleinfreund that's a very good point - that sentence does imply that the name should have something to do with "global object". I'll try to update it to make that more clear.
I understand it’s confusing, but that’s what this proposal is for - the global this value. The global object is not actually directly accessible, and altho most community members (myself included) colloquially refer to it as the global object, browser representatives on TC39 flatly refused to allow it to proceed unless it explicitly did not imply that it was the global object.
@ljharb Hmm. What is their name for what the global this
points to?
The same as in the spec, and in this proposal - the “global this value”.
Browsers have the concept of the “WindowProxy” (mentioned in the readme) that encapsulates access to the actual global object - i believe for security reasons dealing with iframes and cross-window access.
OK, I see and accept the constraints. I’m still unhappy, because my hope (enabled by ES6!) had been that we’d be able to eventually (mostly) forget about this
outside methods.
I'm on your team here :-) I'd be delighted if the warts of the language, including sloppy mode semantics, would eventually be able to fully disappear - I think things would be much clearer for everyone, new and experienced users alike. Unfortunately, I suspect that won't be the case :-/
Thank you for the feedback - I’m not happy about the result either, but web compat has left no other palatable practical options.
I would advocate doing nothing over globalThis
The global object is not actually directly accessible
this is an amazing argument against caring about the fact that there is this hidden/internal global
that no one consuming this API can ever use.
Doing nothing would be worse - we desperately need a non-eval way to access the global this value, especially with CSP as a thing that exists.
If you’re content with “nothing”, I’m not sure why this identifier that you can choose not to use will matter to you - if you’ll use it, by don’t like the name, then “nothing” certainly shouldn’t be preferable.
Probably getting a bit off-topic, but why would I not advocate against something that I believe would be worse than nothing?
globalObject
would be better than nothing.
global
would be in line with the last 10 or so years of precident.
@KoryNunn Jordan just explained the constraints against globalObject
and why having something is useful (but maybe not for you).
@KoryNunn As for global
and self
, see this issue:
https://github.com/tc39/proposal-global/issues/11
And what about globalScope
?
Scott
@ljharb Got it. To clarify: Given that it’s called “global this
” in the spec, the name globalThis
is OK. I’d rather it were called something else in the spec (with a matching identifier).
@smolinari it's not actually a scope (global const/lets, for example, are not properties on the global this value), and there isn't any reified "scope" concept in the spec (by design).
By "global this value", are we meaning "the thing 'this' will point to in a non-strict function that has a 'this' reference"?
If so, I'd suggest that perspective on that value, used to name it, is far less relevant (and becoming less so as time goes on) compared to "the object that holds properties of all my global variables". IME the latter is far more common in terms of mentally describing what that thing is, and why we want to access it. The former is literally something most of us teach and advocate as "you should never access that if you can avoid it." I've said countless times in my courses, "if you're trying to access 'this' and it's the global object, that's usually a mistake, and that's why strict mode took that away."
So "globalThis" may be pedantically correct but it's not even remotely the common name we should be propagating for it.
As usual, @ljharb, the tone of "it's already been decided, get over it" is not helpful. You didn't consult enough of us teachers likrle @rauschma and myself to realize that TC39's perspectives here are skewed from the direction we should be going. I know that's upsetting to hear, but every time you ignore this perspective you can expect (and I assume, ultimately ignore) my pushback.
For the sake of bikeshedding, I would have preferred "globalContext" or "globalScope" or even "globalSelf" infinitely more than "globalThis". Those names all point to the identity and purpose of that object that more closely aligns with how devs interact with it, and also what many of us teachers are trying to steers devs towards.
+@littledan
I don't think I've offered a tone or wording of "it's been decided, get over it" here, and I don't think that's being particularly charitable. Also, I don't think it's fair to assume that nobody on TC39 is a teacher - I consider myself a teacher of JavaScript, too, in some ways.
(regarding bikeshedding, "globalScope", as I've explained above, would be a very confusing name - a scope is not a noun in javascript. "globalContext" is interesting, but "context" isn't a commonly used term, so I'd find that confusing as well, and "globalSelf" would imply it's different than "non-global self
", which it's not in browsers, and "self" isn't a thing at all in all JS engines)
"the object that holds properties of all my global variables"
@getify This is wrong assumption, only top var
declarations becomes properties of the global
(known as legacy defect), but not top let
or const
declarations (which fixes the behavior):
This is going to be one of those painful proposals that I associate with lost opportunities, isn't it? Like that issue about using #
for private fields instead of private
where everyone talked over each other
I'm getting really tired of sensible language design being blocked by elitist pedantry
@suchipi what do you think would be a sensible design here?
I think globalObject
makes sense- no one has ever been confused by window
referring to a WindowProxy instead of the window object, so the distinction between the two doesn't seem useful. Also I thought the Window/WindowProxy duality wasn't part of the ECMAScript standard anyway, so it doesn't make much sense to give it affordances here.
Given that some browsers would refuse to implement it under that name, what else would you suggest?
Under the name globalObject
? Why would they refuse it? Are there web compatibility issues with that name?
@suchipi check out #32 if you haven't already.
@suchipi they refused it specifically because it's not actually the global object, and they did care about the WindowProxy duality.
Well, I think that is an example of elitist pedantry getting in the way of the needs of the average user.
What about Global
?
As I commented on #32, it was in my original list of possibilities, but the general reaction I got was that it's not a constructor and not quite the same as a namespace like Math, JSON, Reflect, etc.
At some point, I had to create a minimal list of 3-5 possibilities in order to gather web compat data, and I had to make a judgement call to prune the longer list down to that, and it didn't include Global.
Sorry for the duplication, I'll move to #32
If global
isn't acceptable, what about globals
? Not sure if it already was suggested.
@pleerock it’s already been suggested, and it’s one of the ones i collected data on - it’s not an option, because of web compatibility.
I agree globalThis
is an awkward name. Based on what @ljharb says it seems to be a case of specification terminology being moved in to the language:
The same as in the spec, and in this proposal - the “global this value”.
whereas normally I'd expect the reverse (the terminology to be determined for the language then written in to the spec).
I appreciate this has moved far along enough to shipping to be difficult to change - especially since this looks to ship in Chrome stable in 5 days... maybe that should be postponed for a little more thought?
I can see how this will quickly turn in to an epic new episode of bikeshedding, but I can't resist throwing in globalRef
, which doesn't seem to have been discussed yet. It doesn't refer to "this" and doesn't imply it points to "the global object". JavaScript variables reference objects so it can be technically described as being a reference to the "global this object" (as the spec describes it), yet should be intuitive to the average developer since they can think of it as referencing what they informally think of as "the global object" (where their global variables/properties go). Hopefully it is also more straightforward to explain to beginners since it doesn't refer to "this" and is indeed a reference (but I don't teach programming).
In fact the term "the global reference" is natural enough that it was mentioned in #32, apparently in passing, without being directly suggested (emphasis added):
Global
— There was discussion of this, but it was thrown out because the pascal-cased names are supposed to be reserved for constructors and for namespaces. But when you think about the 99% use case for people, the "global reference" is always for namespacing reasons, and it is often referred to as the "global namespace". So to me it seems like an extremely relevant naming choice.
So it seems to be a relatively natural term that doesn't use "this" and doesn't call it a global "object", "scope", "context" or anything else that might be misleading, since like all object variables it is indeed a reference.
As for web compatibility though, I don't know - I can only say anecdotally I've not seen it used.
I haven't been following this proposal TBH, so I might be missing something, but this confuses me:
@ljharb
globalThis is the global this value, which applies to sloppy mode Scripts, the Function constructor even in modules, and the upcoming Realms API - it’s not the global object, and being correct (not merely pedantic) is important.
Is it not the purpose of this proposal to be able to access the global object? I assume what you are referring is the following (from InitializeHostDefinedRealm
):
If the host requires that the
this
binding in realm's global scope return an object other than the global object, letthisValue
be such an object created in an implementation-defined manner. Otherwise, letthisValue
beundefined
, indicating that realm's global this binding should be the global object.
ATM there don't seem to be any requirements imposed by the spec onto the relationship between the global this and the global object. Is this going to change?
Because if an implementation decides to use different values for this
and the global object, I don't see why I would want to access globalThis
?
Another thing I want to point, even though I know that non-normative sections are not .... well ... normative, the fact that the spec contains the following statement probably isn't helping the discussion:
This global object is the value returned by the global Environment Record's GetThisBinding concrete method.
https://www.ecma-international.org/ecma-262/9.0/#sec-global-environment-records
@fkling due to browser concerns all global property access should go through WindowProxy not the Realm's global object which is the Window, see https://github.com/tc39/ecma262/issues/1200 for an example of this being brought up.
@bmeck, I think I understand that. Global this
is WindowProxy
which forwards property access to global object (Window
). So using globalThis
in a browser context makes sense.
However, afaik, the spec currently does not require property access to be forwarded from the global this
value to the global object. In an environment where this doesn't happen, globalThis
doesn't seem useful and as such doesn't actually provide an environment independent way to access global variables (which is the goal of this proposal?).
Or am I missing something?
@fkling global variables are different from global properties since they are not on the global this nor the global object actually and this is where we get more into the weeds. This proposal is about exposing the intended view of the global namespace of properties not variable inspection. I'll leave this as an example of how to see the difference in global variables vs properties:
$ node
> let a = 1
undefined
> a
1
> global.a
undefined
When we talk about non-browser environments, there are none that I know of that differentiate the global object and the global this value such that they are different.
@bmeck I guess I was referring to "global properties" then.
When we talk about non-browser environments, there are none that I know of that differentiate the global object and the global this value such that they are different.
So this proposal assumes that
this
to global objecteven though neither is enforced in the spec? If that's the case it should at least be pointed out or it should be made clear that there are plans to amend the spec.
Either way, it seems that the argument for using the name globalThis
was that the global this
value and the global object are different. Yet it also seems the proposal assumes that the global this
value somehow proxies the global object. This seems almost contradictory.
Naming is hard.
I would just like to voice my support for something other than globalThis
, if only because its very naming carries JS design debt into the foreseeable future. Explaining what globalThis
means and how it got to be is a 200+ word essay that new JS users are likely not to understand. Additionally, the very name itself is contradictory: global
in this context implies a singleton, whereas this
implies one of many, i.e. this scope, this object, this planet that we live on. So at face value, it seems to mean "one global singleton" which really feels messy.
I understand how it got this way but I strongly believe new language proposals should feel like they are making the language more approachable rather than less. JS got to its massive level of acceptance in large part because it was a small, approachable language.
It's obvious that the community is resisting this change. As it is not yet shipped in mainline versions nor accepted into the spec it is a perfect time to demonstrate that this body embraces the community, rather than proceeding on without them. The cost of going back to the drawing board is minimal. The cost of alienating the community is high.
@ljharb: I think this is a good opportunity for you and TC39 to consider how community feedback is solicited and handled. In particular, these comments are contradictory and make us feel shut-out:
https://github.com/tc39/proposal-global/issues/31#issuecomment-442737125
I don't think I've offered a tone or wording of "it's been decided, get over it" here,
https://github.com/tc39/proposal-global/issues/32#issuecomment-442734194
@ianstormtaylor it's a bit late for suggestions, as we've already selected the name globalThis, vetted its web compatibility, and it's already beginning to ship in browsers. In other words, the final decision has effectively been made.
Given the upcoming Realms API and especially https://github.com/tc39/proposal-realms#example-simple-realm, why not rootRealm
? Realms are forward-looking. globalThis
looks toward the past.
I know it’s late, but please reconsider the name
globalThis
:this
has always been a topic that mystifies programmers, especially those who are new to JavaScript. There is a constant stream of blog posts about it.this
inside method definitions.globalThis
doesn’t even refer to an existing concept.The name
globalThis
would makethis
more complicated again.One possibility (but I’m OK with anything that doesn’t have
this
in it):globalObject
– that’s what it’s always been called.global*
is not really the global object, but I don’t find it helpful to be pedantic in this case.