This is trouble

I’ve run into a bit of JS this trouble. Take a look a this dog object:

var dogs = [];

function Dog(name){
  this.name = name;

  this.bark = function(){
    console.log("Woof! My name is" + this.name);
  }
  this.friends = function(){
    dogs.forEach(function(dog){
      console.log("My name is " + this.name + " and I'm friends with " + dog.name);
    });
  }
}

ruffy = new Dog("ruffy");
rex = new Dog("rex");
spot = new Dog("spot");

dogs.push(ruffy, rex, spot);

ruffy.bark();
ruffy.friends();

When I run ruffy.bark(), I get Woof! My name is ruffy So, then, what would you expect the the result of ruffy.friends() to be? Here’s what I’m getting:

My name is undefined and I'm friends with ruffy
My name is undefined and I'm friends with rex
My name is undefined and I'm friends with spot

This was strange, because I figured this would refer to the object – after all, the same technique works for getting the dog’s name!

After a bit of console.log-ging, I’ve found that in bark() this refers to the Dog object, but within the forEach loop, this refers to the global variable. I’ve found a few fixes:

  1. use a for loop instead of a forEach loop
  2. use the ES6 for of loop
  3. create a variable to store this outside of the forEach  loop.
this.friends = function(){
  var self = this;                 // self == this, the object instance calling the method
  dogs.forEach(function(dog){
    console.log("My name is " + self.name + " and I'm friends with " + dog.name);
  });
}

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s