开发者

"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,

  1. for the construct x.f(), this inside the function (f) will evaluate to the value of x.

  2. for all other cases, this will evaluate to window inside the invoked function. (The functions call, apply, and bind can also alter this... 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜