【问题标题】:JavaScript object call one method from anotherJavaScript 对象从另一个方法调用一个方法
【发布时间】:2012-10-04 03:41:28
【问题描述】:

鉴于以下对象文字,我如何从 b 中调用 c

更新 1 - 错过了我使用 JQuery 加载的一件事,这会改变上下文:

var a = {
    b: function (e) {

        $o.load(path, function (e) { // need to call c from here });
    },
    c: function (e) { 
    }
};

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    你应该可以在.b里面做a.c()

    var a = {
        b: function(e) {
            a.c();
        },
        c: function(e) {}
    };
    
    a.b(); // calls c
    

    此外,this 将绑定到 a 对象,这将允许您使用 this.property 访问其属性:

    b: function(e) {
        this.c();
    },
    

    【讨论】:

    • 对不起,我错过了一个细节 - 我使用 JQuery 加载调用,所以我需要以某种方式代理加载的事件处理程序......
    • 请注意,this === a 只有在您致电a.b() -直接 时才能确定。将b 函数分配给另一个obj,或者将其用作jQuery 事件处理程序,this 将发生变化。
    【解决方案2】:
    var a = {
        b: function (e) {
            a.c();
        },
    
        c: function (e) {
            // magic goes here
        }
    };
    

    a 将是一个闭包,因此它可以在函数中访问(也就是说,a 定义在一个宽的外部范围中,每个函数中的较窄的内部范围都继承了该范围)。调用上下文无关;闭包是在定义函数的时间和地点形成的,因此在b 内部,对象a 将始终保持不变(不像this,它可以更改)。

    【讨论】:

      【解决方案3】:

      试试这个:-

      var a = {
      b: function(e) {
          a.c();
      },
      c: function(e) {}
      };
      
      a.b(); 
      

      【讨论】:

        【解决方案4】:

        从方法b 你可以使用this.c 调用c,只要它们在同一个对象上。但是对于传递给$o 的函数表达式,我建议您将bindthis 指针b 指向它。这样你就可以了:

        var a = {
            b: function (e) {
                $o.load(path, function (e) {
                    this.c();
                }.bind(this));
            },
            c: function (e) {
            }
        };
        

        编辑:您创建和使用此对象的方式很脆弱。 this 指针可能指向任何东西,例如当您取消绑定方法或使用不同的上下文调用它时。即使使用a.c 也不是万无一失的,因为其他代码可能会更改a,并且当调用b 方法时a 将指向其他内容。

        我会这样做:

        var a = function (a) {
            a.b = function (e) {
                $o.load(path, function (e) {
                    a.c();
                });
            };
        
            a.c = function (e) {
            };
        
            return a;
        }({});
        

        此代码不能被篡改,并允许您创建私有变量和闭包。

        【讨论】:

        • 也许我遗漏了一些东西,但 bind() 并没有改变我加载的处理程序的这一点。我尝试传入一些不同的东西,包括一个字符串,但我的 this 始终是一个 html 对象。
        • 也许你可以给我看看你的实际代码。它对我有用:jsfiddle.net/3bkzD
        • 我发现了比 $,proxy 更优雅的解决方案。看我的回答。
        • JQuery proxy 在浏览器开始原生支持 bind 之前使用。出于任何目的,我不会更喜欢bind。原生 bindapproximately 90% faster 而不是 jquery.proxy
        【解决方案5】:

        需要最少更改的最简单解决方案是使用jQuery.proxy()

        var a = {
            b: function (e) {
        
                $o.load(path, $.proxy(function (e) { this.c(); }, this));
            },
            c: function (e) { 
            }
        };
        

        【讨论】:

        • $.proxy 类似于我使用bind 的方法。事实上我会说我的方法更好:jsperf.com/bind-vs-jquery-proxy/2
        • 但是请注意,这种方法仍然会遇到与我的方法相同的问题。如果this 指针被更改(通过取消绑定方法或使用callapply 更改上下文),那么this 将不会指向正确的对象。在这种情况下最好使用我的第二种方法。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-09
        • 2011-11-01
        • 2015-12-01
        • 1970-01-01
        • 2021-09-25
        • 2017-10-17
        相关资源
        最近更新 更多