user2111743
user2111743

Reputation: 69

Writing an Extend Method in Javascript

I am wondering if someone could help me to understand why it is necessary to add the following line...

if (!obj.hasOwnProperty(key)) continue;

... in the following method:

extend: function(obj) {
  // shallow copy
  for (var key in obj) {
    if (!obj.hasOwnProperty(key)) continue;
      this[key] = obj[key];
  }
}

Upvotes: 0

Views: 62

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074385

When you use for-in to loop through the names of the properties of an object, you see all of the enumerable properties, including those the object inherits from its prototype. It would appear that the person implementing that method didn't want to copy properties inherited from the prototype, and so only included ones that the object itself directly owns.

Here's an example:

function Thing(name) {
    this.name = name;
}
Thing.prototype.speak = function() {
    console.log("I'm " + this.name);
};
Thing.prototype.infoForAllThings = 42;
var t1 = new Thing("Fred");
console.log(t1.name);             // "Fred"
console.log(t1.infoForAllThings); // "42"
t1.speak();                       // "I'm Fred"
var t2 = extend(t1);              // (Where `extend` is like your function,
                                  // but returns the object rather than using `this`
console.log(t2.name);             // "Fred"
console.log(t2.infoForAllThings); // "undefined"
t2.speak();                       // Error

In the above, t1 inherits the infoForAllThings and speak properties from its prototype, which gets set to Thing.prototype when t1 is created. But the extend function uses hasOwnProperty to filter those out, so doesn't copy them to the copy it creates, and so they don't exist on t2. t2 has name because that's been assigned directly to the object, it doesn't come from the prototype, but the others come from the prototype and so don't get copied.

Upvotes: 2

Related Questions