在代码库中,我看到bind
用于在原型上创建函数的绑定副本,用作DOM事件的回调。
为什么可以使用这个习惯用语,而不是直接使用原型上的方法?
这是否在内存消耗方面提供了一些好处/当事件从DOM事件中解除绑定时释放内存的能力?
function F() {
var onFoo = this._onFoo.bind(this); // Why?
document.getElementById('foo').onClick(onFoo);
}
F.prototype._onFoo = function () { /*...*/ }
答案 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}}就可以使用它。