Le Sparte Le Sparte - 7 months ago 9
Javascript Question

How to add a method with ES6 Rest to a JS object

I have a Person constructor and I want to add a method supposed to add friends. I want to allow my user to pass a variable number of friends so I thought about the new "rest" feature of ES6. Sadly, I can't find my way out. Here's my first try (error : "Uncaught TypeError: f.addFriends is not a function(…)"):

// Persons creator
function Person(name){
this.name = name;
this.friends = [];
this.addFriends = function(...a){
a.forEach(function(d){this.friends.push(d)});
}
}

// Create three persons
f = new Person("Fanny");
e = new Person("Eric");
j = new Person("John");

// add Eric & Fanny as friends of Fanny
f.addFriends(e,j);


I've also tried the following code (no error, but no friends added):

// Persons creator
function Person(name){
this.name = name;
this.friends = [];
}

Person.prototype.addFriends = function(...a){
a.forEach(function(d){this.friends.push(d)});
}


// Create three persons
f = new Person("Fanny");
e = new Person("Eric");
j = new Person("John");

// add Eric & Fanny as friends of Fanny
f.addFriends(e,j);


What am I doing wrong?
Many thanks for your help!

Answer

Since you use a callback inside the forEach, the this doesn't refer to the object. Bind the callback to this:

Person.prototype.addFriends = function(...a){
   a.forEach(function(d){this.friends.push(d)}.bind(this));
}

Since we're using ES6, you can use an arrow function instead. Arrow functions lexically binds the this value:

Person.prototype.addFriends = function(...a){
   a.forEach((d) => this.friends.push(d));
}
Comments