一.apply()方法介绍
Function 实例的 apply()
方法会以给定的 this
值和作为数组(或类数组对象)提供的 arguments
调用该函数。apply()
方法主要用于调用一个函数,并且可以指定函数内this
的指向以及以数组的形式传入参数。
二.实例演示
var o = {
uname: 'andy',
};
function fn(arr) {
console.log(this);
console.log(arr);
};
fn(11);
上面这段代码输出结果是 Window对象和 11,也就是说this指向Window对象。
我们再用apply()
方法看看调用函数发生了什么
var o = {
uname: 'andy',
};
function fn(arr) {
console.log(this);
console.log(arr);
};
fn.apply(o, ['pink', 'red']);
这次的输出结果是{uname: 'andy'}对象和 pink,也就是说this指向了o对象。由此我们可以知道apply方法它有两个参数apply(thisArg,argsArray),第一个参数决定了this的指向,是一个对象;第二个参数是一个类数组对象(数组或伪数组)。第二个参数不是必须的,函数没有参数可以不用。
三.对apply()方法第二个参数的理解
我学习的时候发现了一个问题:fn.apply(o, ['pink', 'red']);传进函数的是一个包含两个元素的数组,但是输出的确实pink这个字符串。难道不应该输出['pink', 'red']这个数组吗?搜索之后原因如下:
1.在 apply 方法中,第二个参数是一个数组(或伪数组),数组中的每个元素会作为单独的参数传递给函数。
2. apply 的第二个参数(数组)会拆分成多个实参传递给函数。
3. 函数能接收多少实参取决于它定义了多少形参。
4. 多余实参不会丢失,但需通过 arguments 或剩余参数(...args)访问 !!!!!!所以red其实也传进去了,但是并没有相应的形参来接收它,导致无法输出。
也就是说虽然传的是一个数组,但apply会将数组里面的每一个元素单独作为实参传给函数里,其实fn.apply(o, ['pink', 'red']);相当于是fn('pink','red');这样,传了'pink'和'red'两个实参, 但是函数fn(arr)只有一个形参,多的这个实参没有形参接收,但是多余的形参并没有丢失,可以通过arguments访问输出证明
var o = {
uname: 'andy',
};
function fn(arr) {
console.log(this);
console.log(arguments);
};
fn.apply(o, ['pink', 'red']);
输出结果
所以如果函数有两个形参就可以把另一个数组元素输出。
var o = {
uname: 'andy',
};
function fn(arr1, arr2) {
console.log(this);
console.log(arr1);
console.log(arr2);
};
fn.apply(o, ['pink', 'red']);
结果
四.常用示例
我们可以使用apply()方法结合Math.max() 和 Math.min() 来找出数组中的最大值和最小值。例如:
var arr = [1, 2, 3, 0, 23, 12, 10000, 45, 67, 99, 100];
var m = Math.max.apply(Math, arr); //相当于var m = Math.max(1, 2, 3, 0, 23, 12, 10000, 45, 67, 99, 100)
console.log(m);
可以输出 10000。
注意上面的fn(arr) 的例子和Math.max.apply(Math, arr)的区别,Math.max.apply(Math, arr)这里传进去的数组有11个元素,它能完全接收全部元素,因为Math.max()是一个可变参数函数,能接收任意数量参数。
场景 | fn(arr) 的例子 | Math.max.apply(Math, arr) 的例子 |
函数定义 | 只接受一个参数 arr | 接受任意数量参数(可变参数函数) |
apply 的作用 | 拆解数组,但函数只接收第一个参数 | 拆解数组,所有元素作为参数传给 Math.max |
结果 | 多余参数被忽略(需手动通过 arguments 访问) | 正确计算数组最大值 |