【问题标题】:Asynchronous JavaScript and object permanence异步 JavaScript 和对象持久性
【发布时间】:2011-02-14 10:21:29
【问题描述】:

我的 JS 代码大致是这样的:

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 可以通过 this 关键字访问我的 a 变量,但另一个函数 processData 在被 getData 调用时不会。我了解为什么会发生这种情况,但不知道如何解决。

您将如何最好地以 OOP 风格解决这个问题? (函数 getData 必须可用于多个类)

【问题讨论】:

    标签: javascript oop asynchronous coding-style


    【解决方案1】:

    两种选择:

    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

    【讨论】:

    • +1:对于选项 2,您将调用 getData(function(){ this.processData(); });而不是 getData(thisProcessData);
    • @Eric:不,这行不通。 this 的定义完全取决于函数的调用方式,而不是定义的位置。您的getData(function(){ this.processData(); });getData(this.processData); 会遇到完全相同的问题,但是您可以使用闭包(我添加了一个闭包示例)。
    • @T.J.克劳德:当然,你是对的。感谢您添加示例。
    • 顺便说一句:jQuery 有内置的绑定函数吗?
    【解决方案2】:

    我认为你只需要将“a”定义为局部变量,这样它就可以同时处理 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();
    }
    

    【讨论】:

    • +1 用于在闭包 fetchData 和 processData 的私有范围内设置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    相关资源
    最近更新 更多