概念
call,apply都属于Function.prototype的一个方法,它是JavaScript引擎内在实现的,因为属于Function.prototype,所以每个Function对象实例(就是每个方法)都有call,apply属性,可以通过函数对象来调用。
apply()
apply()方法调用一个具有给定this值的函数,以及以一个数组(或一个类数组对象)的形式提供的参数。
基本语法:
apply(thisArg)
apply(thisArg, argsArray)
参数:
thisArg:在func函数运行时使用的this值 (该参数是谁,this值就是谁)。请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为null或undefined时会自动替换为指向全局对象,原始值会被包装。
argsArray(可选):一个数组或者类数组对象,其中的数组元素将作为单独的参数传给func函数。如果该参数的值为null或undefined,则表示不需要传入任何参数。从ECMAScript5开始可以使用类数组对象。
call()
call()方法使用一个指定的this值和单独给出的一个或多个参数来调用一个函数。
基本语法:
function.call(thisArg, arg1, arg2, ...)
参数:
thisArg 可选的。在 function 函数运行时使用的值。请注意,可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为this、null或undefined时会自动替换为指向全局对象,原始值会被包装。
arg1, arg2, ... 指定的参数列表。
注意:call方法可以用来代替另一个对象调用一个方法,call方法可以将一个函数的对象上下文从初始的上下文改变为thisObj指定的新对象,如果没有提供thisObj参数,那么Global对象被用于thisObj。
作用:
call()方法和apply()方法的作用相同:改变this指向。
区别(接收参数的方式不同):
apply():接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。
call(): 第一个参数和apply()方法的一样,变化的是其余参数都直接传递给函数。在使用call()方法时,传递给函数的参数必须逐个列举出来。
关于this指向的回顾与补充:
1、以函数的形式调用时,this永远都是window。
2、以方法的形式调用时,this就是调用方法的那个对象。
3、以构造函数的形式调用时,this就是新创建的那个对象。
4、使用call和apply调用时,this是指定的那个对象。
arguments
在调用函数时,浏览器每次都会传递进两个隐含的参数:
1、函数的上下文对象this
2、封装实参的对象arguments
arguments是一个类数组对象,它也可以通过索引来操作数据,也可以获取长度。在调用函数时,我们所传递的实参都会在arguments中保存。arguments.length可以用来获取实参的长度。我们即使不定义形参,也可以通过arguments来使用实参,只不过比较麻烦。
arguments[0] 表示第一个实参
arguments[1] 表示第二个实参
它里面有一个属性叫做callee。这个属性对应一个函数对象。
示例:
<script>
const numbers = [5, 6, 2, 3, 7];
// 指定为 null 或 undefined 时会自动替换为指向全局对象
const max = Math.max.apply(null, numbers);
console.log(max);
const min = Math.min.apply(null, numbers);
console.log(min);
const array = ['a', 'b'];
const elements = [0, 1, 2];
// 用 apply 将数组各项添加到另一个数组
array.push.apply(array, elements);
console.info(array);
function greet() {
var reply = [this.animal, '睡觉时间通常在', this.sleepDuration].join(' ');
console.log(reply);
}
var obj = {
animal: 'cats', sleepDuration: '12 and 16 hours'
};
// 当调用方法的时候,该方法的值会绑定到对象
greet.call(obj);
function fun(a, b) {
console.log(arguments instanceof Array);
console.log(Array.isArray(arguments));
console.log(arguments[1]);
console.log(arguments.length);
console.log(arguments.callee);
console.log(arguments.callee == fun);
}
fun(5, 10);
</script>