Taken from ejohn.org:
function katana(){
this.isSharp = true;
}
katana();
assert( isSharp === true, "A global object now exists with that name and value." );
This comes out as true.
Could anyone explain this?
Inside the function we see this.isSharp = true
, doesn't that create an object
which should have the propery isSharp
, and its value would be true
? (I would think the object is katana, since it calls the function, so katana.isSharp
would be true
).
In other words, what exactly does the this
refer to?
How come isSharp
is created as an object?
this
is really wonky in JavaScript.
this
is determined based on the context surrounding a function call, not as a property of the function. If a function is called like this:
f()
then this
will refer to the global object. Adding a property to the global object is equivalent to adding a global variable, as you saw happen. If a function is called like this:
foo.f()
then this
will refer to foo
. Example:
> function printx() { console.log(this.x); }
> x = 300
> obj1 = {x: 20, printx: printx};
> obj2 = {x: 50, printx: printx};
> printx();
300
> obj1.printx();
20
> obj2.printx();
50
Finally, if a function is called like this:
new f()
then a new object is created, this
refers to that new object, and the expression new f()
evaluates to either that new object, or the object returned by f()
if f()
returns an object.
It's all in the spec. Very weird.
You don't use new
, so this
is the global object (window
) in the function.
katana();
is really
window.katana(); // the passed context is window
That's why the assertion isSharp===true
, which tests in fact window.isSharp
, returns true
.
If you want to create a new instance of katana
, use new katana()
, and then this
will be the new instance inside the function, leaving window.isSharp
untouched.
doesn't that create an object which should have the propery isSharp, and its value would be true?
No, because the function was not invoked as a constructor. If you had var obj = new katana()
, then you'd get an object with an isSharp
property. Otherwise, it's just a function call, so what should this
be? JavaScript doesn't know, so it decides it's undefined and falls back to the global object (unless in strict mode).
Determining the value of this
inside functions in JavaScript can be confusing, because it's determined dynamically, depending on how the function is called. The basic rules are, this
will be the global object unless:
- the function is called as an object method (then this will be the object), or
- the function is called as a constructor, with the new operator (in which case this will point to the new object being constructed)
More details on MDN
this
refers to the object context of the call.
In your case it is window.katana();
So this
refers to window