call
和apply
都是立即执行函数,并且可以指定函数的this
指向和参数,不同之处在于参数的传递方式(call
是逐个传递,apply
是以数组形式传递)。
而bind
则是返回一个新函数,可以在以后任何时间执行,同时也可以指定函数的this
指向和参数。
-
call():
call
方法可以改变函数的this
指向,并且立即执行该函数。它的第一个参数是this
要指向的对象,之后的参数是传递给函数的参数,参数列表是逐个传递的。例如:function greet(message) { console.log(message + ', ' + this.name); } var person = {name: 'Tom'}; greet.call(person, 'Hello'); // 输出: Hello, Tom
-
apply():
apply
方法的作用和call
方法类似,也是改变函数的this
指向并立即执行函数。不同之处在于apply
的参数是以数组的形式传递的。例如:function greet(message) { console.log(message + ', ' + this.name); } var person = {name: 'Tom'}; greet.apply(person, ['Hello']); // 输出: Hello, Tom
-
bind():
bind
方法不会立即执行函数,而是返回一个改变了this
指向的新函数,可以在之后任何时间执行。bind
的参数和call
的参数类似,是逐个传递的。例如:function greet(message) { console.log(message + ', ' + this.name); } var person = {name: 'Tom'}; var sayHello = greet.bind(person, 'Hello'); sayHello(); // 输出: Hello, Tom
bind方法和定时器setTimeout的例子
var person = {
name: 'Tom',
sayName: function() {
console.log(this.name);
}
};
// 使用bind方法改变setTimeout中回调函数的this指向
setTimeout(person.sayName.bind(person), 1000);
下面是一个结合bind
方法和定时器setTimeout
的例子:
var person = {
name: 'Tom',
sayName: function() {
console.log(this.name);
}
};
// 使用bind方法改变setTimeout中回调函数的this指向
setTimeout(person.sayName.bind(person), 1000);
person
对象有一个sayName
方法,用来打印对象的name
属性。
如果直接将person.sayName
作为setTimeout
的回调函数,那么在回调函数执行时,this
将指向全局对象(在浏览器中是window
),因此this.name
将不会是我们预期的'Tom'
。
为了解决这个问题,使用bind
方法创建了一个新的函数,这个新函数的this
被绑定到person
对象上。
然后,将这个新函数作为setTimeout
的回调函数。
这样,当定时器到时执行回调函数时,this
将正确地指向person
对象,因此this.name
将输出'Tom'
。