Related
In my code, I deal with an array that has some entries with many objects nested inside one another, where as some do not. It looks something like the following:
// where this array is hundreds of entries long, with a mix
// of the two examples given
var test = [{'a':{'b':{'c':"foo"}}}, {'a': "bar"}];
This is giving me problems because I need to iterate through the array at times, and the inconsistency is throwing me errors like so:
for (i=0; i<test.length; i++) {
// ok on i==0, but 'cannot read property of undefined' on i==1
console.log(a.b.c);
}
I am aware that I can say if(a.b){ console.log(a.b.c)}, but this is extraordinarily tedious in cases where there are up to 5 or 6 objects nested within one another. Is there any other (easier) way that I can have it ONLY do the console.log if it exists, but without throwing an error?
Update:
If you use JavaScript according to ECMAScript 2020 or later, see optional chaining.
TypeScript has added support for optional chaining in version 3.7.
// use it like this
obj?.a?.lot?.of?.properties
Solution for JavaScript before ECMASCript 2020 or TypeScript older than version 3.7:
A quick workaround is using a try/catch helper function with ES6 arrow function:
function getSafe(fn, defaultVal) {
try {
return fn();
} catch (e) {
return defaultVal;
}
}
// use it like this
console.log(getSafe(() => obj.a.lot.of.properties));
// or add an optional default value
console.log(getSafe(() => obj.a.lot.of.properties, 'nothing'));
What you are doing raises an exception (and rightfully so).
You can always do:
try{
window.a.b.c
}catch(e){
console.log("YO",e)
}
But I wouldn't, instead think of your use case.
Why are you accessing data, 6 levels nested that you are unfamiliar of? What use case justifies this?
Usually, you'd like to actually validate what sort of object you're dealing with.
Also, on a side note you should not use statements like if(a.b) because it will return false if a.b is 0 or even if it is "0". Instead check if a.b !== undefined
If I am understanding your question correctly, you want the safest way to determine if an object contains a property.
The easiest way is to use the in operator.
window.a = "aString";
//window should have 'a' property
//lets test if it exists
if ("a" in window){
//true
}
if ("b" in window){
//false
}
Of course you can nest this as deep as you want
if ("a" in window.b.c) { }
Not sure if this helps.
Try this. If a.b is undefined, it will leave the if statement without any exception.
if (a.b && a.b.c) {
console.log(a.b.c);
}
If you are using lodash, you could use their has function. It is similar to the native "in", but allows paths.
var testObject = {a: {b: {c: 'walrus'}}};
if(_.has(testObject, 'a.b.c')) {
//Safely access your walrus here
}
If you use Babel, you can already use the optional chaining syntax with #babel/plugin-proposal-optional-chaining Babel plugin. This would allow you to replace this:
console.log(a && a.b && a.b.c);
with this:
console.log(a?.b?.c);
If you have lodash you can use its .get method
_.get(a, 'b.c.d.e')
or give it a default value
_.get(a, 'b.c.d.e', default)
I use undefsafe religiously. It tests each level down into your object until it either gets the value you asked for, or it returns "undefined". But never errors.
This is a common issue when working with deep or complex json object, so I try to avoid try/catch or embedding multiple checks which would make the code unreadable, I usually use this little piece of code in all my procect to do the job.
/* ex: getProperty(myObj,'aze.xyz',0) // return myObj.aze.xyz safely
* accepts array for property names:
* getProperty(myObj,['aze','xyz'],{value: null})
*/
function getProperty(obj, props, defaultValue) {
var res, isvoid = function(x){return typeof x === "undefined" || x === null;}
if(!isvoid(obj)){
if(isvoid(props)) props = [];
if(typeof props === "string") props = props.trim().split(".");
if(props.constructor === Array){
res = props.length>1 ? getProperty(obj[props.shift()],props,defaultValue) : obj[props[0]];
}
}
return typeof res === "undefined" ? defaultValue: res;
}
I like Cao Shouguang's answer, but I am not fond of passing a function as parameter into the getSafe function each time I do the call. I have modified the getSafe function to accept simple parameters and pure ES5.
/**
* Safely get object properties.
* #param {*} prop The property of the object to retrieve
* #param {*} defaultVal The value returned if the property value does not exist
* #returns If property of object exists it is returned,
* else the default value is returned.
* #example
* var myObj = {a : {b : 'c'} };
* var value;
*
* value = getSafe(myObj.a.b,'No Value'); //returns c
* value = getSafe(myObj.a.x,'No Value'); //returns 'No Value'
*
* if (getSafe(myObj.a.x, false)){
* console.log('Found')
* } else {
* console.log('Not Found')
* }; //logs 'Not Found'
*
* if(value = getSafe(myObj.a.b, false)){
* console.log('New Value is', value); //logs 'New Value is c'
* }
*/
function getSafe(prop, defaultVal) {
return function(fn, defaultVal) {
try {
if (fn() === undefined) {
return defaultVal;
} else {
return fn();
}
} catch (e) {
return defaultVal;
}
}(function() {return prop}, defaultVal);
}
Lodash has a get method which allows for a default as an optional third parameter, as show below:
const myObject = {
has: 'some',
missing: {
vars: true
}
}
const path = 'missing.const.value';
const myValue = _.get(myObject, path, 'default');
console.log(myValue) // prints out default, which is specified above
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
Imagine that we want to apply a series of functions to x if and only if x is non-null:
if (x !== null) x = a(x);
if (x !== null) x = b(x);
if (x !== null) x = c(x);
Now let's say that we need to do the same to y:
if (y !== null) y = a(y);
if (y !== null) y = b(y);
if (y !== null) y = c(y);
And the same to z:
if (z !== null) z = a(z);
if (z !== null) z = b(z);
if (z !== null) z = c(z);
As you can see without a proper abstraction, we'll end up duplicating code over and over again. Such an abstraction already exists: the Maybe monad.
The Maybe monad holds both a value and a computational context:
The monad keeps the value safe and applies functions to it.
The computational context is a null check before applying a function.
A naive implementation would look like this:
⚠️ This implementation is for illustration purpose only! This is not how it should be done and is wrong at many levels. However this should give you a better idea of what I am talking about.
As you can see nothing can break:
We apply a series of functions to our value
If at any point, the value becomes null (or undefined) we just don't apply any function anymore.
const abc = obj =>
Maybe
.of(obj)
.map(o => o.a)
.map(o => o.b)
.map(o => o.c)
.value;
const values = [
{},
{a: {}},
{a: {b: {}}},
{a: {b: {c: 42}}}
];
console.log(
values.map(abc)
);
<script>
function Maybe(x) {
this.value = x; //-> container for our value
}
Maybe.of = x => new Maybe(x);
Maybe.prototype.map = function (fn) {
if (this.value == null) { //-> computational context
return this;
}
return Maybe.of(fn(this.value));
};
</script>
Appendix 1
I cannot explain what monads are as this is not the purpose of this post and there are people out there better at this than I am. However as Eric Elliot said in hist blog post JavaScript Monads Made Simple:
Regardless of your skill level or understanding of category theory, using monads makes your code easier to work with. Failing to take advantage of monads may make your code harder to work with (e.g., callback hell, nested conditional branches, more verbosity).
Appendix 2
Here's how I'd solve your issue using the Maybe monad from monetjs
const prop = key => obj => Maybe.fromNull(obj[key]);
const abc = obj =>
Maybe
.fromNull(obj)
.flatMap(prop('a'))
.flatMap(prop('b'))
.flatMap(prop('c'))
.orSome('🌯')
const values = [
{},
{a: {}},
{a: {b: {}}},
{a: {b: {c: 42}}}
];
console.log(
values.map(abc)
);
<script src="https://www.unpkg.com/monet#0.9.0/dist/monet.js"></script>
<script>const {Maybe} = Monet;</script>
In str's answer, value 'undefined' will be returned instead of the set default value if the property is undefined. This sometimes can cause bugs. The following will make sure the defaultVal will always be returned when either the property or the object is undefined.
const temp = {};
console.log(getSafe(()=>temp.prop, '0'));
function getSafe(fn, defaultVal) {
try {
if (fn() === undefined || fn() === null) {
return defaultVal
} else {
return fn();
}
} catch (e) {
return defaultVal;
}
}
You can use optional chaining from the ECMAScript standart.
Like this:
a?.b?.c?.d?.func?.()
I answered this before and happened to be doing a similar check today. A simplification to check if a nested dotted property exists. You could modify this to return the value, or some default to accomplish your goal.
function containsProperty(instance, propertyName) {
// make an array of properties to walk through because propertyName can be nested
// ex "test.test2.test.test"
let walkArr = propertyName.indexOf('.') > 0 ? propertyName.split('.') : [propertyName];
// walk the tree - if any property does not exist then return false
for (let treeDepth = 0, maxDepth = walkArr.length; treeDepth < maxDepth; treeDepth++) {
// property does not exist
if (!Object.prototype.hasOwnProperty.call(instance, walkArr[treeDepth])) {
return false;
}
// does it exist - reassign the leaf
instance = instance[walkArr[treeDepth]];
}
// default
return true;
}
In your question you could do something like:
let test = [{'a':{'b':{'c':"foo"}}}, {'a': "bar"}];
containsProperty(test[0], 'a.b.c');
I usually use like this:
var x = object.any ? object.any.a : 'def';
You can avoid getting an error by giving a default value before getting the property
var test = [{'a':{'b':{'c':"foo"}}}, {'a': "bar"}];
for (i=0; i<test.length; i++) {
const obj = test[i]
// No error, just undefined, which is ok
console.log(((obj.a || {}).b || {}).c);
}
This works great with arrays too:
const entries = [{id: 1, name: 'Scarllet'}]
// Giving a default name when is empty
const name = (entries.find(v => v.id === 100) || []).name || 'no-name'
console.log(name)
Unrelated to the question's actual question, but might be useful for people coming to this question looking for answers.
Check your function parameters.
If you have a function like const x({ a }) => { }, and you call it without arguments x(); append = {} to the parameter: const x({ a } = {}) => { }.
What I had
I had a function like this:
const x = ({ a }) => console.log(a);
// This one works as expected
x({ a: 1 });
// This one errors out
x();
Which results in "Uncaught TypeError: Cannot destructure property 'a' of 'undefined' as it is undefined."
What I switched it to (now works).
const x = ({ a } = {}) => console.log(a);
// This one works as expected
x({ a: 1 });
// This now works too!
x();
How do I check if an object has a specific property in JavaScript?
Consider:
x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
//Do this
}
Is that the best way to do it?
2022 UPDATE
Object.hasOwn()
Object.hasOwn() is recommended over Object.hasOwnProperty() because it works for objects created using Object.create(null) and with objects that have overridden the inherited hasOwnProperty() method. While it is possible to workaround these problems by calling Object.prototype.hasOwnProperty() on an external object, Object.hasOwn() is more intuitive.
Example
const object1 = {
prop: 'exists'
};
console.log(Object.hasOwn(object1, 'prop'));
// expected output: true
Original answer
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 ) {
var hasOwnProperty = function(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.
With Underscore.js or (even better) Lodash:
_.has(x, 'key');
Which calls Object.prototype.hasOwnProperty, but (a) is shorter to type, and (b) uses "a safe reference to hasOwnProperty" (i.e. it works even if hasOwnProperty is overwritten).
In particular, Lodash defines _.has as:
function has(object, key) {
return object ? hasOwnProperty.call(object, key) : false;
}
// hasOwnProperty = Object.prototype.hasOwnProperty
You can use this (but read the warning below):
var x = {
'key': 1
};
if ('key' in x) {
console.log('has');
}
But be warned: 'constructor' in x will return true even if x is an empty object - same for 'toString' in x, and many others. It's better to use Object.hasOwn(x, 'key').
Note: the following is nowadays largely obsolete thanks to strict mode, and hasOwnProperty. The correct solution is to use strict mode and to check for the presence of a property using obj.hasOwnProperty. This answer predates both these things, at least as widely implemented (yes, it is that old). Take the following as a historical note.
Bear in mind that undefined is (unfortunately) not a reserved word in JavaScript if you’re not using strict mode. 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. :-/
A common alternative is to ensure that undefined is actually undefined, e.g. by putting the code into a function which accepts an additional parameter, called undefined, that isn’t passed a value. To ensure that it’s not passed a value, you could just call it yourself immediately, e.g.:
(function (undefined) {
… your code …
if (x.attribute !== undefined)
… mode code …
})();
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';
};
Considering the following object in Javascript
const x = {key: 1};
You can use the in operator to check if the property exists on an object:
console.log("key" in x);
You can also loop through all the properties of the object using a for - in loop, and then check for the specific property:
for (const prop in x) {
if (prop === "key") {
//Do something
}
}
You must consider if this object property is enumerable or not, because non-enumerable properties will not show up in a for-in loop. Also, if the enumerable property is shadowing a non-enumerable property of the prototype, it will not show up in Internet Explorer 8 and earlier.
If you’d like a list of all instance properties, whether enumerable or not, you can use
Object.getOwnPropertyNames(x);
This will return an array of names of all properties that exist on an object.
Reflections provide methods that can be used to interact with Javascript objects. The static Reflect.has() method works like the in operator as a function.
console.log(Reflect.has(x, 'key'));
// expected output: true
console.log(Reflect.has(x, 'key2'));
// expected output: false
console.log(Reflect.has(object1, 'toString'));
// expected output: true
Finally, you can use the typeof operator to directly check the data type of the object property:
if (typeof x.key === "undefined") {
console.log("undefined");
}
If the property does not exist on the object, it will return the string undefined. Else it will return the appropriate property type. However, note that this is not always a valid way of checking if an object has a property or not, because you could have a property that is set to undefined, in which case, using typeof x.key would still return true (even though the key is still in the object).
Similarly, you can check if a property exists by comparing directly to the undefined Javascript property
if (x.key === undefined) {
console.log("undefined");
}
This should work unless key was specifically set to undefined on the x object
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 independent 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.
The bottom line is there is no cross-browser way (since Internet Explorer doesn't expose __prototype__) to determine that a specific identifier has not been attached to an object or anything in its prototype chain.
If you are searching for a property, then "no". You want:
if ('prop' in obj) { }
In general, you should not care whether or not the property comes from the prototype or the object.
However, because you used 'key' in your sample code, it looks like you are treating the object as a hash, in which case your answer would make sense. All of the hashes keys would be properties in the object, and you avoid the extra properties contributed by the prototype.
John Resig's answer was very comprehensive, but I thought it wasn't clear. Especially with when to use "'prop' in obj".
For testing simple objects, use:
if (obj[x] !== undefined)
If you don't know what object type it is, use:
if (obj.hasOwnProperty(x))
All other options are slower...
Details
A performance evaluation of 100,000,000 cycles under Node.js to the five options suggested by others here:
function hasKey1(k,o) { return (x in obj); }
function hasKey2(k,o) { return (obj[x]); }
function hasKey3(k,o) { return (obj[x] !== undefined); }
function hasKey4(k,o) { return (typeof(obj[x]) !== 'undefined'); }
function hasKey5(k,o) { return (obj.hasOwnProperty(x)); }
The evaluation tells us that unless we specifically want to check the object's prototype chain as well as the object itself, we should not use the common form:
if (X in Obj)...
It is between 2 to 6 times slower depending on the use case
hasKey1 execution time: 4.51 s
hasKey2 execution time: 0.90 s
hasKey3 execution time: 0.76 s
hasKey4 execution time: 0.93 s
hasKey5 execution time: 2.15 s
Bottom line, if your Obj is not necessarily a simple object and you wish to avoid checking the object's prototype chain and to ensure x is owned by Obj directly, use if (obj.hasOwnProperty(x))....
Otherwise, when using a simple object and not being worried about the object's prototype chain, using if (typeof(obj[x]) !== 'undefined')... is the safest and fastest way.
If you use a simple object as a hash table and never do anything kinky, I would use if (obj[x])... as I find it much more readable.
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.hasOwnProperty("key")){
// …
}
because
if(x.key){
// …
}
fails if x.key is falsy (for example, x.key === "").
You can also use the ES6 Reflect object:
x = {'key': 1};
Reflect.has( x, 'key'); // returns true
Documentation on MDN for Reflect.has can be found here.
The static Reflect.has() method works like the in operator as a function.
Do not do this object.hasOwnProperty(key)). It's really bad because these methods may be shadowed by properties on the object in question - consider { hasOwnProperty: false } - or, the object may be a null object (Object.create(null)).
The best way is to do Object.prototype.hasOwnProperty.call(object, key) or:
const has = Object.prototype.hasOwnProperty; // Cache the lookup once, in module scope.
console.log(has.call(object, key));
/* Or */
import has from 'has'; // https://www.npmjs.com/package/has
console.log(has(object, key));
OK, it 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 it does the same thing as below.
if (x.key !== undefined)
Another relatively simple way is using Object.keys. This returns an array which means you get all of the features of an array.
var noInfo = {};
var info = {something: 'data'};
Object.keys(noInfo).length //returns 0 or false
Object.keys(info).length //returns 1 or true
Although we are in a world with great browser support. Because this question is so old I thought I'd add this:
This is safe to use as of JavaScript v1.8.5.
JavaScript is now evolving and growing as it now has good and even efficient ways to check it.
Here are some easy ways to check if object has a particular property:
Using hasOwnProperty()
const hero = {
name: 'Batman'
};
hero.hasOwnProperty('name'); // => true
hero.hasOwnProperty('realName'); // => false
Using keyword/operator in
const hero = {
name: 'Batman'
};
'name' in hero; // => true
'realName' in hero; // => false
Comparing with undefined keyword
const hero = {
name: 'Batman'
};
hero.name; // => 'Batman'
hero.realName; // => undefined
// So consider this
hero.realName == undefined // => true (which means property does not exists in object)
hero.name == undefined // => false (which means that property exists in object)
For more information, check here.
hasOwnProperty "can be used to determine whether an object has the specified property as a direct property of that object; unlike the in operator, this method does not check down the object's prototype chain."
So most probably, for what seems by your question, you don't want to use hasOwnProperty, which determines if the property exists as attached directly to the object itself,.
If you want to determine if the property exists in the prototype chain, you may want to use it like:
if (prop in object) { // Do something }
You can use the following approaches-
var obj = {a:1}
console.log('a' in obj) // 1
console.log(obj.hasOwnProperty('a')) // 2
console.log(Boolean(obj.a)) // 3
The difference between the following approaches are as follows-
In the first and third approach we are not just searching in object but its prototypal chain too. If the object does not have the property, but the property is present in its prototype chain it is going to give true.
var obj = {
a: 2,
__proto__ : {b: 2}
}
console.log('b' in obj)
console.log(Boolean(obj.b))
The second approach will check only for its own properties. Example -
var obj = {
a: 2,
__proto__ : {b: 2}
}
console.log(obj.hasOwnProperty('b'))
The difference between the first and the third is if there is a property which has value undefined the third approach is going to give false while first will give true.
var obj = {
b : undefined
}
console.log(Boolean(obj.b))
console.log('b' in obj);
Given myObject object and “myKey” as key name:
Object.keys(myObject).includes('myKey')
or
myObject.hasOwnProperty('myKey')
or
typeof myObject.myKey !== 'undefined'
The last was widely used, but (as pointed out in other answers and comments) it could also match on keys deriving from Object prototype.
Performance
Today 2020.12.17 I perform tests on MacOs HighSierra 10.13.6 on Chrome v87, Safari v13.1.2 and Firefox v83 for chosen solutions.
Results
I compare only solutions A-F because they give valid result for all cased used in snippet in details section. For all browsers
solution based on in (A) is fast or fastest
solution (E) is fastest for chrome for big objects and fastest for firefox for small arrays if key not exists
solution (F) is fastest (~ >10x than other solutions) for small arrays
solutions (D,E) are quite fast
solution based on losash has (B) is slowest
Details
I perform 4 tests cases:
when object has 10 fields and searched key exists - you can run it HERE
when object has 10 fields and searched key not exists - you can run it HERE
when object has 10000 fields and searched key exists - you can run it HERE
when object has 10000 fields and searched key exists - you can run it HERE
Below snippet presents differences between solutions
A
B
C
D
E
F
G
H
I
J
K
// SO https://stackoverflow.com/q/135448/860099
// src: https://stackoverflow.com/a/14664748/860099
function A(x) {
return 'key' in x
}
// src: https://stackoverflow.com/a/11315692/860099
function B(x) {
return _.has(x, 'key')
}
// src: https://stackoverflow.com/a/40266120/860099
function C(x) {
return Reflect.has( x, 'key')
}
// src: https://stackoverflow.com/q/135448/860099
function D(x) {
return x.hasOwnProperty('key')
}
// src: https://stackoverflow.com/a/11315692/860099
function E(x) {
return Object.prototype.hasOwnProperty.call(x, 'key')
}
// src: https://stackoverflow.com/a/136411/860099
function F(x) {
function hasOwnProperty(obj, prop) {
var proto = obj.__proto__ || obj.constructor.prototype;
return (prop in obj) &&
(!(prop in proto) || proto[prop] !== obj[prop]);
}
return hasOwnProperty(x,'key')
}
// src: https://stackoverflow.com/a/135568/860099
function G(x) {
return typeof(x.key) !== 'undefined'
}
// src: https://stackoverflow.com/a/22740939/860099
function H(x) {
return x.key !== undefined
}
// src: https://stackoverflow.com/a/38332171/860099
function I(x) {
return !!x.key
}
// src: https://stackoverflow.com/a/41184688/860099
function J(x) {
return !!x['key']
}
// src: https://stackoverflow.com/a/54196605/860099
function K(x) {
return Boolean(x.key)
}
// --------------------
// TEST
// --------------------
let x1 = {'key': 1};
let x2 = {'key': "1"};
let x3 = {'key': true};
let x4 = {'key': []};
let x5 = {'key': {}};
let x6 = {'key': ()=>{}};
let x7 = {'key': ''};
let x8 = {'key': 0};
let x9 = {'key': false};
let x10= {'key': undefined};
let x11= {'nokey': 1};
let b= x=> x ? 1:0;
console.log(' 1 2 3 4 5 6 7 8 9 10 11');
[A,B,C,D,E,F,G,H,I,J,K ].map(f=> {
console.log(
`${f.name} ${b(f(x1))} ${b(f(x2))} ${b(f(x3))} ${b(f(x4))} ${b(f(x5))} ${b(f(x6))} ${b(f(x7))} ${b(f(x8))} ${b(f(x9))} ${b(f(x10))} ${b(f(x11))} `
)})
console.log('\nLegend: Columns (cases)');
console.log('1. key = 1 ');
console.log('2. key = "1" ');
console.log('3. key = true ');
console.log('4. key = [] ');
console.log('5. key = {} ');
console.log('6. key = ()=>{} ');
console.log('7. key = "" ');
console.log('8. key = 0 ');
console.log('9. key = false ');
console.log('10. key = undefined ');
console.log('11. no-key ');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"> </script>
This shippet only presents functions used in performance tests - it not perform tests itself!
And here are example results for chrome
Now with ECMAScript22 we can use hasOwn instead of hasOwnProperty (Because this feature has pitfalls )
Object.hasOwn(obj, propKey)
Here is another option for a specific case. :)
If you want to test for a member on an object and want to know if it has been set to something other than:
''
false
null
undefined
0
...
then you can use:
var foo = {};
foo.bar = "Yes, this is a proper value!";
if (!!foo.bar) {
// member is set, do something
}
some easier and short options depending on the specific use case:
to check if the property exists, regardless of value, use the in operator ("a" in b)
to check a property value from a variable, use bracket notation (obj[v])
to check a property value as truthy, use optional
chaining (?.)
to check a property value boolean, use double-not / bang-bang / (!!)
to set a default value for null / undefined check, use nullish coalescing operator (??)
to set a default value for falsey value check, use short-circuit logical OR operator (||)
run the code snippet to see results:
let obj1 = {prop:undefined};
console.log(1,"prop" in obj1);
console.log(1,obj1?.prop);
let obj2 = undefined;
//console.log(2,"prop" in obj2); would throw because obj2 undefined
console.log(2,"prop" in (obj2 ?? {}))
console.log(2,obj2?.prop);
let obj3 = {prop:false};
console.log(3,"prop" in obj3);
console.log(3,!!obj3?.prop);
let obj4 = {prop:null};
let look = "prop"
console.log(4,"prop" in obj4);
console.log(4,obj4?.[look]);
let obj5 = {prop:true};
console.log(5,"prop" in obj5);
console.log(5,obj5?.prop === true);
let obj6 = {otherProp:true};
look = "otherProp"
console.log(6,"prop" in obj6);
console.log(6,obj6.look); //should have used bracket notation
let obj7 = {prop:""};
console.log(7,"prop" in obj7);
console.log(7,obj7?.prop || "empty");
I see very few instances where hasOwn is used properly, especially given its inheritance issues
There is a method, "hasOwnProperty", that exists on an object, but it's not recommended to call this method directly, because it might be sometimes that the object is null or some property exist on the object like: { hasOwnProperty: false }
So a better way would be:
// Good
var obj = {"bar": "here bar desc"}
console.log(Object.prototype.hasOwnProperty.call(obj, "bar"));
// Best
const has = Object.prototype.hasOwnProperty; // Cache the lookup once, in module scope.
console.log(has.call(obj, "bar"));
An ECMAScript 6 solution with reflection. Create a wrapper like:
/**
Gets an argument from array or object.
The possible outcome:
- If the key exists the value is returned.
- If no key exists the default value is returned.
- If no default value is specified an empty string is returned.
#param obj The object or array to be searched.
#param key The name of the property or key.
#param defVal Optional default version of the command-line parameter [default ""]
#return The default value in case of an error else the found parameter.
*/
function getSafeReflectArg( obj, key, defVal) {
"use strict";
var retVal = (typeof defVal === 'undefined' ? "" : defVal);
if ( Reflect.has( obj, key) ) {
return Reflect.get( obj, key);
}
return retVal;
} // getSafeReflectArg
Showing how to use this answer
const object= {key1: 'data', key2: 'data2'};
Object.keys(object).includes('key1') //returns true
We can use indexOf as well, I prefer includes
You need to use the method object.hasOwnProperty(property). It returns true if the object has the property and false if the object doesn't.
The hasOwnProperty() method returns a boolean indicating whether the object has the specified property as its own property (as opposed to inheriting it).
const object1 = {};
object1.property1 = 42;
console.log(object1.hasOwnProperty('property1'));
// expected output: true
console.log(object1.hasOwnProperty('toString'));
// expected output: false
console.log(object1.hasOwnProperty('hasOwnProperty'));
// expected output: false
Know more
Don't over-complicate things when you can do:
var isProperty = (objectname.keyname || "") ? true : false;
It Is simple and clear for most cases...
A Better approach for iterating on object's own properties:
If you want to iterate on object's properties without using hasOwnProperty() check,
use for(let key of Object.keys(stud)){} method:
for(let key of Object.keys(stud)){
console.log(key); // will only log object's Own properties
}
full Example and comparison with for-in with hasOwnProperty()
function Student() {
this.name = "nitin";
}
Student.prototype = {
grade: 'A'
}
let stud = new Student();
// for-in approach
for(let key in stud){
if(stud.hasOwnProperty(key)){
console.log(key); // only outputs "name"
}
}
//Object.keys() approach
for(let key of Object.keys(stud)){
console.log(key);
}
I'm trying to teach myself some JavaScript via Eloquent Javascript.
I'm on chapter 4 practice 4.4 Deep comparison.
I've written my own code, passed all the tests given, even some tests I've made myself, but when I checked the solution, it was something totally different than what I had.
Could anyone tell me whether my code produces the same result as the solution, or some ideas of how to figure out whether if my code is right even when mine is something totally different than what the solution is, not just for this practice problem but also in future problems?
I'm just afraid of having a wrong idea and not realizing since my code works.
The question is:
Write a function, deepEqual, that takes two values and returns true only if they are the same value or are objects with the same properties whose values are also equal when compared with a recursive call to deepEqual.
To find out whether to compare two things by identity (use the === operator for that) or by looking at their properties, you can use the typeof operator. If it produces "object" for both values, you should do a deep comparison. But you have to take one silly exception into account: by a historical accident, typeof null also produces "object".
My code is:
function deepEqual(val1, val2) {
if(typeof val1 !== typeof val2) return false;
else if(typeof val1 !== "object") return val1 === val2;
for(var event in val1){
return deepEqual(val1[event], val2[event]);
}
}
and the solution is:
function deepEqual2(a, b) {
if (a === b) return true;
if (a == null || typeof a != "object" ||
b == null || typeof b != "object")
return false;
var propsInA = 0, propsInB = 0;
for (var prop in a)
propsInA += 1;
for (var prop in b) {
propsInB += 1;
if (!(prop in a) || !deepEqual(a[prop], b[prop]))
return false;
}
return propsInA == propsInB;
}
Thanks in advance!
There are a couple of problems with your code:
You only test the first property in an object, because you have a return in your for-in loop. So when comparing objects, all your code does is check that first property.
If you kept a flag and returned the result after the loop, it would still have the issue that it only checks the properties in a; what if b has a property a doesn't have?
I know that I can test for a JavaScript variable and then define it if it is undefined, but is there not some way of saying
var setVariable = localStorage.getItem('value') || 0;
seems like a much clearer way, and I'm pretty sure I've seen this in other languages.
Yes, it can do that, but strictly speaking that will assign the default value if the retrieved value is falsey, as opposed to truly undefined. It would therefore not only match undefined but also null, false, 0, NaN, "" (but not "0").
If you want to set to default only if the variable is strictly undefined then the safest way is to write:
var x = (typeof x === 'undefined') ? your_default_value : x;
On newer browsers it's actually safe to write:
var x = (x === undefined) ? your_default_value : x;
but be aware that it is possible to subvert this on older browsers where it was permitted to declare a variable named undefined that has a defined value, causing the test to fail.
Logical nullish assignment, ES2020+ solution
New operators are currently being added to the browsers, ??=, ||=, and &&=. This post will focus on ??=.
This checks if left side is undefined or null, short-circuiting if already defined. If not, the right-side is assigned to the left-side variable.
Comparing Methods
// Using ??=
name ??= "Dave"
// Previously, ES2020
name = name ?? "Dave"
// or
if (typeof name === "undefined" || name === null) {
name = true
}
// Before that (not equivalent, but commonly used)
name = name || "Dave" // Now: name ||= "Dave"
Basic Examples
let a // undefined
let b = null
let c = false
a ??= true // true
b ??= true // true
c ??= true // false
Object/Array Examples
let x = ["foo"]
let y = { foo: "fizz" }
x[0] ??= "bar" // "foo"
x[1] ??= "bar" // "bar"
y.foo ??= "buzz" // "fizz"
y.bar ??= "buzz" // "buzz"
x // Array [ "foo", "bar" ]
y // Object { foo: "fizz", bar: "buzz" }
??= Browser Support Oct 2022 - 93%
??= Mozilla Documentation
||= Mozilla Documentation
&&= Mozilla Documentation
The 2018 ES6 answer is:
return Object.is(x, undefined) ? y : x;
If variable x is undefined, return variable y... otherwise if variable x is defined, return variable x.
ES2020 Answer
With the Nullish Coalescing Operator, you can set a default value if value is null or undefined.
const setVariable = localStorage.getItem('value') ?? 0;
However, you should be aware that the nullish coalescing operator does not return the default value for other types of falsy value such as 0 and ''.
However, do take note of the browser support. You may need to use a JavaScript compiler like Babel to convert it into something more backward compatible. If you are using Node.js, it has been supported since version 14.
I needed to "set a variable if undefined" in several places. I created a function using #Alnitak answer. Hopefully it helps someone.
function setDefaultVal(value, defaultValue){
return (value === undefined) ? defaultValue : value;
}
Usage:
hasPoints = setDefaultVal(this.hasPoints, true);
It seems more logical to check typeof instead of undefined? I assume you expect a number as you set the var to 0 when undefined:
var getVariable = localStorage.getItem('value');
var setVariable = (typeof getVariable == 'number') ? getVariable : 0;
In this case if getVariable is not a number (string, object, whatever), setVariable is set to 0
In our days you actually can do your approach with JS:
// Your variable is null
// or '', 0, false, undefined
let x = null;
// Set default value
x = x || 'default value';
console.log(x); // default value
So your example WILL work:
const setVariable = localStorage.getItem('value') || 0;
You can use any of below ways.
let x;
let y = 4;
x || (x = y)
in ES12 or after
let x;
let y = 4;
x ||= y;
If you're a FP (functional programming) fan, Ramda has a neat helper function for this called defaultTo :
usage:
const result = defaultTo(30)(value)
It's more useful when dealing with undefined boolean values:
const result2 = defaultTo(false)(dashboard.someValue)
var setVariable = (typeof localStorage.getItem('value') !== 'undefined' && localStorage.getItem('value')) || 0;
Ran into this scenario today as well where I didn't want zero to be overwritten for several values. We have a file with some common utility methods for scenarios like this. Here's what I added to handle the scenario and be flexible.
function getIfNotSet(value, newValue, overwriteNull, overwriteZero) {
if (typeof (value) === 'undefined') {
return newValue;
} else if (value === null && overwriteNull === true) {
return newValue;
} else if (value === 0 && overwriteZero === true) {
return newValue;
} else {
return value;
}
}
It can then be called with the last two parameters being optional if I want to only set for undefined values or also overwrite null or 0 values. Here's an example of a call to it that will set the ID to -1 if the ID is undefined or null, but wont overwrite a 0 value.
data.ID = Util.getIfNotSet(data.ID, -1, true);
Works even if the default value is a boolean value:
var setVariable = ( (b = 0) => b )( localStorage.getItem('value') );
It seems to me, that for current javascript implementations,
var [result='default']=[possiblyUndefinedValue]
is a nice way to do this (using object deconstruction).
How do I check if an object has a specific property in JavaScript?
Consider:
x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
//Do this
}
Is that the best way to do it?
2022 UPDATE
Object.hasOwn()
Object.hasOwn() is recommended over Object.hasOwnProperty() because it works for objects created using Object.create(null) and with objects that have overridden the inherited hasOwnProperty() method. While it is possible to workaround these problems by calling Object.prototype.hasOwnProperty() on an external object, Object.hasOwn() is more intuitive.
Example
const object1 = {
prop: 'exists'
};
console.log(Object.hasOwn(object1, 'prop'));
// expected output: true
Original answer
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 ) {
var hasOwnProperty = function(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.
With Underscore.js or (even better) Lodash:
_.has(x, 'key');
Which calls Object.prototype.hasOwnProperty, but (a) is shorter to type, and (b) uses "a safe reference to hasOwnProperty" (i.e. it works even if hasOwnProperty is overwritten).
In particular, Lodash defines _.has as:
function has(object, key) {
return object ? hasOwnProperty.call(object, key) : false;
}
// hasOwnProperty = Object.prototype.hasOwnProperty
You can use this (but read the warning below):
var x = {
'key': 1
};
if ('key' in x) {
console.log('has');
}
But be warned: 'constructor' in x will return true even if x is an empty object - same for 'toString' in x, and many others. It's better to use Object.hasOwn(x, 'key').
Note: the following is nowadays largely obsolete thanks to strict mode, and hasOwnProperty. The correct solution is to use strict mode and to check for the presence of a property using obj.hasOwnProperty. This answer predates both these things, at least as widely implemented (yes, it is that old). Take the following as a historical note.
Bear in mind that undefined is (unfortunately) not a reserved word in JavaScript if you’re not using strict mode. 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. :-/
A common alternative is to ensure that undefined is actually undefined, e.g. by putting the code into a function which accepts an additional parameter, called undefined, that isn’t passed a value. To ensure that it’s not passed a value, you could just call it yourself immediately, e.g.:
(function (undefined) {
… your code …
if (x.attribute !== undefined)
… mode code …
})();
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';
};
Considering the following object in Javascript
const x = {key: 1};
You can use the in operator to check if the property exists on an object:
console.log("key" in x);
You can also loop through all the properties of the object using a for - in loop, and then check for the specific property:
for (const prop in x) {
if (prop === "key") {
//Do something
}
}
You must consider if this object property is enumerable or not, because non-enumerable properties will not show up in a for-in loop. Also, if the enumerable property is shadowing a non-enumerable property of the prototype, it will not show up in Internet Explorer 8 and earlier.
If you’d like a list of all instance properties, whether enumerable or not, you can use
Object.getOwnPropertyNames(x);
This will return an array of names of all properties that exist on an object.
Reflections provide methods that can be used to interact with Javascript objects. The static Reflect.has() method works like the in operator as a function.
console.log(Reflect.has(x, 'key'));
// expected output: true
console.log(Reflect.has(x, 'key2'));
// expected output: false
console.log(Reflect.has(object1, 'toString'));
// expected output: true
Finally, you can use the typeof operator to directly check the data type of the object property:
if (typeof x.key === "undefined") {
console.log("undefined");
}
If the property does not exist on the object, it will return the string undefined. Else it will return the appropriate property type. However, note that this is not always a valid way of checking if an object has a property or not, because you could have a property that is set to undefined, in which case, using typeof x.key would still return true (even though the key is still in the object).
Similarly, you can check if a property exists by comparing directly to the undefined Javascript property
if (x.key === undefined) {
console.log("undefined");
}
This should work unless key was specifically set to undefined on the x object
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 independent 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.
The bottom line is there is no cross-browser way (since Internet Explorer doesn't expose __prototype__) to determine that a specific identifier has not been attached to an object or anything in its prototype chain.
If you are searching for a property, then "no". You want:
if ('prop' in obj) { }
In general, you should not care whether or not the property comes from the prototype or the object.
However, because you used 'key' in your sample code, it looks like you are treating the object as a hash, in which case your answer would make sense. All of the hashes keys would be properties in the object, and you avoid the extra properties contributed by the prototype.
John Resig's answer was very comprehensive, but I thought it wasn't clear. Especially with when to use "'prop' in obj".
For testing simple objects, use:
if (obj[x] !== undefined)
If you don't know what object type it is, use:
if (obj.hasOwnProperty(x))
All other options are slower...
Details
A performance evaluation of 100,000,000 cycles under Node.js to the five options suggested by others here:
function hasKey1(k,o) { return (x in obj); }
function hasKey2(k,o) { return (obj[x]); }
function hasKey3(k,o) { return (obj[x] !== undefined); }
function hasKey4(k,o) { return (typeof(obj[x]) !== 'undefined'); }
function hasKey5(k,o) { return (obj.hasOwnProperty(x)); }
The evaluation tells us that unless we specifically want to check the object's prototype chain as well as the object itself, we should not use the common form:
if (X in Obj)...
It is between 2 to 6 times slower depending on the use case
hasKey1 execution time: 4.51 s
hasKey2 execution time: 0.90 s
hasKey3 execution time: 0.76 s
hasKey4 execution time: 0.93 s
hasKey5 execution time: 2.15 s
Bottom line, if your Obj is not necessarily a simple object and you wish to avoid checking the object's prototype chain and to ensure x is owned by Obj directly, use if (obj.hasOwnProperty(x))....
Otherwise, when using a simple object and not being worried about the object's prototype chain, using if (typeof(obj[x]) !== 'undefined')... is the safest and fastest way.
If you use a simple object as a hash table and never do anything kinky, I would use if (obj[x])... as I find it much more readable.
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.hasOwnProperty("key")){
// …
}
because
if(x.key){
// …
}
fails if x.key is falsy (for example, x.key === "").
You can also use the ES6 Reflect object:
x = {'key': 1};
Reflect.has( x, 'key'); // returns true
Documentation on MDN for Reflect.has can be found here.
The static Reflect.has() method works like the in operator as a function.
Do not do this object.hasOwnProperty(key)). It's really bad because these methods may be shadowed by properties on the object in question - consider { hasOwnProperty: false } - or, the object may be a null object (Object.create(null)).
The best way is to do Object.prototype.hasOwnProperty.call(object, key) or:
const has = Object.prototype.hasOwnProperty; // Cache the lookup once, in module scope.
console.log(has.call(object, key));
/* Or */
import has from 'has'; // https://www.npmjs.com/package/has
console.log(has(object, key));
OK, it 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 it does the same thing as below.
if (x.key !== undefined)
Another relatively simple way is using Object.keys. This returns an array which means you get all of the features of an array.
var noInfo = {};
var info = {something: 'data'};
Object.keys(noInfo).length //returns 0 or false
Object.keys(info).length //returns 1 or true
Although we are in a world with great browser support. Because this question is so old I thought I'd add this:
This is safe to use as of JavaScript v1.8.5.
JavaScript is now evolving and growing as it now has good and even efficient ways to check it.
Here are some easy ways to check if object has a particular property:
Using hasOwnProperty()
const hero = {
name: 'Batman'
};
hero.hasOwnProperty('name'); // => true
hero.hasOwnProperty('realName'); // => false
Using keyword/operator in
const hero = {
name: 'Batman'
};
'name' in hero; // => true
'realName' in hero; // => false
Comparing with undefined keyword
const hero = {
name: 'Batman'
};
hero.name; // => 'Batman'
hero.realName; // => undefined
// So consider this
hero.realName == undefined // => true (which means property does not exists in object)
hero.name == undefined // => false (which means that property exists in object)
For more information, check here.
hasOwnProperty "can be used to determine whether an object has the specified property as a direct property of that object; unlike the in operator, this method does not check down the object's prototype chain."
So most probably, for what seems by your question, you don't want to use hasOwnProperty, which determines if the property exists as attached directly to the object itself,.
If you want to determine if the property exists in the prototype chain, you may want to use it like:
if (prop in object) { // Do something }
You can use the following approaches-
var obj = {a:1}
console.log('a' in obj) // 1
console.log(obj.hasOwnProperty('a')) // 2
console.log(Boolean(obj.a)) // 3
The difference between the following approaches are as follows-
In the first and third approach we are not just searching in object but its prototypal chain too. If the object does not have the property, but the property is present in its prototype chain it is going to give true.
var obj = {
a: 2,
__proto__ : {b: 2}
}
console.log('b' in obj)
console.log(Boolean(obj.b))
The second approach will check only for its own properties. Example -
var obj = {
a: 2,
__proto__ : {b: 2}
}
console.log(obj.hasOwnProperty('b'))
The difference between the first and the third is if there is a property which has value undefined the third approach is going to give false while first will give true.
var obj = {
b : undefined
}
console.log(Boolean(obj.b))
console.log('b' in obj);
Given myObject object and “myKey” as key name:
Object.keys(myObject).includes('myKey')
or
myObject.hasOwnProperty('myKey')
or
typeof myObject.myKey !== 'undefined'
The last was widely used, but (as pointed out in other answers and comments) it could also match on keys deriving from Object prototype.
Performance
Today 2020.12.17 I perform tests on MacOs HighSierra 10.13.6 on Chrome v87, Safari v13.1.2 and Firefox v83 for chosen solutions.
Results
I compare only solutions A-F because they give valid result for all cased used in snippet in details section. For all browsers
solution based on in (A) is fast or fastest
solution (E) is fastest for chrome for big objects and fastest for firefox for small arrays if key not exists
solution (F) is fastest (~ >10x than other solutions) for small arrays
solutions (D,E) are quite fast
solution based on losash has (B) is slowest
Details
I perform 4 tests cases:
when object has 10 fields and searched key exists - you can run it HERE
when object has 10 fields and searched key not exists - you can run it HERE
when object has 10000 fields and searched key exists - you can run it HERE
when object has 10000 fields and searched key exists - you can run it HERE
Below snippet presents differences between solutions
A
B
C
D
E
F
G
H
I
J
K
// SO https://stackoverflow.com/q/135448/860099
// src: https://stackoverflow.com/a/14664748/860099
function A(x) {
return 'key' in x
}
// src: https://stackoverflow.com/a/11315692/860099
function B(x) {
return _.has(x, 'key')
}
// src: https://stackoverflow.com/a/40266120/860099
function C(x) {
return Reflect.has( x, 'key')
}
// src: https://stackoverflow.com/q/135448/860099
function D(x) {
return x.hasOwnProperty('key')
}
// src: https://stackoverflow.com/a/11315692/860099
function E(x) {
return Object.prototype.hasOwnProperty.call(x, 'key')
}
// src: https://stackoverflow.com/a/136411/860099
function F(x) {
function hasOwnProperty(obj, prop) {
var proto = obj.__proto__ || obj.constructor.prototype;
return (prop in obj) &&
(!(prop in proto) || proto[prop] !== obj[prop]);
}
return hasOwnProperty(x,'key')
}
// src: https://stackoverflow.com/a/135568/860099
function G(x) {
return typeof(x.key) !== 'undefined'
}
// src: https://stackoverflow.com/a/22740939/860099
function H(x) {
return x.key !== undefined
}
// src: https://stackoverflow.com/a/38332171/860099
function I(x) {
return !!x.key
}
// src: https://stackoverflow.com/a/41184688/860099
function J(x) {
return !!x['key']
}
// src: https://stackoverflow.com/a/54196605/860099
function K(x) {
return Boolean(x.key)
}
// --------------------
// TEST
// --------------------
let x1 = {'key': 1};
let x2 = {'key': "1"};
let x3 = {'key': true};
let x4 = {'key': []};
let x5 = {'key': {}};
let x6 = {'key': ()=>{}};
let x7 = {'key': ''};
let x8 = {'key': 0};
let x9 = {'key': false};
let x10= {'key': undefined};
let x11= {'nokey': 1};
let b= x=> x ? 1:0;
console.log(' 1 2 3 4 5 6 7 8 9 10 11');
[A,B,C,D,E,F,G,H,I,J,K ].map(f=> {
console.log(
`${f.name} ${b(f(x1))} ${b(f(x2))} ${b(f(x3))} ${b(f(x4))} ${b(f(x5))} ${b(f(x6))} ${b(f(x7))} ${b(f(x8))} ${b(f(x9))} ${b(f(x10))} ${b(f(x11))} `
)})
console.log('\nLegend: Columns (cases)');
console.log('1. key = 1 ');
console.log('2. key = "1" ');
console.log('3. key = true ');
console.log('4. key = [] ');
console.log('5. key = {} ');
console.log('6. key = ()=>{} ');
console.log('7. key = "" ');
console.log('8. key = 0 ');
console.log('9. key = false ');
console.log('10. key = undefined ');
console.log('11. no-key ');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"> </script>
This shippet only presents functions used in performance tests - it not perform tests itself!
And here are example results for chrome
Now with ECMAScript22 we can use hasOwn instead of hasOwnProperty (Because this feature has pitfalls )
Object.hasOwn(obj, propKey)
Here is another option for a specific case. :)
If you want to test for a member on an object and want to know if it has been set to something other than:
''
false
null
undefined
0
...
then you can use:
var foo = {};
foo.bar = "Yes, this is a proper value!";
if (!!foo.bar) {
// member is set, do something
}
some easier and short options depending on the specific use case:
to check if the property exists, regardless of value, use the in operator ("a" in b)
to check a property value from a variable, use bracket notation (obj[v])
to check a property value as truthy, use optional
chaining (?.)
to check a property value boolean, use double-not / bang-bang / (!!)
to set a default value for null / undefined check, use nullish coalescing operator (??)
to set a default value for falsey value check, use short-circuit logical OR operator (||)
run the code snippet to see results:
let obj1 = {prop:undefined};
console.log(1,"prop" in obj1);
console.log(1,obj1?.prop);
let obj2 = undefined;
//console.log(2,"prop" in obj2); would throw because obj2 undefined
console.log(2,"prop" in (obj2 ?? {}))
console.log(2,obj2?.prop);
let obj3 = {prop:false};
console.log(3,"prop" in obj3);
console.log(3,!!obj3?.prop);
let obj4 = {prop:null};
let look = "prop"
console.log(4,"prop" in obj4);
console.log(4,obj4?.[look]);
let obj5 = {prop:true};
console.log(5,"prop" in obj5);
console.log(5,obj5?.prop === true);
let obj6 = {otherProp:true};
look = "otherProp"
console.log(6,"prop" in obj6);
console.log(6,obj6.look); //should have used bracket notation
let obj7 = {prop:""};
console.log(7,"prop" in obj7);
console.log(7,obj7?.prop || "empty");
I see very few instances where hasOwn is used properly, especially given its inheritance issues
There is a method, "hasOwnProperty", that exists on an object, but it's not recommended to call this method directly, because it might be sometimes that the object is null or some property exist on the object like: { hasOwnProperty: false }
So a better way would be:
// Good
var obj = {"bar": "here bar desc"}
console.log(Object.prototype.hasOwnProperty.call(obj, "bar"));
// Best
const has = Object.prototype.hasOwnProperty; // Cache the lookup once, in module scope.
console.log(has.call(obj, "bar"));
An ECMAScript 6 solution with reflection. Create a wrapper like:
/**
Gets an argument from array or object.
The possible outcome:
- If the key exists the value is returned.
- If no key exists the default value is returned.
- If no default value is specified an empty string is returned.
#param obj The object or array to be searched.
#param key The name of the property or key.
#param defVal Optional default version of the command-line parameter [default ""]
#return The default value in case of an error else the found parameter.
*/
function getSafeReflectArg( obj, key, defVal) {
"use strict";
var retVal = (typeof defVal === 'undefined' ? "" : defVal);
if ( Reflect.has( obj, key) ) {
return Reflect.get( obj, key);
}
return retVal;
} // getSafeReflectArg
Showing how to use this answer
const object= {key1: 'data', key2: 'data2'};
Object.keys(object).includes('key1') //returns true
We can use indexOf as well, I prefer includes
You need to use the method object.hasOwnProperty(property). It returns true if the object has the property and false if the object doesn't.
The hasOwnProperty() method returns a boolean indicating whether the object has the specified property as its own property (as opposed to inheriting it).
const object1 = {};
object1.property1 = 42;
console.log(object1.hasOwnProperty('property1'));
// expected output: true
console.log(object1.hasOwnProperty('toString'));
// expected output: false
console.log(object1.hasOwnProperty('hasOwnProperty'));
// expected output: false
Know more
Don't over-complicate things when you can do:
var isProperty = (objectname.keyname || "") ? true : false;
It Is simple and clear for most cases...
A Better approach for iterating on object's own properties:
If you want to iterate on object's properties without using hasOwnProperty() check,
use for(let key of Object.keys(stud)){} method:
for(let key of Object.keys(stud)){
console.log(key); // will only log object's Own properties
}
full Example and comparison with for-in with hasOwnProperty()
function Student() {
this.name = "nitin";
}
Student.prototype = {
grade: 'A'
}
let stud = new Student();
// for-in approach
for(let key in stud){
if(stud.hasOwnProperty(key)){
console.log(key); // only outputs "name"
}
}
//Object.keys() approach
for(let key of Object.keys(stud)){
console.log(key);
}