Tested some js code in Chrome Dev Console and I'm a bit confused.
I know that in strict mode functions that are not methods of an object when referred to this keyword should receive undefined instead of global object.
function test(){
"use strict";
return this===undefined;}
test();
Outputs false.
"use strict";
function test(){
return this===undefined;}
test();
Still false.
(function test(){
"use strict";
return this===undefined;}());
Outputs true.
Just wanted to clarify. ʕ •ᴥ•ʔ I'm new to js.
-
2please read a similar question stackoverflow.com/questions/1335851/…Nick Andriopoulos– Nick Andriopoulos2013年02月28日 12:20:40 +00:00Commented Feb 28, 2013 at 12:20
-
4@hexblot this doesn't answer the question though...Christoph– Christoph2013年02月28日 12:37:00 +00:00Commented Feb 28, 2013 at 12:37
3 Answers 3
What you have noticed is simply a side-effect of the way the developer console works. When you enter code there, this is effectively what happens (see this answer for more details):
eval.call(null, "with (window) { \
function test() { \
'use strict'; \
console.log(this); \
} test(); \
}");
This is an indirect call to eval, which means it will always execute in the global execution context (in the browser, that's window).
Effectively, the function is bound to the global object and therefore this holds a reference to the global object, as if you did this in a web page (rather than in the console):
function test(){
"use strict";
return this === undefined;
}
test(); // true
test.call(window); // false
3 Comments
window is not an execution context. An execution context is an abstract program entity; it has a scope chain with objects in it. In this case, it would be the with statement that inserts the object referred to by window in the scope chain for the context of the test() call.window object belongs" but the way I put it was simpler and I think still gets the point across. And the with statement makes no difference in this case - it's the way that eval is called that affects the context in which its argument is evaluated.with statement here might be substantial; it certainly is if you assume (IMO mistakenly) that the window host property of the global object always refers to the global object. Because then the test() call would be equivalent to global.window.test(), where global would be a stand-in for the standard reference to the global object.It is a bug in the Chromium Developer Console that causes this to still refer to the global object. The same code works as specified with javascript: in the location bar, and in documents.
You can test that like so (2 console inputs):
var global = (function () { return this; }());
"use strict";
function test () { return this === global; }
test();
and (one or more console inputs)
var script = document.createElement("script");
script.type = "text/javascript";
script.appendChild(document.createTextNode(
'function test () { "use strict"; return this === undefined; }; console.log(test());'
));
document.body.appendChild(script);
Tested in Chromium Version 25.0.1364.97 Debian 7.0 (183676).
2 Comments
true, because "use strict" must be the first line in it's scope. Your example has it coming after var global ..., so the directive is ignored (as per the spec).debugger; in the function to inspect the call stack.Everything's fine. If you run your code via some HTML page (not a dev console), results meet expectations (always this===undefined).
Additionally in latest Firefox (Firebug):
function test(){
"use strict";
return this===undefined;}
test();
>> true
So this seems to be just another Chrome's bug (feature?). It feels like it has a slightly different approach to the code that is passed via dev console.
Also note that order matters:
<script>
console.log( 'Me First!' );
"use strict";
function test(){
console.log( this );
}
test();
</script>
>>> "Me First!"
>>> Window {top: Window, window: Window, location: Location, external: Object, chrome: Object...}
But:
<script>
"use strict";
console.log( 'Me later!' );
function test(){
console.log( this );
}
test();
</script>
>>> undefined
>>> "Me later!"