call ,apply ,bind 的用法

158 阅读2分钟

在JavaScript中,this的动态切换使变成变得模糊和困难。call, apply, bind 都是Function对象自带的方法,其作用在于切换/固定this的指向。

  • Function.prototype.call

call()  方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。

call() 可以指定函数内部this的指向,在其所指定的作用域中,调用该函数;call方法的参数应该是一个对象,如果参数为空,null,undefined,则默认传入全局对象。

var n = 123;
var obj = { n: 456 };

function a() {
  console.log(this.n);
}

a.call() // 123
a.call(null) // 123
a.call(undefined) // 123
a.call(window) // 123
a.call(obj) // 456

call可以用来调用对象的原生方法。

var obj = {};
obj.hasOwnProperty('toString') // false

// 覆盖掉继承的 hasOwnProperty 方法
obj.hasOwnProperty = function () {
  return true;
};
obj.hasOwnProperty('toString') // true

Object.prototype.hasOwnProperty.call(obj, 'toString') // false
  • Funciton.prototype.apply()

apply() 方法调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。

apply方法的作用与call方法类似,也是改变this指向,然后再调用该函数。唯一的区别就是,它接收一个数组作为函数执行时的参数.其使用格式为:

func.apply(thisValue, [arg1, arg2, ...])

apply方法的第一个参数也是this所要指向的那个对象,如果设为nullundefined,则等同于指定全局对象。第二个参数则是一个数组,该数组的所有成员依次作为参数,传入原函数。

function f(x, y){
  console.log(x + y);
}

f.call(null, 1, 1) // 2
f.apply(null, [1, 1]) // 2
  • Function.prototype.bind()

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

bind方法的参数就是所要绑定this的对象:

var counter = {
  count: 0,
  inc: function () {
    this.count++;
  }
};

var func = counter.inc.bind(counter);
func();
counter.count // 1

如果bind方法的第一个参数是nullundefined,等于将this绑定到全局对象,函数运行时this指向顶层对象

function add(x, y) {
  return x + y;
}

var plus5 = add.bind(null, 5);
plus5(10) // 15