天天看点

call()与apply()的区别

JavaScript函数,事实上是对象,他们均有两个非继承而来的方法,它们就是

call()

apply()

,它们在函数中扮演着什么样的角色呢?

它们俩其实功能是一样一样的,都是在特定的作用域中调用函数,就等于设置函数体中

this

对象的值。但是,它们也有各自的特点。

call()

可以传多个参数,第一个参数是一个对象,后面的参数就是该函数的参数。

apply()

最多只能传两个参数,第一个参数是一个对象,第二个参数是该函数参数组成的数组,也可以是

arguments

对象。

说了这么多文绉绉的东西,举个栗子吧~~~

var name = "李四";
var zhangsan = {
    name: "张三",
    age: 18
};
function getName(){
    return this.name; 
}
function add(a,b){
    return this.age+a+b;
}
console.log(getName());    //  "李四"
console.log(getName.call(zhangsan));    //  "张三"
console.log(add.apply(zhangsan,[2,3]));    //  23
           

第一个输出

"李四"

,这个很好理解,因为

getName()

如果直接执行的话,其

this

指针指向的是

window

,因为

getName()

属于全局函数;

第二个输出

"张三"

,根据上面讲的

call()

的作用可知,此时

getName()

中的

this

指针指向不再是

window

,而改成了

zhangsan

,所以自然

getName()

执行后返回的是

zhangsan.name

;

第三个输出

23

apply()

作用与

call()

作用一致可知,此时

add()

this

指针指向

zhangsan

,而

add

参数中的

a

b

则一 一对应数组

[2,3]

中的每一项,所以

add()

zhangsan.age+2+3

,计算结果为

23

等等,上面提到的

arguments

是什么鬼?在例子中怎么没有出现?

其实嘛,

arguments

是个一种长得很像数组的类数组对象,它也具有

length

属性,却不具有数组的其他方法,所以它并不是数组,可以看做是由函数实参组成的一个集合。

说了这么多,

call()

apply()

到底在实际项目中有什么用呢?

我个人觉得,这两者最大作用莫过于实现对象间的继承了。比如上面提到的那个

arguments

,它不是数组,但是如果想将它变为数组,这该如何实现?

这时

call()

就可以派上用场了。通过

Array.prototype.slice.call(arguments)

就可以将

arguments

这样的类数组转成真正的数组。

再比如,通过

Math.max.apply(null,arr)

这样的方式可以取得一个

arr

数组中的最大值。这是因为

Math.max()

如果直接调用的话是不能够直接传入数组的,必须要一个个参数传进去,所以通过

apply()

可以很方便的实现取数组最大值的功能。

本文重点总结

① call() 与 apply() 功能基本一致,都是用于改变函数作用域

② call() 可以传多个参数,第一个参数后的所有参数为该函数的参数;apply() 只能传两个参数, 且第二个参数是该函数的参数所组成的数组或arguments对象

继续阅读