JavaScript Gotchas and Some Commonly made Mistakes💁‍♀️

·

6 min read

JavaScript Gotchas and Some Commonly made Mistakes💁‍♀️

So JavaScript is probably the world's most widely adopted programming language, it runs on everything so that's the reason why I love JavaScript so much, it's pretty powerful and pretty daunting, you can do crazy stuff.😁

2020-09-27-02-49-13.png

📙typeof:

The typeof operator returns the type of a given variable.

typeof 42; // 'number' 
typeof 'test'; // 'string'
typeof true; // 'boolean'
typeof (void 0); // 'undefined'
typeof BigInt('1234'); // 'bigint'
typeof Symbol('foo'); // 'symbol'
typeof ({ answer: 42 }); // 'object'
typeof function() {}; // 'function'

// As far as `typeof` is concerned, all objects are the same.
class MyClass {}
typeof (new MyClass()); // 'object'

The most glaring issue is that typeof null returns "object".

📙Equality / Truthy vs Falsy

You may already be familiar with the differences between == and ===. == checks only the value, while === includes type checking. That's why 1 === "1" is false but 1 == "1" is true. But, did you know this is true: null == undefined. But of course, this is loose checking with the ==.

false == '0' // true
0 == false   // true
'' == 0      // true
false == ''  // true
[] == ''     // true, but we'll get to this

'1' == true  // true
1 == true    // true
'false' == true // false

📙NaN Gotchas

NaN stands for "not a number". It's one of the more confusing ("number"s?) to deal with in JavaScript. For instance:

NaN === NaN; // false
NaN == NaN; // false as well
typeof NaN; // number
"" == NaN; // false

📙var vs let

To understand var, we need to first learn how they are scoped. Let's look at a simple example below to learn more about it.

function begin () {
 for (var i=0; i<5; i++) {
  console.log(i) 
 }
// i is accessible outside the for loop
 console.log(i)
}

Now, in our code snippet above, we have a variable i that is declared inside the for a loop. The console output that you will see for this code is shown below.

0
1
2
3
4
5

What is strange here is that, although the variable i is declared inside the for-loop, it is still accessible outside the scope of the for-loop. This is because the var variables are accessible within the scope of the function that they are declared.

var variables have a function-scope, if they are not declared within a function, they have a global scope.

let

After ES6/ES2015, JavaScript introduced let to overcome the problems faced with var.

Typically, we want our variables to be scoped within a block of code. If we declare a variable within a block of code say a for-loop, we want it to live within that block and be inaccessible outside of it.

This behavior can be achieved in JavaScript using the let keyword. Let's go back to our previous example, and replace the var with let instead.

function begin () {
 for (let i=0; i<5; i++) {
  console.log(i) 
 }
// i is not defined and will return an error
 console.log(i)
}

The output that we see for this example after replacing it with let will be slightly different than the previous example.

0
1
2
3
4
Uncaught reference error: i is not defined

The console log that happens outside the for-loop block returns an error. It does not know what i is and returns that i is not defined. This is a desirable output that we get with the use of let instead of var.

let is block-scoped and variables declared within a block of code cannot be accessed outside of it. I hope this clears up the difference between var and let, and their usage. The fundamental difference is in their scope.

📙What is the difference between null and undefined?

Undefined usually means a variable has been declared, but not defined.

let value;
console.log(value);
// undefined

null is an assigned value. It means nothing. null is not strictly equal to undefined. But null is loosely equal to undefined.

null !== undefined
null == undefined

📙The '+' can be used for both addition and string concatenation

var a = 10;
var b = '30';
var c = 40;
return a + b; // returns '1030' (concatenation)
return b + c; // returns '3040' (concatenation)
return a + c; // returns 50 (addition)

To avoid this concatenation, if your original intention was to add the variables, make sure to convert the string to an integer.

📙Semicolons can be a problem sometimes

Semicolons are used in several programming languages. JavaScript comes with the automatic semicolon insertion feature. Generally, you can omit semicolons most of the time.

return;
{
  a: 50
};

It actually returns undefined. This is because automatic semicolon insertion takes place making it an empty return statement. Your code should look like this:

return{
  a:50
}

📙Incorrect references to 'this'

this​ is a commonly misunderstood concept in JavaScript. To use this​ in JavaScript, you really need to understand how it works because it operates a bit differently compared to other languages.

Here's an example:

const obj = {
​​    name: "JavaScript",
​​    printName: function () {
​​        console.log(this.name);
​​    },
​​    printNameIn2Secs: function () {
​​        setTimeout(function () {
​​            console.log(this.name);
​​        }, 2000);
​​    },
​​};
​​obj.printName();
​​// JavaScript
​​obj.printNameIn2Secs();
​​// undefined

​​The first result is JavaScript because this.name​ correctly points to the object's name property. The second result is undefined​ because this​ has lost the reference to the object's properties (including name).

This is because this​ depends on the object calling the function in which it lives. There is a this​ variable in every function but the object it points to is determined by the object calling it. The this​ in obj.printName()​ points directly to obj​. The this​ in obj.printNameIn2Secs​ points directly to obj​. But the this​ in the callback function of setTimeout​ does not point to any object because no object called it.

For an object to have called setTimeout​, something like obj.setTimeout...​ would be executed. Since there is no object calling that function, the default object (which is the window​) is used.

​​ the name​ does not exist on the window​, resulting in undefined​.

The best way to go about retaining the reference to this​ in setTimeout is to use bind​, call​, apply​ , or arrow functions (introduced in ES6). Unlike normal functions, arrow functions do not create their own this​.

​​So, the following will retain its reference to this

​​const obj = {
​​    name: "JavaScript",
​​    printName: function () {
​​        console.log(this.name);
​​    },
​​    printNameIn2Secs: function () {
​​        setTimeout(() => {
​​            console.log(this.name);
​​        }, 2000);
​​    },
​​};
​​obj.printName();
​​// JavaScript
​​obj.printNameIn2Secs();
​​// JavaScript

The best thing about JavaScript is its implementation of functions. It got almost everything right. But, as you should expect with JavaScript, it didn't get everything right."

⚡For learning JavaScript in-depth follow Akshay Saini on youtube: youtube.com/channel/UC3N9i_KvKZYP4F84FPIzgPQ

If you need any kind of help you can ping me on linkedin.com/in/riya-jain-6691b8127 and I will be happy to share my knowledge with you all.

Did you find this article valuable?

Support Riya Jain by becoming a sponsor. Any amount is appreciated!