2011-02-14 46 views
3

我有JS代碼大致是這樣的:異步JavaScript和客體永久性

function myObject() 
{ 
    this.a = 13; 

    this.fetchData = function() 
    { 
     alert(this.a); 
     getData(this.processData); 
    } 

    this.processData = function(data) 
    { 
     // do stuff with data 
     alert(this.a); 
    } 

    this.fetchData(); 
} 

function getData(callback) 
{ 
    // do async request for data and call callback with the result 
} 

我的問題是:該功能fetchData有通過關鍵字訪問我一個變量,但其他函數processData不被調用getData。我明白爲什麼會發生這種情況,但不知道如何解決這個問題。

你會如何處理這個問題,最好在OOP風格? (該功能的getData必須是可用到多類)

回答

4

兩個選項:

1)有getData接受上下文參數(通常稱爲contextthisArg),並使用callback.apply(context, ...)callback.call(context, ...)調用它。所以:

function getData(callback, context) { 
    // ...when it's time to call it: 
    callback.call(context, arg1, arg2); 
    // or 
    callback.apply(context, [arg1, arg2]); 
} 

2)創建,調用它時,會調頭調用原始的回調與this設置爲正確的值的函數。 (這有時被稱爲「綁定」。)

例如,使用一個明確的關閉:

this.fetchData = function() 
{ 
    var self = this; 

    alert(this.a); 
    getData(getDataCallback); 

    function getDataCallback(arg1, arg2) { 
     self.processData(arg1, arg2); 
    } 
} 

或者有一個通用的bind功能做到這一點(這也將涉及到一個封閉的,但在一個不錯的受控上下文,因此它不會關閉你不需要的東西)。有關簡單的bind函數的示例,請參閱下面的鏈接。

更多:You must remember this

+0

+1:對於選項2,你可以調用getData(function(){this.processData();});而不是getData(thisProcessData); – 2011-02-14 10:27:36

+0

@Eric:不,那不行。 `this`完全由函數的調用方式來定義,而不是定義在哪裏。你的`getData(function(){this.processData();});`會和getData(this.processData)有完全相同的問題;`但你可以使用閉包(我已經添加了一個閉包例子)。 – 2011-02-14 10:28:50

1

我認爲你只需要定義「一」爲局部變量,以便它在應對這兩個fetchData和的getData,像這樣的:

function myObject() { 
    var a = 13; 

    this.fetchData = function() { 
     alert(a); 
     getData(this.processData); 
    } 

    this.processData = function(data) { 
     // do stuff with data 
     alert(a); 
    } 

    this.fetchData(); 
} 

你也可以這樣做,

function myObject() { 
    this.a = 13; 
    var that = this; 

    this.fetchData = function() { 
     alert(that.a); 
     getData(this.processData); 
    } 

    this.processData = function(data) { 
     // do stuff with data 
     alert(that.a); 
    } 

    this.fetchData(); 
}