0

I've been testing JavaScript's Object.prototype.hasOwnProperty. From my understanding, it is designed to weed out direct object properties from inherited object properties.

However, in the contrived examples I've tested so far (including MDN's own's example), I have been unsuccessful at console-logging inherited properties (i.e. toString) when .hasOwnProperty() returns false, which makes me a bit skeptical on its functionality. So,

1) Could you provide example code which I can run in the console, that will log inherited properties when hasOwnProperty() returns false?

2) When adding the hasOwnProperty tag to this question, the SO description that popped up states "...does not traverse through the prototype chain". If that's the case, what is the point of Mozilla's example below, since the "else clause will never be executed?

Here's Mozilla's example code:

var buz = {   fog: 'stack' };

for (var name in buz) {   if (buz.hasOwnProperty(name)) {
      console.log('this is fog (' + name + ') for sure. Value: ' + buz[name]);   
  } else {
      console.log(name); // toString or something else
  }
}
Govind Rai
  • 14,406
  • 9
  • 72
  • 83
  • 2
    `for...in` only iterates over *enumerable* properties. All the properties on `Object.prototype` are not enumerable. An example that would look inherited properties: `var foo = {abc: 123}; var buz = Object.create(foo, {fog: {value: 'stack', enumerable: true}}); /*your for loop */`. – Felix Kling Jan 10 '17 at 02:12
  • @FelixKling Make that an answer? – Barmar Jan 10 '17 at 02:24
  • @FelixKling you're absolutely right. what a succint comment and answer... – Govind Rai Jan 10 '17 at 02:27
  • You don't need `hasOwnProperty` inside usual `for … in` loops. – Bergi Jan 10 '17 at 02:49
  • @Bergi by complete luck discovered why `hasOwnProperty` can be useful in `for...in` loops. Added a second answer to the question. – Govind Rai Jan 10 '17 at 05:44
  • @GovindRai You'll hardly ever use a `for … in` loop on an object that *has* inherited enumerable properties. And even then, in 95 percent of the case the solution is to make the properties non-enumerable, not to add a `hasOwnProperty` call to the loop. – Bergi Jan 10 '17 at 15:08

2 Answers2

1

for...in only iterates over enumerable properties. All the properties on Object.prototype are not enumerable, so they won't actually be iterated over.

Here is an example that would show inherited properties. We create a new object that inherits from another object, not from Object.prototype:

var foo = {abc: 123};
// Creates an object with property `fog: 'stack'` but has `foo` as its prototype
var buz = Object.create(foo, {fog: {value: 'stack', enumerable: true}}); 

for (var name in buz) {
  if (Object.prototype.hasOwnProperty.call(buz, name)) {
    console.log('this is fog (' + name + ') for sure. Value: ' + buz[name]);   
  } else {
    console.log(name); // toString or something else
  }
}

(of course we could also assign to Object.prototype, but we are trying to be good citizens :) )

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
0

Using a for...in loop without hasOwnProperty() will return enumerable properties from the prototype chain.

This is an answer to Part 2 of my question. Excerpt from the MDN site, but hidden under Object.getOwnPropertyNames()

If you want only the enumerable properties, see Object.keys() or use a for...in loop (although note that this will return enumerable properties not found directly upon that object but also along the prototype chain for the object unless the latter is filtered with hasOwnProperty()).

So, even though the object that is created in the MDN example has no inherited, enumerable properties, if those criteria were met, you would see the difference in output, (namely more properties would be logged to the console), if you were to not employ hasOwnProperty().

Govind Rai
  • 14,406
  • 9
  • 72
  • 83