Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at RIA Unleashed (Nov. 2010) with:

Javascript's hasOwnProperty() Method Is More Consistent Than The IN Operator

By Ben Nadel on

This is just a very quick follow-up to my previous post on using Javascript's IN operator with String values. When I first blogged a while back about using Javascript's IN operator, James Padolsey had mentioned to me that the hasOwnProperty() method was basically doing the same thing that the IN operator was doing. After finding out that Javascript's IN operator failed to work with String objects, I figured I'd see if I had any better luck with this hasOwnProperty() method. I took the previous demo code and reworked it to use this new method:

  • <!DOCTYPE HTML>
  • <html>
  • <head>
  • <title>Javascript hasOwnProperty() Method And String Objects</title>
  • <script type="text/javascript">
  •  
  • // Create a number of different data types to test.
  • var stringValue = "";
  • var objectValue = {};
  • var arrayValue = [];
  • var dateValue = new Date();
  • var numberValue = new Number( 1 );
  • var boolValue = true;
  •  
  • // -------------------------------------------------- //
  • // -------------------------------------------------- //
  •  
  • // Run control group known to work.
  • console.log( "Object", objectValue.hasOwnProperty( "length" ) );
  •  
  • // Run test on array.
  • console.log( "Array", arrayValue.hasOwnProperty( "length" ) );
  •  
  • // Run test on date object.
  • console.log( "Date", dateValue.hasOwnProperty( "length" ) );
  •  
  • // Run test on number object.
  • console.log( "Number", numberValue.hasOwnProperty( "length" ) );
  •  
  • // Run test on boolean object.
  • console.log( "Boolean", boolValue.hasOwnProperty( "length" ) );
  •  
  • // Try to use the IN operator on a String value.
  • console.log( "String", stringValue.hasOwnProperty( "length" ) );
  •  
  • </script>
  • </head>
  • <body>
  • <!-- Intentionally left blank. -->
  • </body>
  • </html>

As you can see, I'm simply using the hasOwnProperty() method in lieu of the IN operator. When we run this code, we get the following console output:

Object false
Array true
Date false
Number false
Boolean false
String true

As you can see, the hasOwnProperty() method works perfectly with all the tested data types (even the String and the Boolean value which was not previously demonstrated).

The hasOwnProperty() method is doing, more or less, what the IN operator is doing with one major exception - the IN operator inspects the object's prototype chain while the hasOwnProperty() method does not. As such, the hasOwnProperty() method will return false even if an object has the given inherited property. Essentially, the hasOwnProperty() method checks to see if an object has the given key defined locally and not whether it has access to such a key at all.

Personally, I'd like to see the IN operator work with all of Javascript's core data types; but since it doesn't, the hasOwnProperty() method can work in place of it to some degree. And, of course, as Ben Alman pointed out, you can always use the typeof() function to check the type of objects you are dealing with before making use of the IN operator.




Reader Comments

Papa Crockford recommends combining the two for looping through object properties. 'in' is used to enumerate the properties and hasOwnProperty ensures the property is a method of your object and not part of the chain ie.

function each( object, callback, args ){
var prop;
for( prop in object ){
if( object.hasOwnProperty( i ) ){
callback.apply( prop, args );
}
}
}

http://javascript.crockford.com/code.html#for statement

jQuery uses object[prop] to check those values. string["length"] worked, so maybe this is a viable shortcut to the longer name?
http://github.com/jquery/jquery/blob/master/src/core.js line 542

@Drew,

He says that it should be used as a "defensive" move to make sure an object truly has a given property; but, I am not sure I fully understand that concept. If objects are going to inherit from each other, it seems counter-productive to try and check around the inheritance chain.

I'm not a OO master, though, so I am probably just not seeing something.

That is a good point, I bet that is probably why jQuery uses the object["property"] technique. This would include inherited properties.

@Ben: the point is to let you reliably use Objects as dictionaries/maps/hashes by making sure that no extra keys show up besides the ones you put into a given instance.

This is mostly a problem when you're using a third-party library that monkeypatches Object.prototype. If it adds its new .niftyMethod(), then if you do this:

var obj = { "a": 1, "b":, 2, "c": 3}
for (var k in obj) {
v = obj[k];
...
}

The body of your loop will be executed four times, not three; the extra iteration will have k set to "niftyMethod" and v set to that method's closure body.

@Mark,

I understand what you're saying; but, I am having trouble thinking of times when I would need to worry about that kind of object-definition "security". I'm relatively new to the world of OO, so I am sure there is good theory behind this.

What I have found is that hasOwnProperty is excellent in most cases but if you use a javascript class library such as John Resig's or JavascriptMVC's and you want to callback a method laying inside the parent class you'll need to use the IN keyword because as you have explained prototype inheritance isn't supported in hasOwnProperty.

for instance:

Class.extends('parent', {

methodWithCallback: function(obj, args, callback) {

...

//Will Not Work
if(obj.hasOwnProperty(callback)) {
self[callback](obj);
}

//Will Work
if(callback in obj) {
self[callback](obj);
}

...

},

callbackName: function(obj)

});

class.extends('child', {

withCallback: function() {

try {

var self = this;

this.methodWithCallback(self, args, "callbackName");

} catch(e) {}

}

});

At least I couldn't make it work but I've only been working with JavascriptMVC for a few days now.

True, hasOwnProperty() is used to distinguish actual properties of an object from those in the prototype. https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/hasOwnProperty

in is a pretty horrible way to find properties, because it requires the browser to find ALL properties of an object up the entire chanin, then look for the property you are asking it. This is quite slow, but may be useful if you don't know the name of the property you are looking for.

@Drew

You are right of course. The problem is that when you try to make js work like a conventional class-based inheritance language you have to use its slower constructs. What I do is do a typeof == string to see if I don't know the name (ie I need to look at the object members ) then look to the child class's methods first for a callback with hasOwnProperty and failing that I look for the member using IN.

I store the callback names in my object inside a member object. It will either store a string for unknowns I wan to pass in as an argument or I pass in a function to that callback object when I set an input to a jquery reference.

so if typeof callback == "string" it will do its dirty dance through the properties then execute the callback.

if it is typeof callback == "function" it will just execute the function.

The latter is the preferred method but I like giving the framework entry options. This way anything that needs to be appliaction wide can go in the parent and anything localized to my child can go there. And if something is quick and dirty it can just be put in the init() call when I set inputs and callbacks for said input.

I noticed recently that .hasOwnProperty() doesn't exist on DOM nodes in IE8 or IE7, which is unfortunate, because it's commonly used to detect features on the DOM by coders who are unaware of the issue. I worked around the issue with typeof node.property !== 'undefined'.

If you're protecting against iterating over the prototype, use .hasOwnProperty(). If you're checking for the existence of an attribute on an object (including the prototype), use "in" or typeof.

Hi there,
I love hasOwnProperty as we all do but recently I run into a weird problem. I was trying to call it on window object:

window.hasOwnProperty('onbeforeunload')

and guess what... it gave me false! Of course, I compared it with:
'onbeforeunload' in window
which returned true.

It looks like the 'onbeforeunload' property is inherited from window object's parent (whatever it is). I also checked some other properties, like 'onload' - the same result.
Isn't the window object supposed to be the top object in the DOM? I mean, I can distinguish the DOM tree and the Javascript object inheritance but still, objects not representing the DOM shouldn't contain properties such as 'onload', 'onbeforeunload', 'onclick' etc.
Do you have any logical explanation for this whole situation?