If your checking standard objects that are the result of parsing a JSON string, .hasOwnProperty
has no obvious benefit. Except, of course, if you or some lib you're using has been messing around with the Object.prototype
.
In general, undefined
as such can be redefined, but I haven't encountered this myself - nor do I think I will ever do so. It is, however impossible (AFAIK) to mess up the return values of typeof
. In that respect, the latter is the safest way to go. I do believe some ancient browsers don't work well with the undefined
keyword, too.
In resuming: no need to go and replace every single typeof
check. On a personal note: I believe it to be good practice to get in the habit of using .hasOwnProperty
, though. Hence I'd suggest that, in cases a property might exist, yet be undefined, .hasOwnPorperty
is the safest bet.
In response to your comment: yes, typeof
will fit your needs ~95% of the time. .hasOwnProperty
will work 99% of times. However, as the name indicates: properties higher up the inheritance chain won't be checked, consider the following example:
Child.prototype = new Parent();
Child.prototype.constructor=Child;//otherwise instance.constructor points to parent
function Parent()
{
this.foo = 'bar';
}
function Child()
{
this.bar = 'baz';
}
var kiddo = new Child();
if (kiddo.hasOwnProperty('foo'))
{
console.log('This code won\'t be executed');
}
if (typeof kiddo.foo !== 'undefined')
{
console.log('This will, foo is a property of Parent');
}
So if you want to check if a single object has a property, hasOwnProperty
is what you need. Especially if you're going to change the value of that property (if it's a prototype property, all instances can be altered).
If you want to know if a property has a value (other then undefined
), regardless of where it is situated in the inheritance chain, you'll need typeof
. I've got a recursive function somewhere to determine where the property can be found in the inheritance chain. Once I've found it, I'll post it here, too.
Update:
As promised, the function to locate a property in an inheritance chain. It's not the actual function I used a while back, so I put together a working draft. It's not perfect, but it could well help you on your way:
function locateProperty(obj,prop,recursion)
{
recursion = recursion || false;
var current = obj.constructor.toString().match(/function\s+(.+?)\s*\(/m)[1];
if (!(obj.hasOwnProperty(prop)))
{
if (current === 'Function' || recursion === current)
{
return false;
}
return locateProperty(new window[current](),prop,current);
}
return current;
}
//using the object kiddo
locateProperty(kiddo,'foo');//returns 'Parent'
locateProperty(kiddo,'bar');//returns 'Parent', too
To avoid this last glitch, you could either replace the last return current;
statement with return obj;
. Or, better still, add the following line to the above snippet:
Child.prototype.constructor=Child;
I forgot that in the first edit...