call,apply和bind都是JavaScript中的函数方法,它们都可以改变函数调用时this的指向。不过它们之间各有其特定的使用场景和差异。
call: call()方法接受一个参数列表,这个方法无需改变函数的调用时机,可立即执行函数。常常用来借用别的对象的方法。
func.call(thisArg, arg1, arg2, ...)
apply: apply()方法接受一个包含多个参数的数组,与call()类似,apply()也会立即执行函数。当你不知道要传递给函数多少个参数,或者参数是作为一个数组存在时,apply()非常有用。
func.apply(thisArg, [argsArray])
bind: bind()方法返回一个新的函数,使得这个新函数将this设置为bind()的第一个参数。bind()不会立即执行函数,而是返回一个绑定了正确this值的新函数,这点是bind()和call()、apply()的主要区别。bind()非常适合用在事件监听上。
newFunc = func.bind(thisArg[, arg1[, arg2[, ...]]])
总结一下:
call和apply都是为了解决不同对象之间方法的借用,包括他们的参数列表形式不同之处。
bind是将函数体内this对象绑定为指定对象,返回一个新函数,供日后调用。
apply和call都会立即执行函数,而bind不会。
案例:
// // 数组连接(concatenate): 使用apply将一个数组添加到另一个数组的末尾。
let array1 = [1, 2, 3]
let array2 = [4, 5, 6]
Array.prototype.push.apply(array1, array2)
console.log(array1) // 输出: [1, 2, 3, 4, 5, 6]
// // 这个例子中,apply方法改变了push方法的上下文并执行它,新的上下文是array1,参数是array2。
// // // 找到数组中的最大值: 使用apply或者call找到数组中的最大值
let array = [1, 2, 3, 4, 5]
console.log(Math.max.apply(null, array)); //5
// // 在这个例子中,apply方法更改了Math.max的上下文并执行它,通过传递数组作为参数。同样,call也可帮助我们达到同样的效果:
console.log(Math.max.call(null, ...array)); //5
// // 这里...array是ES6的语法特性,它将数组转为参数序列。
// 函数柯里化: bind经常用于函数柯里化。它允许你部分地应用函数,将其余的参数留到函数被实际调用时指定。
function add(x) {
return function (y) {
return x + y
}
}
let add5 = add(5).bind(this);
console.log(add5(3));
// 在这个例子中,bind方法创建了一个新的add5函数,它是add(5)的一个固定版本,现在它总是将5作为第一个参数加到其余的参数上。