When Should JavaScript Developers Use hasOwnProperty?

Every aspiring JavaScript developer should read and reread JavaScript Garden (discovered via @javascripting), which provides a great overview of some of the most confusing and misunderstood JavaScript behavior. Experienced JS developers have probably learned most of this already, but may have reduced a lot of furniture to kindling in the process.

One statement that gave me pause was in the section about for...in loops. After explaining how the prototype chain can poison an object’s properties, the section concludes:

It is recommended to always use hasOwnProperty. Assumptions should never be made about the environment the code is running in, or whether the native prototypes have been extended or not.

There are strong arguments for this approach. Even if you are sure in a given context that the objects you are manipulating will not have additional properties on their prototype chain, code has a way of changing over time. Who knows how your seemingly safe code will be mangled and reused over time? Not protecting against future code evolution is exactly how subtle errors sneak into your code, leading to hours of frustrating debugging (and much smashed furniture).

On the other hand, there is a trade-off here, since using hasOwnProperty in every for...in loop makes code less readable. Consider the following example:

for (var key in obj) {
	if (obj.hasOwnProperty(key)) {
    	var subObj = obj[key];
        for (var subKey in subObj) {
        	if (subObj.hasOwnProperty(subKey)) {
            	console.log(subKey);
            }
        }
    }
}

Contrast it with:

for (var key in obj) {
	var subObj = obj[key];
    for (var subKey in subObj) {
    	console.log(subKey);
    }
}

Besides requiring a lot more typing, the former version is harder to read and understand. If you are sure that obj does not have anything on its prototype chain (e.g. you just parsed it from JSON) and that Object has not been extended with enumerable properties (which should definitely be banned), there is a reasonable case to be made for leaving hasOwnProperty out. After all, obscure code is a common source of errors as well. The risk that this code will be reused and abused in the future might not be the overriding consideration.

My inclination would be to retain a fair amount of discretion about hasOwnProperty rather than blindly using it always. Or just use CoffeeScript, where you can get both safety and brevity with for own key, value in obj.

Matthew Gertner

Matthew Gertner