15

There are a lot of blogs saying that a hasOwnProperty check should be used whenever the for..in loop is used, but I don't understand why that's the case. Both with and without the check we get the same results.

Check out this fiddle.

xaxxon
  • 19,189
  • 5
  • 50
  • 80
Gautham Renganathan
  • 647
  • 1
  • 9
  • 18

4 Answers4

18

If you're creating a basic object with {}, or getting it from JSON using JSON.parse, then hasOwnProperty is globally useless.

But if you're extending a "class" (using prototype), then it helps you to know if you're accessing your "own properties" (direct properties, including direct functions).

Note that a basic object has at least one (not direct) property, that you may discover with console.log({}); or console.log({}.toString) but it's not enumerable and not seen in a for... in loop :

A for...in loop does not iterate over non–enumerable properties. Objects created from built–in constructors like Array and Object have inherited non–enumerable properties from Object.prototype and String.prototype that are not enumerable, such as String's indexOf method or Object's toString method. The loop will iterate over all enumerable properties of the object or that it inherits from its constructor's prototype (including any which overwrite built-in properties).

Kamafeather
  • 8,663
  • 14
  • 69
  • 99
Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • 2
    `hasOwnProperty` is not useless and necessary when you don't have full control over the code in your page. Say someone modifies `Object.prototype` as in Cristoph's answer.. even with a simple object you will get unpredictable results without `hasOwnProperty`. – Radu Aug 01 '12 at 16:47
  • 2
    I'd say that messing code which you don't have full control is a different category from *creating a basic object with {}, or getting it from JSON* – Andre Figueiredo Feb 14 '18 at 15:59
13

Without hasOwnProperty you don't know whether the property is a native property of your object or inherited from it's prototype.

Your modified fiddle

var obj1 = {a:"10",b:"20"};

Object.prototype.c = "prototype:30";

var i;
for(i in obj1) {
    document.getElementById("div1").innerHTML += obj1[i]+" ";
}
// result 10 20 prototype:30

for(i in obj1) {
    if(obj1.hasOwnProperty(i)) {
        document.getElementById("div2").innerHTML += obj1[i] +" ";
    }          
}
// result 10 20
​

In this case obj1 inherits the property c from it's Prototype Object and you would erroneously list it in your first loop.

Christoph
  • 50,121
  • 21
  • 99
  • 128
1

Often you will get the same result with or without hasOwnProperty, but the latter ignores properties that are inherited rather than living directly on the object in question.

Consider this basic inheritance system. Dogs inherit from the master Animal class.

function Animal(params) { this.is_animal = true; }
function Dog(params) { for (var i in params) this[i] = params[i]; }
Dog.prototype = new Animal();
var fido = new Dog({name: 'Fido'});

If we peer into fido, hasOwnProperty helps us ascertain which are its own properties (name) and which are inherited.

for (var i in fido) if (fido.hasOwnProperty(i)) alert(i+' = '+fido[i]);

...alerts name=Fido but not is_animal=true.

Mitya
  • 33,629
  • 9
  • 60
  • 107
1

this is why we need hasOwnProperty() method in for..in statement : this is not useless, this is very important to make your code safe and to make it always do right thing.because some libraries or some dependencies could touch Object.prototype on your program context in anytime, Without hasOwnProperty check, your for...in statement might be iterating unexpected keys. So you need to make your for...in statement safe using hasOwnProperty().

var obj = {
  a: 1,
  b: 2
};
Object.prototype.haha = 3;
for (var k in obj) {
   if (obj.hasOwnProperty(k)){
  console.log(k); // prints a, b
  }
}   

var obj = {
  a: 1,
  b: 2
};

Object.prototype.haha = 3;

for (var k in obj) {
  console.log(k); // prints a, b, haha
}
Azer8
  • 539
  • 8
  • 18