Javascript Concepts - Part1

 

Article Image

JAVASCRIPT

INTERVIEW

Javascript Concepts - Part1

New Features in ES6

Some of the new features of javascript introductes in ES6 are:

  • The Let keyword
  • The Const keyword
  • Arrow Functions
  • Promises
  • Map Object
// Create a new Map
const fruits = new Map();

// Add new Elements to the Map
fruits.set(apples, 500);
fruits.set(bananas, 300);
fruits.set(oranges, 200);
  • Set Object
// Create a Set
const letters = new Set();

// Add some values to the Set
letters.add("a");
letters.add("b");
letters.add("c");
  • Classes
class ClassName {
  constructor() { ... }
}

// Example
class Car {
  constructor(name, year) {
    this.name = name;
    this.year = year;
  }
}

Difference between Let and Var and Const

Comparision of Declarations

One of the biggest problems with declaring variables with the var keyword is that you can easily overwrite variable declarations:

var camper = "James";
var camper = "David";
console.log(camper);

In the code above, the camper variable is originally declared as James, and is then overridden to be David. The console then displays the string David.

If you replace var with let in the code above, it results in an error:

let camper = "James";
let camper = "David";
The error can be seen in your browser console.(Uncaught SyntaxError: Identifier 'camper' has already been declared)

So unlike var, when you use let, a variable with the same name can only be declared once.

Comparison of scopes of the var and let Keywords

When you declare a variable with the var keyword, it is declared globally. The let keyword behaves similarly, but with some extra features. When you declare a variable with the let keyword inside a block, statement, or expression, its scope is limited to that block, statement, or expression.

var numArray = [];
for (var i = 0; i < 3; i++) {
  numArray.push(i);
}
console.log(numArray);
console.log(i);
Here the console will display the values [0, 1, 2] and 3.

With the var keyword, i is declared globally. So when i++ is executed, it updates the global variable.

This behavior will cause problems if you were to create a function and store it for later use inside a for loop that uses the i variable. This is because the stored function will always refer to the value of the updated global i variable.

var printNumTwo;
for (var i = 0; i < 3; i++) {
  if (i === 2) {
    printNumTwo = function() {
      return i;
    };
  }
}
console.log(printNumTwo());
Here the console will display the value 3.

As you can see, printNumTwo() prints 3 and not 2. This is because the value assigned to i was updated and the printNumTwo() returns the global i and not the value i had when the function was created in the for loop.

The let keyword does not follow this behavior:

let printNumTwo;
for (let i = 0; i < 3; i++) {
    if (i === 2) {
        printNumTwo = function() {
            return i;
        };
    }
}
console.log(printNumTwo());
console.log(i);

Here the console will display the value 2, and an error that i is not defined. i is not defined because it was not declared in the global scope. It is only declared within the for loop statement. printNumTwo() returned the correct value because three different i variables with unique values (0, 1, and 2) were created by the let keyword within the loop statement.

Const

While var and let can be declared without being initialized, const must be initialized during declaration. Const cannot be initialized after declaritions

However, it is important to understand that objects (including arrays and functions) assigned to a variable using const are still mutable. Using the const declaration only prevents reassignment of the variable identifier.

const s = [5, 6, 7];
s = [1, 2, 3];
s[2] = 45;
console.log(s);
The console.log will display the value [5, 6, 45].

s = [1, 2, 3] will result in an error.

As you can see, you can mutate the object [5, 6, 7] itself and the variable s will still point to the altered array [5, 6, 45]. Like all arrays, the array elements in s are mutable, but because const was used, you cannot use the variable identifier s to point to a different array using the assignment operator.

Variable shadowing

let number = 10;

function displayDouble() {
  //new variable is defined with the same name as variable on line 1 - outer scope
  let number = 3;

  number *= 2;
  console.log(number); //=> 6
}

displayDouble();
console.log(number); //=> 10

In this case, both variables on line 1 and 5 are defined with the same name — number.This has a significant result: the variable defined in the outer scope is ‘shadowed’ by the variable defined in the inner scope.

String in Javascript

In JavaScript, String values are immutable, which means that they cannot be altered once created.

For example, the following code:

let myStr = "Bob"; myStr[0] = "J"; cannot change the value of myStr to Job, because the contents of myStr cannot be altered.

Escape Sequences in Strings

Code   Output
\' single quote
\" double quote
\\ backslash
\n newline
\r carriage return
\t tab
\b word boundary
\f form feed

Difference between '==' and '===' in javascript

Strict equality (===) is the counterpart to the equality operator (==). However, unlike the equality operator, which attempts to convert both values being compared to a common type, the strict equality operator does not perform a type conversion.

If the values being compared have different types, they are considered unequal, and the strict equality operator will return false.

Examples 1:

3 === 3 //true
3 === '3' // false
1 == [1] //true
1 === [1] //false
null == undefined //true
Example 2:‌
const number = 1234
const stringNumber = '1234'

console.log(number == stringNumber) //true
console.log(number === stringNumber)  //false

The value of number and stringNumber looks similar here. However, the type of number is Number and type of stringNumber is string. Even though the values are same, the type is not the same. Hence a == check returns true, but when checked for value and type, the value is false.

Example 3:
console.log(0 == false) //true
console.log(0 === false) //false
Reason: same value, different type. Type coercion

This is an interesting case. The value of 0 when checked with false is same. It is so because 0 and false have the same value for JavaScript, but when checked for type and value, the value is false because 0 is a number and false is boolean.

Example 4:
const str = ""

console.log(str == false) //true
console.log(str === false) //false

The value of empty string and false is same in JavaScript. Hence, == returns true. However, the type is different and hence === returns false.

Example 5:
let obj1 = { a: 1, b: 2 };
let obj2 = { a: 1, b: 2 };
console.log(obj1 == obj2); //false
console.log(obj1 === obj2); //false

The important thing to understand here is that the variables, obj1 and obj2 (which could be an Object, Array or Function) each contain only a reference to a location in memory. Not the value of the object.

Explain how this works in JavaScript

To access a property of an object from within a method of the same object, you need to use the this keyword.

const person = {
    name: 'John',
    age: 30,

    // accessing name property by using this.name
    greet: function() { console.log('The name is' + ' ' + this.name); }
};

person.greet();

In the above example, a person object is created. It contains properties (name and age) and a method greet. In the method greet, while accessing a property of an object, this keyword is used. In order to access the properties of an object, this keyword is used following by . and key.

This keyword refers to the object where it is called.

1 this Inside Global Scope

When this is used alone, this refers to the global object (window object in browsers). For example,

let a = this;
console.log(a);  // Window {}

this.name = 'Sarah';
console.log(window.name); // Sarah

2 this Inside Function

When this is used in a function, this refers to the global object (window object in browsers). For example,

function greet() {
    // this inside function
    // this refers to the global object
    console.log(this);
}
greet(); // Window {}

3 this Inside Constructor Function

In JavaScript, constructor functions are used to create objects. When a function is used as a constructor function, this refers to the object inside which it is used. For example,

function Person() {
    this.name = 'Jack';
    console.log(this);
}

let person1 = new Person();
console.log(person1.name);

Here, this refers to the person1 object. That's why, person1.name gives us Jack. When this is used with ES6 classes, it refers to the object inside which it is used.

For example,

// creating a class
class Person {
  constructor(name) {
    this.name = name;
  }
}
The class keyword is used to create a class. The properties are assigned in a constructor function.

// creating a class
class Person {
  constructor(name) {
    this.name = name;
  }
}

// creating an object
const person1 = new Person('John');
const person2 = new Person('Jack');

console.log(person1.name); // John
console.log(person2.name); // Jack

4 this Inside Object Method

When this is used inside an object's method, this refers to the object it lies within. For example,

const person = {
name : 'Jack',
age: 25,
    // this inside method
    // this refers to the object itself
    greet() {
        console.log(this);
        console.log(this.name);
    }

}

person.greet();
Output
{name: "Jack", age: 25, greet: ƒ}
Jack

5 this Inside Inner Function

When you access this inside an inner function (inside a method), this refers to the global object. For example,

const person = {
name : 'Jack',
age: 25,

    // this inside method
    // this refers to the object itself
    greet() {
        console.log(this);        // {name: "Jack", age ...}
        console.log(this.age);  // 25

        // inner function
        function innerFunc() {
            // this refers to the global object
            console.log(this);       // Window { ... }
            console.log(this.age);    // undefined
        }
        innerFunc();
    }
}
person.greet();

6 this Inside Arrow Function

Inside the arrow function, this refers to the parent scope. For example,

const greet = () => {
    console.log(this);
}
greet(); // Window {...}

Arrow functions do not have their own this. When you use this inside an arrow function, this refers to its parent scope object. For example,

const greet = {
    name: 'Jack',

    // method
    sayHi () {
        let hi = () => console.log(this.name);
        hi();
    }
}
greet.sayHi(); // Jack
const person = {
    name : 'Jack',
    age: 25,

    // this inside method
    // this refers to the object itself
    greet() {
        console.log(this);
        console.log(this.age);

        // inner function
        let innerFunc = () => {

            // this refers to the global object
            console.log(this);
            console.log(this.age);
        }
        innerFunc();
    }
}

person.greet();

Output:
{name: "Jack", age: 25, greet: ƒ}
25
{name: "Jack", age: 25, greet: ƒ}
25
Here, innerFunc() is defined using the arrow function. It takes this from its parent scope. Hence, this.age gives 25.

7 this Inside Function with Strict Mode

When this is used in a function with strict mode, this is undefined. For example,

'use strict';
this.name = 'Jack';
function greet() {

    // this refers to undefined
    console.log(this);
}
greet(); // undefined

How is arrow functions different from normal functions in javascript

this Keyword

Inside a regular function, this keyword refers to the function where it is called.

However, this is not associated with arrow functionsArrow function does not have its own this. So whenever you call this, it refers to its parent scope.

Inside a regular function

function Person() {
    this.name = 'Jack',
    this.age = 25,
    this.sayName = function () {

        // this is accessible
        console.log(this.age);

        function innerFunc() {
            // this refers to the global object
            console.log(this.age);
            console.log(this);
        }
        innerFunc();
    }
}

let x = new Person();
x.sayName();

Output:
25
undefined
Window {}

Here, this.age inside this.sayName() is accessible because this.sayName() is the method of an object.

However, innerFunc() is a normal function and this.age is not accessible because this refers to the global object (Window object in the browser). Hence, this.age inside the innerFunc() function gives undefined.

Inside an arrow function

function Person() {
    this.name = 'Jack',
    this.age = 25,
    this.sayName = function () {

        console.log(this.age);
        let innerFunc = () => {
            console.log(this.age);
        }
        innerFunc();
    }
}

const x = new Person();
x.sayName();

Output
25
25

Here, the innerFunc() function is defined using the arrow function. And inside the arrow function, this refers to the parent's scope. Hence, this.age gives 25.

Arguments Binding

Regular functions have arguments binding. That's why when you pass arguments to a regular function, you can access them using the arguments keyword.

let x = function () {
    console.log(arguments);
}
x(4,6,7); // Arguments [4, 6, 7]

Arrow functions do not have arguments binding. When you try to access an argument using the arrow function, it will give an error. For example,

let x = () => {
    console.log(arguments);
}
x(4,6,7);
// ReferenceError: Can't find variable: arguments

To solve this issue, you can use the spread syntax.

let x = (...n) => {
  console.log(n);
}
x(4,6,7); // [4, 6, 7]

Thanks for reading!!!

No comments:

Post a Comment

The Importance of Cybersecurity in the Digital Age

 The Importance of Cybersecurity in the Digital Age Introduction: In today's digital age, where technology is deeply intertwined with ev...