call、apply、bind 的用法

this的动态切换,固然为 JavaScript 创造了巨大的灵活性,但也使得编程变得困难和模糊。有时,需要把this固定下来,避免出现意想不到的情况。JavaScript 提供了call、apply、bind这三个方法,来切换/固定this的指向。
1.Function.prototype.call()

func.call(thisValue, arg1, arg2, ...)

call方法,可以指定函数内部this的指向(即函数执行时所在的作用域),然后在所指定的作用域中,调用该函数。

1.call()可以接受多个参数,第一参数是this指向的那个对象,当第一个参数的值是undefined或者null时,this指向window;后面的参数时调用函数时所需的参数。
2.call方法的一个应用是调用对象的原生方法(原型上的方法)。

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

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

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

上面代码中,hasOwnProperty是obj对象继承的方法,如果这个方法一旦被覆盖,就不会得到正确结果。call方法可以解决这个问题,它将hasOwnProperty方法的原始定义放到obj对象上执行,这样无论obj上有没有同名方法,都不会影响结果。
2.Function.prototype.apply()
apply方法的作用与call方法类似,也是改变this指向,然后再调用该函数。唯一的区别就是,它接收一个数组作为函数执行时的参数,数组的所有成员依次作为参数,传入原函数。原函数的参数,在call方法中必须一个个添加,但是在apply方法中,必须以数组形式添加。

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

3.Function.prototype.bind()
由于apply方法(或者call方法)不仅绑定函数执行时所在的对象,还会立即执行函数,因此不得不把绑定语句写在一个函数体内。

bind方法用于将函数体内的this绑定到某个对象,然后返回一个新函数。
bind方法虽然与call,apply的用法有点不同,但是其作用也是一样的,也是可以改变函数体内this的指向。
MDN的解释是:bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。

function showColor(){
    console.log("my color is:" + this.color);
}
window.color = "red";
showColor.bind(window); 
showColor.bind(window)();    //my color is:red

apply、call、bind的不同之处。bind方法是创建一个函数,然后可以在需要调用的时候再执行函数,并非是立即执行函数;而call,apply是在改变了上下文中的this指向后并立即执行函数。

猜你喜欢

转载自blog.csdn.net/wang_liuyong/article/details/81539462
今日推荐