Understanding The Mad King Of Web, JavaScript!

“JavaScript is the world’s most misunderstood programming language.” Douglas Crockford

Mar 9, 2020 · 7 min read
Is JavaScript The Mad King of Web? Photo Taken from Youtube

At its core, Javascript is very different from pretty much every other programming language out there. It's a powerful too, because you can write an entire software without adopting any other programming language at all. So why did the programming community adopt it? The short answer is, well, we didn’t have a choice.

JavaScript is Mad? Yes.. It Seems Like that sometime!

Here are few example of why people tell this a weird programming language.

Taken from SoftwareEngineers FB Page

Null is an Object

console.log(typeof null) //Object

In JavaScript null is "nothing". It is supposed to be something that doesn't exist.Unfortunately, in JavaScript, the data type of null is an object.

Another interesting thing as null is an instance of object as per previous understanding, but its actually not.

console.log(null instanceof Object) //returns false

Well, Here is why

At run time, the result of the instanceof operator is true if the value of the RelationalExpression is not null and the reference could be cast to the ReferenceTypewithout raising a ClassCastException. Otherwise the result is false

NaN is a number

console.log(typeof NaN) // Number

Okey. Fine. That means i can do this

console.log(NaN === NaN) //Should return true but its not.

Now let see why this happen

NaN is still a numeric type, despite the fact it actually stands for Not-A-Number. As NaNcan not be equal to another NaNbecause they can be different values like 301212 is not equal to 3012323232 .

So how i can check NaN ? This way ..


[] is equal ![]

console.log([] == ![]) // Should return false but strange returns true

Lets see why

[] is truthy, but not true . Well what does this means?

console.log([]) // it shows Array(0) []
console.log(![]) // shows false i.e [] is equivalent to true
console.log(!![]) // shows true

The abstract equality operator converts both sides to numbers to compare them.Lets experiment now.

console.log(~~[])// returns 0 as array is coerced to a number without
// becoming a boolean first, and empty arrays are coerced to 0
console.log(~~![]) // returns 0 as [] is truthy i.e ![] is false
// i.e 0 == 0 which is true

Adding arrays

console.log([1, 2, 3] + [4, 5, 6]) // shows 1,2,34,5,6 , interesting. HUH !

Why? Because of concatenation.

console.log([1, 2, 3].toString() + [2,3,4].toString()) // This is what happed here. 
// The output is actually a string "1,2,32,3,4"

true is not equal ![], but not equal [] too

Array is not equal true, but not Array is not equal true too; Array is equal false, not Array is equal false too:

true == []; // -> false
true == ![]; // -> false
false == []; // -> true
false == ![]; // -> true

Let experiment this now

console.log(![]) // return false // i.e console.log([]) should return true? Actually No!// [] is truthy but not true console.log(~~[]) // return false or 0console.log([] == true) // 0 is not equal to true, Right? So false.


console.log("b" + "a" + +"a" + "a") // output baNaNa
console.log("foo" + +"bar") // output fooNaN

Here is why?

console.log("foo" + +("bar")) 
// its actually tries to convert +("bar") to number
// and failed and return NaN So finally fooNaN
console.log("b" + "a" + +("a") + "a") // +("a") return NaN
Finally baNaNa


var someValue
console.log(someValue === undefined) //True as expected

Let define undefined and see what happened.

var undefined = "I’m not undefined!";
var someValue
console.log(someValue == undefined) // Ha Ha.

Funny math

console.log(3–1) // -> 2
console.log(3 + 1) // -> 4
console.log("3" — 1) // -> 2
console.log("3" + 1) // -> ‘31’
// Thats Funny? Really?
// Its actually equivalent to ("3" + "1") which is "31"

Strings aren’t instances of String

console.log( typeof "Am I Mad?"); // -> ‘string’
console.log("Am I Mad?" instanceof String); // -> false. What?

Lets try to explain this

var value = new String(“SampleString”)
console.log(value instanceof String) // Both true
console.log(value instanceof Object) // True
console.log(new String("str") instanceof String) //Now Make Sense //right?

Be Aware of Array equality

[] == ''   // -> true
[] == 0 // -> true
[''] == '' // -> true
[0] == 0 // -> true
[0] == '' // -> false
[''] == 0 // -> true

[null] == '' // true
[null] == 0 // true
[undefined] == '' // true
[undefined] == 0 // true

[[]] == 0 // true
[[]] == '' // true

[[[[[[]]]]]] == '' // true
[[[[[[]]]]]] == 0 // true

[[[[[[ null ]]]]]] == 0 // true
[[[[[[ null ]]]]]] == '' // true

[[[[[[ undefined ]]]]]] == 0 // true
[[[[[[ undefined ]]]]]] == '' // true

true is false

!!"false" == !!"true"; // -> true
!!"false" === !!"true"; // -> true

Here is why.

// true is 'truthy' and represented by value 1 (number), 'true' in //string form is NaN.// 'false' is not the empty string, so it's a truthy value
!!"false"; // -> true
!!"true"; // -> true

Calling functions with backticks

function f(...args) {
return args;
console.log(f(1, 2, 3)); // -> shows [ 1, 2, 3 ]
// Now you can call this way alsoconsole.log(f`true is ${true}, false is ${false}, array is ${[1, 2, 3]}`)
//This return something like this below
function with backticks

Well, this is not magic at all if you’re familiar with Tagged template literals. In the example above, f function is a tag for template literal. Tags before template literal allow you to parse template literals with a function. The first argument of a tag function contains an array of string values. The remaining arguments are related to the expressions. Example:

function template(strings, ...keys) {
// do something with strings and keys…

This is the magic behind famous library called 💅 styled-components, which is popular in the React community.

NaN is not a NaN

console.log(NaN === NaN)// x === y returns true if 
// -> x and y both are same type
// -> if x is NaN then return false
// -> if y is NaN then return false. Now you got it right?

Check this as reference. Strict Equality Comparison

Tricky return

Return statement is bit tricky. Lets have an experiment.

(function() {
b: 10;
})(); // This should return an object {b:10} but its undefined! //What?
(function() { // { ** is in the same Line
return {
b: 10
})(); // As expected { b: 10 }

This is because of a concept called Automatic Semicolon Insertion, which automagically inserts semicolons after most newlines. That is

(function() {
return ; // JS insert a extra semicolon after the return
b: 10
})(); // -> { b: 10 }

Tricky arrow functions

// Arrow function famous shorthand we all know, right?let myArrowFunction = ()=>10;

Now let return an object instead of 10.

let myArrowFunction = ()=>{};
console.log(myArrowFunction()) // Dam. it return undefined not "{}"

This is because the curly braces are part of the syntax of the arrow functions, so f will return undefined. It is however possible to return the {} object directly from an arrow function, by enclosing the return value with brackets.

let myArrowFunction = ()=>({});
console.log(myArrowFunction()) // Now its return "{}"

Equality Operator

console.log("12" == 12) 
// Return true because == converts both to
// number and then compare them !

Here are the rules

  • Two strings are strictly equal when they have the same sequence of characters, same length, and same characters in corresponding positions.
console.log("12" === "12") //return true as both same string
  • Two numbers are strictly equal when they are numerically equal (have the same number value). NaN is not equal to anything, including NaN. Positive and negative zeros are equal to one another.
console.log(12 === 12)// true
console.log(NaN === NaN) // false
console.log(0 === -0) //true
  • Two Boolean operands are strictly equal if both are true or both are false.
console.log(true === true) // true
  • Two distinct objects are never equal for either strict or abstract comparisons.
console.log({} === {}) // false
  • An expression comparing Objects is only true if the operands reference the same Object.
var obj = {}
console.log(obj === obj) // true
  • Null and Undefined Types are strictly equal to themselves and abstractly equal to each other.
console.log(undefined === undefined) // true
console.log(null === null) // true
console.log(undefined == undefined) // true
console.log(null == null) // true

Checkout this awesome github repository named WTFJS for more like above.

Tired of reading something serious. Let take a mind refresher from here.

32+ funny Code Comments that people actually wrote.

Thanks for reading. Cheers 🥂

The Startup

Get smarter at building your thing. Join The Startup’s +792K followers.

Thanks to Zack Shapiro

Sign up for Top 10 Stories

By The Startup

Get smarter at building your thing. Subscribe to receive The Startup's top 10 most read stories — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.


Written by


Software Writer || Javascript Journalist || Now Learning Flutter.

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +792K followers.


Written by


Software Writer || Javascript Journalist || Now Learning Flutter.

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +792K followers.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store