So:
x = {'key': 1};
if x.hasOwnProperty('key') {
//do this
}
Is that the best way to do that?
So:
x = {'key': 1};
if x.hasOwnProperty('key') {
//do this
}
Is that the best way to do that?
Yes it is :) I think you can also do Object.prototype.hasOwnProperty.call(x, 'key')
which should also work if x
has a property called hasOwnProperty
:)
But that tests for own properties. If you want to check if it has an property that may also be inhered you can use typeof x.foo != 'undefined'
.
if (x.key !== undefined)
Armin Ronacher seems to have already beat me to it, but:
Object.prototype.hasOwnProperty = function(property) {
return this[property] !== undefined;
};
x = {'key': 1};
if (x.hasOwnProperty('key')) {
alert('have key!');
}
if (!x.hasOwnProperty('bar')) {
alert('no bar!');
}
A safer, but slower solution, as pointed out by Konrad Rudolph and Armin Ronacher would be:
Object.prototype.hasOwnProperty = function(property) {
return typeof(this[property]) !== 'undefined'
};
Yes, that is a good way to check, but keep in mind that hasOwnProperty does not check the prototype chain.
OK, looks like I had the right answer unless if you don't want inherited properties:
if (x.hasOwnProperty('key'))
Here are some other options to include inherited properties:
if (x.key) // quick and dirty but does the same thing as below.
if (x.key !== undefined)
@[enobrev],
@[sheats],
bear in mind that undefined
is (unfortunately) not a reserved word in JavaScript. Therefore, someone (someone else, obviously) could have the grand idea of redefining it, breaking your code.
A more robust method is therefore the following:
if (typeof(x.attribute) !== 'undefined')
On the flip side, this method is much more verbose and also slower. :-/
I'm really confused by the answers that have been given - most of them are just outright incorrect. Of course you can have object properties that have undefined, null, or false values. So simply reducing the property check to typeof this[property]
or, even worse, x.key
will give you completely misleading results.
It depends on what you're looking for. If you want to know if an object physically contains a property (and it is not coming from somewhere up on the prototype chain) then object.hasOwnProperty
is the way to go. All modern browsers support it. (It was missing in older versions of Safari - 2.0.1 and older - but those versions of the browser are rarely used any more.)
If what you're looking for is if an object has a property on it that is iterable (when you iterate over the properties of the object, it will appear) then doing: prop in object
will give you your desired effect.
Since using hasOwnProperty
is probably what you want, and considering that you may want a fallback method, I present to you the following solution:
var obj = {
a: undefined,
b: null,
c: false
};
// a, b, c all found
for ( var prop in obj ) {
document.writeln( "Object1: " + prop );
}
function Class(){
this.a = undefined;
this.b = null;
this.c = false;
}
Class.prototype = {
a: undefined,
b: true,
c: true,
d: true,
e: true
};
var obj2 = new Class();
// a, b, c, d, e found
for ( var prop in obj2 ) {
document.writeln( "Object2: " + prop );
}
function hasOwnProperty(obj, prop){
var proto = obj.__proto__ || obj.constructor.prototype;
return (prop in obj) &&
(!(prop in proto) || proto[prop] !== obj[prop]);
}
if ( Object.prototype.hasOwnProperty ) {
function hasOwnProperty(obj, prop){
return obj.hasOwnProperty(prop);
}
}
// a, b, c found in modern browsers
// b, c found in Safari 2.0.1 and older
for ( var prop in obj2 ) {
if ( hasOwnProperty(obj2, prop) ) {
document.writeln( "Object2 w/ hasOwn: " + prop );
}
}
The above is a working, cross-browser, solution to hasOwnProperty
, with one caveat: It is unable to distinguish between cases where an identical property is on the prototype and on the instance - it just assumes that it's coming from the prototype. You could shift it to be more lenient or strict, based upon your situation, but at the very least this should be more helpful.
Let's cut through some confusion here. First let's simplify by assuming hasOwnProperty already exists, this is true of the vast majority of current browsers in use.
hasOwnProperty returns true if the attribute name that is passed to it has been added to the object. It is entirely independant of the actual value assigned to it which may be exactly undefined
Hence:-
var o = {}
o.x = undefined
var a = o.hasOwnProperty('x') // a is true
var b = o.x === undefined // b is also true
However:-
var o = {}
var a = o.hasOwnProperty('x') // a is now false
var b = o.x === undefined // b is still true
The problem is what happens when an object in the prototype chain has an attribute with the value of undefined? hasOwnProperty
will be false for it and so will !== undefined
yet for..in
will still list it in the enumeration.
Bottom line is there is no cross browser way (since IE doesn't expose __prototype__) to determine that a specific identifier has not been attached to an object or anything in its prototype chain.
I generally just do the quick and dirty
if (x.key)
as I normally don't need to check if the property is from the .prototype or the object itself. I also like existence checks for all kinds of things like
var a = []
// some code to potentially populate the array.
if (a.length) {
// mind blowing code.
}
or
if (!a.length) {
// other mind blowing code
}