改变this的指向

280 阅读1分钟

根据MDN整理,传送门:callapplybind

callapplybind都可以改变this的指向(将某个对象传递为this

callapply会立即执行;而bind是函数调用时执行,返回的是一个新的函数

callapply的区别

共同点

使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数,返回的是函数的返回值 || undefiend,即不传其他参数时它们的用法没什么不同

不同点

call() 方法接受的是一个参数列表,而 apply() 方法接受的是一个包含多个参数的数组,后面的参数可选

  • call

    // this 对象后面的参数可以有多个
    func.call(thisArg, args1, args2, ..., argsn)
    
  • apply

    // this对象后面的参数只能有一个,相当于[...argsArray]
    func.apply(thisArg, argsArray)
    
let arr1 = [1, 2, 3]
let arr2 = [4, 5]
let arr2 = [6, 7]

[].push.call(arr1, arr2) // 5 => arr1.push(arr2)
arr1 // [1, 2, 3, [4, 5]]
arr2 // [4, 5]

[].push.apply(arr1, arr2) // 7 => arr1.push([...arr2])
arr1 // [1, 2, 3, [4, 5], 4, 5]
arr2 // [4, 5]

bind

bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用

this.x = 9;    // 在浏览器中,this 指向全局的 "window" 对象
const module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); //  81

const retrieveX = module.getX;
retrieveX(); //  返回 9 - 因为函数是在全局作用域中调用的

// 创建一个新函数,把 'this' 绑定到 module 对象
// 新手可能会将全局变量 x 与 module 的属性 x 混淆
const boundGetX = retrieveX.bind(module);
boundGetX(); //  81