在全局上下文中运行的Javascript中的绑定函数

时间:2016-07-02 19:31:19

标签: javascript binding bind

我一直在试图弄清楚如何让这段代码发挥作用。我的目标是通过将larry eats pie, larry eats candy, larry eats cake对象中的函数eats绑定到alice对象来生成输出larry。我希望下面的代码是将alice.eats函数绑定到larry对象将larry用作this.name,然后使用larryFoods数组应用该函数,I希望它会为每个参数产生larry eats + [food]

//-----------------Does not work--------------//
var alice = {
      name: "alice",
      speak: function(){
      console.log("Hi, I'm " + this.name);
      },
      eats : function(){
        var theArgs = Array.prototype.slice.call(arguments);
        theArgs.forEach(function(arg){
          console.log(this.name + " eats " + arg);
        });
      }
};
var larry = {
    name: "larry"
};
var larrySpeak = alice.speak.bind(larry);
larrySpeak();
var larryFoods = [" pie", " candy", " and cake"];
var larryEats = alice.eats.bind(larry);
larryEats.apply(larryFoods);

我假设forEach函数将在全局上下文中运行,这就是为什么我希望bind能够解决问题。任何见解都是最受欢迎的。

2 个答案:

答案 0 :(得分:1)

this不适用于"#34;在forEach函数中的eats内。或视觉上:

theArgs.forEach(function(arg){
    // "this".name is trying to resolve name according to the scope of the forEach
    console.log(this.name + " eats " + arg);
});

你可以在eats函数中解决这个问题:

var scope = this;
theArgs.forEach(function(arg){
    console.log(scope.name + " eats " + arg);
});

最后,您需要在最后一行修复apply的使用。 apply需要绑定的上下文。由于您已将函数绑定到larry,因此您可以将null作为第一个参数传递:

此:

larryEats.apply(larryFoods);

应该是:

larryEats.apply(null, larryFoods);

解决这些问题之后,这是一个有效的例子:



var alice = {
  name: "alice",
  speak: function() {
    console.log("Hi, I'm " + this.name);
  },
  eats: function() {
    var theArgs = Array.prototype.slice.call(arguments);
    var scope = this;
    theArgs.forEach(function(arg) {
      console.log(scope.name + " eats " + arg);
    });
  }
};
var larry = {
  name: "larry"
};
var larrySpeak = alice.speak.bind(larry);
larrySpeak();
var larryFoods = ["pie", "candy", "and cake"];
var larryEats = alice.eats.bind(larry);
larryEats.apply(null, larryFoods);




答案 1 :(得分:0)

这对我有用:

var alice = {
      name: "alice",
      speak: function(){
      console.log("Hi, I'm " + this.name);
      },
      eats : function(){
        var theArgs = Array.prototype.slice.call(arguments);
        let that = this;
        theArgs.forEach(function(arg){
          console.log(that.name + " eats " + arg);
        });
      }
};
var larry = {
    name: "larry"
};
var larrySpeak = alice.speak.bind(larry);
larrySpeak();
var larryFoods = [" pie", " candy", " and cake"];
var larryEats = alice.eats;
larryEats.apply(larry, larryFoods);