I've tried looking in the ES6 draft myself, but I'm not sure where to look:
Can someone tell me if this
in ES6 necessarily refers to the global object? Also, will this object have same members as the global scope?
If you could answer for ES5 that would be helpful as well.
I know this
in global scope refers to the global object in the browser and in most other ES environments, like Node. I just want to know if that's the defined behavior by the spec or if that's extended behavior that implementers have added (and if this behavior will continue in ES6 implementations). In addition, is the global object always the same thing as the global scope? Or are there distinctions?
Update - Why I want to know: I am basically trying to figure out how to get the global object reliably in ES5 & 6. I can't rely on window
because that's specific to the browser, nor can I rely on global
because that's specific to environments like Node. I know this
in Node can refer to module
in module scope, but I think it still refers to global
in global scope. I want a cross-environment ES5 & 6 compliant way to get the global object (if possible). It seems like in all the environments I know of this
in global scope does that, but I want to know if it's part of the actual spec (and so reliable across any environment that I may not be familiar with).
I also need to know if the global scope and the global object are the same thing by the spec. In other words will all variables in global scope be the same as globalobject.variable_name
?
Update 2 - What I'm trying to do:
I have developed some ES6 shims for ES5 environments. I want to know the best way to (1) check to see if the ES6 built-ins already exist so that they can be used when possible instead of my shims, and (2) add my shims to the global scope if the built-ins do not already exist.
Currently I'm following this pattern:
(function() {
// Indirect eval to run in global scope.
// (We get whatever "this" is in global scope, hoping that it's the global object...
// Whether this line does what I want it to is the crux of my question.)
var global = (0, eval)('this');
// If Symbol does not already exist in global scope,
if (!global.Symbol)
// Then add Symbol to global scope.
global.Symbol = (function() {
// ...
// Return my Symbol shim
})();
})();
There are some other possibilities for (1), but at the end of the day I need a way to add something to global scope without using var
in global scope (because that would override the built-ins before I can check for them, due to var
hoisting [at least in the naive case, perhaps I could indirect eval
a var
statement as well?]). I want my code to be able to run in strict mode, so that compounds the problem.
I have discovered that, by the ES5 spec, indirect eval
executes code in global scope. So I am at least able to do that. My questions are if I get this
in global scope, (1) Will checking the properties of that object let me know if a built-in already exists in global scope? and (2) Will adding properties to that object allow me to add variables to global scope?
Yes,
this
in global scope will continue to refer to the global object in ES6. (Generally, ES6 is supposed to be fully backwards compatible, i.e. any code that was guaranteed to work in ES5 should also work in ES6).The notion of "global scope", however, will no longer be identical with the global object in ES6. It introduces new declaration forms that are lexically scoped (
let
,const
,class
,module
, and a few more). The conclusion at the last meeting was that none of these will appear as properties of the global object. There is a variety of technical and methodological reasons for that, but the bottom line is that it is best to avoid using the global object directly altogether (this has always been true, but is even more so in ES6).Is there something specific you need the global object for?
Mostly yes.
Passing
this
in any non-object (or non-setthis
) will refer to the global object:This behavior is intended to stay in ES6 (for understandable backward compatibility issues). And that's how most of multiplatform (Browser/Node) plugins I know of are accessing the global object. For example: https://github.com/documentcloud/underscore/blob/master/underscore.js#L12
Although, it's true that plugin on the server only access
this
as beingmodule
(which is exported). But, that's what you want in node. Your global space isn't cleaned up ever (except if done manually, or on server restart). So it's shared between all client connections; assigning anything to the global space is really not a good idea.The only notable difference in how
this
is handled between javascript "version" is instrict mode
, where it will throw an error is ifnull
orundefined
is passed tocall
orapply
orbind
(in the position of thethis value
). In un-strict mode,this
was only coerced to the global object.Hope this help!