Related
How do I determine if variable is undefined or null?
My code is as follows:
var EmpName = $("div#esd-names div#name").attr('class');
if(EmpName == 'undefined'){
// DO SOMETHING
};
<div id="esd-names">
<div id="name"></div>
</div>
But if I do this, the JavaScript interpreter halts execution.
You can use the qualities of the abstract equality operator to do this:
if (variable == null){
// your code here.
}
Because null == undefined is true, the above code will catch both null and undefined.
The standard way to catch null and undefined simultaneously is this:
if (variable == null) {
// do something
}
--which is 100% equivalent to the more explicit but less concise:
if (variable === undefined || variable === null) {
// do something
}
When writing professional JS, it's taken for granted that type equality and the behavior of == vs === is understood. Therefore we use == and only compare to null.
Edit again
The comments suggesting the use of typeof are simply wrong. Yes, my solution above will cause a ReferenceError if the variable doesn't exist. This is a good thing. This ReferenceError is desirable: it will help you find your mistakes and fix them before you ship your code, just like compiler errors would in other languages. Use try/catch if you are working with input you don't have control over.
You should not have any references to undeclared variables in your code.
Combining the above answers, it seems the most complete answer would be:
if( typeof variable === 'undefined' || variable === null ){
// Do stuff
}
This should work for any variable that is either undeclared or declared and explicitly set to null or undefined. The boolean expression should evaluate to false for any declared variable that has an actual non-null value.
if (variable == null) {
// Do stuff, will only match null or undefined, this won't match false
}
if (typeof EmpName != 'undefined' && EmpName) {
will evaluate to true if value is not:
null
undefined
NaN
empty string ("")
0
false
Probably the shortest way to do this is:
if(EmpName == null) { /* DO SOMETHING */ };
Here is proof:
function check(EmpName) {
if(EmpName == null) { return true; };
return false;
}
var log = (t,a) => console.log(`${t} -> ${check(a)}`);
log('null', null);
log('undefined', undefined);
log('NaN', NaN);
log('""', "");
log('{}', {});
log('[]', []);
log('[1]', [1]);
log('[0]', [0]);
log('[[]]', [[]]);
log('true', true);
log('false', false);
log('"true"', "true");
log('"false"', "false");
log('Infinity', Infinity);
log('-Infinity', -Infinity);
log('1', 1);
log('0', 0);
log('-1', -1);
log('"1"', "1");
log('"0"', "0");
log('"-1"', "-1");
// "void 0" case
console.log('---\n"true" is:', true);
console.log('"void 0" is:', void 0);
log(void 0,void 0); // "void 0" is "undefined"
And here are more details about == (source here)
BONUS: reason why === is more clear than == (look on agc answer)
jQuery attr() function returns either a blank string or the actual value (and never null or undefined). The only time it returns undefined is when your selector didn't return any element.
So you may want to test against a blank string. Alternatively, since blank strings, null and undefined are false-y, you can just do this:
if (!EmpName) { //do something }
Edited answer: In my opinion, you shouldn't use the function from my below old answer. Instead, you should probably know the type of your variable and use the according to check directly (for example, wondering if an array is empty? just do if(arr.length===0){} etc.). This answer doesn't even answer OP's question.
I've come to write my own function for this. JavaScript is weird.
It is usable on literally anything. (Note that this also checks if the variable contains any usable values. But since this information is usually also needed, I think it's worth posting). Please consider leaving a note.
function empty(v) {
let type = typeof v;
if (type === 'undefined') {
return true;
}
if (type === 'boolean') {
return !v;
}
if (v === null) {
return true;
}
if (v === undefined) {
return true;
}
if (v instanceof Array) {
if (v.length < 1) {
return true;
}
} else if (type === 'string') {
if (v.length < 1) {
return true;
}
if (v === '0') {
return true;
}
} else if (type === 'object') {
if (Object.keys(v).length < 1) {
return true;
}
} else if (type === 'number') {
if (v === 0) {
return true;
}
}
return false;
}
TypeScript-compatible.
This function should do exactly the same thing like PHP's empty() function (see RETURN VALUES)
Considers undefined, null, false, 0, 0.0, "0" {}, [] as empty.
"0.0", NaN, " ", true are considered non-empty.
The shortest and easiest:
if(!EmpName ){
// DO SOMETHING
}
this will evaluate true if EmpName is:
null
undefined
NaN
empty
string ("")
0
false
If the variable you want to check is a global, do
if (window.yourVarName) {
// Your code here
}
This way to check will not throw an error even if the yourVarName variable doesn't exist.
Example: I want to know if my browser supports History API
if (window.history) {
history.back();
}
How this works:
window is an object which holds all global variables as its properties, and in JavaScript it is legal to try to access a non-existing object property. If history doesn't exist then window.history returns undefined. undefined is falsey, so code in an if(undefined){} block won't run.
In JavaScript, as per my knowledge, we can check an undefined, null or empty variable like below.
if (variable === undefined){
}
if (variable === null){
}
if (variable === ''){
}
Check all conditions:
if(variable === undefined || variable === null || variable === ''){
}
Since you are using jQuery, you can determine whether a variable is undefined or its value is null by using a single function.
var s; // undefined
jQuery.isEmptyObject(s); // will return true;
s = null; // defined as null
jQuery.isEmptyObject(s); // will return true;
// usage
if(jQuery.isEmptyObject(s)){
alert('Either variable: s is undefined or its value is null');
}else{
alert('variable: s has value ' + s);
}
s = 'something'; // defined with some value
jQuery.isEmptyObject(s); // will return false;
I've just had this problem i.e. checking if an object is null.
I simply use this:
if (object) {
// Your code
}
For example:
if (document.getElementById("enterJob")) {
document.getElementById("enterJob").className += ' current';
}
You can simply use the following (I know there are shorter ways to do this, but this may make it easier to visually observe, at least for others looking at the code).
if (x === null || x === undefined) {
// Add your response code here, etc.
}
source: https://www.growthsnippets.com/how-can-i-determine-if-a-variable-is-undefined-or-null/
jQuery check element not null:
var dvElement = $('#dvElement');
if (dvElement.length > 0) {
// Do something
}
else{
// Else do something else
}
With the newest javascript changes, you can use the new logical operator ??= to check if the left operand is null or undefined and if so assign the value of right operand.
SO,
if(EmpName == null){ // if Variable EmpName null or undefined
EmpName = 'some value';
};
Is equivalent to:
EmpName ??= 'some value';
The easiest way to check is:
if(!variable) {
// If the variable is null or undefined then execution of code will enter here.
}
I run this test in the Chrome console. Using (void 0) you can check undefined:
var c;
undefined
if (c === void 0) alert();
// output = undefined
var c = 1;
// output = undefined
if (c === void 0) alert();
// output = undefined
// check c value c
// output = 1
if (c === void 0) alert();
// output = undefined
c = undefined;
// output = undefined
if (c === void 0) alert();
// output = undefined
With the solution below:
const getType = (val) => typeof val === 'undefined' || !val ? null : typeof val;
const isDeepEqual = (a, b) => getType(a) === getType(b);
console.log(isDeepEqual(1, 1)); // true
console.log(isDeepEqual(null, null)); // true
console.log(isDeepEqual([], [])); // true
console.log(isDeepEqual(1, "1")); // false
etc...
I'm able to check for the following:
null
undefined
NaN
empty
string ("")
0
false
To test if a variable is null or undefined I use the below code.
if(typeof sVal === 'undefined' || sVal === null || sVal === ''){
console.log('variable is undefined or null');
}
if you create a function to check it:
export function isEmpty (v) {
if (typeof v === "undefined") {
return true;
}
if (v === null) {
return true;
}
if (typeof v === "object" && Object.keys(v).length === 0) {
return true;
}
if (Array.isArray(v) && v.length === 0) {
return true;
}
if (typeof v === "string" && v.trim().length === 0) {
return true;
}
return false;
}
(null == undefined) // true
(null === undefined) // false
Because === checks for both the type and value. Type of both are different but value is the same.
Let's look at this,
let apple; // Only declare the variable as apple
alert(apple); // undefined
In the above, the variable is only declared as apple. In this case, if we call method alert it will display undefined.
let apple = null; /* Declare the variable as apple and initialized but the value is null */
alert(apple); // null
In the second one it displays null, because variable of apple value is null.
So you can check whether a value is undefined or null.
if(apple !== undefined || apple !== null) {
// Can use variable without any error
}
The foo == null check should do the trick and resolve the "undefined OR null" case in the shortest manner. (Not considering "foo is not declared" case.) But people who are used to have 3 equals (as the best practice) might not accept it. Just look at eqeqeq or triple-equals rules in eslint and tslint...
The explicit approach, when we are checking if a variable is undefined or null separately, should be applied in this case, and my contribution to the topic (27 non-negative answers for now!) is to use void 0 as both short and safe way to perform check for undefined.
Using foo === undefined is not safe because undefined is not a reserved word and can be shadowed (MDN). Using typeof === 'undefined' check is safe, but if we are not going to care about foo-is-undeclared case the following approach can be used:
if (foo === void 0 || foo === null) { ... }
You can do something like this, I think its more efficient for multiple value check on the same variable in one condition
const x = undefined;
const y = null;
const z = 'test';
if ([undefined, null].includes(x)) {
// Will return true
}
if ([undefined, null].includes(y)) {
// Will return true
}
if ([undefined, null].includes(z)) {
// Will return false
}
No one seems to have to posted this yet, so here we go:
a?.valueOf() === undefined works reliably for either null or undefined.
The following works pretty much like a == null or a == undefined, but it could be more attractive for purists who don't like == 😎
function check(a) {
const value = a?.valueOf();
if (value === undefined) {
console.log("a is null or undefined");
}
else {
console.log(value);
}
}
check(null);
check(undefined);
check(0);
check("");
check({});
check([]);
On a side note, a?.constructor works too:
function check(a) {
if (a?.constructor === undefined) {
console.log("a is null or undefined");
}
}
check(null);
check(undefined);
check(0);
check("");
check({});
check([]);
Calling typeof null returns a value of “object”, as the special value null is considered to be an empty object reference. Safari through version 5 and Chrome through version 7 have a quirk where calling typeof on a regular expression returns “function” while all other browsers return “object”.
var x;
if (x === undefined) {
alert ("only declared, but not defined.")
};
if (typeof y === "undefined") {
alert ("not even declared.")
};
You can only use second one: as it will check for both definition and declaration
var i;
if (i === null || typeof i === 'undefined') {
console.log(i, 'i is undefined or null')
}
else {
console.log(i, 'i has some value')
}
I still think the best/safe way to test these two conditions is to cast the value to a string:
var EmpName = $("div#esd-names div#name").attr('class');
// Undefined check
if (Object.prototype.toString.call(EmpName) === '[object Undefined]'){
// Do something with your code
}
// Nullcheck
if (Object.prototype.toString.call(EmpName) === '[object Null]'){
// Do something with your code
}
Is it possible to have object extensions in JavaScript? For example
Extensions.js
function any.isNullOrEmpty() {
if (this == null || this == "") {
return true
}
return false
}
app.js
var x = ""
console.log(x.isNullOrEmpty()) //should log true
is this possible? How do I do it?
You could add a method to the Object prototype, and use the valueOf method to get the value of the string:
...but, because null is a primitive that cannot have a method, the only way I can think of to get the target to be null would be to use call, apply or bind.
But you would never do this in production code, because modifying the prototype of built-in objects is discouraged.
'use strict' // important for the use of `call` and `null`
Object.prototype.isNullOrEmpty = function() { return this === null || this.valueOf() === '' }
const s = ''
console.log(s.isNullOrEmpty())
const t = null
console.log(Object.prototype.isNullOrEmpty.call(t))
You could use Object.prototype to extend this type of functionality in JavaScript.
Object.prototype.isNullOrEmpty = function() {
if (this == null || this == "") {
return true
}
return false
}
var x = "";
x.isNullOrEmpty(); // returns true
you need to add your custom method into prop type of object or array or everything u want to use your method on it.
but in your case you need to this like code below:
Object.prototype.isNullOrEmpty = function(){
if (this === null || this == "") {
return true
}
return false
}
let a = {a:'10'}
console.log(a.isNullOrEmpty())
function validateValue(value){
function isNullEmpty(){
return (value === void (0) || value == null)
}
return { isNullOrEmpty }
}
}
This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
After an AJAX request, sometimes my application may return an empty object, like:
var a = {};
How can I check whether that's the case?
ECMA 5+:
// because Object.keys(new Date()).length === 0;
// we have to do some additional check
obj // 👈 null and undefined check
&& Object.keys(obj).length === 0
&& Object.getPrototypeOf(obj) === Object.prototype
Note, though, that this creates an unnecessary array (the return value of keys).
Pre-ECMA 5:
function isEmpty(obj) {
for(var prop in obj) {
if(Object.prototype.hasOwnProperty.call(obj, prop)) {
return false;
}
}
return JSON.stringify(obj) === JSON.stringify({});
}
jQuery:
jQuery.isEmptyObject({}); // true
lodash:
_.isEmpty({}); // true
Underscore:
_.isEmpty({}); // true
Hoek
Hoek.deepEqual({}, {}); // true
ExtJS
Ext.Object.isEmpty({}); // true
AngularJS (version 1)
angular.equals({}, {}); // true
Ramda
R.isEmpty({}); // true
If ECMAScript 5 support is available, you can use Object.keys():
function isEmpty(obj) {
return Object.keys(obj).length === 0;
}
For ES3 and older, there's no easy way to do this. You'll have to loop over the properties explicitly:
function isEmpty(obj) {
for(var prop in obj) {
if(obj.hasOwnProperty(prop))
return false;
}
return true;
}
For those of you who have the same problem but use jQuery, you can use jQuery.isEmptyObject.
Performance
Today 2020.01.17, I performed tests on macOS High Sierra 10.13.6 on Chrome v79.0, Safari v13.0.4, and Firefox v72.0; for the chosen solutions.
Conclusions
Solutions based on for-in (A, J, L, M) are fastest
Solutions based on JSON.stringify (B, K) are slow
Surprisingly, the solution based on Object (N) is also slow
NOTE: This table does not match the photo below.
Details
There are 15 solutions presented in the snippet below.
If you want to run a performance test on your machine, click HERE.
This link was updated 2021.07.08, but tests originally were performed here - and results in the table above came from there (but now it looks like that service no longer works).
var log = (s, f) => console.log(`${s} --> {}:${f({})} {k:2}:${f({ k: 2 })}`);
function A(obj) {
for (var i in obj) return false;
return true;
}
function B(obj) {
return JSON.stringify(obj) === "{}";
}
function C(obj) {
return Object.keys(obj).length === 0;
}
function D(obj) {
return Object.entries(obj).length === 0;
}
function E(obj) {
return Object.getOwnPropertyNames(obj).length === 0;
}
function F(obj) {
return Object.keys(obj).length === 0 && obj.constructor === Object;
}
function G(obj) {
return typeof obj === "undefined" || !Boolean(Object.keys(obj)[0]);
}
function H(obj) {
return Object.entries(obj).length === 0 && obj.constructor === Object;
}
function I(obj) {
return Object.values(obj).every((val) => typeof val === "undefined");
}
function J(obj) {
for (const key in obj) {
if (hasOwnProperty.call(obj, key)) {
return false;
}
}
return true;
}
function K(obj) {
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
return false;
}
}
return JSON.stringify(obj) === JSON.stringify({});
}
function L(obj) {
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) return false;
}
return true;
}
function M(obj) {
for (var k in obj) {
if (obj.hasOwnProperty(k)) {
return false;
}
}
return true;
}
function N(obj) {
return (
Object.getOwnPropertyNames(obj).length === 0 &&
Object.getOwnPropertySymbols(obj).length === 0 &&
Object.getPrototypeOf(obj) === Object.prototype
);
}
function O(obj) {
return !(Object.getOwnPropertyNames !== undefined
? Object.getOwnPropertyNames(obj).length !== 0
: (function () {
for (var key in obj) break;
return key !== null && key !== undefined;
})());
}
log("A", A);
log("B", B);
log("C", C);
log("D", D);
log("E", E);
log("F", F);
log("G", G);
log("H", H);
log("I", I);
log("J", J);
log("K", K);
log("L", L);
log("M", M);
log("N", N);
log("O", O);
You can use Underscore.js.
_.isEmpty({}); // true
if(Object.getOwnPropertyNames(obj).length === 0){
//is empty
}
see http://bencollier.net/2011/04/javascript-is-an-object-empty/
How about using JSON.stringify? It is almost available in all modern browsers.
function isEmptyObject(obj){
return JSON.stringify(obj) === '{}';
}
There is a simple way if you are on a newer browser.
Object.keys(obj).length === 0
Old question, but just had the issue. Including JQuery is not really a good idea if your only purpose is to check if the object is not empty. Instead, just deep into JQuery's code, and you will get the answer:
function isEmptyObject(obj) {
var name;
for (name in obj) {
if (obj.hasOwnProperty(name)) {
return false;
}
}
return true;
}
Using Object.keys(obj).length (as suggested above for ECMA 5+) is 10 times slower for empty objects! keep with the old school (for...in) option.
Tested under Node, Chrome, Firefox and IE 9, it becomes evident that for most use cases:
(for...in...) is the fastest option to use!
Object.keys(obj).length is 10 times slower for empty objects
JSON.stringify(obj).length is always the slowest (not suprising)
Object.getOwnPropertyNames(obj).length takes longer than Object.keys(obj).length can be much longer on some systems.
Bottom line performance wise, use:
function isEmpty(obj) {
for (var x in obj) { return false; }
return true;
}
or
function isEmpty(obj) {
for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }
return true;
}
See detailed testing results and test code at Is object empty?
My take:
function isEmpty(obj) {
return Object.keys(obj).length === 0;
}
var a = {
a: 1,
b: 2
}
var b = {}
console.log(isEmpty(a)); // false
console.log(isEmpty(b)); // true
Just, I don't think all browsers implement Object.keys() currently.
I am using this.
function isObjectEmpty(object) {
var isEmpty = true;
for (keys in object) {
isEmpty = false;
break; // exiting since we found that the object is not empty
}
return isEmpty;
}
Eg:
var myObject = {}; // Object is empty
var isEmpty = isObjectEmpty(myObject); // will return true;
// populating the object
myObject = {"name":"John Smith","Address":"Kochi, Kerala"};
// check if the object is empty
isEmpty = isObjectEmpty(myObject); // will return false;
from here
Update
OR
you can use the jQuery implementation of isEmptyObject
function isEmptyObject(obj) {
var name;
for (name in obj) {
return false;
}
return true;
}
Just a workaround. Can your server generate some special property in case of no data?
For example:
var a = {empty:true};
Then you can easily check it in your AJAX callback code.
Another way to check it:
if (a.toSource() === "({})") // then 'a' is empty
EDIT:
If you use any JSON library (f.e. JSON.js) then you may try JSON.encode() function and test the result against empty value string.
1. Using Object.keys
Object.keys will return an Array, which contains the property names of the object. If the length of the array is 0, then we know that the object is empty.
function isEmpty(obj) {
return Object.keys(obj).length === 0 && obj.constructor === Object;
}
We can also check this using Object.values and Object.entries.
This is typically the easiest way to determine if an object is empty.
2. Looping over object properties with for…in
The for…in statement will loop through the enumerable property of object.
function isEmpty(obj) {
for(var prop in obj) {
if(obj.hasOwnProperty(prop))
return false;
}
return true;
}
In the above code, we will loop through object properties and if an object has at least one property, then it will enter the loop and return false. If the object doesn’t have any properties then it will return true.
#3. Using JSON.stringify
If we stringify the object and the result is simply an opening and closing bracket, we know the object is empty.
function isEmptyObject(obj){
return JSON.stringify(obj) === '{}';
}
4. Using jQuery
jQuery.isEmptyObject(obj);
5. Using Underscore and Lodash
_.isEmpty(obj);
Resource
function isEmpty(obj) {
for(var i in obj) { return false; }
return true;
}
The following example show how to test if a JavaScript object is empty, if by empty we means has no own properties to it.
The script works on ES6.
const isEmpty = (obj) => {
if (obj === null ||
obj === undefined ||
Array.isArray(obj) ||
typeof obj !== 'object'
) {
return true;
}
return Object.getOwnPropertyNames(obj).length === 0;
};
console.clear();
console.log('-----');
console.log(isEmpty('')); // true
console.log(isEmpty(33)); // true
console.log(isEmpty([])); // true
console.log(isEmpty({})); // true
console.log(isEmpty({ length: 0, custom_property: [] })); // false
console.log('-----');
console.log(isEmpty('Hello')); // true
console.log(isEmpty([1, 2, 3])); // true
console.log(isEmpty({ test: 1 })); // false
console.log(isEmpty({ length: 3, custom_property: [1, 2, 3] })); // false
console.log('-----');
console.log(isEmpty(new Date())); // true
console.log(isEmpty(Infinity)); // true
console.log(isEmpty(null)); // true
console.log(isEmpty(undefined)); // true
The correct answer is:
function isEmptyObject(obj) {
return (
Object.getPrototypeOf(obj) === Object.prototype &&
Object.getOwnPropertyNames(obj).length === 0 &&
Object.getOwnPropertySymbols(obj).length === 0
);
}
This checks that:
The object's prototype is exactly Object.prototype.
The object has no own properties (regardless of enumerability).
The object has no own property symbols.
In other words, the object is indistinguishable from one created with {}.
jQuery have special function isEmptyObject() for this case:
jQuery.isEmptyObject({}) // true
jQuery.isEmptyObject({ foo: "bar" }) // false
Read more on http://api.jquery.com/jQuery.isEmptyObject/
Caveat! Beware of JSON's limitiations.
javascript:
obj={ f:function(){} };
alert( "Beware!! obj is NOT empty!\n\nobj = { f:function(){} }" +
"\n\nJSON.stringify( obj )\n\nreturns\n\n" +
JSON.stringify( obj ) );
displays
Beware!! obj is NOT empty!
obj = { f:function(){} }
JSON.stringify( obj )
returns
{}
To really accept ONLY {}, the best way to do it in Javascript using Lodash is:
_.isEmpty(value) && _.isPlainObject(value)
In addition to Thevs answer:
var o = {};
alert($.toJSON(o)=='{}'); // true
var o = {a:1};
alert($.toJSON(o)=='{}'); // false
it's jquery + jquery.json
Sugar.JS provides extended objects for this purpose. The code is clean and simple:
Make an extended object:
a = Object.extended({})
Check it's size:
a.size()
Pure Vanilla Javascript, and full backward compatibility
function isObjectDefined (Obj) {
if (Obj === null || typeof Obj !== 'object' ||
Object.prototype.toString.call(Obj) === '[object Array]') {
return false
} else {
for (var prop in Obj) {
if (Obj.hasOwnProperty(prop)) {
return true
}
}
return JSON.stringify(Obj) !== JSON.stringify({})
}
}
console.log(isObjectDefined()) // false
console.log(isObjectDefined('')) // false
console.log(isObjectDefined(1)) // false
console.log(isObjectDefined('string')) // false
console.log(isObjectDefined(NaN)) // false
console.log(isObjectDefined(null)) // false
console.log(isObjectDefined({})) // false
console.log(isObjectDefined([])) // false
console.log(isObjectDefined({a: ''})) // true
IsEmpty Object, unexpectedly lost its meaning i.e.: it's programming semantics, when our famous guru from Yahoo introduced the customized non-enumerable Object properties to ECMA and they got accepted.
[ If you don't like history - feel free to skip right to the working code ]
I'm seeing lots of good answers \ solutions to this question \ problem.
However, grabbing the most recent extensions to ECMA Script is not the honest way to go. We used to hold back the Web back in the day to keep Netscape 4.x, and Netscape based pages work and projects alive, which (by the way) were extremely primitive backwards and idiosyncratic, refusing to use new W3C standards and propositions [ which were quite revolutionary for that time and coder friendly ] while now being brutal against our own legacy.
Killing Internet Explorer 11 is plain wrong! Yes, some old warriors that infiltrated Microsoft remaining dormant since the "Cold War" era, agreed to it - for all the wrong reasons. - But that doesn't make it right!
Making use, of a newly introduced method\property in your answers and handing it over as a discovery ("that was always there but we didn't notice it"), rather than a new invention (for what it really is), is somewhat 'green' and harmful. I used to make such mistakes some 20 years ago when I still couldn't tell what's already in there and treated everything I could find a reference for, as a common working solution...
Backward compatibility is important !
We just don't know it yet. That's the reason I got the need to share my 'centuries old' generic solution which remains backward and forward compatible to the unforeseen future.
There were lots of attacks on the in operator but I think the guys doing that have finally come to senses and really started to understand and appreciate a true Dynamic Type Language such as JavaScript and its beautiful nature.
My methods aim to be simple and nuclear and for reasons mentioned above, I don't call it "empty" because the meaning of that word is no longer accurate. Is Enumerable, seems to be the word with the exact meaning.
function isEnum( x ) { for( var p in x )return!0; return!1 };
Some use cases:
isEnum({1:0})
true
isEnum({})
false
isEnum(null)
false
Thanks for reading!
Best one-liner solution I could find (updated):
isEmpty = obj => !Object.values(obj).filter(e => typeof e !== 'undefined').length;
console.log(isEmpty({})) // true
console.log(isEmpty({a: undefined, b: undefined})) // true
console.log(isEmpty({a: undefined, b: void 1024, c: void 0})) // true
console.log(isEmpty({a: [undefined, undefined]})) // false
console.log(isEmpty({a: 1})) // false
console.log(isEmpty({a: ''})) // false
console.log(isEmpty({a: null, b: undefined})) // false
Another alternative is to use is.js (14kB) as opposed to jquery (32kB), lodash (50kB), or underscore (16.4kB). is.js proved to be the fastest library among aforementioned libraries that could be used to determine whether an object is empty.
http://jsperf.com/check-empty-object-using-libraries
Obviously all these libraries are not exactly the same so if you need to easily manipulate the DOM then jquery might still be a good choice or if you need more than just type checking then lodash or underscore might be good. As for is.js, here is the syntax:
var a = {};
is.empty(a); // true
is.empty({"hello": "world"}) // false
Like underscore's and lodash's _.isObject(), this is not exclusively for objects but also applies to arrays and strings.
Under the hood this library is using Object.getOwnPropertyNames which is similar to Object.keys but Object.getOwnPropertyNames is a more thorough since it will return enumerable and non-enumerable properties as described here.
is.empty = function(value) {
if(is.object(value)){
var num = Object.getOwnPropertyNames(value).length;
if(num === 0 || (num === 1 && is.array(value)) || (num === 2 && is.arguments(value))){
return true;
}
return false;
} else {
return value === '';
}
};
If you don't want to bring in a library (which is understandable) and you know that you are only checking objects (not arrays or strings) then the following function should suit your needs.
function isEmptyObject( obj ) {
return Object.getOwnPropertyNames(obj).length === 0;
}
This is only a bit faster than is.js though just because you aren't checking whether it is an object.
I know this doesn't answer 100% your question, but I have faced similar issues before and here's how I use to solve them:
I have an API that may return an empty object. Because I know what fields to expect from the API, I only check if any of the required fields are present or not.
For example:
API returns {} or {agentID: '1234' (required), address: '1234 lane' (opt),...}.
In my calling function, I'll only check
if(response.data && response.data.agentID) {
do something with my agentID
} else {
is empty response
}
This way I don't need to use those expensive methods to check if an object is empty. The object will be empty for my calling function if it doesn't have the agentID field.
We can check with vanilla js with handling null or undefined check also as follows,
function isEmptyObject(obj) {
return !!obj && Object.keys(obj).length === 0 && obj.constructor === Object;
}
//tests
isEmptyObject(new Boolean()); // false
isEmptyObject(new Array()); // false
isEmptyObject(new RegExp()); // false
isEmptyObject(new String()); // false
isEmptyObject(new Number()); // false
isEmptyObject(new Function()); // false
isEmptyObject(new Date()); // false
isEmptyObject(null); // false
isEmptyObject(undefined); // false
isEmptyObject({}); // true
I liked this one I came up with, with the help of some other answers here. Thought I'd share it.
Object.defineProperty(Object.prototype, 'isEmpty', {
get() {
for(var p in this) {
if (this.hasOwnProperty(p)) {return false}
}
return true;
}
});
let users = {};
let colors = {primary: 'red'};
let sizes = {sm: 100, md: 200, lg: 300};
console.log(
'\nusers =', users,
'\nusers.isEmpty ==> ' + users.isEmpty,
'\n\n-------------\n',
'\ncolors =', colors,
'\ncolors.isEmpty ==> ' + colors.isEmpty,
'\n\n-------------\n',
'\nsizes =', sizes,
'\nsizes.isEmpty ==> ' + sizes.isEmpty,
'\n',
''
);
It's weird that I haven't encountered a solution that compares the object's values as opposed to the existence of any entry (maybe I missed it among the many given solutions).
I would like to cover the case where an object is considered empty if all its values are undefined:
const isObjectEmpty = obj => Object.values(obj).every(val => typeof val === "undefined")
console.log(isObjectEmpty({})) // true
console.log(isObjectEmpty({ foo: undefined, bar: undefined })) // true
console.log(isObjectEmpty({ foo: false, bar: null })) // false
Example usage
Let's say, for the sake of example, you have a function (paintOnCanvas) that destructs values from its argument (x, y and size). If all of them are undefined, they are to be left out of the resulting set of options. If not they are not, all of them are included.
function paintOnCanvas ({ brush, x, y, size }) {
const baseOptions = { brush }
const areaOptions = { x, y, size }
const options = isObjectEmpty(areaOptions) ? baseOptions : { ...baseOptions, areaOptions }
// ...
}
For example, this is the value of the object I am processing:
object = {"message":"success","dataList":{"state":"error","count":"25"}}
I know that to check if key "message" exists, I can do the following:
if(object['message']){
//"message" exists. do stuff.
} else{
//"message" does not exist
}
How do I check for the existence of "state" or "count" though?
if(object['dataList']['state']){
// dataList["state"] exists. do stuff.
} else {
// dataList["state"] does not exist
}
or the (in my opinion) more readable:
if(object.dataList.state){ ... }
Edit: It would also be a good idea to check for all parent objects so you will not get an unexpected error when, for example, dataList does not exist on the object:
if (object && object.dataList && object.dataList.state)
try like this:
object = {"message":"success","dataList":{"state":"error","count":"25"}};
if(object.message =='success'){
console.log(object.dataList);// your datalist object here use it
console.log(object.dataList.state);
console.log(object.dataList.count);
} else{
//"message" does not exist
}
if you are trying to check state do this:
if(typeof(object.dataList.state) !='undefined' && object.dataList.state.length > 0){
// dataList.state exists. do stuff.
} else {
// dataList.state does not exist
}
if (object.dataList.state || object.dataList.count) {
// ...
}
First of all, if you are checking the existence of a property, you should use if ('message' in object). If you use if (object['message']), for the case object = {'message': null}, the result is wrong.
In your question, the object is nested into two layers. If there are more than two, you can try a generic solution using recursion:
function findProperty (obj, key) {
if (typeof obj === "object") {
if (key in obj) return true;
var childReturned = false;
for (k in obj) {
childReturned = findProperty(obj[k], key);
if (childReturned) return true;
}
}
return false;
}
var obj = {"message":"success","dataList":{"state":"error","count":"25"}};
findProperty(obj, 'message'); // => true
findProperty(obj, 'dataList'); // => true
findProperty(obj, 'state'); // => true
findProperty(obj, 'count'); // => true
I am in the following situation:
I have to check if the object parameter passed to a function is valid:
Exmaple:
function (opt) {
if (opt && opt.key && opt.key2) {
// make something
}
}
Is there a better way to make this kind of check?
Not really.
Unless you can use opt.pleaseReadMyMind() ;-)
You could create a method that will check if all fields have values different to null, though.
That's the most compact way of doing it.
The most correct way would be:
if( typeof opt !== "undefined" && typeof opt.key !== "undefined" && typeof opt.key2 !== "undefined") {
But as you can see that's quite a mouthful and not really necessary.
Just write a simple test routine to verify the object given a list of property names:
// usage: testProps(object to test, [list, of, property, names])
// returns true if object contains all properties
function testProps(obj, props)
{
if (obj === null)
return false;
var i;
for (i=0; i<props.length; ++i)
{
if (!(props[i] in obj))
return false;
}
return true;
}
And then in your function:
if (!testProps(obj, ['key', 'key2'])
return;
What you are doing is valid, but it does have flaws.
if (opt && opt.key && opt.key2) {
This check would fail if opt.key has falsely values [0,null,false,and so on]
In that case you would have to do a typeof check to make sure it is not undefined.
if (opt && typeof opt.key !== "undefined" && opt.key2) {
Yeah, but it's only "better" if you have a lot of keys to check, not just three. Something like this:
function opt(opt) {
for(var i = 0; i<3; i++) {
if(typeof opt["key"+((i > 0) ? "" : i + 1))] === "undefined") {
return;
}
}
// create object
}
If opt is undefined all its keys will be too, so there's an implicit check for that as well.
You could also define the variable names you want to check in array, something like this:
var propsToCheck = ["key", "key1", "key2"];
function(opt) {
for(var i = 0, ii = propsToCheck.length; i<ii; i++) {
if(typeof opt[propsToCheck[i]] === "undefined") {
return;
}
// create object
}
}
Not really much of a better solution, but it does allow for less typing if you're planning on checking more than three or four properties.
You could always do it like this:
function validate(o, args) {
if (typeof(o) == 'object' && args instanceof Array) {
for (var i = args.length - 1; i >= 0; --i) {
if (typeof(o[args[i]]) === 'undefined') return false;
}
return true;
} else {
return false;
}
}
function myFunction(obj) {
if (validate(obj, ['foo', 'bar'])) {
// Your code goes here.
} else {
// Object passed to the function did not validate.
}
}
Here's a fiddle for you: http://jsfiddle.net/reL2g/