22

I'm learing JavaScript. I cannot grasp the idea of an empty object. As I understand, there are situations when I need to check a variable whether it holds an object and has a value.

So far, I know that a variable can be undefined.

var car; // the value is undefined, as well as the type (which is it? number, array, etc.)

I also know, that everything that has a value, is true:

var car = "Opel";
Boolean(car); // true 

And anything without a value is false:

var car = ""; // typeof string, but it is empty, so
Boolean(car); // false
Boolean(null); // false 

So why doesn't it work the same way with arrays and objects? Why is all of this true? Shouldn't empty arrays and objects return false?

var car = {make: "Opel", year: 2015};
Boolean(car); // true
car = {};
Boolean(car); // true
car = ["BMW", "Opel"]; 
Boolean(car); // true
car = [];
Boolean(car); // true

Now I see that there are methods, that can be applied to check an object's length, I just haven't reached that part yet.

I'm learning at W3Schools website and this bit just got me puzzled:

But you cannot test if an object is null, because this will throw an error if the object is undefined:

Incorrect:

if (myObj === null) 

To solve this problem, you must test if an object is not null, and not undefined.

But this can still throw an error:

Incorrect:

if (myObj !== null && typeof myObj !== "undefined")

Because of this, you must test for not undefined before you can test for not null:

Correct:

if (typeof myObj !== "undefined" && myObj !== null)

I still cannot understand the last line here.

VantaBlack
  • 223
  • 1
  • 2
  • 5
  • 3
    does `Object.entries(car).length > 0` work for you? – Other Me Jan 27 '21 at 19:39
  • 1
    okay, I see this. I just haven't learnt this yet. – VantaBlack Jan 27 '21 at 19:46
  • [everything that has a value, is true - And anything without a value is false], actually these are wrong assumptions, 0 is a value, as well as empty string, even boolean false itself is a value, it's not about having value, it's about truthy values and falsy values, read more about how different values are treated when converted to boolean value – Zac Jan 27 '21 at 19:49
  • 1
    That's a good point. I'm just learning so my choosing of words might have been inaccurate. – VantaBlack Jan 27 '21 at 19:55

9 Answers9

41

Checking if an object is empty:

Object.keys(yourObject).length
AdriSolid
  • 2,570
  • 1
  • 7
  • 17
6
var car = {};
var isEmpty = Object.entries(car).length > 0; //false

var car = {make: "Opel", year: 2015};
var isEmpty = Object.entries(car).length > 0; //true

This should solve your problem, if your curious about the utility function Object.entries you can look on mdn

Other Me
  • 498
  • 2
  • 7
  • 4
    To ensure that isEmpty does not lead to confusion a better alternative, in my opinion, is: `var isEmpty = Object.entries(car).length === 0;` – Rodrigo Vargas Jun 27 '21 at 11:54
2

I also know, that everything that has a value, is true

I wouldn't say that. All the examples given are values, even undefined and null are predefined values in JavaScript.

Shouldn't empty arrays and objects return false?

It is like that by specification. And that is really the answer to your question. It is a choice made by the designers of the language.

You could find some logic in it though. In JavaScript, values representing objects (and so also arrays) are references. These references are memory addresses/pointers, and although you cannot find out what exactly those addresses are, these are non-zero, even when an object has no properties.

Note that your example objects ({} and []) still have some non-enumerable properties, such a __proto__ and (for array) length, so they are not really as empty as you think.

The most empty object you can create, is: Object.create(null)

trincot
  • 317,000
  • 35
  • 244
  • 286
  • Then why does an empty string is false? `var car = ""; car.length` still works – VantaBlack Jan 28 '21 at 09:13
  • 1
    That is because of autoboxing: The string primitive does not have properties, but when you access a property like `length`, then the engine will on-the-fly make a `String` *object* for the primitive (which really is an object, not a primitive), and that *does* have the `length` property. – trincot Jan 28 '21 at 11:01
  • 1
    So `car.length` is interpreted as `new String(car).length`, and now note that `Boolean(new String(car))` is `true`. – trincot Jan 28 '21 at 11:07
2

You can check wheather a object is empty or not in this simple way.

function objectLength( object ) {
    return Object.keys(object).length;
}

if(objectLength(yourObject) == 0){ 
    //object is empty
}else{
    //object not empty 
}
infomasud
  • 2,263
  • 1
  • 18
  • 12
1

No, they should not be false.

All objects are 'truthy', in that they return true when evaluated as a Boolean. In Javascript, all arrays are objects (try console.log(typeof [])), so they also return true, regardless of whether or not they are empty.

To check if any array is empty:

if (MYARRAY.length === 0) {
  // console.log(true);
}

To check if an object is empty:

if (Object.keys(MYOBJECT).length === 0) {
  // console.log(true);
}
Trever Thompson
  • 619
  • 6
  • 18
1

Checking if an object is empty:

Reflect.ownKeys(car).length

Returns an array with one element when a Symbol is used as the key:

let key = Symbol('vin')
let car = { [key]: 'honda' }
Reflect.ownKeys(car).length // => 1

Whereas Object.keys returns an array with zero elements in this case:

let key = Symbol('vin')
let car = { [key]: 'honda' }
Object.keys(car).length // => 0
vhs
  • 9,316
  • 3
  • 66
  • 70
0

I would always use typeof myvar !== 'undefined' and checks for content myvar !== '' This would always would have a clear result.

Sascha
  • 124
  • 5
0

There are concepts which are Truthy and Falsy values in JavaScript. I highly recommend you to read MDN documents about this issue.

All values are truthy unless they are defined as falsy (i.e., except for false, 0, -0, 0n, "", null, undefined, and NaN).

Truthy values

Falsy values

0

You can use

  if ($('#element').is(':empty')){
  //do something
  }

OR

function isEmpty( el ){
      return !$.trim(el.html())
  }
  if (isEmpty($('#element'))) {
      // do something
  }

Here are some examples: http://api.jquery.com/is/

But if you need it in JavaScript:

if( typeof foo !== 'undefined' ) {
    // foo could get resolved and it's defined
}

You can simply use typeof

GucciBananaKing99
  • 1,473
  • 1
  • 11
  • 31