2011-11-29 49 views
6

可能重复:
In Javascript, why is the “this” operator inconsistent?JavaScript类变量的作用域

我有下面的类:

function Chat(some, nick, url) { 
    this.socket = null; 
    this.Nickname = nick; 
    this.Url = url; 

    this.Connect = function() { 
     socket = io.connect(this.Url); 
     socket.on('connect', function (data) { 
      var p = this.Nickname; //this.Nickname is undefined why? 
      // how can I acess to the Nickname variable or function? 
     } 
    }; 
} 

我怎样才能存取权限的实例变量或函数从连接回调函数?

+1

在'this.Connect'上方,你应该可以做'var obj = this;'然后在该函数中使用该变量。 – Danny

+0

感谢您的所有awnsers!有一切正确!但我只能选择一个。 – elranu

回答

26

最简单的办法就是使用that

var that = this; //that is a normal variable 
       //so it is lexically scoped 
       //and can be used in inner functions 

socket.on('connect', function(data){ 
    var p = that.NickName; 
}); 

另一种可能性是可明确绑定正确的这个回调函数

socket.on('connect', function(data){ 
    var p = this.Nickname; 
}.bind(this)); 

that伎俩有嵌套到尽可能多的优势回调你想要的和绑定版本的优点是可以让你仍然在里面使用“this”。

绑定方法的一个缺点是它不支持在IE < = 8中,因此如果您需要支持古代浏览器,您可能需要使用填充。

编辑:这个答案有点旧。现在你可能不需要担心IE6了,你可以使用fat arrow syntax,它不会覆盖this

+4

有关注意bind()方法的一点是,由于您在node.js中(并且您知道您的Javascript引擎),因此您知道V8中实现了一些ECMAScript 5功能(https://github.com/ joyent/node/wiki/ECMA-5-Mozilla-Features-Implemented-in-V8),你实际上拥有bind()函数并且可以安全地使用它! :) – RyanWilcox

2

问题是this javascript中的值可能会根据回调调用的方式而改变。解决此问题的最简单方法是将原始对象this保存到名为self的本地。本地在回调中被捕获,并可用于访问成员值。例如。

function Chat(some, nick, url) { 
    var self = this; 
    this.socket = null; 
    this.Nickname = nick; 
      this.Url = url; 

    this.Connect = function() { 
     socket = io.connect(this.Url); 
     socket.on('connect', function (data) { 
      var p = self.Nickname; //this.Nickname is undifined why? 
      // how can I acess to the Nickname variable or function? 
     } 
    }; 
    } 
2

你可以改变这一点:var p = this.Nickname; 这个var p = nick;

您的问题是this是指您使用的回调函数的局部范围。这不是外部函数的范围。

1

“this”代表您在该范围内的功能。

尝试:

function Chat(some, nick, url) { 
    this.socket = null; 
    this.Nickname = nick; 
     this.Url = url; 

    var that = this; 

    this.Connect = function() { 
     socket = io.connect(this.Url); 
     socket.on('connect', function (data) { 
      var p = that.Nickname; //this.Nickname is undifined why? 
      // how can I acess to the Nickname variable or function? 
     } 
    }; 
} 

注意的分配 “这个” 成 “是”

+0

'this'确实代表*函数*吗?我认为它代表*来电*? –

+0

这是一个很好的问题,我知道,我不确定它是代表调用者还是此方法所属的对象。无论如何,你是对的,它并不代表内部功能。 –

+0

@Uzi:Javascript是根据函数的调用方式设置的。如果你做f()这将是未定义的或全局对象。如果你做obj.f()这将是obj,最后你也可以用f.call(myThis,1,2)或f.apply来使用你的选择。函数做* *不知道他们来自哪个“类”,而“这个”是混乱的。 – hugomg

1

JavaScript有关闭这是,至少可以说,漂亮。

看一看这个问题:

How do JavaScript closures work?

它会帮助你理解为什么每个人都告诉你把一个var something = this上面的函数,并使用something它内部保持原来的一个参考this

1

下面是显示了使用这个本地副本小提琴:

http://jsfiddle.net/k7vC6/1/

在这种情况下,thisself是一样的,但使用self是安全的。