javascript "use strict" and Nick's find global function - javascript

So I saw a function that was, quite frankly beautiful in its simplicity as it allowed you to find the global object ( which depending on environ at the time may NOT have been window ) while within an anonymous function; however when you throw javascripts' "use strict"; mode it crumbles, due to the evaluation of the keyword 'this' changing. There were a few ways to accomplish this?
(function () {
var win = function () {
return (function () {
return this;
}());
};
//win now points to the global object no matter where it is called.
}());
Now, if these are called within the context of "use strict" we lose the functionality described, is there any equivalent that can be done in ES5 strict mode?
For reference
(function () {
"use strict"
//code here is in strict mode
}())

Access to the Global Object (before ES5)
If you need to access the global object without hard-coding the identifier window, you can do the following from any level of nested function scope:
var global = (function () {
return this;
}());
This way you can always get the global object, because inside functions that were invoked
as functions (that is, not as constrictors with new) this should always point to
the global object.
This is actually no longer the case in ECMAScript 5 in strict mode,
so you have to adopt a different pattern when your code is in strict mode.
For example,
if you’re developing a library, you can wrap your library code in an immediate function
(discussed in Chapter 4) and then from the global scope, pass a reference to this as a
parameter to your immediate function.
Access to the Global Object (after ES5)
Commonly, the global object is passed as an argument to the immediate function so
that it’s accessible inside of the function without having to use window: this way makes
the code more interoperable in environments outside the browser:
(function (global) {
// access the global object via `global`
}(this));
“JavaScript Patterns, by Stoyan Stefanov
(O’Reilly). Copyright 2010 Yahoo!, Inc., 9780596806750.”

Solution:
var global = Function('return this')();
Works in all Browsers, Engines, ES3, ES5, strict, nested scope, etc.
A slight variation will pass JSLINT:
var FN = Function, global = FN('return this')();
Discussion
See How to get the global object in JavaScript?

Here's a snippet from Perfection Kills, using global eval.
var root = (function () {
return this || (0 || eval)('this');
}());
ECMA3, ECMA5, Strict mode, etc compatible, passes JSLint.

Related

Chrome: Javascript replaces `undefined` by `window` in "this" context [duplicate]

I'm trying to understand what rule for "this" that "use strict"; modifies in the below case.
After reading (http://unschooled.org/2012/03/understanding-javascript-this/) my best guess is that since the functon isStrictModeOn() is not "attached" to anything, this refers to null. Which is suppose to be a more sensible alternative to Javascript just attaching the this to the global object. Is that the correct interpretation of the change that "use strict" is making in this case?
http://www.novogeek.com/post/ECMAScript-5-Strict-mode-support-in-browsers-What-does-this-mean.aspx
function isStrictMode(){
return !this;
}
//returns false, since 'this' refers to global object and '!this' becomes false
function isStrictModeOn(){
"use strict";
return !this;
}
//returns true, since in strict mode, the keyword 'this' does not refer to global object, unlike traditional JS. So here,'this' is null and '!this' becomes true.
That's almost correct. In strict mode, when a function is invoked without a receiver then this is undefined (not null). A better version of that function would be:
function isStrict() {
"use strict";
return (typeof this) === 'undefined';
}
An inherent problem with functions like that is that "strictness" is determined lexically, like scope, so it's static. A tester function that includes its own "use strict"; isn't very useful; it really only tells you whether the JavaScript runtime understands strict mode. One without its own "use strict"; tells you whether the lexical context in which it's defined is in strict mode. That is:
function isStrict() {
function test() {
return (typeof this) === 'undefined';
}
return test();
}
will tell you, when called, whether a "use strict"; was in effect for the scope at which the function is defined. I guess that could be useful. However, if a reference to that function "leaks" into some other context whose "strictness" differs, it's going to continue to report on its static strictness at the point of its definition.
Personally, I would opt for simply ensuring that my code is definitely in strict mode by invoking "use strict"; at the outermost layer possible. That way there's really no need to check for it.

What does "this" mean in this revealing module pattern

var abc=(function(){
var self=this;
return {
self:self
}
})();
When doing abc.self I get undefined what does this happen to be in this context.
What you have can be simplified for the purpose of the explanation in
(function(){ console.log(this) })();
Your expression (in the first set of parenthesis) defines a function. You then call this function without context (the this). This construct is called an IIFE. As you don't pass a context, the behavior depends whether it is called in strict mode or not :
In non strict mode, you would have the global object (window in a browser, global in node).
In strict mode, a missing context of a function call isn't replaced, it's undefined.
As you get undefined, I guess you're in strict mode. You probably have "use strict"; at the start of the file or in an enclosing function.
If you wanted to pass a context, you might for example have done
(function(){ console.log(this) }).call(someobject);
in that "root scope" this is window
and
console.log(abc.self);
results for me in
Window {top: Window, window: Window, ...}
this refers to the current object. In your condition this will be window, and as you're trying to get the value abc.self, you need to use like this:
this.self = this;
Now, only you can get the value:
var xyz = new abc();
xyz.self
But to note, you cannot use abc as the constructor like above code because you are using the closure.

Javascript Pattern to access the global object [duplicate]

I want to check in a script if a certain other module is already loaded.
if (ModuleName) {
// extend this module
}
But if ModuleName doesn't exist, that throws.
If I knew what the Global Object was I could use that.
if (window.ModuleName) {
// extend this module
}
But since I want my module to work with both browsers and node, rhino, etc., I can't assume window.
As I understand it, this doesn't work in ES 5 with "use strict";
var MyGLOBAL = (function () {return this;}()); // MyGlobal becomes null
This will also fail with a thrown exception
var MyGLOBAL = window || GLOBAL
So it seems like I'm left with
try {
// Extend ModuleName
}
catch(ignore) {
}
None of these cases will pass JSLint.
Am I missing anything?
Well, you can use the typeof operator, and if the identifier doesn't exist in any place of the scope chain, it will not throw a ReferenceError, it will just return "undefined":
if (typeof ModuleName != 'undefined') {
//...
}
Remember also that the this value on Global code, refers to the global object, meaning that if your if statement is on the global context, you can simply check this.ModuleName.
About the (function () { return this; }()); technique, you are right, on strict mode the this value will simply be undefined.
Under strict mode there are two ways to get a reference to the Global object, no matter where you are:
Through the Function constructor:
var global = Function('return this')();
Functions created with the Function constructor don't inherit the strictness of the caller, they are strict only if they start their body with the 'use strict' directive, otherwise they are non-strict.
This method is compatible with any ES3 implementation.
Through an indirect eval call, for example:
"use strict";
var get = eval;
var global = get("this");
The above will work because in ES5, indirect calls to eval, use the global environment as both, the variable environment and lexical environment for the eval code.
See details on Entering Eval Code, Step 1.
But be aware that the last solution will not work on ES3 implementations, because an indirect call to eval on ES3 will use the variable and lexical environments of the caller as the environments for the eval code itself.
And at last, you may find useful to detect if strict mode is supported:
var isStrictSupported = (function () { "use strict"; return !this; })();
Update 2019
With all of today's Webpacks and Broccolis, and Gulps and Grunts, and TypeScripts and AltScripts, and create-react-apps, etc, this is pretty useless, but if you're just working with plain, old, VanillaJS and you want to make it isomorphic, this is probably your best option:
var global
try {
global = Function('return this')();
} catch(e) {
global = window;
}
The Function constructor invocation will work even when using --use_strict in node, as the Function constructor always executes in a global non-strict scope.
If the Function constructor fails, it's because you're in a browser with eval disabled by CSP headers.
Of course, with Deno on the way (the node replacement), they may also disallow the Function constructor, in which case it's back to enumerating objects like global, module, exports, globalThis and window, and then duck-type checking which is the global exhaustively... :-/
Crazy one-line solution (Original):
var global = Function('return this')() || (42, eval)('this');
.
.
.
Works
in every environment (that I tested)
in strict mode
and even in a nested scope
Update 2014-Sept-23
This can now fail if HTTP headers in the latest browsers explicitly forbid eval.
A workaround would be to try / catch the original solution as only browsers are known to run this type of subset of JavaScript.
var global;
try {
global = Function('return this')() || (42, eval)('this');
} catch(e) {
global = window;
}
Example:
---
(function () {
var global = Function('return this')() || (42, eval)('this');
console.log(global);
// es3 context is `global`, es5 is `null`
(function () {
"use strict";
var global = Function('return this')() || (42, eval)('this');
console.log(global);
}());
// es3 and es5 context is 'someNewContext'
(function () {
var global = Function('return this')() || (42, eval)('this');
console.log(global);
}).call('someNewContext');
}());
Tested:
---
* Chrome v12
* Node.JS v0.4.9
* Firefox v5
* MSIE 8
Why:
---
In short: it's some weird quirk. See the comments below (or the post above)
In `strict mode` `this` is never the global, but also in `strict mode` `eval` operates in a separate context in which `this` *is* always the global.
In non-strict mode `this` is the current context. If there is no current context, it assumes the global. An anonymous function has no context and hence in non-strict mode assumes the global.
Sub Rant:
There's a silly misfeature of JavaScript that 99.9% of the time just confuses people called the 'comma operator'.
var a = 0, b = 1;
a = 0, 1; // 1
(a = 0), 1; // 1
a = (0, 1); // 1
a = (42, eval); // eval
a('this'); // the global object
Why just don't simply use this in a global scope as param to a wrapper function, as follows?
(function (global) {
'use strict';
// Code
}(this));
Here you go :)
var globalObject = (function(){return this;})();
This should work from anywhere, for example from within another closure.
Edit - just read your post more carefully and saw the part about ES5 strict mode. Can anyone shed some more light on that? This has been the accepted way to get the the global object for as long as I can remember... I sure hope it doesn't end up getting broken.
Edit 2 - CMS' answer has more info on ES5 strict mode's treatment of this.
I think this is pretty much okay in rhino, node, browser and with jslint (without additional workaround flags) - would this help? Am I missing something?
x = 1;
(function(global){
"use strict";
console.log(global.x);
}(this));
Though I myself tend to use the window object and if I do need headless testing I can use env.js (rhino) or Phantom (node).
ECMAScript will be adding this to its standard soon:
https://github.com/tc39/proposal-global
Until its done, this is what's recommended:
var getGlobal = function () {
// the only reliable means to get the global object is
// `Function('return this')()`
// However, this causes CSP violations in Chrome apps.
if (typeof self !== 'undefined') { return self; }
if (typeof window !== 'undefined') { return window; }
if (typeof global !== 'undefined') { return global; }
throw new Error('unable to locate global object');
};
This is not passing jslint: var Fn = Function, global = Fn('return this')();
Try it yourself: http://www.jslint.com/
this will: var Fn = Function, global = new Fn('return this')();
But effectively those are same thing according to MDN:
Invoking the Function constructor as a function (without using the new operator) has the same effect as invoking it as a constructor.
This following solution works in:
Chrome
Node.JS
Firefox
MSIE
Web Workers
The code is:
(function (__global) {
// __global here points to the global object
})(typeof window !== "undefined" ? window :
typeof WorkerGlobalScope !== "undefined" ? self :
typeof global !== "undefined" ? global :
Function("return this;")());
You just need to change X for the name of the variable that you would like to
I had this problem before, I'm not happy with the solution, but it works and passes JSLint (assume browser|assume node):
"use strict";
var GLOBAL;
try{
/*BROWSER*/
GLOBAL = window;
}catch(e){
/*NODE*/
GLOBAL = global;
}
if(GLOBAL.GLOBAL !== GLOBAL){
throw new Error("library cannot find the global object");
}
once you have the GLOBAL var you can do your checking, and at the end of the script type
delete GLOBAL.GLOBAL;
Here's what I am using:
"use strict";
if(this && this.hasOwnProperty && !this.hasOwnProperty('globalScope')){
try {
globalScope = Function('return this')();
}catch(ex){
if(this.hasOwnProperty('window')){
globalScope = window;
}else{
throw 'globalScope not found';
}
}
}

node.js: Confusing usage of 'this' in the global scope

I've been toying with node.js lately and I ran into a weird behavior about the usage of this in the global scope of a module.
this is bound to module.exports in the global scope:
console.log(this === exports); // -> true
But this is bound to global in a method scope:
(function() { console.log(this === global); })(); // -> true
This also lead to this confusing behavior:
this.Foo = "Weird";
console.log(Foo); // -> throws undefined
(function() { this.Bar = "Weird"; })();
console.log(Bar); // -> "Weird"
I guess that the solution is to never use this in the global scope and explicitly use extends or global instead, but is there a logic behind all this or is it a bug or limitation in node.js?
The "logic" behind that is, that the value of this always depends on how a function is invoked.
In your case, you have a self-executing anonymous function, there, this always references the global object (non strict mode) or undefined (ES5 strict).
If you want to access the "outer" this value, you could either store a reference before executing that function, like
var outerScope = this;
(function() { outerScope.Bar = "Weird"; })();
console.log(Foo); // -> throws undefined
or re- .bind() the functions scope yourself, like
(function() { this.Bar = "Weird"; }).bind(this)();
In working on a simple CommonJS modules implementation, I had to think about what to do with this in the global scope of the module; it's not addressed by the spec.
I also set it up as the exports object at first, because I thought that would be useful, but later found some code I needed to "modulize" that was using this to get a handle to the global object, so I changed this back to the global object to provide as close of an environment to "normal" as possible for module code.
We can only guess at why node is set up the way it is (or ask the author), but my guess is it was done simply because it seemed like a useful idea, similar to the way you can give the module object an exports property in node and have it reflected in the module's actual exports (this behavior also isn't part of the spec, but doesn't go against it either).
As for the part of your question about this referencing global in functions, as the other answers explain, that's just the way this works; it's not a node-specific behavior, it's a weird javascript behavior.
I don't know if this is the exact intention of Node.js team, but I would be surprised if it was not. Consider this example ran in the dev console of a browser (e.g. chrome):
var x = function(){console.log(this)}
a = {}
a.x = x
a.xx = function(){x()}
a.x()
>> Object
a.xx()
>> DOMWindow
x()
>> DOMWindow
As you can see executing a method without specifying its context sets the context to be the global one. In this case the DOMWindow object.
When you are inside a module your context is the module, but executing a method in it without specifying a context with .call or .apply or obj. will use the global context, global, instead of the local one, module.exports.

Reason behind this self invoking anonymous function variant

While looking at code on github, I found the following:
(function() {
}).call(this);
This is clearly a self invoking anonymous function. But why is it written this way? I'm used to seeing the canonical variant (function() {})().
Is there any particular advantage to using .call(this) for a self invoking anonymous function?
Edit: It looks like some commonjs environments set this to a non-global value at the top level of a module. Which ones, and what do they set this to that you might want to preserve?
By default, invoking a function like (function(){/*...*/})() will set the value of this in the function to window (in a browser) irrespective of whatever the value of this may be in the enclosing context where the function was created.
Using call allows you to manually set the value of this to whatever you want. In this case, it is setting it to whatever the value of this is in the enclosing context.
Take this example:
var obj = {
foo:'bar'
};
(function() {
alert( this.foo ); // "bar"
}).call( obj );
http://jsfiddle.net/LWFAp/
You can see that we were able to manually set the value of this to the object referenced by the obj variable.
.call(this) (was actually just () until I changed it) ensures your top level this to be consistent through strict mode, --bare option and/or the running environment (where top level this doesn't point to global object).
By using:
> (function() {
> ...
> }).call(this);`
then this in the scope of the code (probaby the global object) is set as the function's this object. As far as I can tell, it's equivalent to:
(function(global) {
// global references the object passed in as *this*
// probably the global object
})(this);
In a browser, usually window is (or behaves as if it is) an alias for the global object.
C={
descript: "I'm C!<br>",
F: function() {
//set this to the caller context's 'this'
(function() {
document.write(this.descript);
}).call(this);
//set this to 'window' or 'undefined' depend the mode
(function() {
document.write(this.descript);
})();
//member function's 'this' is the object self
document.write(this.descript);
}
}
window.descript="I'm window!<br>";
C.F();
(function() {}).call(this); could set the this in the anonymous to the caller context this, in above is C.(function() {})(); will set this to window or undefined depend the mode.
Self-invoking function are useful to execute its content immediately when the script is loaded. This is convenient to initialize global scope elements.

Categories