每个函数都包含两个非继承而来的方法:apply()与call()。
这两个方法除了接收的参数不同,功能上相差无几,二者用途皆为在某作用域中调用函数,修改函数体内的this指向。
用例子通俗易懂的解释:
window.color = 'red'
let obj = {color: 'blue'}
function ff() {
console.log(this)
return this.color
}
我们在全局中定义一个color和一个对象,一个函数。
直接执行 ff()
函数:
因为是在全局中调用,所以this指向全局,打印的值为:red。
使用 ff.apply(obj)
:
此时的this指向obj对象,所以打印的值为:blue。
使用 ff.call(obj)
:
与apply一样,this指向obj对象,打印的值为:blue。
我们可以看到,二者在不传参的情况下,作用一致,接下来我们看一下传参各自的表现.
修改一下代码,打印接收到arguments
window.color = 'red'
let obj = {color: 'blue'}
function ff() {
console.log('arguments.length',arguments.length)
console.log(arguments)
return this.color
}
使用 ff.apply(obj,['one','two','three'])
:
我们可以的看到,传入的参数是一个具有三个项的数组,但是打印出来的是三个分开单独参数,且arguments的长度也为3。
传入非数组参数apply会报错,因为只能接收数组或类数组对象。
ff.apply(obj,'one')
使用 ff.call(obj,['one','two','three'])
:
使用call()和apply的不同点是,传入的是一个数组,打印出来的参数也就是一个数组,rguments的长度为1。
如果我们想让其分别传递,就只能将参数分开传递:ff.call(obj,'one','two','three')
总结
二者在功能上并无差异,仅仅只是在处理传递进来的参数上有所区别,何时使用apply何时使用call,完全取决于使用场景,如果我们想要传入数组参数或者arguments,apply更方便,否则就是call方便,但是我们要记得,apply只能接收数组或arguments,call是其他类型都能接收。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。