DEV Community

Cover image for Some Strange Concept of JavaScript
Jatin Sharma
Jatin Sharma

Posted on • Updated on

Some Strange Concept of JavaScript

In this article, we are going to look at some weird and strange concepts of Javascript, Some of which you may know and some may not. So stay tuned till the end.

Undefined

In non-strict mode, it’s actually possible (though incredibly ill-advised!)
to assign a value to the globally provided undefined identifier:

// non-strict
function foo() {
  undefined = 2; // really bad idea!
}

foo();
Enter fullscreen mode Exit fullscreen mode
// Strict Mode
function foo() {
  "use strict";
  undefined = 2; // TypeError!
}

foo();
Enter fullscreen mode Exit fullscreen mode

In both non-strict mode and strict mode, however, you can create a local variable of the name undefined. But again, this is a terrible idea!

function foo() {
  var undefined = 2;
  console.log(undefined); // 2
}
foo();
Enter fullscreen mode Exit fullscreen mode

The not number (NaN)

Any mathematic operation you perform without both operands being numbers (or values that can be interpreted as regular numbers in base 10 or base 16) will result in the operation failing to produce a valid number, in which case you will get the NaN value.

let a = 2 / "foo"; // NaN
typeof a === "number"; // true
Enter fullscreen mode Exit fullscreen mode

In other words, “the type of not-a-number is number!” Hooray for confusing names and semantics.

var a = 2 / "foo";
isNaN(a); // true
Enter fullscreen mode Exit fullscreen mode

Easy enough, right? I've use the built-in global utility called isNaN(..) and it tells us if the value is NaN or not. Problem solved! Not so fast.

The isNaN(..) utility has a fatal flaw. It appears it tried to take the meaning of NaN (“Not a Number”) too literally—that its job is basically, “test if the thing passed in is either not a number or is a number.” But that’s not quite accurate:

var a = 2 / "foo";
var b = "foo";
a; // NaN
b; //"foo"
window.isNaN(a); // true
window.isNaN(b); // true--ouch!
Enter fullscreen mode Exit fullscreen mode

Clearly, "foo" is literally not a number. it's a string but when you do isNaN("16") then it will return false because when javascript does implicit conversion it perfectly converts to number that's why it returns false

Infinities

Developers from traditional compiled languages like C are probably used to seeing either a compiler error or runtime exception, like divide by zero for an operation like:

let a = 1 / 0;
Enter fullscreen mode Exit fullscreen mode

However, in JS, this operation is well-defined and results in the value Infinity (aka Number.POSITIVE_INFINITY). Unsurprisingly:

var a = 1 / 0; // Infinity
var b = -1 / 0; // -Infinity
Enter fullscreen mode Exit fullscreen mode

Zeros

While it may confuse the mathematics-minded reader, JavaScript has both a normal zero 0 (otherwise known as a positive zero +0) and a negative zero -0. Before I explain why the -0 exists, we should examine how JS handles it, because it can be quite confusing.

Besides being specified literally as -0, negative zero also results from certain mathematic operations. For example:

var a = 0 / -3; // -0
var b = 0 * -3; // -0
Enter fullscreen mode Exit fullscreen mode

;Let's see some more example of zeros :

var a = 0;
var b = 0 / -3;
a == b; // true
-0 == 0; // true
a === b; // true
-0 === 0; // true
0 > -0; // false
a > b; // false
Enter fullscreen mode Exit fullscreen mode

Null

So as we know typeof is an operator, by which we check the type of a variable like this :

typeof undefined === "undefined"; // true
typeof true === "boolean"; // true
typeof 42 === "number"; // true
typeof "42" === "string"; // true
typeof { life: 42 } === "object"; // true
Enter fullscreen mode Exit fullscreen mode

As you may have noticed, I excluded null from the above listing. It’s special—special in the sense that it’s buggy when combined with the typeof operator:

typeof null === "object"; // true
Enter fullscreen mode Exit fullscreen mode

It would have been nice (and correct!) if it returned null, but this original bug in JS has persisted for nearly two decades, and will likely never be fixed because there’s so much existing web content that relies on its buggy behavior that “fixing” the bug would create more “bugs” and break a lot of web software.

null is the only primitive value that is falsy but which also returns object from the typeof check.

BONUS

What are falsy value?
A falsy (sometimes written falsey) value is a value that is considered false when encountered in a Boolean context.

if (false)
if (null)
if (undefined)
if (0)
if (-0)
if (0n)
if (NaN)
if ("")
Enter fullscreen mode Exit fullscreen mode

What are Truthy value?
In JavaScript, a truthy value is a value that is considered true when encountered in a Boolean context.

if (true)
if ({})
if ([])
if (42)
if ("0")
if ("false")
if (new Date())
if (-42)
if (12n)
if (3.14)
if (-3.14)
if (Infinity)
if (-Infinity)
Enter fullscreen mode Exit fullscreen mode

Conclusion

It's not the end, there are bunch of things likes this which I will cover it the future, So consider to follow. And If you learned something new then give a thumbs up.

You can now extend your support by buying me a Coffee.😊👇

Buy Me A Coffee

Also Read

Discussion (9)

Collapse
joaolss profile image
João Lucas Silva

Nice article, it would be good to explain why such behaviors, for example isNaN actually makes use of js been weakly typed (js will try to convert anything, so if it expects a number, it will try to convert what you pass to a number) so isNaN("foo") = true, but isNaN("16") = false, because Number("foo") = NaN, but Number("16") = 16 so this is not a bug, or a flaw, it's just implicit conversion in action....also the fact that typeof null = "object", although controversial, is because how js was thought to be used, first everything is a object (including numbers and string, although treated as primitives) so null was conceived to be used as "an object with no defined value" and undefined was conceived to be "the absence of an object, or a object which was declared, but not yet initialized" that's why if you try retrieving a attribute that doesn't exist, it's value is undefined and that's why in json you have null but not undefined becaude you can have a object that has no value, but you can't have a object that doesn't exist....perhaps those kind of explanations were beyond the scope of the post, but i think they add to the undestanding behind the language and how it works, instead of just this feeling that people who created it and who manages it are just dumb hahah

Collapse
j471n profile image
Jatin Sharma Author

Thanks for you suggestion man, I have edited that part. :)

Collapse
peerreynders profile image
peerreynders • Edited on

In other words, “the type of not-a-number is number!” Hooray for confusing names and semantics.

The thing is:

  1. that's not even a "JavaScript thing"
  2. it applies to any language that supports the IEEE 754 floating-point storage format — and many languages (including C and C++) do.

What Every Programmer Should Know About Floating-Point Arithmetic or Why don’t my numbers add up?

Any value where all 11 bits of the exponent are set to "1" are considered NaN in IEEE 754-1985.

From that perspective the heading should have been

NaN (not a number)

JavaScript's problem was that it only supports the floating point format (now there's BigInt though that's not as performant as sticking to integers that can be represented accurately within the 53 bit signifcand).

Furthermore isNaN() exists for backward compatibility. New code should be using Number.isNaN() instead:

show('NaN');     // "old: true new: false"
show(undefined); // "old: true new: false"
show({});        // "old: true new: false"
show('blabla');  // "old: true new: false"

function show(value) {
  console.log(`old: ${isNaN(value)} new: ${Number.isNaN(value)}`);
}
Enter fullscreen mode Exit fullscreen mode
Collapse
illusionelements profile image
IllusionElements

Good article just one thing though, undefined can no longer be reassigned. If you try to do const,let, var undefined = xxx get an error, and if you try to reassign it the value stays unchanged undefined remains undefined. Basically undefined is immutable now

Collapse
j471n profile image
Jatin Sharma Author

Well, I don't think that is the case. we can use undefined as a variable but we should not. And yes we can assign the value to it until and unless it is const. Here is the demo -

demo

This image shows that we can use undefined as a variable name. I have not declared it because browser's console declare it by default to undefined .

by default

If you wish to use it *.js file you can also do that

let undefined = 3;       // `var` also works fine but not `const`
console.log(undefined);         // output : 3
undefined = 9;
console.log(undefined);         // output : 9
Enter fullscreen mode Exit fullscreen mode

The above example shows that you can use undefined as long as it is not const because const is immutable. Since we are using it as a varible name.

Collapse
yendenikhil profile image
Nik

This is well written article about the quirks of language (js). Thanks for sharing.

Collapse
j471n profile image
Jatin Sharma Author

My pleasure :)

Collapse
rayhan_nj profile image
Raihan Nismara

well, actually it's feature!

Collapse
j471n profile image
Jatin Sharma Author

Yes, now it is.