回调嵌套,这

问题描述:

的范围我理解的“这个”特别是嵌套代码回调嵌套,这

这里时,我有

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

JavaScript中的'this'与其他语言不同。具体来说,所有函数都有'this',而不仅仅是方法。所以如果你嵌套函数,那么嵌套函数中的'this'来自'function(){}'而不是'MyClass'。下面是一个解释“this'如何工作的答案:http://*.com/questions/13441307/how-does-the-this-keyword-in-javascript-act-within-an-object-literal/13441628? = 1 | 3.8887#13441628 – slebetman

让我用一个小例子解释一下:

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(); 

它会因为f为作为一个“独立”的功能执行打印"2",这样的背景下是“全球范围内”,并没有“名“属性创建。

回调时要小心,因为它们可以被其他对象或函数执行。例如,如果您设置了事件侦听器回调(您创建的函数在用户单击某处时执行),则该事件的侦听器将执行该事件。因此,一个经典的技巧是创建一个变量为“我”,“自我”或“_this”存储在clausure所需的背景:

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...])