使用bind的成语

时间:2015-01-25 20:14:11

标签: javascript

在代码库中,我看到bind用于在原型上创建函数的绑定副本,用作DOM事件的回调。

为什么可以使用这个习惯用语,而不是直接使用原型上的方法?

这是否在内存消耗方面提供了一些好处/当事件从DOM事件中解除绑定时释放内存的能力?

function F() {
  var onFoo = this._onFoo.bind(this); // Why?

  document.getElementById('foo').onClick(onFoo);
}

F.prototype._onFoo = function () { /*...*/ }

1 个答案:

答案 0 :(得分:1)

问题是事件处理程序在调用回调时为this设置了自己的值。该值通常与事件处理程序有关,而与该方法绑定的对象无关。例如,在您的示例中:

document.getElementById('foo').onClick(myObj.myFunc);

this中的myFunc指针将被设置为附加了事件处理程序的DOM元素(在本例中为foo元素)。但那不是myObj所以myFunc因此this无法通过.bind()指针访问任何实例变量(方法访问它们的正常方式)实例数据)。

因此,如果您有一个方法想要在事件处理程序直接调用它时访问它自己的实例数据,那么除了将该方法传递给事件处理程序之外,您还必须执行其他操作。有几种方法可以解决这个问题。

这样做的一种方法是使用this返回一个新的存根函数,它的功能是在调用你的函数之前设置document.getElementById('foo').addEventListener('click', myObj.myFunc.bind(myObj));

.bind()

在这种情况下,this实际上会返回一个新的存根函数,其功能是在调用myObj之前将myFunc的值设置为document.getElementById('foo').addEventListener('click', function(e) { myObj.myFunc(); }); 。< / p>

您也可以自己手动执行此操作:

.bind()

但是,正如您所看到的,.bind()提供了一种快捷方式,可以减少代码(这就是它被发明的原因)。


在某些情况下使用this的一个潜在缺点是,您可能无法再访问回调调用者自己设置的.bind()值,因为e扔了那个价值取而代之的是你自己的。在上面的事件处理程序示例中,这不是问题,因为事件的原始源可以通过传递给事件处理程序的this参数进行访问,因此如果需要它也不会丢失。


我知道上述两种方法在内存消耗或垃圾收集方面没有任何有意义的差异。两者都创建了一个新函数,用于调用原始函数并在调用原始函数时控制var x = {}; x.myFunc = function() {console.log("hello");}; x.myFunc(); // generates "hello" in the console var t = x.myFunc; // save reference to the function that x.myFunc currently points to delete x.myFunc; // remove property myfunc from the x object t(); // generates "hello" in the console 的值。两者都将具有相同的垃圾收集生命周期。


看来有一件让你感到困惑的事情是Javascript中的对象是由指针分配或传递的(有些是通过引用来调用它,但是它有一些内容不适用于此,所以我将使用指针的短语。

t()
删除x.myFunc后,

delete x.myFunc仍然有效,因为t和x.myFunc都有一个指向同一函数的引用(或指针)。执行x只是从x.myFunc对象中删除了myFunc属性。 t指向的函数将仅被释放&#34;当GC没有其他参考时。但是,t()中还有另一个对该函数的引用,因此只要t存在就不会释放它,{{1}}就可以使用它。