Why does [] == ![] return TRUE in JavaScript?

JavaScript weirdness, commenting woes, and more

News for humans, by humans.

  • Today's news.

  • Edited to be unbiased as humanly possible.

  • Every morning, we triple-check headlines, stories, and sources for bias.

  • All by hand with no algorithms.

Can you complete this versatile adding function?

It's hard to believe.

How can an Array not be an Array?

It makes no sense — [] is truthy and ![] should be false.

So how can [] equal false?

And this somehow doesn’t happen for other types like strings and numbers:

Are JavaScript arrays broken?

What happened here

Dump all the blame on the dangerous == operator.

This is just another instance of why we always tell new JavaScript devs to NEVER use it (ever).

Especially if they’ve already been coding with stubbornly strict languages like C#.

At first glance, it doesn’t seem like there’s anything wrong with ==:

// C#
int num = 2;

Console.WriteLine(num == 10); // false
Console.WriteLine(num == 2); // true
// JS
let num = 2;

console.log(num == 10); // false
console.log(num == 2); // true

But now look what happens here:

// C#
int num = 2;

// ❌ Error: can't compare int and string
Console.WriteLine(num == "2"); // false

But look what happens in JavaScript:

// JS
let num = 2;

console.log(num == "2"); // true?

Most comments are actually a sign of bad code.

In the vast majority of cases, developers use comments to explain terribly written code desperately in need of refactor.

Good code should explain itself. It should tell the full story.

❌ Before:

You did too much in one go and you know it -- so you drop in a bad comment to explain yourself:

// Check if user can watch video
if (
  !user.isBanned &&
  user.pricing === 'premium' &&
  user.isSubscribedTo(channel)
) {
  console.log('Playing video');
}

// codingbeautydev.com

✅ After:

Now you take things step-by-step, creating a clear and descriptive variable before using it:

Comment gone.

const canUserWatchVideo =
  !user.isBanned &&
  user.pricing === 'premium' &&
  user.isSubscribedTo(channel);

if (canUserWatchVideo) {
  console.log('is playing video');
}

// codingbeautydev.com

You see now the variable is here mainly for readability purposes rather than storing data. It's a cosmetic variable rather than a functional one.

✅ Or even better, you abstract the logic away into a function:

if (canUserWatchVideo(user, channel)) {
  console.log('is playing video');
}

function canUserWatchVideo(user, channel) {
  return (
    !user.isBanned &&
    user.pricing === 'premium' &&
    user.isSubscribedTo(channel)
  );
}

// codingbeautydev.com

Or it could have been in the class itself:

if (user.canWatchVideo(channel)) {
  console.log('is playing video');
}

class User {
  canWatchVideo(channel) {
    return (
      !this.isBanned &&
      this.pricing === 'premium' &&
      isSubscribedTo(channel)
    );
  }
}

// codingbeautydev.com

Whichever one you choose, they all have one thing in common: breaking down complex code into descriptive, nameable, self-explanatory steps eradicating the need for comments.

When you write comments you defeat the point of having expressive, high-level languages. There is almost always a better way.

Your var names are terrible

❌ Before: Lazy variable naming so now you're using comments to cover it up:

Thanks for taking the time to read today’s issue.

Don’t let the bugs byte,
Tari Ibaba