2011-02-14 42 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(); 
}