2

这是主观的(基于意见) - 但只是在一定程度上,不要急于投票结束。在工作中引起一些争论,因为每个人都有不同的意见,并且人们正试图强制执行一种单一的方式。

简单的上下文:当您可以选择在您的闭包中保存对实例的引用或使用 polyfillFunction.prototype.bind时,您认为这两种方法可能存在哪些缺点?

为了说明可能的用例,我只是编造了一些类方法。

模式一,保存参考:

obj.prototype.addEvents = function(){
    var self = this;

    // reference can be local also - for unbinding. 
    this.onElementClick = function(){
        self.emit('clicked');
        self.element.off('click', self.onElementClick);
    };

    this.element.on('click', this.onElementClick);
};

模式二,一个简单的 fn.bind:

obj.prototype.addEvents = function(){
    // saved reference needs to be bound to this to be unbound
    // once again, this can be a local var also.  
    this.onElementClick = function(){
        this.emit('clicked');
        this.element.off('click', this.onElementClick);
    }.bind(this);

    this.element.on('click', this.onElementClick);
};

模式二半,proto方法到事件:

obj.prototype.addEvents = function(){
    // delegate event to a class method elsewhere 
    this.element.on('click', this.onElementClick.bind(this));
};

obj.prototype.onElementClick = function(){
    this.emit('clicked');
    this.element.off('click', this.onElementClick); // not matching due to memoized bound 
};

就个人而言,我认为没有一种正确的方法可以做到这一点,应该根据具体情况进行判断。我非常喜欢尽可能保存的参考模式。我被告知了。

问题回顾:

是否有任何 GC 问题需要考虑/注意?

对于这两种方法,您是否还有其他明显的缺点或陷阱?

Polyfill 性能或事件原生.bind与保存的参考?

4

2 回答 2

1

是否有任何 GC 问题需要考虑/注意?

较旧的引擎不会从闭包中推断出哪些变量仍在使用,并且会保留整个范围。使用bind确实很容易,因为上下文是显式传递的,并且未收集的范围不包含其他变量。

但是,如果您仍然使用函数表达式(如模式#1 和#2),这并没有什么不同。

对于这两种方法,您是否还有其他明显的缺点或陷阱?

保存参考:

  • 需要一个额外的行来声明变量,有时甚至是一个全新的范围(IEFE)
  • 代码不能轻易移动,因为您需要重命名变量

使用绑定:

  • this在函数表达式的末尾容易被忽略(就像调用 IEFE 一样),从上到下阅读时不清楚指的是什么
  • 容易忘记

我个人倾向于使用 bind 因为它的简洁性,但仅限于在其他地方声明的函数(方法)。

Polyfill 性能或事件原生 .bind 与保存的参考?

你不在乎。


在您的示例中,您实际上不需要对绑定函数和off方法的引用。jQuery 可以自己解决这个问题,您可以使用绑定 fire-once 侦听器的one方法。然后您的代码可以缩短为

obj.prototype.addEvents = function(){
    this.element.one('click', this.emit.bind(this, 'clicked'));
};
于 2013-10-25T12:21:24.163 回答
1

我个人的偏好是使用保存的参考方法。由于thisJavaScript 处理this.

绑定很好,但如果你错过了.bind(this)它看起来像一个错误。

后者暴露太多;每次需要回调时,都需要在 API 中公开另一个帮助程序。


有很多方法可以使用原型。我认为最重要的是选择一个并坚持下去。

于 2013-10-25T11:16:47.543 回答