I was under the impression that the "this" keyword represents the current owner that is in scope. Obviously, this is wrong. Let me get to the code:
alert(this); // alerts as [object Window] -- Okay
function p1() {
alert(this);
}
var p2 = function() {
alert(this);
}
p1(); // alerts as undefined -- ???
p2(); // alerts as undefined -- ??
window.p1(); // alerts as [object Window] -- Okay
window.p2(); // alerts as [object Window] -- Okay
The code above first alerts [object Window], as I would expect but then the next two calls to p1() and p2() alert "this" as "undefined". The final two calls to p1() and p2() alert "this" as [object Window].
Isn't it the case that p1() and p2() exist in the global (i.e., window) scope? I thought that calling window.p1() is synonymous with calling p1(), just like calling alert() is synonymous with window.alert().
To my (C#) way of thinking, p1() and p2() are in the global scope. These functions are members of the global window object so when they refer to "this" they should be referring to [object Window]. Obviously, I'm very wrong here.
Becasue you are using strict mode
and as per the spec:
If this is evaluated within strict mode code, then the this value is not coerced to an object.
The code you have does alert
window
in all instances of alert, but because you are in strict mode, it is undefined
(as it should be)
UPDATE: chrome dev tools alerts window
not undefined
, however if you wrap it in a self executing function you get undefined
as expected
(function(){
'use strict';
alert(this);
}());
When you call a function like foo()
, then the value of this
depends on whether the code runs in strict mode or not (the default actually).
In strict mode, this
will be undefined
(as you already found out).
In "loose mode" this
will indeed refer to window
, but that's not because the functions are global, i.e. "owned" by the global scope. You get the same behavior for local functions:
(function() {
function foo() {
console.log(this); // logs the window object, but `foo` is not global
}
foo();
}());
This is simply an explicitly defined behavior:
- If the function code is strict code, set the ThisBinding to thisArg.
- Else if thisArg is null or undefined, set the ThisBinding to the global object.
- Else if Type(thisArg) is not Object, set the ThisBinding to ToObject(thisArg). ...
As you can see, in "loose" mode, if thisArg
is undefined
, which is the case if you call the function "normally" as foo()
, then it will be set to window
explicitly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With