【问题标题】:OOP JavaScript: Call method from inside of Callback FunctionOOP JavaScript:从回调函数内部调用方法
【发布时间】:2014-05-18 12:27:33
【问题描述】:

我正在使用 OOP 原则构建一个 jQuery 应用程序,并且我正在尝试实现一个外部添加的回调函数,该函数从我的对象内部调用一个方法。

function testObject() {
    var self = this;

    var functions = new Array();

    this.updateObject = function() {
        console.log('updated')
    }

    this.addFunction = function(func) {
        functions.push(func)
    }

    this.callFunctions = function() {
        $.each(functions, function(key, value) {
            functions[key]()
        })
    }
}



var myobject = new testObject();
myobject.addFunction(
        function() {
            $(':text').on('change', function() {
                return self.updateObject();
            })
        }
)

这是我正在构建的插件的过度简化版本。回调工作正常,但我不能使用 self.updateObject();在里面,因为它输出非法调用。

如何正确调用回调内部的方法?

【问题讨论】:

    标签: javascript jquery function oop methods


    【解决方案1】:

    问题是self 超出了回调函数的范围,因为该函数只有在其定义范围内的变量。回调是在testObject 之外定义的。

    一种解决方案是当您在callFunctions() 中调用它时,使用Function.prototype.call(self) 将回调函数中的this 上下文绑定到self。然后在回调中,您可以使用this 来引用testObject 实例。在您的回调示例中,它包含一个 jQuery 事件,因此您将丢失 this 上下文。为了纠正您可以在jQuery更改事件之前创建一个等于this的本地self

    function testObject() {
        var self = this;
    
        var functions = new Array();
    
        this.updateObject = function() {
            console.log('updated')
        }
    
        this.addFunction = function(func) {
            functions.push(func)
        }
    
        this.callFunctions = function() {
            $.each(functions, function(key, value) {
                functions[key].call(self); // call it and bind the context to self
            })
        }
    }
    
    var myobject = new testObject();
    myobject.addFunction(
            function() {
                var self = this; // needed because the change event will overwrite 'this'
                $(':text').on('change', function() {
                    return self.updateObject(); // use self to access testObject
                })
            }
    )
    myobject.callFunctions();
    

    或者,您可以将self 作为参数传递给回调。为此,请将.call() 行更改为:

    functions[key].call(null, self);
    

    并更改回调以接受如下参数:

    myobject.addFunction(
            function(self) { // self as an argument
                $(':text').on('change', function() {
                    return self.updateObject(); // use self to refer to testObject
                })
            }
    )
    

    【讨论】:

    • 嗨 MrCode!非常感谢您的复杂回答。不幸的是,我仍然遇到同样的错误。未捕获的 TypeError:非法调用。我试过用很多方法调用它,但它不起作用,即使理论上应该这样做。
    • 编辑。我第一次就做对了。问题出在非法调用方法的 updateObject() 方法中。感谢您的帮助
    【解决方案2】:
    function testObject() {
        var self = this;
    
        var functions = new Array();
    
        this.updateObject = function() {
            console.log('updated')
        }
    
        this.addFunction = function(func) {
            functions.push(func.bind(self)) // Bind the context
        }
    
        this.callFunctions = function() {
            $.each(functions, function(key, value) {
                functions[key]()
            })
        }
    }
    
    var myobject = new testObject();
    
    myobject.addFunction(
            function() {
                var self = this;
    
                $(':text').on('change', function() {
                    return self.updateObject();
                })
            }
    )
    

    或者你也可以使用它:

     myobject.addFunction(
                function() {    
                    $(':text').on('change', this.updateObject);
                }
        )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多