0

我用来在我的 jQuery 函数bind()中保留this(这是我的类的一个实例):

if (!Function.prototype.bind) { 
    Function.prototype.bind = function(){ 
    var fn = this, args = Array.prototype.slice.call(arguments),
        object = args.shift(); 
    return function(){ 
        return fn.apply(object, 
             args.concat(Array.prototype.slice.call(arguments))); 
        }; 
    };
}

问题是,例如,如果我有一个单击事件,并且我不能再使用该元素访问该元素$(this),也不应该能够访问该元素。

例如:

View.prototype.sayHelloBind = function(){
    this.$el.find('#bind').on('click', (function(){

        // This no longer works
        $(this).css('color', 'red');

        alert(this.message);
    }).bind(this));
}

正如您将在 JSFiddle 中看到的那样,我知道 using e.data,也就是说,事实上,我想使用它的原因bind()是我可以摆脱这种语法。

我的问题是,有没有一种方法可以bind()用来保存this和访问当前的 jQuery 对象?

相关的 JSFiddle

4

3 回答 3

1

1) 使用(您的)原件bind()

View.prototype.sayHelloBind = function(){
    var el = this.$el.find('#bind');
    el.on('click', (function(elem){
        $(elem).css('border', '1px solid red')
        alert(this.message);
    }).bind(this, el));
}

缺点:event在上下文中没有。


2)您可以创建自己的变体bind()

//if (!Function.prototype.bind_elem) {
  Function.prototype.bind_elem = function(){ 
    var fn = this, args = Array.prototype.slice.call(arguments);
    var that = args.shift(); // view
    var obj = args.shift(); // DOM object
    return function(event){ 
        var argggs = [event, obj].concat(args);
        return fn.apply(that, argggs); 
    }; 
  };
//}


var View = function(element, msg){
    this.$el = $(element);    
    this.message = msg;
}

View.prototype.sayHelloBind = function(){
    var el = this.$el.find('#bind');
    el.on('click', (function(event, elem){
        event.preventDefault();
        $(elem).css('border', '1px solid red')
        alert(this.message);
    }).bind_elem(this, el));
}

$(function(){
    var view = new View('#test', 'Hello World!');
    view.sayHelloBind();
});

一个完整的 JSFiddle:http: //jsfiddle.net/cek125i/24AmT/

event在上下文中添加了,因为它通常很有用。

一个缺点是我们必须引用el两次:

el.on('click', (func...).bind_elem(this, el));

我看不出有什么办法...


3) KISS 原则?

如果用例不是特别复杂,也许使用更简单的东西:

View.prototype.sayHelloBind = function(){
    var el = this.$el.find('#bind');
    var that = this;
    el.on('click', function(event){
        event.preventDefault();
        $(this).css('border', '1px solid red')
        alert(that.message);
    });
}
于 2013-11-08T01:07:54.820 回答
0

this在事件处理程序中必须是默认值(即单击的元素)或者它可能是您的容器对象,不能同时是两者。

由于默认语义是人们最习惯的语义,为什么不:

View.prototype.sayHelloBind = function() {
    var self = this;          // copy of "this" to use inside the closure
    this.$el.find('#bind').on('click', function() {

        $(this).css('color', 'red');

        alert(self.message);  // use the closed variable
    });
}

这实际上比使用更有效,.bind并且还避免了垫片。 .bind必须创建并返回一个全新的关闭函数this及其参数,那么为什么不使用语言自己的特性并关闭this自己呢?

于 2013-11-08T01:14:33.963 回答
0

在这种情况下,您可以使用event.currentTarget来引用当前元素

View.prototype.sayHelloBind = function(){
    this.$el.find('#bind').on('click', (function(event){

        // This no longer works
        $(event.currentTarget).css('color', 'red');

        alert(this.message);
    }).bind(this));
}

演示:小提琴

jQuery没有使用.bind(),而是提供了一个名为$.proxy()的跨平台实现

View.prototype.sayHelloBind = function(){
    this.$el.find('#bind').on('click', $.proxy(function(event){

        // This no longer works
        $(event.currentTarget).css('color', 'red');

        alert(this.message);
    }, this));
}

演示:小提琴

于 2013-11-08T00:03:23.947 回答