JavaScript OOP - 为方法传递的参数与事件绑定

时间:2014-06-27 02:21:50

标签: javascript jquery oop bind

我正在尝试将参数传递给class方法,但是当我将该方法与事件绑定时,它只在启动类时才起作用。

但是当我在没有传递参数的情况下尝试时,它会像往常一样工作,并且在事件中正常运行。

我无法在类中为displayMessageWithParam($param)设置参数,因为它可能被其他人使用,我希望它们传递参数。它可以在不绑定事件的情况下工作,但为什么不在绑定事件时呢?

请告诉我我做错了什么:

jQuery(function() {

    // create document
    Klass.site = new Klass.site();
    // need to call init manually with jQuery
    Klass.site.initialize();

});

// namespace our code
window.Klass = {};

// my class (no Class.create in JQuery so code in native JS)
Klass.site = function() {};

// add functions to the prototype
Klass.site.prototype = {
    // automatically called
    initialize: function() {
        // this works as usual
        jQuery('#field').keyup( jQuery.proxy(this.displayMessage, this));

        // but this wont work
        jQuery('#field').keyup( jQuery.proxy(this.displayMessageWithParam('chanaged'), this));
    },
    displayMessage:function(){
        console.log('chanaged');
    }
    displayMessageWithParam:function($parm){
        console.log($parm);
    }

};

感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

括号的存在(例如Obj.method(...))会立即调用方法。要引用方法,必须使用不带括号表达式的名称。

如果您查看API文档,jQuery.proxy可以将其他参数作为参数传递。

jQuery('#field').keyup(jQuery.proxy(this.displayMessageWithParam, this, 'changed'));

懒惰评估没有语言支持,所以在jQuery.proxy之外你必须自己创建并传递一个callable。上面的替代方法通常是使用匿名函数:

jQuery('#field').keyup(jQuery.proxy(function () {
        this.displayMessageWithParam('changed');
    }, this));

请注意,您可以使用此方法绑定对象:

var self = this;
jQuery('#field').keyup(function () {
        self.displayMessageWithParam('changed');
    });

您还可以创建通用参数绑定功能:

function bindParam(f, param) {
    return function () {
        var args = [].slice.apply(arguments);
        args.unshift(param);
        return f.apply(this, args);
    };
}

请注意,这是jQuery.proxy本身的变体。用法:

... bindParam(this.displayMessageWithParam, 'changed') ...;

如果浏览器支持Function.bind(另请参阅MDNMSDN文档以了解实施说明/用法),您可以使用该文档代替jQuery.proxy以及上述内容

jQuery('#field').keyup(this.displayMessageWithParam.bind(this, 'changed'));

如果不支持浏览器,则实施Function.bind作为练习。

此外,JS不支持语言级别的类,因此它没有类和实例方法(某些库添加基于类的继承,但这不是语言的一部分)。它使用所谓的“基于原型的编程”。如果你想要用另一种语言称为“类方法”,可以在构造函数上定义方法,而不是在原型上定义:

Klass.method = function () {...};

与其他一些语言不同,如果您尝试直接从实例调用它,则不会调用此“类方法”((new Klass).methodKlass.method无关)。

答案 1 :(得分:1)

您没有绑定displayMessageWithParam函数,而是调用该函数之后的值。使用Function.prototype.bind绑定参数:

jQuery('#field').keyup( jQuery.proxy(this.displayMessageWithParam.bind(this,'chanaged'), this));

答案 2 :(得分:1)

this.displayMessageWithParam不同,this.displayMessageWithParam('chanaged')不是函数引用;而是立即执行该函数并使用其返回值(undefined)。

但是,您可以指示jQuery.proxy()传递其他参数,例如:

jQuery('#field').keyup(jQuery.proxy(this.displayMessageWithParam, this, 'changed'));

或者:

jQuery('#field').keyup(jQuery.proxy(this, 'displayMessageWithParam', 'changed'));

然后调用该函数:

this.displayMessageWithParam('changed', event)