DEV Community

5hfT
5hfT

Posted on

The Weird Javascript

This is Mehedi Hasan Shifat. I am trying to write about the things I feel weird about javascript (not saying bad :3). i will write something about javascript everyday whenever I get some free time. Mark watch The-Weird-Javascript to get latest update.

Note : This is not a blog/article/repo to learn javascript. you can get some awesome blogs and video playlists about javascript which are really awesome. And feel free to correct me.

Table of Contents

Contents

Undefined || Error ?

Let's look at some code snippets.

code-01
console.log(num);
num = 10;
var num;
Enter fullscreen mode Exit fullscreen mode

Guess, what is the output of the code ?
Is it a compilation error ? just kidding :v

output :

undefined
Enter fullscreen mode Exit fullscreen mode

It says undefined. Okey, let's take another look -

code-02
num = 10;
console.log(num);
var num;
Enter fullscreen mode Exit fullscreen mode

Guess again undefined ? Shouldn't it be undefined as the variable num is declared after the console.log() ? or the code should break as 10 is inserted(? will talk about later) into num before initializing it ?

output :

10
Enter fullscreen mode Exit fullscreen mode

Great! if it matches with your thinking, if doesn't then let's discover the mystery of bermuda triangle :D

If javascript(hight level language) is your first one & only language then may be you will find it normal* but people like us coming from a low level language like C will find this fucking weird :3

It's all about hoisting. Javascript actually split the initialization and declaration and moves declarations(like var num) to the top. So actually what / how the code was we can say like this :

var num = undefined;
num = 10;
console.log(num);
Enter fullscreen mode Exit fullscreen mode

So for var a variable is declared with undefined at the top, then when the line of declaration comes it assign value to it.

Then why in the first example it printed undefined ?
If we look at the code carefully we can see that, at the first code snippet, we print the value of num before store the value when it was undefined.But in the second case it was already initialized.
Actually in the first example the code were executed like this :

var num = undefined;
console.log(num); // so it was undefined when we were logging num
num = 10;
Enter fullscreen mode Exit fullscreen mode

Note : This is not the actual scenario but something like this was happened. And one thing more about the words insert and initialize value to a variable , we will talk about it later.

For that reason we can call a function in js before initializing it like this -

code-03
printSum(100);

function printSum(n) {
  // print sum of 1 to n
  console.log((n * (n - 1)) / 2);
}
Enter fullscreen mode Exit fullscreen mode

Let's find some corner cases how can we declare (?) or initialize variables in js.

code-04
num = 10;
console.log(num);
Enter fullscreen mode Exit fullscreen mode

Now i have just removed var from the previous code (code-02). will it run properly ? Is it undefined for hoisting ? or Reference error ?

output :

10
Enter fullscreen mode Exit fullscreen mode

As there is no var num in our code there is no hoisting. It just initialized x. This could be a different scenario if we were using strict mode. Strict mode is a feature of ES5. It applies some restrictions.

"use strict";
num = 10;
console.log(num);
Enter fullscreen mode Exit fullscreen mode

In this case we will get ReferenceError: num is not defined

You can also set strict mode for individual functions too.

var note = "The whole script is not in strict mode now";

function strictMode() {
  "use strict";
  // do your stuffs
}
Enter fullscreen mode Exit fullscreen mode

We have learnt about hoisting. Javascript has now a few more declaration keys like the weird var , they are let, const. Why the hack we need let or const as we already have var ? We have enough weirdness in js, why adding some more?

Wait, think positive. May be it can save us from the devil var :3

Before going to let & const, let's observe some weirdness of var and why var is the devil :3

code-05
var x = 10;
var x = "hello";
var x = true;
console.log(x);
Enter fullscreen mode Exit fullscreen mode

What the hack is this ? I have initialized x with 10 which is a number , then again with "hello" string and at last with a boolean true. Is the program runnable ? error error error ? reference error ?

Let's see the output :

true
Enter fullscreen mode Exit fullscreen mode

For hoisting, x was declared at the top before execution and then it was initialized with 10,"hello" and true accordingly.As at the last before logging it was a boolean, it printed true.

var actually declares a function-scoped or globally-scoped variable. There are some interesting facts here. Usingvar for declaration javascript moves the declaration at the top of the function(*) actually. Let's see the code -

code-06
function foo() {
  var x = 10;

  if (x > 50) {
    var x = 51;
  } else {
    var x = -1;
  }

  console.log(x);
}

foo();
Enter fullscreen mode Exit fullscreen mode

output :

-1
Enter fullscreen mode Exit fullscreen mode

Inside the function its always the same x.

code-07
function goo() {
  var x = 10;
  function foo() {
    var x = 20;
  }
  foo();
  console.log(x);
}
goo();
Enter fullscreen mode Exit fullscreen mode

Can you guess the output this time ? 20 haa ??

Output :

10
Enter fullscreen mode Exit fullscreen mode

Shouldn't surprise as I have told before that var declares a function scoped variable so x inside foo is hoisted at the top of the foo function not globally. That's why global x and x inside foo is not same.Let's see another example -

code-08
var x = 10;
function foo() {
  var y = 10;
}
foo();
console.log(y);
Enter fullscreen mode Exit fullscreen mode

Output :

ReferenceError: y is not defined
Enter fullscreen mode Exit fullscreen mode

YES! Successfully created a reference error again :3

You can't access a variable out of its scope, and thats actually gooood!

here is a nested functional scope example of var -

code-09
function google() {
  function foo() {
    var y = 10;
    function bar() {
      var p = 12;
      console.log("value of y : ", y); // will print 10
    }
    bar();
    console.log("value of p : ", p); // reference error for p
  }
  foo();
}
google();
Enter fullscreen mode Exit fullscreen mode

Actually when we declare a variable it is available everywhere in the scope as well as any lower/child/inner scopes.

Beside that, as we can see declaring variables with var is risky. There is a very good possibility of using the same name of two different variables for different task and it can produce a bug which will be difficult to find out and fix it.

To solve this problem, they introduced let. const is the constant form of let actually.

In mathematics we used to say, let x ...... Most languages like Scheme adopt let from mathematical statement. If you have done some study on how js was created or how, it will be more clear to understand. btw Scheme has also let*.

Let's rewrite some of the previously written code snippets with let.

code-10
console.log(num);
let num = 10;
Enter fullscreen mode Exit fullscreen mode

Output :

ReferenceError: Cannot access 'num' before initialization
Enter fullscreen mode Exit fullscreen mode
code-11
let x = 10;
// .......
// .......
// .......
// .......
let x = "shifat"; // SyntaxError: Identifier 'x' has already been declared
Enter fullscreen mode Exit fullscreen mode
code-12
let num = 10;
if (1) {
  let num = 1000; // num is a new variable here ,not the global one
}

console.log(num);
Enter fullscreen mode Exit fullscreen mode

output :

10
Enter fullscreen mode Exit fullscreen mode

let declares block-scoped which is limited to the scop of the block.The variable is said to be in a "temporal dead zone" (TDZ) from the start of the block until the initialization has completed. The variables are not accessible until fully initialization. let saves us a lot. Most of the weird stuffs of var is covered with let . So its safer to use let then var.

Top comments (0)