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

Is passing class methods directly as a callback possible when using prototypes?

本文关键字:类方法 回调 原型 是否      更新时间:2023-09-26

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

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功能,addCallback(myClass.myMethod)那么有没有办法使原型在这一行中为myClass工作?

我知道bind,这种方法addCallback(person.printName.bind(person));,但在我看来,它看起来比像function () { person.printName ();}这样的标准句法噪声更糟糕,因为至少后一种噪声变体人们更习惯于调出。

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

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

考虑到以上所有因素,这是您会使用的东西吗?

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

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

但后来他删除了它,因为我没有具体说明我在说哪个绑定技巧,他可能认为我提到了它。你能重新添加你的答案吗,Mat(如果我没记错的话(,这样我就可以接受它?谢谢!

使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());