Putting `global` reference in specs

# Andrea Giammarchi (9 years ago)

We have window in DOM land, self in Workers, and global in most common server side JS engines ... plus we have this in ES6 specification:

In addition to the properties defined in this specification the global

object may have additional host defined properties. This may include a property whose value is the global object itself; for example, in the HTML document object model the window property of the global object is the global object itself.

Now, accordingly with this madness:

8.5 millions checks for typeof global search?q='typeof+global'&type=Code&ref=searchresults&utf8=

14.1 millions checks for typeof window search?q='typeof+window'&type=Code&ref=searchresults&utf8=

Does anyone have a concrete reason for NOT specifying global as reference to whatever window or self reference already?

I've suggested to stick this on top of every wen page:

<script>var global=global||this;</script>

and this on top of every Worker

var global=global||this;

But I'm pretty sure if ECMAScript would have that in specs we might see the end of the debate and the infamouse typeof window or typeof global check.

Thanks in advance for thoughts

# Boris Zbarsky (9 years ago)

On 4/17/15 10:55 AM, Andrea Giammarchi wrote:

We have window in DOM land, self in Workers

We have self in DOM land too, so you can consistently use self across Window and Workers.

and global in most common server side JS engines

Sounds like they should add self. ;)

# Kevin Smith (9 years ago)

We have self in DOM land too, so you can consistently use self across Window and Workers.

Why didn't I know this!? Cool : )

and global in most common server side JS engines

Sounds like they should add self. ;)

That would make sense.

# Andrea Giammarchi (9 years ago)

I know that, reason JSLint complains when used internally instead of that, but self is the most misleading name ever for whoever comes from Python and PHP or mostly any other language + self is nowehere in ECMAScript specifications.

So I'd say we should not have self (if stays on global and Worker I don't actually care) and add a global that nobody needs explanation to understand what it is in JavaScript

# Anne van Kesteren (9 years ago)

On Fri, Apr 17, 2015 at 5:12 PM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:

So I'd say we should not have self (if stays on global and Worker I don't actually care) and add a global that nobody needs explanation to understand what it is in JavaScript

Indeed, three ways to reference the global object is not nearly enough.

# Andrea Giammarchi (9 years ago)

there's actually no way, officially, to reference what ES2015 call the global object, just pointless fragmentation between engines.

# Mark S. Miller (9 years ago)

(1,eval)('"use strict"; this')

# Boris Zbarsky (9 years ago)

On 4/17/15 11:27 AM, Mark S. Miller wrote:

(1,eval)('"use strict"; this')

This has the drawback of making eyes bleed, but the benefit of working reliably (unlike "window", "self", or "global").... ;)

# Andreas Rossberg (9 years ago)

On 17 April 2015 at 17:27, Mark S. Miller <erights at google.com> wrote:

(1,eval)('"use strict"; this')

Is the 'use strict' relevant here? Seems overkill.

# Andrea Giammarchi (9 years ago)

it's a no-go under CSP so it's as bad as Function('return this')()

# Mark S. Miller (9 years ago)

I almost omitted it, but one should never need to encounter or think about sloppy code unless absolutely necessary. For my brain, adding the "use strict"; makes this snippet of code much simpler.

# Andrea Giammarchi (9 years ago)

also eval can be in-scope redefined as much as global, window, or self, so no, that's actually not a solution.

Btw, I wasn't asking for a workaround, I was proposing to officially bring ES 2015 global object as language reference in ES7/201X

It's a very tiny improvement for every developer benefit ( 8.5 + 14.1 millions of results in Github for typeof global apparently got unnoticed )

# Mark S. Miller (9 years ago)

On Fri, Apr 17, 2015 at 8:33 AM, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote:

it's a no-go under CSP so it's as bad as Function('return this')()

Precisely. Which raises an interesting point. Does anyone know of a precise statement of the actual threat model that CSP's "no eval" is suppose to protect against?

The reason I ask is that I suspect that there's no valid reason for SES's "eval", "confine", and "Function" to be disabled by CSP's no-eval mode. Indeed, SES-with-eval is much safer for most purposes than JS-without-eval.

# Alex Kocharin (9 years ago)

An HTML attachment was scrubbed... URL: esdiscuss/attachments/20150417/4a58088c/attachment

# Mark S. Miller (9 years ago)

On Fri, Apr 17, 2015 at 8:39 AM, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote:

also eval can be in-scope redefined as much as global, window, or self, so no, that's actually not a solution.

Btw, I wasn't asking for a workaround, I was proposing to officially bring ES 2015 global object as language reference in ES7/201X

In an unshadowable manner? Never gonna happen. Everything that provides authority must be virtualizable.

# Glen Huang (9 years ago)

You guys are talking about referencing the global object in modules right? Since in scripts you can reliably get hold of the global object by using "this" in the root scope.

And es 2015 made an explicit choice to clobber "this" in the root scope of a module, I guess that means module code really isn't supposed to get hold of the global object?

# Mark Miller (9 years ago)

This is one of several cases where, post ES6, we can provide a std module import that provides a built-in that carries authority. Another example is the constructor for making weak references, which necessarily provide the ability to read a covert channel. As with shadowable globals, this module import must be easy to virtualize. We purposely postponed this along with the Loader and Realm API as it is security sensitive and we don't yet have enough usage experience with modules to know how to design this separation well.

In particular, we rejected the obvious Reflect.global as it bundles the global together with authority-free safe things, which makes virtualization of the global alone needlessly unpleasant.

# Mameri, Fred (HBO) (9 years ago)

At some point in the past, I proposed that we introduce syntax for that. In my proposal, prefixing an identifier with a "." would create an unambiguous reference to the global version of that variable.

For example:

var x;
function f(x) {
   x; // local
   .x; // global
}

This is an idea I borrowed from C++'s :: operator.

From: Mark Miller <erights at gmail.com<mailto:erights at gmail.com>>

Date: Friday, April 17, 2015 at 8:53 AM To: Glen Huang <curvedmark at gmail.com<mailto:curvedmark at gmail.com>>

Cc: "Mark S. Miller" <erights at google.com<mailto:erights at google.com>>, "es-discuss at mozilla.org<mailto:es-discuss at mozilla.org>" <es-discuss at mozilla.org<mailto:es-discuss at mozilla.org>>

Subject: Re: Putting global reference in specs

This is one of several cases where, post ES6, we can provide a std module import that provides a built-in that carries authority. Another example is the constructor for making weak references, which necessarily provide the ability to read a covert channel. As with shadowable globals, this module import must be easy to virtualize. We purposely postponed this along with the Loader and Realm API as it is security sensitive and we don't yet have enough usage experience with modules to know how to design this separation well.

In particular, we rejected the obvious Reflect.global as it bundles the global together with authority-free safe things, which makes virtualization of the global alone needlessly unpleasant.

On Fri, Apr 17, 2015 at 8:45 AM, Glen Huang <curvedmark at gmail.com<mailto:curvedmark at gmail.com>> wrote:

You guys are talking about referencing the global object in modules right? Since in scripts you can reliably get hold of the global object by using "this" in the root scope.

And es 2015 made an explicit choice to clobber "this" in the root scope of a module, I guess that means module code really isn't supposed to get hold of the global object?

On Apr 17, 2015, at 11:34 PM, Mark S. Miller <erights at google.com<mailto:erights at google.com>> wrote:

I almost omitted it, but one should never need to encounter or think about sloppy code unless absolutely necessary. For my brain, adding the "use strict"; makes this snippet of code much simpler.

On Fri, Apr 17, 2015 at 8:30 AM, Andreas Rossberg <rossberg at google.com<mailto:rossberg at google.com>> wrote:

On 17 April 2015 at 17:27, Mark S. Miller <erights at google.com<mailto:erights at google.com>> wrote: (1,eval)('"use strict"; this')

Is the 'use strict' relevant here? Seems overkill.

/Andreas

On Fri, Apr 17, 2015 at 8:23 AM, Andrea Giammarchi <andrea.giammarchi at gmail.com<mailto:andrea.giammarchi at gmail.com>> wrote:

there's actually no way, officially, to reference what ES2015 call the global object, just pointless fragmentation between engines.

On Fri, Apr 17, 2015 at 4:19 PM, Anne van Kesteren <annevk at annevk.nl<mailto:annevk at annevk.nl>> wrote:

On Fri, Apr 17, 2015 at 5:12 PM, Andrea Giammarchi <andrea.giammarchi at gmail.com<mailto:andrea.giammarchi at gmail.com>> wrote:

So I'd say we should not have self (if stays on global and Worker I don't actually care) and add a global that nobody needs explanation to understand what it is in JavaScript

Indeed, three ways to reference the global object is not nearly enough.

-- annevankesteren.nl

# Mark S. Miller (9 years ago)

Which would have made virtualization without translation impossible. Glad we dodged that bullet ;).

# Andrea Giammarchi (9 years ago)

I've never said unshadowable ... I am saying that global should be a global reference to the global object which is mentioned in ES6/2015 but it's not specified how it should be referenced. window is not welcome even in DOM tools like browserify, global is ubiquitous in its meaning, it does not confuse anyone like a self in node.js or others would do, and it will solve forever the hassle of referencing by deafault a global object without needing to eval, Function('return this'), [].sort(), or whatever wizardy you coudl came up to retrieve and/or reference the global object.

It's deadly simple: whatever freedom implementors have to put window and/or self in, they MUST put a global reference too ... that will make everything else redundant, in the long term, and not vice-versa

Is this really that complicated to ship?

# Jonathan Bond-Caron (9 years ago)

Not so pretty but: import * as global from “@global”;

Or some bindings: import {Promise} from “@global”;

From: es-discuss [mailto:es-discuss-bounces at mozilla.org] On Behalf Of Mark Miller Sent: April 17, 2015 11:53 AM To: Glen Huang Cc: Mark S. Miller; es-discuss at mozilla.org Subject: Re: Putting global reference in specs

This is one of several cases where, post ES6, we can provide a std module import that provides a built-in that carries authority. Another example is the constructor for making weak references, which necessarily provide the ability to read a covert channel. As with shadowable globals, this module import must be easy to virtualize. We purposely postponed this along with the Loader and Realm API as it is security sensitive and we don't yet have enough usage experience with modules to know how to design this separation well.

In particular, we rejected the obvious Reflect.global as it bundles the global together with authority-free safe things, which makes virtualization of the global alone needlessly unpleasant.

On Fri, Apr 17, 2015 at 8:45 AM, Glen Huang <curvedmark at gmail.com<mailto:curvedmark at gmail.com>> wrote:

You guys are talking about referencing the global object in modules right? Since in scripts you can reliably get hold of the global object by using "this" in the root scope.

And es 2015 made an explicit choice to clobber "this" in the root scope of a module, I guess that means module code really isn't supposed to get hold of the global object?

On Apr 17, 2015, at 11:34 PM, Mark S. Miller <erights at google.com<mailto:erights at google.com>> wrote:

I almost omitted it, but one should never need to encounter or think about sloppy code unless absolutely necessary. For my brain, adding the "use strict"; makes this snippet of code much simpler.

On Fri, Apr 17, 2015 at 8:30 AM, Andreas Rossberg <rossberg at google.com<mailto:rossberg at google.com>> wrote:

On 17 April 2015 at 17:27, Mark S. Miller <erights at google.com<mailto:erights at google.com>> wrote: (1,eval)('"use strict"; this')

Is the 'use strict' relevant here? Seems overkill.

/Andreas

On Fri, Apr 17, 2015 at 8:23 AM, Andrea Giammarchi <andrea.giammarchi at gmail.com<mailto:andrea.giammarchi at gmail.com>> wrote:

there's actually no way, officially, to reference what ES2015 call the global object, just pointless fragmentation between engines.

On Fri, Apr 17, 2015 at 4:19 PM, Anne van Kesteren <annevk at annevk.nl<mailto:annevk at annevk.nl>> wrote:

On Fri, Apr 17, 2015 at 5:12 PM, Andrea Giammarchi <andrea.giammarchi at gmail.com<mailto:andrea.giammarchi at gmail.com>> wrote:

So I'd say we should not have self (if stays on global and Worker I don't actually care) and add a global that nobody needs explanation to understand what it is in JavaScript

Indeed, three ways to reference the global object is not nearly enough.

-- annevankesteren.nl

# Mark S. Miller (9 years ago)

Yes, something like that is quite plausible. Note though the difference. Promise is an authority-free safe thing stdized as a global primordial by the ES spec, with a behavior spec'ed by the ES spec. Although one might still wish to virtualize it, the reasons are very different.

# Mark S. Miller (9 years ago)

On Fri, Apr 17, 2015 at 9:05 AM, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote:

I've never said unshadowable ...

You did:

# Andrea Giammarchi (9 years ago)

oh ... that one, it was for Boris who wrote:

This has the drawback of making eyes bleed, but the benefit of working

reliably (unlike "window", "self", or "global").... ;)

I meant that your eval wasn't more reliable than window, self, or global, because ot could have been redefined as well ... but this is not about shadowability, it's about having one name that fits in every JS situation: server, worker, document

global instead of window and/or self is a clear win for everyone, being curse forever to check it typeof window or typeof global is not undefined is ... well, the most basic and striking fragmentation case we have at the root of the language ^_^

# Domenic Denicola (9 years ago)

One thing I'm surprised nobody has brought up yet is that "global" would be an incorrect name in the case of browsers. The actual global object is not (and must never be) directly accessible. Instead you get a window proxy when you use window, self, this, etc.

As such I think our best bet is for server-side JS runtimes to use self or window.

The latter isn't as crazy as it sounds: just start adding phrases to the ES spec like "all JavaScript code runs within a certain context, called a window, which has a corresponding window object. In some runtimes the window object will be equivalent to the global object, but not always. Scripts run within window scope, whereas modules run in their own lexical context. The value of this in window scope is the window object."

It's not as if window actually means "window" anymore, given tabs and iframes and frames. We might as well move it into the set of terms like "realm" or "vat" or "environment" that are more abstract than real.

# Andrea Giammarchi (9 years ago)

As such I think our best bet is for server-side JS runtimes to use self

or window.

I personally hope that would never happen, and you managed to over-engineer the simplest alignment requirement I could possibly think of ... indeed ...

We might as well move it into the set of terms like "realm" or "vat" or "environment" that are more abstract than real.

a new term like realm will just create more fragmentation =>

xkcd.com/927 + there's no such thing on server side, at least not the same there is on front end

vat is at least semantic in this case since it means Value-Added Tax ... but I am back to previous point

environment is confusing with process.env

Let's avoid the introduction of more problems please ... I rather leave things as it is since we are unable to be pragmatic, no matter how straight forward is the solution.

# Calvin Metcalf (9 years ago)

This came up in iojs, did not go over well. iojs/io.js#1043

# Brendan Eich (9 years ago)

Just for historians who might not know, when I did ur-JS in 1995, I made multiple names for the global, in part because event handlers (which prefigured nested functions in general, and added with-like DOM object scoping -- a regret); but also in part because <a target="_self"> was a

thing in Netscape 2.

# Andrea Giammarchi (9 years ago)

And that's indeed the only place on Web world where self makes sense: it's referring to the frame (scoped) context its running, not to the top (global) tab wrapper.

# Brendan Eich (9 years ago)

The principle extends just fine to workers, and has.

# Jordan Harband (9 years ago)

I was under the impression there'd been some interest in a Reflect.global() as a uniform method of providing the global object, or a proxy to one, in all engines. That would be something that's easily polyfilled back as far as we like, would allow most code that currently relies on indirect eval to work in a CSP environment (including the es6-shim), and would not impose any new global variables, nor any restrictions on global variables, on existing engines.

Is there some reason that a Reflect function (or accessor, but I'd prefer a function for ES3 engine support) wouldn't be an option?

# Andrea Giammarchi (9 years ago)

Sure workers too, but it doesn't in server side and it doesn't mean anything meaningful for all developers coming from other languages. self is a misleading word and in ES6 specs we have mentioned global object and never a single word for the self keyword, or its meaning.

global does not need that kind of explanation you put down for historical purpose, global is well known meaning for everyone in JS world, including members in this ML that would refer to the global scope, and the global object, regardless they mean sometimes realm ... or isn't it?

# Brendan Eich (9 years ago)

Jordan Harband wrote:

Is there some reason that a Reflect function (or accessor, but I'd prefer a function for ES3 engine support) wouldn't be an option?

Upthread: esdiscuss.org/topic/putting-global-reference-in-specs#content

# Brendan Eich (9 years ago)

We cannot introduce a global property named global at this point.

I don't think everyone replying lately has read the whole thread carefully :-|.

# Andrea Giammarchi (9 years ago)

at this point you mean it will never be introduced, not even as alias in ES7 or ES8, do I understand correctly?

Best