"this" keyword in Object method points to Window
var name = 'The Window';
var object = {
name: 'My Object',
getNameFunc: function(){
return function() {
return this.name;
};
}
};
console.log( object.getNameFunc()() );
when i tested the code. the result is The Window. but i think this.name;
should be开发者_JS百科 My Object
. what's wrong with my thinking.
when i add var before the name : "My Object",
it show's an error.? why?
this
inside a function is the "receiver" it was invoked upon.
That is,
for the construct
x.f()
,this
inside the function (f
) will evaluate to the value ofx
.for all other cases,
this
will evaluate towindow
inside the invoked function. (The functionscall
,apply
, andbind
can also alterthis
... but that's another story.)
In the posted example the second function (the one with this.name
) is not invoked using the x.f()
form and so this
is the window
object.
The "simple fix" is to use a closure: (The first function is invoked in the x.f()
form and thus this
is the same as object
, which is as expected. We capture the value of this
in the current scope via a closure created with self
and the returned function.)
getNameFunc : function () {
var self = this
return function () {
return self.name
}
}
However, I may consider another design, depending :)
Happy coding.
Additional clarification, for comment:
...that is because you are using circle.getArea()
which is of the form x.f()
. Thus this
inside the getArea function evaluates to circle
.
In the code posted you are invoking two different functions in a row. Imagine writing the code like this:
var nameFunc = object.getNameFunc()
nameFunc()
The first function call is in the form of x.f()
and thus this
inside getNameFunc is the evaluation of object
. However, in the second line, the function (nameFunc) is not invoked in the form x.f()
. Therefore, the this
inside nameFunc (the function returned from getNameFunc) will evaluate to window
, as discussed above.
var myObject = {
name:'My Object'
};
console.log(myObject.name);
console.log(myObject['name']);
There are various other ways to make objects in javascript.
this
is a hidden argument that is automatically passed from the calling function to the callee. The traditional way is to do:
function MyObject() {
this.name = 'My Object';
}
myObject = new MyObject();
console.log(myObject.name);
Nowadays you might just use closures:
[**edit**: redacted because not a good method]
Nowadays you might just use closures, correctly:
function makeObject() {
var THIS = {};
THIS.name = 'My Object';
THIS.sayMyName = function () {
return THIS.name+" is my name";
}
return THIS;
}
There are many libraries that support "smarter" ways to make objects as well.
You need to use .bind()
to set the right context for the method, so the this
keyword will be what you want it to actually be.
The default is in such a scenario for the this
keyword is to point to the window
object, because...this is how the JS engine works.
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
}.bind(this); // <-- sets the context of "this" to "object"
}
};
console.log( object.getNameFunc()() );
As the others have written, you need to target this
. I believe this piece of code will help you to understand how this
in javascript works
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
that = this; // targeting this
return function() {
return that.name;
};
}
};
alert(object.getNameFunc()()); // it is My Object now
var object = {
name : "My Object",
getNameFunc : function(){
return (function(){
return this.name;
}).bind(this);
}
};
.bind
, use the ES5-shim for browser support
The problem lies in the way you have declared your function.
The important point we need to remember while placing function inside a method is to use arrow function (if our function block is going to have a this keyword).
Instead of declaring a new variable and assigning this keyword to the variable, we can easily solve this problem using Arrow Functions.
Just convert the normal function into arrow function and boom it will work.
var name = 'The Window';
var object = {
name: 'My Object',
getNameFunc: function(){
return () => {
return this.name;
};
}
};
console.log( object.getNameFunc()() );
This works because arrow functions are always lexically binded and not dynamically binded like any other functions.
精彩评论