for..in and hasOwnProperty

Javascript

Javascript Problem Overview


> Possible Duplicate:
> How do I check if an object has a specific property in JavaScript?

I found the following snippet in Twitter's JavaScript files. Why do they need to call the hasOwnProperty function to see dict has the key property? The for loop is running for each 'key' in 'dict' which means 'dict' has 'key'. Am I missing a point?

function forEach(dict, f) {
    for (key in dict) {
        if (dict.hasOwnProperty(key))
            f(key, dict[key]);
    }
}

Javascript Solutions


Solution 1 - Javascript

Because if you don't, it will loop through every property on the prototype chain, including ones that you don't know about (that were possibly added by somebody messing with native object prototypes).

This way you're guaranteed only the keys that are on that object instance itself.

Solution 2 - Javascript

The hasOwnProperty method lets you know if a property is directly on an instance of an object or inherited from its prototype chain.

Consider the following

function ObjWithProto() {
    this.foo = 'foo_val';
}

ObjWithProto.prototype = {bar: 'bar_val'};

var dict = new ObjWithProto();
dict.foobar = 'foobar_val';

I.e., you have an Object dict with properties foo and foobar that also inherits a property bar from its prototype chain.

Now run it through (a modified version of) your code:

function forEach(dict) {
    var key;
    for (key in dict) {
        if (dict.hasOwnProperty(key)) 
            console.log('has', key, dict[key]);
        else 
            console.log('not', key, dict[key]);
    }
}
forEach(dict);

You will see

has foo foo_val
has foobar foobar_val
not bar bar_val

This lets you separate properties that an object has itself and those it has inherited (which are usually methods that aren't relevant to the loop).

Furthermore, if you now do dict.bar = 'new_bar_val';, the last result will change to has bar new_bar_val, letting you distinguish even between properties of the same name as those inherited.

Solution 3 - Javascript

Every object in JavaScript is a dictionary. This means that "toString" and every other method is a key of every Object:

var myObj = {};
console.log(myObj["toString"]);

But this function is inherited from Object class, so hasOwnProperty tells you if this key is owned by the dictionary or if it is inherited.

"toString" in myObj; // true
myObj.hasOwnProperty("toString") // false

Solution 4 - Javascript

blockhead is right here. For example, the Prototype.js framework used to extend native arrays with extra helper methods (I do not know the situation with current versions of a framework).

Thus straight usage of "for (key in dict)" would return all the elements of the div plus references to helper methods. Which is kind of unexpected :)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionscusyxxView Question on Stackoverflow
Solution 1 - JavascriptblockheadView Answer on Stackoverflow
Solution 2 - JavascriptPaul S.View Answer on Stackoverflow
Solution 3 - JavascriptA. Matías QuezadaView Answer on Stackoverflow
Solution 4 - Javascriptd1pr3dView Answer on Stackoverflow