JAVASCRIPT 中的 call,apply,bind
Javascript 中有几个有趣的方法,它们位于 Function 对象原型上面,分别是:
- Function.prototype.call
- Function.prototype.apply
- Function.prototype.bind
今天我们就说说它们的用法和区别。
Function.prototype.call
MDN 上面是这样定义它的
fun.call(thisArg, arg1, arg2, …)
第一个参数是传递给 fun 的 this 对象,后面的参数则是 function 所接受的参数列表
1 | Math.max.call(null, 5, 6, 7, 1) // 7 |
因为 max 函数不需要 this 对象,所以一个参数可以传递 null 或者 undefined
1 | function helloWorld(){ |
上面例子可以看得出,我们能够通过使用 call 来动态的指定 function 中的 this 的真正对象。
上面的例子还能够得知,arguments 这个保留字就是在 function 中拿到参数列表的属性,同时使用 Array 对象原型上面的 slice 方法能够将其转化为数组。
1 | const args = [1, 2, 3, 4] |
使用 call 和 apply 来调用 javascript 对象原型方法需要理解其第一个参数 this 的含义,如同上面例子一样,我们一般使用 slice 的方法就是在一个 array 对象上面使用,就是这个 array 就是调用 slice 的 this 对象,所以使用 call 或者 apply 的时候,第一个参数就是 array 对象,就是需要使用 slice 的对象。后续的参数,才是传递给 slice 的参数。
Function.prototype.apply
MDN 上面是这样定义它的
func.apply(thisArg, [argsArray])
和 Function.prototype.call 类似,第一个参数是传递给func的this对象,但后面参数则是func的参数数组
1 | Math.max.apply(null, [5, 6, 7, 1]) // 7 |
Function.prototype.apply 也能够动态的改变func中的this对象
所以能够使用 call 的地方也能够使用 apply, 唯一需要改变的是把参数列表换成参数数组
1 | const args = [1, 2, 3, 4] |
Function.prototype.bind
MDN 上面这样定义它的
fun.bind(thisArg[, arg1[, arg2[, …]]])
它的第一个参数是传递给func的this对象,后面的参数则是传递给func的参数列表
1 | const obj = { |
bind 还有一个比较有意思的用法则是可以使一个函数拥有预设的一些初始参数。
1 | function addSomeNumber(){ |
从上面的例子可以看到,从bind的第二个参数开始,都是传递给func的参数,所以我们可以通过bind方法,给func默认指定一些参数
总结
Function.prototype.call和Function.prototype.apply 属于间接执行某个方法的另一种途径,同时它们拥有改变方法内部的this的对象的能力,也就是说,如果我们想改变某个方法内部的this的指向,则可以使用call或者apply。
Function.prototype.bind则是直接绑定方法的this指向,如果 bind 有两个以上的参数,那么后面的参数则作为方法的初始参数。因为bind完之后,方法并没有执行,所以还需要手动调用一次bind返回之后的函数