Reference Instance Variables in Javascript Constru

2019-05-10 14:47发布

I'm trying to maintain state on an object by doing something like this:

obj = function() { 
    this.foo = undefined; 
    this.changeState = function () { 
        (function () { this.foo = "bar" })(); // This is contrived, but same idea.
    }; 
};

I want to set the instance variable foo to "bar" when I call the changeState method.

For instance:

o = new obj();
o.changeState();
alert(o.foo); // This should say "bar"

As far as I can tell, what is happening is that "this" in the inner anonymous function is pointing to window. I'm not sure what's going on.

Am I on the right track? Is there a better approach?

4条回答
干净又极端
2楼-- · 2019-05-10 15:09
function obj() { 
    this.foo = undefined; 
    this.changeState = function () { this.foo = "bar" };
};

var o = new obj();
o.changeState();
alert(o.foo);

works for me. I'm not sure why you would want to use a self-invoking function just to assign a function reference, nor why you use a function expression for your constructor rather than a function declaration.

查看更多
SAY GOODBYE
3楼-- · 2019-05-10 15:09

I figured it out. Just needed to save a reference to the current context and use that in the inner anonymous function:

obj = function() { 
    this.foo = undefined; 
    var self = this; 
    this.changeState = function () { 
        (function () { self.foo = "bar" })();
    }; 
}; 
查看更多
小情绪 Triste *
4楼-- · 2019-05-10 15:24

this topic comes up a lot, but it's hard to serach for since "this" is removed from SO searches.

Basically, in JavaScript, this always refers to the calling object, not the context object. Since here we call o.changeState() from the global scope, this refers to window.

You actually don't need the inner function for the closure to work in this case - the changeState function itself is enough to close a lexical scope.

obj = function()
{
  var self = this; 
  this.foo = undefined; 
  this.changeState = function()
  {
    self.foo = "bar";
  }
} 
查看更多
Deceive 欺骗
5楼-- · 2019-05-10 15:25

Unless you specify a this context when calling a function the default will be the global (which in browsers is window).

Alternatives are:-

obj = function() { 
  this.foo = undefined; 
  this.changeState = function () { 
    (function () { this.foo = "bar" }).call(this); // This is contrived, but same idea.
  }; 

};

or:-

obj = function() {
  var self = this;
  this.foo = undefined; 
  this.changeState = function () { 
    (function () { self.foo = "bar" })(); // This is contrived, but same idea.
  }; 

};

查看更多
登录 后发表回答