【问题标题】:JavaScript OOP - when parameters passed for method bind with an eventJavaScript OOP - 当为方法传递的参数与事件绑定时
【发布时间】:2014-08-18 01:02:08
【问题描述】:

我正在尝试将参数传递给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);
    }

};

感谢您的帮助。

【问题讨论】:

标签: javascript jquery oop bind


【解决方案1】:

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

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

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

惰性求值没有语言支持,因此在jQuery.proxy 之外,您必须自己创建并传递一个可调用对象。通常可以使用上述方法的替代方法是使用匿名函数:

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 无关)。

【讨论】:

  • 感谢您的帮助。我在构造函数中定义了一个方法,但还是同样的问题。
【解决方案2】:

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

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

【讨论】:

  • 我可以传递任意数量的参数,例如:displayMessageWithParam.bind(this, $parm1, $param2, ..) 吗?
【解决方案3】:

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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多