gpt4 book ai didi

javascript - 使用绑定(bind)的习惯用法

转载 作者:行者123 更新时间:2023-12-03 10:59:51 25 4
gpt4 key购买 nike

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

为什么要使用这个习惯用法,而不是直接使用原型(prototype)上的方法?

这在内存消耗/事件与 DOM 事件解除绑定(bind)时释放内存使用的能力方面是否提供了一些好处?

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

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

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

最佳答案

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

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

myFunc 中的 this 指针将被设置为附加了事件处理程序的 DOM 元素(在本例中为 foo 元素)。但这不是 myObj,因此在这种情况下 myFunc 无法通过 this 指针访问它自己的任何实例变量(通常的方式是方法访问其实例数据)。

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

这样做的一种方法是使用.bind(),它返回一个新的 stub 函数,其功能是在调用函数之前设置this,如下所示:

document.getElementById('foo').addEventListener('click', myObj.myFunc.bind(myObj));

在这种情况下,.bind()实际上返回一个新的 stub 函数,其功能是将this的值设置为它之前的myObj调用myFunc

您也可以自己手动执行此操作,如下所示:

document.getElementById('foo').addEventListener('click', function(e) {
myObj.myFunc();
});

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

<小时/>

在某些情况下,使用 .bind() 的一个潜在缺点是您可能无法再访问回调调用者拥有的 this 值设置自身,因为 .bind() 丢弃了该值并将其替换为您自己的值。在上面的事件处理程序示例中,这不是问题,因为可以通过传递给事件处理程序的 e 参数访问事件的原始源,因此如果您需要它,它不会丢失。

<小时/>

我知道上述两种方法在内存消耗或垃圾收集方面没有任何有意义的差异。两者都创建一个新函数,用于调用原始函数并在调用原始函数时控制 this 的值。两者将具有相同的垃圾收集生命周期。

<小时/>

似乎让您感到困惑的一件事是 Javascript 中的对象是通过指针分配或传递的(有些人称其为引用,但这有一些不适用于此的含义,所以我将使用“通过指针”这个短语)。

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
在删除 x.myFunc 后,

t() 仍然有效,因为 t 和 x.myFunc 都具有对同一函数的引用(或指针)。执行delete x.myFunc 只是从x 对象中删除myFunc 属性。 x.myFunc 指向的函数只有在没有其他引用时才会被 GC“释放”。但是,t 中还有另一个对该函数的引用,因此它不会被释放,并且 t() 可以使用它,只要 t存在。

关于javascript - 使用绑定(bind)的习惯用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28140975/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com