在使用原型时,是否可以直接将类方法作为回调传递?

时间:2016-02-15 18:45:29

标签: javascript callback prototype

假设有人希望能够添加这样的回调:

btn.addEventListener('click', class.method);

这种方法的问题是'this'不会再指向正确的对象,因此必须使用var self = this;技巧创建方法:

function Person(name){
  this.name = name;
  var self = this;

  this.printName = function(){ console.log(self.name); };
}

var person = new Person('Bob');

// Creating a button to have an event listener to subscribe to
var btn = document.createElement('button');
btn.innerHTML = "print name";
document.getElementById('container').appendChild(btn);

// Actual example
btn.addEventListener('click', person.printName);

但是,上述方法似乎与原型不兼容。如果不支持旧浏览器并且可以使用最新的javascript功能,有没有办法让myClass的原型在这行addCallback(myClass.myMethod)中工作?

我知道bind和这种方法addCallback(person.printName.bind(person));,但在我看来,它看起来比标准句法噪音更糟糕,例如function () { person.printName ();},因为至少后者是噪音人们更习惯调出。

如果没有解决方案,那么任何潜在的(可能是主观的)代码美学效益值得潜在的性能下降吗?我理解它原型的方式提供了更快的对象创建性能,但不一定在创建这些方法时使用方法。

然后,有一个问题是人们可能期望在同一代码库中编写的所有对象都以这种方式运行,但如果有任何性能权衡,那么这可能是不可取的。

考虑到以上所有因素,您会使用这个吗?

编辑:有人已经回答了,这实际上看起来很不错。我没有以正确的方式使用bind(在构造函数中使用bind)。答案主要是关于这样做:

function Person(){
...
this.printName = this.printName.bind(this); 
}

Person.prototype.printName = function(){ console.log(this.name); };

但后来他删除了它,因为我并没有具体说明我在谈论哪种绑定技巧,他可能认为我提到了它。请你重新加一下你的答案,Mat(如果我记得你的名字正确的话),这样我就可以接受了吗?谢谢!

1 个答案:

答案 0 :(得分:1)

使bind更具可读性的一个选项是这样的包装:

    function bound(obj) {
        var res = {};
        for (var key in obj) {
            if (obj[key].bind)
                res[key] = obj[key].bind(obj);
        }
        return res;
    }

然后

something.addEventListener('click', bound(this).method);

而不是

something.addEventListener('click', this.method.bind(this));

如果你已经在ES6上,箭头功能也是一个选项:

something.addEventListener('click', () => this.method());