Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

hasOwnProperty when to use, and when not needed?

Tags:

javascript

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

like image 927
albanx Avatar asked Aug 12 '15 15:08

albanx


1 Answers

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).

like image 110
apsillers Avatar answered Oct 26 '22 18:10

apsillers