2015-09-28 68 views
1

的範圍我理解的「這個」特別是嵌套代碼回調嵌套,這

這裏時,我有

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://stackoverflow.com/questions/13441307/how-does-the-this-keyword-in-javascript-act-within-an-object-literal/13441628? = 1 | 3.8887#13441628 – slebetman

回答

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

它會因爲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...])