1、作用

  1. 都是为了改变某个函数运行时的上下文(context),也就是改变函数内部的this指向,继承其他对象的属性。
  2. 三个方法是每个函数都有的__proto__,而且是非继承而来的方法。

通俗来讲,A、B为构造函数对象,A有C方法,B没有C方法。

如果你想让B去调用C方法,就使用A.C.apply(B) or A.C.call(B) or A.C.bind(B);

2、使用方式

​ apply(obj, []): apply方法后面跟两个参数,第一个参数是要指向的obj对象,第二个参数是数组。

​ call(obj, property):call方法后面跟多个参数,第一个参数是要指向的obj对象,从第二个参数起就是单个要传递的属性。

​ bind(obj, [])(): 相比于apply来说,使用上加个().

以Person为例,使用Person.apply(this, [name, age])。

// 定义Person类
function Person (name, age) {
  this.name = name;
  this.age = age;
  this.getPersonInfo = function() {
  	console.log(`姓名:${this.name} 年龄:${this.age}`)
  }
}

// 定义学生类
function Student (name, age, grade) {
  Person.apply(this, [name, age]); // 这里使用apply,其中第一个参数是this,指向student
  this.grade = grade;
}

let student = new Student('xiaming', 18, '1');
console.log(student);
student.getPersonInfo();

打印结果:

从打印结果上看,student多了name,age以及getPersonInfo(),其来源就是继承于Person。

call 比 apply 的性能要好,平常可以多用 call, call 传入参数的格式正是内部所需要的格式。

3、关于apply的思考

我们在调用apply()的时候,第二个参数是个数组,它可以将数组( [ param1, param2, param3] )默认转化成属性参数的形式(param1, param2, param3),利用这一特点可以在需要属性传值的地方使用apply()传入对应数组,简化代码。

例如我们要取数组的最大值,但是Math.max()不支持传入数组,这时候可以使用Math.max(null, arr)。这里第一个参数传入null,是因为没有对象去调用这回方法,我们只需要调用到Math的max()返回结果就行了。

4、使用场景

  1. 继承。如上例person.

  2. 获取数组最大值或者最小值。 最大值:Math.max.apply(null, arr); 最小值: Math.min.apply(null, arr)

  3. 合并数组,但是不会去重。

let arr1 = [1, 2, 3], arr2 = [3, 5, 6];
Array.prototype.push.apply(arr1, arr2);
console.log(arr1); // 打印 [1, 2, 3, 3, 5, 6]
console.log(arr2); // 打印 [1, 2, 3]