apply、call
阅读 1.5k
在JavaScript中,每个函数都包含两个方法:apply()和call()。本篇就来说说这两个方法。
apply
在初学JavaScript时,我一直有个疑惑,为什么要设计这么一个方法呢?如果是为了改变作用域
,有bind()方法,在仔细思考了它的命名和接受的参数特征后,我慢慢明白了,它是一种特殊的调用函数
的方式,和bind()方法有着本质的不同,bind()只是绑定函数作用域,并没有调用函数,而apply()则是指定作用域的同时,用指定的参数来调用函数,用apply这个命名,名副其实。
该方法的语法如下:
func.apply(thisArg, [argsArray])
它接收两个参数:
- thisArg:必选的。在
func
函数运行时使用的this
值。 - argsArray:可选的。一个数组或者类数组对象。
先来看一个常用的例子:
const numbers = [5, 6, 2, 3, 7]
const max = Math.max.apply(null, numbers) // 7
因为Math.max()无法接受数组
作为参数,而apply()则可以。所以,上面的方法能够得到数组中的最大值。
再来看一个小例子:
function sayName() {
console.log(this.name, arguments)
}
window.name = 'foo'
const obj = { name: 'bar' }
sayName(10, 20, 30) // 直接调用
sayName.bind(obj)(10, 20, 30) // 绑定obj后调用
sayName.apply(obj, [10, 20, 30]) // 用apply()方法调用
上面用了三种调用函数的方法,第一种,就是最常用的调用方式,函数名后接()直接调用;第二种,通过绑定this后再进行调用(其实也属于第一种调用方式);第三种,则是通过apply()方法来调用。
call
理解了apply()之后,那么call()就容易理解了,他们二者唯一的区别就是第二项参数的不同,来看看它的语法:
function.call(thisArg, arg1, arg2, ...)
来看一个例子:
function sayName() {
console.log(this.name, arguments)
}
window.name = 'foo'
const obj = { name: 'bar' }
sayName(10, 20, 30) // 直接调用
sayName.apply(obj, [10, 20, 30]) // 用apply()调用
sayName.call(obj, 10, 20, 30) // 用call()调用
还是上面的例子,用apply()调用使用的是一个数组,而用call则是一个一个的值,它们二者得到的结果是完全一样的。
小结
和bind()不同,bind()只是绑定函数体中的this值,并不进行函数调用,而apply()和call()都是调用函数,可以说,它们作为一种特殊的调用方式,一种更强大的调用方式,给函数调用提供了更多的灵活性。
最后编辑于: 2022-09-26