6

It is recommended to always use hasOwnProperty, but in many cases this is not needed. For example consider the following code:

var object = JSON.parse(somejsontext);
for(var prop in object) {
   console.log(object[prop]);
}

I know in this case that prop is part of the object, it is explict define by the for..in.

But according to MOZ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty we should use it to avoid iterating over non-enumarable props, with this example:

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
  }
}

But testing this code actually, never goes to the else.

So when does make sense the use of hasOwnProperty ?

UPDATE: Considering the choosen answer, we can safetly avoid the use of hasOwnProperty in this cases: - Object js has not been extended by any javascript library or by our code - Object is a simple code that we have control on

albanx
  • 6,193
  • 9
  • 67
  • 97

1 Answers1

7

The problem arises when a prototype includes enumerable properties that your code did not anticipate. For example, suppose this ran just before your example:

Object.prototype.foobar = "hello";

In this case, iterating over buz would include the enumerable foobar prototype property. This hasOwnProperty pattern allows your code to differentiate between properties that are directly on the object, versus properties that are inherited from a prototypal ancestor.

The problem is not "enumerating over non-enumerable properties" (that's by definition not possible, unless you explicitly get them via getOwnPropertyNames for each level of the prototype hierarchy), but rather enumerating over inherited properties. This is a concern when using libraries that may add enumerable properties to high-level prototypes, exactly as I have illustrated above.

If you want to add a property to a prototype without causing that property to be enumerated, you can make a non-enumerable property with Object.defineProperty:

Object.defineProperty(Object.prototype, "foobar", {
    value: "hello",
    enumerable: false,
    writeable: true,
    configurable: true
});

Such a property would not appear in a for..in loop on buz (or in a for..in loop directly on Object.prototype, either).

apsillers
  • 112,806
  • 17
  • 235
  • 239
  • yes but it would make no sense when having the control of you code, ( hoping that a library does not have extend the prototype of a basic object ) – albanx Aug 12 '15 at 16:06
  • @albanx Many libraries extend native objects heavily, even `Object.prototype` might be extended. – Teemu Aug 12 '15 at 16:09
  • But in the mozilla example why it does not itarete through the toString method. . – albanx Aug 12 '15 at 16:17
  • @albanx Because `Object.prototype.toString` is not enumerable; see that `Object.getOwnPropertyDescriptor(Object.prototype, "toString")` returns a descriptor object with `enumerable: false`. – apsillers Aug 12 '15 at 16:19
  • @albanx Edited with more on non-enumerable properties. – apsillers Aug 12 '15 at 16:24
  • so definitively we should use hasOwnProperty only when we are sure that the Object has not been extended. – albanx Aug 12 '15 at 17:14