今天,介绍这两个方法的区别以及一些妙用,还有用法相似的 bind 的方法。
它们最主要的作用,是改变 this
的指向。在平时的工作中,除了在写一些基础类,或者公用库方法的时候会用到它们,其他时候应用场景并不多( React
我习惯用箭头函数)。
基本介绍
func.call(thisArg, arg1, arg2, ...)
func.apply(thisArg, [argsArray])
func.bind(thisArg[, arg1[, arg2[, ...]]])
简单来说,他们都是改变函数执行时的上下文,参数形式都是差不多的。
先来看 call()
和 apply()
两个方法,乍一看没啥区别,除了参数部分,也都是于JavaScript 1.3
中实现。
var test = {
color: '红色',
say: function(){
console.log("颜色是"+this.color)
}
}
test.say()
// 颜色是红色
var test2 = {
color:"黄色"
}
test.say.call(test2) // 颜色是黄色
test.say.apply(test2) // 颜色是黄色
这样看来确实很容易搞混,具体的区别看以下例子🌰
var test = {
color:'红色',
say:function(n,graph){
console.log(`${n}个${this.color}的${graph}`)
}
}
test.say.call({color:'绿色'}, 10, '矩形') // 10个绿色的矩形
test.say.apply({color:'蓝色'}, 2, '三角形') // Uncaught TypeError: CreateListFromArrayLike called on non-object
test.say.apply({color:'蓝色'}, [2, '三角形']) // 2个蓝色的三角形
昂,差别就是这个了,传入的参数形式不一样,因为现在有了展开符 来 传入/接受 参数,所以差异已经不大了,
但是在早期的环境中,如果不确定参数的话,一般都会选择用 apply
来一次性传入,并且使用 arguments
来处理。
说完了 apply
和 call
,再来说说 bind
bind
方法与 apply
和 call
很相似,也是可以改变函数体内 this
的指向。
bind()
方法创建一个新的函数,在bind()
被调用时,这个新函数的this
被指定为bind()
的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
还是举个例子来说吧:
var test = {
color: '红色',
say: function(){
console.log("颜色是"+this.color)
}
}
test.say()
// 颜色是红色
var test2 = {
color:"黄色"
}
test.say.call(test2) // 颜色是黄色
test.say.apply(test2) // 颜色是黄色
test.say.bind(test2) // f() {..}
// 可以看到bind()并没有输出,需要自执行或者赋值给一个变量然后调用
test.say.bind(test2)() // 颜色是黄色
var bindTest2 = test.say.bind(test2)
bindTest2() // 颜色是黄色
简单总结来说
call()
/apply()
/bind()
都可以改变函数内的this
指向;call()
/apply()
会立即执行函数,而bind()
不会立即执行;bind()
会返回一个新得函数,并不会马上执行;apply()
,传入的参数需要数组格式;fun.apply(thisArg, [arg1, arg2, ...])
↔fun.call(thisArg, arg1, arg2, ...)
bind()
传入的参数的方式和call()
一样。fun.call(thisArg, arg1, arg2, ...)
,fun.bind(thisArg, arg1, arg2, ...)
疑惑部分
1.bind()
传入的参数部分是否可以在 bind
的时候不传入,后续使用的时候在传入?
可以
function add(a, b) {
return a + b;
}
var add1 = add.bind(null);
console.log(add1(1,3)); // 4
var add2 = add.bind(null,10)
console.log(add2(5)); // 15
参考
Function.prototype.call() - MDN
Function.prototype.apply() - MDN
Function.prototype.bind() - MDN
OBKoro1 - js 面试官想了解你有多理解 call,apply,bind?
Micherwa - 「干货」细说 call、apply 以及 bind 的区别和用法
公子 - 如何理解,javascript bind
Schaos - 一次搞懂前端面試最愛問的 apply、bind、call