call
call()
方法使用一个指定的this
值和单独给出的一个或多个参数来调用一个函数。
function list() {
return Array.prototype.slice.call(arguments, 0, 1);
}
list(1, 2, 3, 4, 5); // [1]
我们经常能看到以上代码 Array.prototype.slice.call(arguments)
或者 [].slice.call(arguments)
,这种用法一般用在类数组对象想要使用数组方法的时候(如果你想直接用在数组上当然也不会报错,但是这样就多此一举了。然而有一些情况也是会用到数组上的,见 apply
)。
数组的所有方法都是挂在 Array
的 prototype
上的,如图:
而类数组对象本身是没有这些方法的,当然也无法调用:
那么想在一些对象上调用这个对象本身没有的方法就可以用 call
方法,以下图为例:
nodeList
是一个类数组对象它本身没有 slice
方法,所以调用的时候是 undefined
。
Array.prototype.slice.call(nodeList, 0, 1)
这段代码就相当于 nodeList.slice(0, 1)
。
因为 nodeList
没有 slice
方法而 Array.prototype
有,那么就在 Array.prototype
上调用 slice
方法,并且使用 call
方法让 slice
作用在 nodeList
上, call
方法的后两个参数就当作 slice
的参数传入。
当然,使用 [].slice.call(nodeList, 0, 1)
也是一样的,只要 slice
前面的对象上有 slice
这个方法就可以。
apply
的用法也是一样的, 区别是 apply()
方法接受的是一个参数数组。
apply
apply()
方法调用一个具有给定this
值的函数,以及作为一个数组(或类似数组对象)提供的参数。
var array = ['a', 'b'];
var elements = [0, 1, 2];
array.push.apply(array, elements);
console.info(array); // ["a", "b", 0, 1, 2]
上例中这一段代码 array.push.apply(array, elements)
相当于 array.push(0, 1, 2)
。
这里 array
是数组对象本身也有 push
方法,主要是用到 apply
将第二个参数 elements
这个数组参数拆成一个参数列表 0, 1, 2
。
虽然 apply
的第二个参数接收的是一个数组,但是它会把数组中的每一个元素依次作为给定调用方法的参数,而不是将这个数组作为一整个参数。
如果直接 array.push(elements)
,那么 elements
将作为一个元素插入到 array
中:
当 call
和 apply
的第一参数为 null
或 undefined
时,this
指向 window
(非严格模式下):
var numbers = [1, 3, 5, 7, 19];
Math.max.apply(null, numbers); // 19
Math.min.apply(null, numbers); // 1
bind
bind()
方法创建一个新的函数,在调用时设置this
关键字为提供的值。并在调用新函数时,将给定参数列表作为原函数的参数序列的前若干项。
var module = {
x: 42,
getX: function() {
return this.x;
}
}
var unboundGetX = module.getX;
unboundGetX(); // undefined
var boundGetX = unboundGetX.bind(module);
boundGetX(); // 42
参考
Function.prototype.call()
Function.prototype.apply()
Function.prototype.bind()