call, apply, bind三兄弟的用法和特点

253 阅读2分钟

这仨兄弟有个共同的存在意义:改变函数执行的上下文,或者说他们可以改变当前函数的执行环境,本质上其实就是可以改变函数this的指向。为什么要这么做呢?那是因为我们想在我们当前的函数中使用另一个函数的功能,从而实现函数复用,简化代码,提高代码可维护性。

三个方法的区别

这三个方法发挥的作用其实非常相似,但是还是有一些差别的。 call和apply的区别,他们俩之间的差别是参数的差别,call和apply的第一个参数都是要改变执行上下文的对象,但是call从第二个参数开始以参数列表的形式存在,apply则是把剩余的参数放在数组里作为第二个参数。

let arr = [1, 3, 2, 6];
console.log(Math.max.call(null, 1, 3, 2, 6)); // 6
console.log(Math.max.apply(null, arr1)); //6

call、apply和bind的区别 call和apply改变了函数的上下文后就开始执行,而bind则是返回了改变上下文后的一个函数,它不会立即执行,而是需要我们之后调用这个返回的函数。

call的用法

Function.call(obj, [param1, [param2, ... [,paramN]]]) 注意:

  • 调用call的对象必须是Function
  • call的第一个参数是对象,调用call的函数的this将指向这个对象,如果不传的话将默认为window。
  • 第二个参数开始后,可以接收任意多个参数,每一个参数都会映射到function相应参数位置上。

apply的用法

Function.apply(obj,[argArray]) 注意:

  • 它的调用者必须是一个Function
  • 第一参数必须是对象,这个和call一样
  • 第二个参数必须是数组或者类数组,并且会映射到function相应参数位置

bind的用法

Function.bind(obj,arg1[,arg2[,...]]]) 注意:

  • 如果第一个参数是null或者undefined,则this指向全局对象window
  • 使用bind返回一个新的函数,需要调用才能得到结果

使用案例和小技巧

  • call可以用于是实现继承
function superClass() {
    this.a = 1;
    this.print = function() {
        console.log(this.a);
    }
}

function subClass(){
    superClass.call(this);
    this.print();
}

subClass(); //1
  • call可以实现借用方法
  • apply可以用来求数组中的最大值
let max = Math.max.apply(null, array)
  • apply可以方便地实现数组的合并
let arr1 = [1,2,3];
let arr2 = [4,5,6];
Array.prototype.push.apply(arr1,arr2);
console.log(arr1); //[1,2,3,4,5,6]