如何在这里进行apply / call / bind工作?

时间:2017-05-26 18:06:44

标签: javascript

我需要一只手来让它发挥作用 我以为我理解这个'但这真的很痛苦。

如果我运行此代码,第一个console.log按预期工作。它退出:' bob red,blue' ,this.name引用' bob'。

第二个console.log做了一些奇怪的事情,它注销了'结果为红色'并且'结果蓝色' - this.name引用'结果' 我不知道它得到了什么结果'但这不是我的主要问题。

我知道我可以var that = this提及“bob'与that.name。
我的主要问题是:你如何在第二个console.log中引用this.name引用' bob'使用apply / call或bind?



const person = {
  name: 'bob',
  cars: ['red', 'blue'],
  output: function() {
    console.log(this.name + ' ' + this.cars);
    this.cars.forEach(function(car) {
      console.log(`${this.name} ${car}`)
    })
  }
}

person.output()




3 个答案:

答案 0 :(得分:4)

我建议3种方法。首先,箭头功能(如果您的环境支持它):



const person = {
  name: 'bob',
  cars: ['red', 'blue'],
  output: function() {
    console.log(this.name + ' ' + this.cars);
    this.cars.forEach((car) => { // <--
      console.log(`${this.name} ${car}`);
    });
  }
}

person.output();
&#13;
&#13;
&#13;

接下来,将使用forEach本身的一项功能,并将this作为最后一个参数:

&#13;
&#13;
const person = {
  name: 'bob',
  cars: ['red', 'blue'],
  output: function() {
    console.log(this.name + ' ' + this.cars);
    this.cars.forEach(function(car) {
      console.log(`${this.name} ${car}`);
    }, this); // <--
  }
}

person.output();
&#13;
&#13;
&#13;

最后,你可以这样使用bind

&#13;
&#13;
const person = {
  name: 'bob',
  cars: ['red', 'blue'],
  output: function() {
    console.log(this.name + ' ' + this.cars);
    this.cars.forEach(function(car) {
      console.log(`${this.name} ${car}`);
    }.bind(this)); // <--
  }
}

person.output();
&#13;
&#13;
&#13;

从理论上讲,您可以使用applycall,但这样会更麻烦:

&#13;
&#13;
const person = {
  name: 'bob',
  cars: ['red', 'blue'],
  output: function() {
    console.log(this.name + ' ' + this.cars);
    function printCar(car) {
      console.log(`${this.name} ${car}`);
    }
    
    const self = this;
    this.cars.forEach(function(car) {
      printCar.call(self, car);
    });
  }
}

person.output();
&#13;
&#13;
&#13;

&#13;
&#13;
const person = {
  name: 'bob',
  cars: ['red', 'blue'],
  output: function() {
    console.log(this.name + ' ' + this.cars);
    function printCar(car) {
      console.log(`${this.name} ${car}`);
    }
    
    const self = this;
    this.cars.forEach(function(car) {
      printCar.apply(self, [car]);
    });
  }
}

person.output();
&#13;
&#13;
&#13;

答案 1 :(得分:1)

使用JavaScript,您需要缓存this,否则会丢失其上下文。使用箭头功能它可以工作(用function替换=>),但这是另一个故事。

更新示例:

&#13;
&#13;
const person = {
  name: 'bob',
  cars: ['red', 'blue'],
  output: function() {
    var that = this;
    console.log(this.name + ' ' + this.cars);
    this.cars.forEach(function(car) {
      console.log(`${that.name} ${car}`)
    })
  }
}

person.output()
&#13;
&#13;
&#13;

答案 2 :(得分:1)

这些是我现在能想到的所有组合。我还添加了箭头函数(没有词法环境)以及forEach的this参数的用法。

&#13;
&#13;
const person = {
	name: 'bob',
  cars: ['red', 'blue'],
  output: function() {
  	console.log(this.name + ' ' + this.cars);
    
    console.info("Arrow function");
    
    this.cars.forEach((car) => {
    	console.log(`${this.name} ${car}`)
    });
    
    console.info("thisArg of forEach");
    
    this.cars.forEach(function (car) {
    	console.log(`${this.name} ${car}`)
    }, this);
    
    console.info(".bind()");
    
    this.cars.forEach(function (car) {
    	console.log(`${this.name} ${car}`)
    }.bind(this));
    
    console.info(".call()");
    
    (function (cars) {
      for (let c of cars) {
    	  console.log(`${this.name} ${c}`)
      }
    }).call(this, this.cars);   
    
    console.info(".apply()");
    
    (function (...cars) {
      for (let c of cars) {
    	  console.log(`${this.name} ${c}`)
      }
    }).apply(this, this.cars);   
  }
}

person.output()
&#13;
&#13;
&#13;