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?
-
1this possibly refers to window herehop– hop2013年03月19日 18:07:32 +00:00Commented Mar 19, 2013 at 18:07
4 Answers 4
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.
Comments
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.
Comments
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
Comments
this refers to the object context of the call.
In your case it is window.katana();
So this refers to window