我在理解'this'的范围时遇到问题,特别是在嵌套代码时
这是我遇到问题的例子
var callbacks = [];
MyClass.protoype.CallServer = function(name,index,callback)
{
//some code
callbacks[callback.length] = callback;
callserverfor(name,index, callbacks.length-1);
}
MyClass.prototype.ReceiveFromServer = function(callbackId,param)
{
//somecode for simplicity let's say
if(param)
callbacks[callbackId].call(param);
else
callbacks[callbackId].call();
}
MyClass.prototype.Connect(Index,callback)
{
CallServer('Connect' , Index, callback);
}
MyClass.prototype.Start= function(Index)
{
this.Connect(Index,function()
{
this.ISConnected = true;
//HERE this lost scope
this.GetIdentified(Index, function( Identifier)
{
alert('Identifier');
});
});
}
我甚至尝试过绑定
MyClass.prototype.ReceiveFromServer = function(callbackId,param)
{
//somecode for simplicity let's say
if(param)
callbacks[callbackId].call(param);
else
callbacks[callbackId].call();
}
MyClass.prototype.Connect(Index,callback)
{
CallServer('Connect' , Index, callback);
}
MyClass.prototype.Start= function(Index)
{
this.Connect(Index,function()
{
this.ISConnected = true;
var GetIdentifier = this.GetIdentifier;
GetIdentifier.bind(this);
//HERE this lost scope
this.GetIdentifier(Index, function( Identifier)
{
alert('Identifier');
});
});
}
当我尝试使用我在代码中指向此内容时...它有效.. 我可以理解这里发生了什么,因为我没有得到它
MyClass.prototype.ReceiveFromServer = function(callbackId,param)
{
//somecode for simplicity let's say
if(param)
callbacks[callbackId].call(param);
else
callbacks[callbackId].call();
}
MyClass.prototype.Connect(Index,callback)
{
CallServer('Connect' , Index, callback);
}
MyClass.prototype.Start= function(Index)
{
var Me= this;
this.Connect(Index,function()
{
Me.ISConnected = true;
//HERE this lost scope
Me.GetIdentifier(Index, function( Identifier)
{
alert('Identifier');
});
});
}
有没有更好的方法来做到这一点或确定回调的范围?任何建议
答案 0 :(得分:1)
让我用一个小例子解释一下:
var functions=[]; //a common array
functions.name="functions" //we add an attribute to that object
function generator(v) {
var temp=v;
return function () {
console.log(this.name+temp);
};
}
for (var i=0;i<5;i++) {
functions[i]=generator(i); // here we add a bunch of functions to that object
}
如果执行functions[2]()
,您将在控制台中获得"functions2"
。为什么?因为您正在调用属于对象的函数,(因此该函数是该对象的方法),并且该对象是“当前上下文”。
然后,如果你执行这样的事情:
var f= functions[2];
f();
它将打印"2"
,因为f作为“独立”函数执行,因此上下文是“全局上下文”,并且没有创建“名称”属性。
小心回调,因为它们可以由其他对象或函数执行。例如,如果设置事件侦听器回调(您创建要在用户单击某处时执行的函数),那么该事件的侦听器将执行它。所以一个经典的技巧是创建一个变量“me”“self”或“_this”来存储所需的上下文:
var myObj={ name:'my object'};
myObject= function () {
var self=this; //here
window.onclick=function(e) {
console.log("I'm keeping a link to myObj: "+ self.name);
}
}
如果您想选择其他背景,也可以使用f.call(context, first_parameter)
或f.apply(context,[param0,param1...])