TransWikia.com

comparing with `{}` and truthyness

Stack Overflow Asked by dcsan on December 5, 2021

I have an API that calls me with {} for a param that I need to replace.
But having trouble as in … can you guess what happens below?

const log = console.log

const a = {}

log('a is ', a)

// cannot compare with either == or ===
if (a == {}) {
  log('a is {}')
} else {
  log('a is NOT {}')
}

// a is truthy too
const b = (a || 'not a')

console.log('b is ', b)

So given its both truthy and fails to compare I’m wondering how to replace it?

I’d also be interested to know why, what object comparison is going on under the hood.

my understanding was that:

  • == tested for equal by value (comparison)
  • === tested for equal by reference (pointer to same object in memory).

But i guess I need to do an actual comparison for objects? I’m using to doing this with unit test frameworks where toBe() or toEqual and toDeepEqual work.

And WAT!

4 Answers

Perhaps this will clarify things:

let a = {}; // Object Literal
let b = {}; // Object Literal
let c = a;  

// both a and b above are separate objects

console.log(b == a)   // false
console.log(c == a)   // true
console.log({} == {}) // false, as both are different Objects

// if you want to test if two things are the same type you could do
console.log(({}).toString() == ({}).toString()) // true
console.log(a.toString() == b.toString()) // true

// the reason why those work is, because now we are comparing strings... not the objects
console.log(({}).toString()) // "[object Object]"

// to simply check that the Object is "true", you could.
console.log(!!{});

// Specifying your own false, if empty comparisons "as values"...

console.log(!!Object.keys({}).length) // false
// or, even
console.log( !("{}" == JSON.stringify({}) ) ) // false

I would caution against using JSON.stringify if there is any chance the object of interest could be a function or contains any non json safe values, as you will get an error in the case of functions or false positives in you comparison


JavaScript Equality

=== is Strict Equality Comparison ("identity")

== is Abstract Equality Comparison ("loose equality")

"===" is simple, are the objects being compared the same object "instance"

"==" is a bit more complicated, as coercion comes into play, so it's more like "can they be the same"

Check out this article which goes into the mechanics of what is going on...

Loose Equals vs. Strict Equals

Loose equals is the == operator, and strict equals is the === operator. Both operators are used for comparing two values for "equality," but the "loose" vs. "strict" indicates a very important difference in behavior between the two, specifically in how they decide "equality."

A very common misconception about these two operators is: "== checks values for equality and === checks both values and types for equality." While that sounds nice and reasonable, it's inaccurate. Countless well-respected JavaScript books and blogs have said exactly that, but unfortunately they're all wrong.

The correct description is: "== allows coercion in the equality comparison and === disallows coercion.

Answered by rexfordkelly on December 5, 2021

Object always has a true boolean value (object exists? then true). Primitives like strings and numbers are compared by their value, while objects like arrays, dates, and plain objects are compared by their reference. That comparison by reference basically checks to see if the objects given refer to the same location in memory. You can check if objects are equals by JSON.stringify.

const a = {}

if (JSON.stringify(a) === JSON.stringify({})) {
  log('a is {}')
} else {
  log('a is NOT {}')
}

console.log(Boolean({}));   //Object exist?: True

const b = (a || 'not a')
console.log('b is ', b)

Answered by sonEtLumiere on December 5, 2021

If all you need to do is detect if something is an empty object, something like this would probably work:

const a = {};
const b = { hello: 'world' };
const c = 'test';

function isEmptyObject(arg) {
  return typeof arg === 'object' && Object.keys(arg).length === 0;
}

console.log(`a is ${isEmptyObject(a)}`);
console.log(`b is ${isEmptyObject(b)}`);
console.log(`c is ${isEmptyObject(c)}`);

Answered by Alexander Nied on December 5, 2021

You could try this

const a = {}

log=console.log
log('a is ', a)

// cannot compare with either == or ===
if (typeof a == "object"&& Object.keys(a).length==0) {// the && part to check if the object is empty
  log('a is {}')
} else {
  log('a is NOT {}')
}

Answered by Sven.hig on December 5, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP