在本教程中,您将了解 JavaScript bind()
方法并知道如何有效地使用它。
JavaScript bind()方法介绍
bind()
方法返回一个函数,在调用时,函数内部的 this
设置为指定的值。
下面是 bind()
方法的语法:
fn.bind(thisArg[, arg1[, arg2[, ...]]])
在此语法中,bind()
方法返回具有指定 this
值 (thisArg
)和参数 (arg1
, arg2
, …)的 fn
函数副本。
与 call()
和 apply()
方法不同bind()
方法不会立即执行函数。它只是返回一个新版本的函数,其 this
设置为参数 thisArg
。
使用 JavaScript bind() 进行函数绑定
当您将一个对象的方法作为回调函数传递给另一个函数时,对象方法内部的 this
值将会被改变。例如:
let person = {
name: 'John Doe',
getName: function() {
console.log(this.name);
}
};
setTimeout(person.getName, 1000);
输出:
undefined
从输出中可以清楚地看到,person.getName()
返回 undefined
而不是 'John Doe'
。这是因为 setTimeout()
函数 person.getName
独立于 person
。
因此可以将语句:
setTimeout(person.getName, 1000);
重写为:
let f = person 上下文.getName;
setTimeout(f, 1000); // 丢失 person 上下文
setTimeout()
函数内部在非严格模式下 this
设置为全局对象,严格模式 this
设置为 undefined
。
因此,调用回调 person.getName
时,全局对象中不存在 name
,它被设置为 undefined
。
要解决此问题,您可以将 person.getName
方法在匿名函数中调用,如下所示:
setTimeout(function () {
person.getName();
}, 1000);
这是可以工作的,因为它从外部作用域获取 person
,然后调用 getName()
方法。
或者您可以使用 bind()
方法:
let f = person.getName.bind(person);
setTimeout(f, 1000);
在这段代码中:
- 首先,将
person.getName
方法绑定到person
对象。 - 其次,将已经绑定
this
值的函数f
,传递给setTimeout()
函数。
使用 bind 从不同的对象借用方法
假设您有一个 runner
对象,它有方法 run()
:
let runner = {
name: 'Runner',
run: function(speed) {
console.log(this.name + ' runs at ' + speed + ' mph.');
}
};
以及 flyer
对象,它有方法 fly()
:
let flyer = {
name: 'Flyer',
fly: function(speed) {
console.log(this.name + ' flies at ' + speed + ' mph.');
}
};
如果您希望 flyer
对象能够运行 run
,您可以使用 bind()
方法创建 run()
函数并将 run()
函数内部的 this
设置为 flyer
:
let run = runner.run.bind(flyer, 20);
run();
在这个声明中:
- 调用
runner.run()
的bind()
方法并且将flyer
对象作为第一个参数,20 作为第二个参数。 - 调用
run()
函数。
输出:
Flyer runs at 20 mph.
结论
bind()
方法创建一个函数,在调用时将this
设置为指定的值。bind()
方法允许一个对象从另一个对象借用方法,而无需复制该方法。这在 JavaScript 中称为函数借用。