根据一道题引起的call、apply、bind方法总结

这是一道今天遇到的面试题面试

clipboard.png

由于setTimeout属于匿名函数,this指向window,因此this.id = 1
但仍是先总结一下call和apply的用法。app

首先介绍一下call和apply的定义函数

obj.call(thisObj, arg1, arg2,...)
obj.apply(thisObj, [arg1, arg2,...])

call和apply的做用是改变函数运行时的上下文环境(改变this的指向),将obj绑定到thisObj,或者说this.Obj调用了obj里面的方法。this

call和apply的做用

当一个对象须要调用另一个对象里面的方法的时候,能够用到call和apply,call和apply能够理解成是继承另一个对象的方法。spa

首先咱们创建两个对象obj1和obj2code

clipboard.png

若是obj2对象要调用obj1中的func1方法(能够理解为在obj2的环境中执行obj1.func1方法),则对象

obj1.func1.call(obj2); //输出:obj2Name
 obj1.func1.apply(obj2);//输出:obj2Name

call和apply第一个参数都是表示obj1绑定的对象,若是obj1要绑定到this,此时obj1就是绑定到全局,如:blog

obj1.func1.call(this);//输出:windowName
 obj1.func1.apply(this);//输出:windowName

若是obj2对象要调用obj1中的func2方法,则继承

obj1.func2.call(obj2,1,2);//输出:3
  obj1.func2.apply(obj2,[1,2]);//输出:3

call和apply实现继承

使用call方法调用父构造函数ip

function Product(name, price) {
  this.name = name;
  this.price = price;

  if (price < 0) {
    throw RangeError(
      'Cannot create product ' + this.name + ' with a negative price'
    );
  }
}

function Food(name, price) {
  Product.call(this, name, price);
  this.category = 'food';
}

//等同于
function Food(name, price) {
  this.name = name;
  this.price = price;
  if (price < 0) {
    throw RangeError(
      'Cannot create product ' + this.name + ' with a negative price'
    );
  }

  this.category = 'food';
}

//function Toy 同上
function Toy(name, price) {
  Product.call(this, name, price);
  this.category = 'toy';
}

var cheese = new Food('feta', 5);
var fun = new Toy('robot', 40);

bind方法和call、apply的区别

bind方法也是用来改变this的指向

var a = {
    user:"追梦子",
    fn:function(){
        console.log(this.user);
    }
}
var b = a.fn;
b.bind(a);

没有被打印,这就是bind方法与apply、call方法的不一样。bind方法返回的是修改事后的函数

var a = {
    user:"追梦子",
    fn:function(){
        console.log(this.user); //追梦子
    }
}
var b = a.fn;
var c = b.bind(a);
c();

执行成功

相关文章
相关标签/搜索