方法重用:call() 和 apply()
- 不带参数的使用方法非常相似。
- 带参数的使用方法有所区别:
方法 | 参数 | 举例 |
---|---|---|
call() | 参数列表 | person.fullName.call(person1, “Oslo”, “Norway”); |
apply() | 数组形式 | person.fullName.apply(person1, [“Oslo”, “Norway”]); |
- 如果要使用数组而不是参数列表,则 apply() 方法非常方便。
面试题
语句var arr=[a,b,c,d];执行后,数组arr中每项都是一个整数,能得到其中最大整数语句有:
Math.max(arr[0], arr[1], arr[2], arr[3])
Math.max.call(Math, arr[0], arr[1], arr[2], arr[3])
Math.max.apply(Math,arr)
不能得到其中最大整数语句有:
1 | Math.max(arr) |
解析
Math的max()不支持传入数组,所以错误。
JavaScript 函数 Call
可以通过 call()
调用属于另一个对象的方法。
例子1:普通方法调用
- 下面的例子创建了带有三个属性的对象(firstName、lastName、fullName)。
1
2
3
4
5
6
7
8var person = {
firstName:"Bill",
lastName: "Gates",
fullName: function () {
return this.firstName + " " + this.lastName;
}
}
person.fullName(); // 将返回 "Bill Gates" - fullName 属性是一个方法。person 对象是该方法的拥有者。
- fullName 属性属于 person 对象的方法。
例子2:使用函数 Call
分别让person1与person2去调用person的fullName 方法:
1 | var person = { |
例子3:带参数的 call() 方法
让person1带着参数”Seattle”, “USA”去调用person的fullName属性(方法):
1 | var person = { |
JavaScript 函数 Apply
apply()
会改变this的指向,- 可以通过
apply()
方法调用属于另一个对象的方法。 - 但不仅限于此,当设置第一个参数为null时可以在某些本来需要写成遍历数组变量的任务中使用内建的函数,也就是说此时apply()的作用不是调用属于另一个对象的方法,而是使参数数组中的每一个元素都去执行func函数。【如:下方例子“使用Apply()在数组上模拟 max 方法”】
- call()方法的作用和 apply() 方法类似,区别就是call()方法接受的是参数列表,而apply()方法接受的是一个参数数组。
- apply() 方法调用一个具有给定this值的函数,以及作为一个数组(或类似数组对象)提供的参数。
- 语法:
func.apply(thisArg, [argsArray])
参数 | 描述 |
---|---|
thisArg | 可选的。 在 func 函数运行时使用的 this 值。 请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 null 或 undefined 时this会自动替换为指向全局对象,原始值会被包装。 |
argsArray | 可选的。 一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。 如果该参数的值为 null 或 undefined,则表示不需要传入任何参数。 从ECMAScript 5 开始可以使用类数组对象。 |
- 返回值:调用有指定this值和参数的函数的结果。
- 描述:在调用一个存在的函数时,你可以为其指定一个 this 对象。 this 指当前对象,也就是正在调用这个函数的对象。 使用 apply, 你可以只写一次这个方法然后在另一个对象中继承它,而不用在新对象中重复写该方法。
你也可以使用 arguments对象作为 argsArray 参数。 arguments 是一个函数的局部变量。 它可以被用作被调用对象的所有未指定的参数。 这样,你在使用apply函数的时候就不需要知道被调用对象的所有参数。 你可以使用arguments来把所有的参数传递给被调用对象。 被调用对象接下来就负责处理这些参数。
例子:使用函数Apply
让person1去调用person的fullName 方法:
1 | var person = { |
例子:带参数的 apply() 方法
apply() 方法接受数组中的参数:
1 | var person = { |
使用Apply()在数组上模拟 max 方法
Math的max()方法
首先我们了解可以使用 Math.max()
方法找到(数字列表中的)最大数字:
1 | Math.max(1,2,3); // 会返回 3 |
让数组调用Math的max()方法
但是JavaScript 数组没有 max() 方法,因此我们可以通过apply()让数组调用 Math的max() 方法:
1
Math.max.apply(null, [1,2,3]); // 也会返回 3
完整例子
第一个参数(null)无关紧要。在本例中未使用它。这些例子会给出相同的结果:
Math.max.apply(Math, [1,2,3]); // 也会返回 3
Math.max.apply(" ", [1,2,3]); // 也会返回 3
Math.max.apply(0, [1,2,3]); // 也会返回 3
JavaScript 严格模式
在 JavaScript 严格模式下,如果 apply()
方法的第一个参数不是对象,则它将成为被调用函数的所有者(对象)。在“非严格”模式下,它成为全局对象。
不能改变箭头函数this指向
- 注意: call, apply, bind 都不能改变箭头函数中的 this 指向
- 因为箭头函数的this只和定义时的作用域this有关,和调用者/调用环境无关,也永远不会改变