0

I've been driving myself a bit mad trying to figure out how to make this code work. My goal is to produce the output larry eats pie, larry eats candy, larry eats cake by binding the function eats within the alice object to the larry object. My hope with the code below was that binding the alice.eats function to the larry object would use larry as this.name, and subsequently applying that function using an array of larryFoods, I would hope that it would produce larry eats + [food] for each argument.

//-----------------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);

I am assuming that the forEach function will operate in the global context, which is why I was hoping bind would solve the problem. Any insight would be most welcome.

1
  • Note that the forEach callback has a new this, so you lost the context there. Commented Jul 2, 2016 at 19:34

2 Answers 2

1

this is not scoped to the "person" inside of your forEach in the eats function. Or visually:

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

You can fix this like this inside of the eats function:

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

Finally, you will need to fix your use of apply at the very last line. apply needs a context to bind to. Since you already bound the function to larry, you can just pass null as the first argument:

This:

larryEats.apply(larryFoods);

should be:

larryEats.apply(null, larryFoods);

After fixing those things, here is a working example:

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);

Sign up to request clarification or add additional context in comments.

Comments

0

This works for me :

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.