JavaScript: hasOwnProperty vs Truthy vs in
In JavaScript we often check if property exists or not on the object to make some decision, for example lets look at the following code:-
HasOwnProperty
function process(c) {
if(c.hasOwnProperty("element")) {
... do something
return;
}
... do something otherwise...
}
But it turns out that it is very slow, as hasOwnProperty
lives in the prototype of Object
. So if c
is an array,
- JavaScript engine will first check if
hasOwnProperty
exists inc
itself - Then it will check in
Array.prototype
. - And finally it will fetch the function from
Object.prototype
and then call method by passingthis
and parameterelement
.
Note, the steps 1,3 will have many intermediate prototype checks if c
is basically a subclass of subclass of subclass of something.
Check for Truthy
Another faster alternative is
function process(c) {
if(c.element)) {
... do something
return;
}
... do something otherwise...
}
This is called checking for Truthy
, if an object is not zero/false/null/undefined or empty string, then it is considered as a true
.
However, this is faster, but this is not same as hasOwnProperty
, c.element
will be false if c
has the property element
but it is zero/false/null/undefined or empty string.
Check for not undefined
So we can change it to,
function process(c) {
if(c.element !== undefined)) {
... do something
return;
}
... do something otherwise...
}
This will determine if the c
has property or not. But this still has a problem, c.element
will not be undefined, even if c
does not have element
but its prototype has it.
And if c
has a element
getter, and if it returns undefined
, the logic will still fail.
Check using in
function process(c) {
if("element" in c) {
... do something
return;
}
}
This will check if element
exists in c
or it's prototype chain. It will return true
irrespective of property value, as it will not evaluate the property, it will only check if any member exists with same name or not. It will return true
if it has an empty accessor.
Examples
class A {
get a() {
return undefined;
}
}
class B extends A {
get b() {
return 1;
}
}
var r = new B();
r.c = 0;
console.log(!! r.a);
// prints false
console.log(!! r.b);
// prints true
console.log(!! r.c);
// prints false
console.log("a" in r);
// prints true
console.log("b" in r);
// prints true
console.log("c" in r);
// prints true
console.log(r.hasOwnProperty("a"));
// prints false
console.log(r.hasOwnProperty("b"));
// prints false
console.log(r.hasOwnProperty("c"));
// prints true
Summary
hasOwnProperty | Truthy | Check for Undefined | in | |
---|---|---|---|---|
Checks if property exists in the object only | Yes | No | No | No, see 1. |
Checks if property is true | No | Yes | No | No, see 2. |
Checks if property exists in the object or in the base class | No | No, see 3. | No, see 4. | Yes |
It may return
true
if property exists in base class, it does not check if it istrue
.It only checks if property exists in the same or base class, it does not check if it is
true
.As property may exist but value may be
false
.As getter may exist but value may return
undefined
.
Like | Comment | Save | Share |