Part-5 : 500 JavaScript Important Questions with Answers and Explanation

Part-5 : 500 JavaScript Important Questions with Answers and Explanation

401-500 JS questions

·

38 min read

JavaScript Interview Questions & Answers

Table of Contents

  1. What is RxJS

    RxJS (Reactive Extensions for JavaScript) is a library for implementing reactive programming using observables that makes it easier to compose asynchronous or callback-based code. It also provides utility functions for creating and working with observables.

    ⬆ Back to Top

  2. What is the difference between Function constructor and function declaration

    The functions which are created with Function constructor do not create closures to their creation contexts but they are always created in the global scope. i.e, the function can access its own local variables and global scope variables only. Whereas function declarations can access outer function variables(closures) too.

    Let's see this difference with an example,

    Function Constructor:

    var a = 100;
    function createFunction() {
        var a = 200;
        return new Function('return a;');
    }
    console.log(createFunction()()); // 100
    

    Function declaration:

    var a = 100;
    function createFunction() {
        var a = 200;
        return function func() {
            return a;
        }
    }
    console.log(createFunction()()); // 200
    

    ⬆ Back to Top

  3. What is a Short circuit condition

    Short circuit conditions are meant for condensed way of writing simple if statements. Let's demonstrate the scenario using an example. If you would like to login to a portal with an authentication condition, the expression would be as below,

    if (authenticate) {
       loginToPorta();
    }
    

    Since the javascript logical operators evaluated from left to right, the above expression can be simplified using && logical operator

    authenticate && loginToPorta();
    

    ⬆ Back to Top

  4. What is the easiest way to resize an array

    The length property of an array is useful to resize or empty an array quickly. Let's apply length property on number array to resize the number of elements from 5 to 2,

    var array = [1, 2, 3, 4, 5];
    console.log(array.length); // 5
    
    array.length = 2;
    console.log(array.length); // 2
    console.log(array); // [1,2]
    

    and the array can be emptied too

    var array = [1, 2, 3, 4, 5];
    array.length = 0;
    console.log(array.length); // 0
    console.log(array); // []
    

    ⬆ Back to Top

  5. What is an observable

    An Observable is basically a function that can return a stream of values either synchronously or asynchronously to an observer over time. The consumer can get the value by calling subscribe() method. Let's look at a simple example of an Observable

    import { Observable } from 'rxjs';
    
    const observable = new Observable(observer => {
      setTimeout(() => {
        observer.next('Message from a Observable!');
      }, 3000);
    });
    
    observable.subscribe(value => console.log(value));
    

    Screenshot

    Note: Observables are not part of the JavaScript language yet but they are being proposed to be added to the language

    ⬆ Back to Top

  6. What is the difference between function and class declarations

    The main difference between function declarations and class declarations is hoisting. The function declarations are hoisted but not class declarations.

    Classes:

    const user = new User(); // ReferenceError
    
    class User {}
    

    Constructor Function:

     const user = new User(); // No error
    
     function User() {
     }
    

    ⬆ Back to Top

  7. What is an async function

    An async function is a function declared with the async keyword which enables asynchronous, promise-based behavior to be written in a cleaner style by avoiding promise chains. These functions can contain zero or more await expressions.

    Let's take a below async function example,

    async function logger() {
    
      let data = await fetch('http://someapi.com/users'); // pause until fetch returns
      console.log(data)
    }
    logger();
    

    It is basically syntax sugar over ES2015 promises and generators.

    ⬆ Back to Top

  8. How do you prevent promises swallowing errors

    While using asynchronous code, JavaScript’s ES6 promises can make your life a lot easier without having callback pyramids and error handling on every second line. But Promises have some pitfalls and the biggest one is swallowing errors by default.

    Let's say you expect to print an error to the console for all the below cases,

     Promise.resolve('promised value').then(function() {
           throw new Error('error');
     });
    
     Promise.reject('error value').catch(function() {
           throw new Error('error');
     });
    
     new Promise(function(resolve, reject) {
           throw new Error('error');
     });
    

    But there are many modern JavaScript environments that won't print any errors. You can fix this problem in different ways,

    1. Add catch block at the end of each chain: You can add catch block to the end of each of your promise chains

       Promise.resolve('promised value').then(function() {
           throw new Error('error');
       }).catch(function(error) {
         console.error(error.stack);
       });
      

      But it is quite difficult to type for each promise chain and verbose too.

    2. Add done method: You can replace first solution's then and catch blocks with done method

       Promise.resolve('promised value').done(function() {
           throw new Error('error');
       });
      

      Let's say you want to fetch data using HTTP and later perform processing on the resulting data asynchronously. You can write done block as below,

       getDataFromHttp()
         .then(function(result) {
           return processDataAsync(result);
         })
         .done(function(processed) {
           displayData(processed);
         });
      

      In future, if the processing library API changed to synchronous then you can remove done block as below,

        getDataFromHttp()
          .then(function(result) {
            return displayData(processDataAsync(result));
          })
      

      and then you forgot to add done block to then block leads to silent errors.

    3. Extend ES6 Promises by Bluebird: Bluebird extends the ES6 Promises API to avoid the issue in the second solution. This library has a “default” onRejection handler which will print all errors from rejected Promises to stderr. After installation, you can process unhandled rejections

       Promise.onPossiblyUnhandledRejection(function(error){
           throw error;
       });
      

      and discard a rejection, just handle it with an empty catch

       Promise.reject('error value').catch(function() {});
      

    ⬆ Back to Top

  9. What is deno

    Deno is a simple, modern and secure runtime for JavaScript and TypeScript that uses V8 JavaScript engine and the Rust programming language.

    ⬆ Back to Top

  10. How do you make an object iterable in javascript

    By default, plain objects are not iterable. But you can make the object iterable by defining a Symbol.iterator property on it.

    Let's demonstrate this with an example,

    const collection = {
      one: 1,
      two: 2,
      three: 3,
      [Symbol.iterator]() {
        const values = Object.keys(this);
        let i = 0;
        return {
          next: () => {
            return {
              value: this[values[i++]],
              done: i > values.length
            }
          }
        };
      }
    };
    
    const iterator = collection[Symbol.iterator]();
    
    console.log(iterator.next());    // → {value: 1, done: false}
    console.log(iterator.next());    // → {value: 2, done: false}
    console.log(iterator.next());    // → {value: 3, done: false}
    console.log(iterator.next());    // → {value: undefined, done: true}
    

    The above process can be simplified using a generator function,

     const collection = {
       one: 1,
       two: 2,
       three: 3,
       [Symbol.iterator]: function * () {
         for (let key in this) {
           yield this[key];
         }
       }
     };
     const iterator = collection[Symbol.iterator]();
     console.log(iterator.next());    // {value: 1, done: false}
     console.log(iterator.next());    // {value: 2, done: false}
     console.log(iterator.next());    // {value: 3, done: false}
     console.log(iterator.next());    // {value: undefined, done: true}
    

    ⬆ Back to Top

  11. What is a Proper Tail Call

    First, we should know about tail call before talking about "Proper Tail Call". A tail call is a subroutine or function call performed as the final action of a calling function. Whereas Proper tail call(PTC) is a technique where the program or code will not create additional stack frames for a recursion when the function call is a tail call.

    For example, the below classic or head recursion of factorial function relies on stack for each step. Each step need to be processed upto n * factorial(n - 1)

    function factorial(n) {
      if (n === 0) {
        return 1
      }
      return n * factorial(n - 1)
    }
    console.log(factorial(5)); //120
    

    But if you use Tail recursion functions, they keep passing all the necessary data it needs down the recursion without relying on the stack.

    function factorial(n, acc = 1) {
      if (n === 0) {
        return acc
      }
      return factorial(n - 1, n * acc)
    }
    console.log(factorial(5)); //120
    

    The above pattern returns the same output as the first one. But the accumulator keeps track of total as an argument without using stack memory on recursive calls.

    ⬆ Back to Top

  12. How do you check an object is a promise or not

    If you don't know if a value is a promise or not, wrapping the value as Promise.resolve(value) which returns a promise

        function isPromise(object){
           if(Promise && Promise.resolve){
           return Promise.resolve(object) == object;
           }else{
           throw "Promise not supported in your environment"
           }
        }
    
        var i = 1;
        var promise = new Promise(function(resolve,reject){
           resolve()
        });
    
        console.log(isPromise(i)); // false
        console.log(isPromise(p)); // true
    

    Another way is to check for .then() handler type

     function isPromise(value) {
        return Boolean(value && typeof value.then === 'function');
     }
     var i = 1;
     var promise = new Promise(function(resolve,reject){
        resolve()
     });
    
     console.log(isPromise(i)) // false
     console.log(isPromise(promise)); // true
    

    ⬆ Back to Top

  13. How to detect if a function is called as constructor

    You can use new.target pseudo-property to detect whether a function was called as a constructor(using the new operator) or as a regular function call.

    1. If a constructor or function invoked using the new operator, new.target returns a reference to the constructor or function.
    2. For function calls, new.target is undefined.

      function Myfunc() {
      if (new.target) {
         console.log('called with new');
      } else {
         console.log('not called with new');
      }
      }
      
      new Myfunc(); // called with new
      Myfunc(); // not called with new
      Myfunc.call({}); not called with new
      

    ⬆ Back to Top

  14. What are the differences between arguments object and rest parameter

    There are three main differences between arguments object and rest parameters

    1. The arguments object is an array-like but not an array. Whereas the rest parameters are array instances.
    2. The arguments object does not support methods such as sort, map, forEach, or pop. Whereas these methods can be used in rest parameters.
    3. The rest parameters are only the ones that haven’t been given a separate name, while the arguments object contains all arguments passed to the function

    ⬆ Back to Top

  15. What are the differences between spread operator and rest parameter

    Rest parameter collects all remaining elements into an array. Whereas Spread operator allows iterables( arrays / objects / strings ) to be expanded into single arguments/elements. i.e, Rest parameter is opposite to the spread operator.

    ⬆ Back to Top

  16. What are the different kinds of generators

    There are five kinds of generators,

    1. Generator function declaration:

        function* myGenFunc() {
             yield 1;
             yield 2;
             yield 3;
        }
        const genObj = myGenFunc();
      
    2. Generator function expressions:

      const myGenFunc = function* () {
             yield 1;
             yield 2;
             yield 3;
      };
      const genObj = myGenFunc();
      
    3. Generator method definitions in object literals:

       const myObj = {
           * myGeneratorMethod() {
              yield 1;
              yield 2;
              yield 3;
           }
       };
       const genObj = myObj.myGeneratorMethod();
      
    4. Generator method definitions in class:

        class MyClass {
           * myGeneratorMethod() {
              yield 1;
              yield 2;
              yield 3;
           }
        }
        const myObject = new MyClass();
        const genObj = myObject.myGeneratorMethod();
      
    5. Generator as a computed property:

      const SomeObj = {
        *[Symbol.iterator] () {
          yield 1;
          yield 2;
          yield 3;
        }
      }
      
      console.log(Array.from(SomeObj)); // [ 1, 2, 3 ]
      

    ⬆ Back to Top

  17. What are the built-in iterables

    Below are the list of built-in iterables in javascript,

    1. Arrays and TypedArrays
    2. Strings: Iterate over each character or Unicode code-points
    3. Maps: iterate over its key-value pairs
    4. Sets: iterates over their elements
    5. arguments: An array-like special variable in functions
    6. DOM collection such as NodeList

    ⬆ Back to Top

  18. What are the differences between for...of and for...in statements

    Both for...in and for...of statements iterate over js data structures. The only difference is over what they iterate:

    1. for..in iterates over all enumerable property keys of an object
    2. for..of iterates over the values of an iterable object.

    Let's explain this difference with an example,

    let arr = ['a', 'b', 'c'];
    
    arr.newProp = 'newVlue';
    
    // key are the property keys
    for (let key in arr) {
      console.log(key);
    }
    
    // value are the property values
    for (let value of arr) {
      console.log(value);
    }
    

    Since for..in loop iterates over the keys of the object, the first loop logs 0, 1, 2 and newProp while iterating over the array object. The for..of loop iterates over the values of a arr data structure and logs a, b, c in the console.

    ⬆ Back to Top

  19. How do you define instance and non-instance properties

    The Instance properties must be defined inside of class methods. For example, name and age properties defined insider constructor as below,

    class Person {
      constructor(name, age) {
        this.name = name;
        this.age = age;
      }
    }
    

    But Static(class) and prototype data properties must be defined outside of the ClassBody declaration. Let's assign the age value for Person class as below,

    Person.staticAge = 30;
    Person.prototype.prototypeAge = 40;
    

    ⬆ Back to Top

  20. What is the difference between isNaN and Number.isNaN?

    1. isNaN: The global function isNaN converts the argument to a Number and returns true if the resulting value is NaN.
    2. Number.isNaN: This method does not convert the argument. But it returns true when the type is a Number and value is NaN.

    Let's see the difference with an example,

    isNaN(‘hello’);   // true
    Number.isNaN('hello'); // false
    

    ⬆ Back to Top

  21. How to invoke an IIFE without any extra brackets?

    Immediately Invoked Function Expressions(IIFE) requires a pair of parenthesis to wrap the function which contains set of statements.

    (function(dt) { 
       console.log(dt.toLocaleTimeString()); 
     })(new Date());
    

    Since both IIFE and void operator discard the result of an expression, you can avoid the extra brackets using void operator for IIFE as below,

     void function(dt) { 
       console.log(dt.toLocaleTimeString()); 
     }(new Date());
    

    ⬆ Back to Top

  22. Is that possible to use expressions in switch cases?

    You might have seen expressions used in switch condition but it is also possible to use for switch cases by assigning true value for the switch condition. Let's see the weather condition based on temparature as an example,

    const weather = function getWeather(temp) {
       switch(true) {
           case temp < 0: return 'freezing';
           case temp < 10: return 'cold';
           case temp < 24: return 'cool';
           default: return 'unknown';
       }
       }(10);
    

    ⬆ Back to Top

  23. What is the easiest way to ignore promise errors?

    The easiest and safest way to ignore promise errors is void that error. This approach is ESLint friendly too.

    await promise.catch(e => void e);
    

    ⬆ Back to Top

  24. How do style the console output using CSS?

    You can add CSS styling to the console output using the CSS format content specifier %c. The console string message can be appended after the specifier and CSS style in another argument. Let's print the red the color text using console.log and CSS specifier as below,

    console.log("%cThis is a red text", "color:red");
    

    It is also possible to add more styles for the content. For example, the font-size can be modified for the above text

    console.log("%cThis is a red text with bigger font", "color:red; font-size:20px");
    

    ⬆ Back to Top

  25. Coding Exercise

1. What is the output of below code

var car = new Vehicle("Honda", "white", "2010", "UK");
console.log(car);

function Vehicle(model, color, year, country) {
    this.model = model;
    this.color = color;
    this.year = year;
    this.country = country;
}
  • 1: Undefined
  • 2: ReferenceError
  • 3: null
  • 4: {model: "Honda", color: "white", year: "2010", country: "UK"}
Answer

Answer: 4 The function declarations are hoisted similar to any variables. So the placement for Vehicle function declaration doesn't make any difference.


⬆ Back to Top

2. What is the output of below code

function foo() {
    let x = y = 0;
    x++;
    y++;
    return x;
}

console.log(foo(), typeof x, typeof y);
  • 1: 1, undefined and undefined
  • 2: ReferenceError: X is not defined
  • 3: 1, undefined and number
  • 4: 1, number and number
Answer

Answer: 3 Of course the return value of foo() is 1 due to the increment operator. But the statement let x = y = 0 declares a local variable x. Whereas y declared as a global variable accidentally. This statement is equivalent to, javascript let x; window.y = 0; x = window.y; Since the block scoped variable x is undefined outside of the function, the type will be undefined too. Whereas the global variable y is available outside the function, the value is 0 and type is number.


⬆ Back to Top

3. What is the output of below code

function main(){
   console.log('A');
   setTimeout(
      function print(){ console.log('B'); }
   ,0);
   console.log('C');
}
main();
  • 1: A, B and C
  • 2: B, A and C
  • 3: A and C
  • 4: A, C and B
Answer

Answer: 4 The statements order is based on the event loop mechanism. The order of statements follows the below order, 1. At first, the main function is pushed to the stack. 2. Then the browser pushes the fist statement of the main function( i.e, A's console.log) to the stack, executing and popping out immediately. 3. But setTimeout statement moved to Browser API to apply the delay for callback. 4. In the meantime, C's console.log added to stack, executed and popped out. 5. The callback of setTimeout moved from Browser API to message queue. 6. The main function popped out from stack because there are no statements to execute 7. The callback moved from message queue to the stack since the stack is empty. 8. The console.log for B is added to the stack and display on the console.


⬆ Back to Top

4. What is the output of below equality check

console.log(0.1 + 0.2 === 0.3);
  • 1: false
  • 2: true
Answer

Answer: 1 This is due to the float point math problem. Since the floating point numbers are encoded in binary format, the addition operations on them lead to rounding errors. Hence, the comparison of floating points doesn't give expected results. You can find more details about the explanation here 0.30000000000000004.com/


⬆ Back to Top

5. What is the output of below code

var y = 1;
  if (function f(){}) {
    y += typeof f;
  }
  console.log(y);
  • 1: 1function
  • 2: 1object
  • 3: ReferenceError
  • 4: 1undefined
Answer

Answer: 4 The main points in the above code snippets are, 1. You can see function expression instead function declaration inside if statement. So it always returns true. 2. Since it is not declared(or assigned) anywhere, f is undefined and typeof f is undefined too. In other words, it is same as javascript var y = 1; if ('foo') { y += typeof f; } console.log(y); Note: It returns 1object for MS Edge browser


⬆ Back to Top

6. What is the output of below code

function foo() {
  return
  {
    message: "Hello World"
  };
}
console.log(foo());
  • 1: Hello World
  • 2: Object {message: "Hello World"}
  • 3: Undefined
  • 4: SyntaxError
Answer

Answer: 3 This is a semicolon issue. Normally semicolons are optional in JavaScript. So if there are any statements(in this case, return) missing semicolon, it is automatically inserted immediately. Hence, the function returned as undefined. Whereas if the opening curly brace is along with the return keyword then the function is going to be returned as expected. javascript function foo() { return { message: "Hello World" }; } console.log(foo()); // {message: "Hello World"}


⬆ Back to Top

7. What is the output of below code

var myChars = ['a', 'b', 'c', 'd']
delete myChars[0];
console.log(myChars);
console.log(myChars[0]);
console.log(myChars.length);
  • 1: [empty, 'b', 'c', 'd'], empty, 3
  • 2: [null, 'b', 'c', 'd'], empty, 3
  • 3: [empty, 'b', 'c', 'd'], undefined, 4
  • 4: [null, 'b', 'c', 'd'], undefined, 4
Answer

Answer: 3 The delete operator will delete the object property but it will not reindex the array or change its length. So the number or elements or length of the array won't be changed. If you try to print myChars then you can observe that it doesn't set an undefined value, rather the property is removed from the array. The newer versions of Chrome use empty instead of undefined to make the difference a bit clearer.


⬆ Back to Top

8. What is the output of below code in latest Chrome

var array1 = new Array(3);
console.log(array1);

var array2 = [];
array2[2] = 100;
console.log(array2);

var array3 = [,,,];
console.log(array3);
  • 1: [undefined × 3], [undefined × 2, 100], [undefined × 3]
  • 2: [empty × 3], [empty × 2, 100], [empty × 3]
  • 3: [null × 3], [null × 2, 100], [null × 3]
  • 4: [], [100], []
Answer

Answer: 2 The latest chrome versions display sparse array(they are filled with holes) using this empty x n notation. Whereas the older versions have undefined x n notation. Note: The latest version of FF displays n empty slots notation.


⬆ Back to Top

9. What is the output of below code

const obj = {
  prop1: function() { return 0 },
  prop2() { return 1 },
  ['prop' + 3]() { return 2 }
}

console.log(obj.prop1());
console.log(obj.prop2());
console.log(obj.prop3());
  • 1: 0, 1, 2
  • 2: 0, { return 1 }, 2
  • 3: 0, { return 1 }, { return 2 }
  • 4: 0, 1, undefined
Answer

Answer: 1 ES6 provides method definitions and property shorthands for objects. So both prop2 and prop3 are treated as regular function values.


⬆ Back to Top

10. What is the output of below code

console.log(1 < 2 < 3);
console.log(3 > 2 > 1);
  • 1: true, true
  • 2: true, false
  • 3: SyntaxError, SyntaxError,
  • 4: false, false
Answer

Answer: 2 The important point is that if the statement contains the same operators(e.g, < or >) then it can be evaluated from left to right. The first statement follows the below order, 1. console.log(1 < 2 < 3); 2. console.log(true < 3); 3. console.log(1 < 3); // True converted as 1 during comparison 4. True Whereas the second statement follows the below order, 1. console.log(3 > 2 > 1); 2. console.log(true > 1); 3. console.log(1 > 1); // False converted as 0 during comparison 4. False


⬆ Back to Top

11. What is the output of below code in non-strict mode

function printNumbers(first, second, first) {
  console.log(first, second, first);
}
printNumbers(1, 2, 3);
  • 1: 1, 2, 3
  • 2: 3, 2, 3
  • 3: SyntaxError: Duplicate parameter name not allowed in this context
  • 4: 1, 2, 1
Answer

Answer: 2 In non-strict mode, the regular JavaScript functions allow duplicate named parameters. The above code snippet has duplicate parameters on 1st and 3rd parameters. The value of the first parameter is mapped to the third argument which is passed to the function. Hence, the 3rd argument overrides the first parameter. Note: In strict mode, duplicate parameters will throw a Syntax Error.


⬆ Back to Top

12. What is the output of below code

const printNumbersArrow = (first, second, first) => {
  console.log(first, second, first);
}
printNumbersArrow(1, 2, 3);
  • 1: 1, 2, 3
  • 2: 3, 2, 3
  • 3: SyntaxError: Duplicate parameter name not allowed in this context
  • 4: 1, 2, 1
Answer

Answer: 3 Unlike regular functions, the arrow functions doesn't not allow duplicate parameters in either strict or non-strict mode. So you can see SyntaxError in the console.


⬆ Back to Top

13. What is the output of below code

const arrowFunc = () => arguments.length;
console.log(arrowFunc(1, 2, 3));
  • 1: ReferenceError: arguments is not defined
  • 2: 3
  • 3: undefined
  • 4: null
Answer

Answer: 1 Arrow functions do not have an arguments, super, this, or new.target bindings. So any reference to arguments variable tries to resolve to a binding in a lexically enclosing environment. In this case, the arguments variable is not defined outside of the arrow function. Hence, you will receive a reference error. Where as the normal function provides the number of arguments passed to the function javascript const func = function () { return arguments.length; } console.log(func(1, 2, 3)); But If you still want to use an arrow function then rest operator on arguments provides the expected arguments javascript const arrowFunc = (...args) => args.length; console.log(arrowFunc(1, 2, 3));


⬆ Back to Top

14. What is the output of below code

console.log( String.prototype.trimLeft.name === 'trimLeft' );
console.log( String.prototype.trimLeft.name === 'trimStart' );
  • 1: True, False
  • 2: False, True
Answer

Answer: 2 In order to be consistent with functions like String.prototype.padStart, the standard method name for trimming the whitespaces is considered as trimStart. Due to web web compatibility reasons, the old method name 'trimLeft' still acts as an alias for 'trimStart'. Hence, the prototype for 'trimLeft' is always 'trimStart'


⬆ Back to Top

15. What is the output of below code

console.log(Math.max());
  • 1: undefined
  • 2: Infinity
  • 3: 0
  • 4: -Infinity
Answer

Answer: 4 -Infinity is the initial comparant because almost every other value is bigger. So when no arguments are provided, -Infinity is going to be returned. Note: Zero number of arguments is a valid case.


⬆ Back to Top

16. What is the output of below code

console.log(10 == [10]);
console.log(10 == [[[[[[[10]]]]]]]);
  • 1: True, True
  • 2: True, False
  • 3: False, False
  • 4: False, True
Answer

Answer: 1 As per the comparison algorithm in the ECMAScript specification(ECMA-262), the above expression converted into JS as below javascript 10 === Number([10].valueOf().toString()) // 10 So it doesn't matter about number brackets([]) around the number, it is always converted to a number in the expression.


⬆ Back to Top

17. What is the output of below code

console.log(10 + '10');
console.log(10 - '10');
  • 1: 20, 0
  • 2: 1010, 0
  • 3: 1010, 10-10
  • 4: NaN, NaN
Answer

Answer: 2 The concatenation operator(+) is applicable for both number and string types. So if any operand is string type then both operands concatenated as strings. Whereas subtract(-) operator tries to convert the operands as number type.


⬆ Back to Top

18. What is the output of below code

console.log([0] == false);
if([0]) {
console.log("I'm True");
} else {
console.log("I'm False");
}
  • 1: True, I'm True
  • 2: True, I'm False
  • 3: False, I'm True
  • 4: False, I'm False
Answer

Answer: 1 In comparison operators, the expression [0] converted to Number([0].valueOf().toString()) which is resolved to false. Whereas [0] just becomes a truthy value without any conversion because there is no comparison operator.

19. What is the output of below code

console.log([1, 2] + [3, 4]);
  • 1: [1,2,3,4]
  • 2: [1,2][3,4]
  • 3: SyntaxError
  • 4: 1,23,4
Answer

Answer: 4 The + operator is not meant or defined for arrays. So it converts arrays into strings and concatenates them.


⬆ Back to Top

20. What is the output of below code

const numbers = new Set([1, 1, 2, 3, 4]);
console.log(numbers);

const browser = new Set('Firefox);
console.log(browser);
  • 1: {1, 2, 3, 4}, {"F", "i", "r", "e", "f", "o", "x"}
  • 2: {1, 2, 3, 4}, {"F", "i", "r", "e", "o", "x"}
  • 3: [1, 2, 3, 4], ["F", "i", "r", "e", "o", "x"]
  • 4: {1, 1, 2, 3, 4}, {"F", "i", "r", "e", "f", "o", "x"}
Answer

Answer: 1 Since Set object is a collection of unique values, it won't allow duplicate values in the collection. At the same time, it is case sensitive data structure.


⬆ Back to Top

21. What is the output of below code

console.log(NaN === NaN);
  • 1: True
  • 2: False
Answer

Answer: 2 JavaScript follows IEEE 754 spec standards. As per this spec, NaNs are never equal for floating-point numbers.


⬆ Back to Top

22. What is the output of below code

let numbers = [1, 2, 3, 4, NaN];
console.log(numbers.indexOf(NaN));
  • 1: 4
  • 2: NaN
  • 3: SyntaxError
  • 4: -1
Answer

Answer: 4 The indexOf uses strict equality operator(===) internally and NaN === NaN evaluates to false. Since indexOf won't be able to find NaN inside an array, it returns -1 always. But you can use Array.prototype.findIndex method to find out the index of NaN in an array or You can use Array.prototype.includes to check if NaN is present in an array or not. javascript let numbers = [1, 2, 3, 4, NaN]; console.log(numbers.findIndex(Number.isNaN)); // 4 console.log(numbers.includes(Number.isNaN)); // true


⬆ Back to Top

23. What is the output of below code

let [a, ...b,] = [1, 2, 3, 4, 5];
console.log(a, b);
  • 1: 1, [2, 3, 4, 5]
  • 2: 1, {2, 3, 4, 5}
  • 3: SyntaxError
  • 4: 1, [2, 3, 4]
Answer

Answer: 3 When using rest parameters, trailing commas are not allowed and will throw a SyntaxError. If you remove the trailing comma then it displays 1st answer javascript let [a, ...b,] = [1, 2, 3, 4, 5]; console.log(a, b); // 1, [2, 3, 4, 5]


⬆ Back to Top

25. What is the output of below code

async function func() {
   return 10;
}
console.log(func());
  • 1: Promise {: 10}
  • 2: 10
  • 3: SyntaxError
  • 4: Promise {: 10}
Answer

Answer: 1 Async functions always return a promise. But even if the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise. The above async function is equivalent to below expression, javascript function func() { return Promise.resolve(10) }


⬆ Back to Top

26. What is the output of below code

async function func() {
   await 10;
}
console.log(func());
  • 1: Promise {: 10}
  • 2: 10
  • 3: SyntaxError
  • 4: Promise {: undefined}
Answer

Answer: 4 The await expression returns value 10 with promise resolution and the code after each await expression can be treated as existing in a .then callback. In this case, there is no return expression at the end of the function. Hence, the default return value of undefined is returned as the resolution of the promise. The above async function is equivalent to below expression, javascript function func() { return Promise.resolve(10).then(() => undefined) }


⬆ Back to Top

27. What is the output of below code

function delay() {
  return new Promise(resolve => setTimeout(resolve, 2000));
}

async function delayedLog(item) {
  await delay();
  console.log(item);
}

async function processArray(array) {
  array.forEach(item => {
    await delayedLog(item);
  })
}

processArray([1, 2, 3, 4]);
  • 1: SyntaxError
  • 2: 1, 2, 3, 4
  • 3: 4, 4, 4, 4
  • 4: 4, 3, 2, 1
Answer

Answer: 1 Even though “processArray” is an async function, the anonymous function that we use for forEach is synchronous. If you use await inside a synchronous function then it throws a syntax error.


⬆ Back to Top

28. What is the output of below code

function delay() {
  return new Promise(resolve => setTimeout(resolve, 2000));
}

async function delayedLog(item) {
  await delay();
  console.log(item);
}

async function process(array) {
  array.forEach(async (item) => {
    await delayedLog(item);
  });
  console.log('Process completed!');
}
process([1, 2, 3, 5]);
  • 1: 1 2 3 5 and Process completed!
  • 2: 5 5 5 5 and Process completed!
  • 3: Process completed! and 5 5 5 5
  • 4: Process completed! and 1 2 3 5
Answer

Answer: 4 The forEach method will not wait until all items are finished but it just runs the tasks and goes next. Hence, the last statement is displayed first followed by a sequence of promise resolutions. But you control the array sequence using for..of loop, javascript async function processArray(array) { for (const item of array) { await delayedLog(item); } console.log('Process completed!'); }


⬆ Back to Top

29. What is the output of below code

var set = new Set();
set.add("+0").add("-0").add(NaN).add(undefined).add(NaN);;
console.log(set);
  • 1: Set(4) {"+0", "-0", NaN, undefined}
  • 2: Set(3) {"+0", NaN, undefined}
  • 3: Set(5) {"+0", "-0", NaN, undefined, NaN}
  • 4: Set(4) {"+0", NaN, undefined, NaN}
Answer

Answer: 1 Set has few exceptions from equality check, 1. All NaN values are equal 2. Both +0 and -0 considered as different values


⬆ Back to Top

30. What is the output of below code

const sym1 = Symbol('one');
const sym2 = Symbol('one');

const sym3 = Symbol.for('two');
const sym4 = Symbol.for('two');

cnsooe.log(sym1 === sym2, sym3 === sym4);
  • 1: true, true
  • 2: true, false
  • 3: false, true
  • 4: false, false
Answer

Answer: 3 Symbol follows below conventions, 1. Every symbol value returned from Symbol() is unique irrespective of the optional string. 2. Symbol.for() function creates a symbol in a global symbol registry list. But it doesn't necessarily create a new symbol on every call, it checks first if a symbol with the given key is already present in the registry and returns the symbol if it is found. Otherwise a new symbol created in the registry. Note: The symbol description is just useful for debugging purposes.


⬆ Back to Top

31. What is the output of below code

const sym1 = new Symbol('one');
console.log(sym1);
  • 1: SyntaxError
  • 2: one
  • 3: Symbol('one')
  • 4: Symbol
Answer

Answer: 1 Symbol is a just a standard function and not an object constructor(unlike other primitives new Boolean, new String and new Number). So if you try to call it with the new operator will result in a TypeError


⬆ Back to Top

32. What is the output of below code

let myNumber = 100;
let myString = '100';

if (!typeof myNumber === "string") {
   console.log("It is not a string!");
} else {
    console.log("It is a string!");
}

if (!typeof myString === "number"){
   console.log("It is not a number!")
} else {
   console.log("It is a number!");
}
  • 1: SyntaxError
  • 2: It is not a string!, It is not a number!
  • 3: It is not a string!, It is a number!
  • 4: It is a string!, It is a number!
Answer

Answer: 4 The return value of typeof myNumber (OR) typeof myString is always the truthy value (either "number" or "string"). Since ! operator converts the value to a boolean value, the value of both !typeof myNumber or !typeof myString is always false. Hence the if condition fails and control goes to else block.


⬆ Back to Top

33. What is the output of below code

console.log(JSON.stringify({ myArray: ['one', undefined, function(){}, Symbol('')] }));
console.log(JSON.stringify({ [Symbol.for('one')]: 'one' }, [Symbol.for('one')]));
  • 1: {"myArray":['one', undefined, {}, Symbol]}, {}
  • 2: {"myArray":['one', null,null,null]}, {}
  • 3: {"myArray":['one', null,null,null]}, "{ [Symbol.for('one')]: 'one' }, [Symbol.for('one')]"
  • 4: {"myArray":['one', undefined, function(){}, Symbol('')]}, {}
Answer

Answer: 2 The symbols has below constraints, 1. The undefined, Functions, and Symbols are not valid JSON values. So those values are either omitted (in an object) or changed to null (in an array). Hence, it returns null values for the value array. 2. All Symbol-keyed properties will be completely ignored. Hence it returns an empty object({}).


⬆ Back to Top

34. What is the output of below code

class A {
  constructor() {
    console.log(new.target.name)
  }
}

class B extends A { constructor() { super() } }

new A();
new B();
  • 1: A, A
  • 2: A, B
Answer

Answer: 2 Using constructors, new.target refers to the constructor (points to the class definition of class which is initialized) that was directly invoked by new. This also applies to the case if the constructor is in a parent class and was delegated from a child constructor.


⬆ Back to Top

35. What is the output of below code

const [x, ...y,] = [1, 2, 3, 4];
console.log(x, y);
  • 1: 1, [2, 3, 4]
  • 2: 1, [2, 3]
  • 3: 1, [2]
  • 4: SyntaxError
Answer

Answer: 4 It throws a syntax error because the rest element should not have a trailing comma. You should always consider using a rest operator as the last element.


⬆ Back to Top

36. What is the output of below code

const {a: x = 10, b: y = 20} = {a: 30};

console.log(x);
console.log(y);
  • 1: 30, 20
  • 2: 10, 20
  • 3: 10, undefined
  • 4: 30, undefined
Answer

Answer: 1 The object property follows below rules, 1. The object properties can be retrieved and assigned to a variable with a different name 2. The property assigned a default value when the retrieved value is undefined


⬆ Back to Top

37. What is the output of below code

function area({length = 10, width = 20}) {
  console.log(length*width);
}

area();
  • 1: 200
  • 2: Error
  • 3: undefined
  • 4: 0
Answer

Answer: 2 If you leave out the right-hand side assignment for the destructuring object, the function will look for at least one argument to be supplied when invoked. Otherwise you will receive an error Error: Cannot read property 'length' of undefined as mentioned above. You can avoid the error with either of the below changes, 1. Pass at least an empty object: javascript function area({length = 10, width = 20}) { console.log(length*width); } area({}); 2. Assign default empty object: javascript function area({length = 10, width = 20} = {}) { console.log(length*width); } area();


⬆ Back to Top

38. What is the output of below code

const props = [
  { id: 1, name: 'John'},
  { id: 2, name: 'Jack'},
  { id: 3, name: 'Tom'}
];

const [,, { name }] = props;
console.log(name);
  • 1: Tom
  • 2: Error
  • 3: undefined
  • 4: John
Answer

Answer: 1 It is possible to combine Array and Object destructuring. In this case, the third element in the array props accessed first followed by name property in the object.


⬆ Back to Top

39. What is the output of below code

function checkType(num = 1) {
  console.log(typeof num);
}

checkType();
checkType(undefined);
checkType('');
checkType(null);
  • 1: number, undefined, string, object
  • 2: undefined, undefined, string, object
  • 3: number, number, string, object
  • 4: number, number, number, number
Answer

Answer: 3 If the function argument is set implicitly(not passing argument) or explicitly to undefined, the value of the argument is the default parameter. Whereas for other falsy values('' or null), the value of the argument is passed as a parameter. Hence, the result of function calls categorized as below, 1. The first two function calls logs number type since the type of default value is number 2. The type of '' and null values are string and object type respectively.


⬆ Back to Top

40. What is the output of below code

function add(item, items = []) {
  items.push(item);
  return items;
}

console.log(add('Orange'));
console.log(add('Apple'));
  • 1: ['Orange'], ['Orange', 'Apple']
  • 2: ['Orange'], ['Apple']
Answer

Answer: 2 Since the default argument is evaluated at call time, a new object is created each time the function is called. So in this case, the new array is created and an element pushed to the default empty array.


⬆ Back to Top

41. What is the output of below code

function greet(greeting, name, message = greeting + ' ' + name) {
  console.log([greeting, name, message]);
}

greet('Hello', 'John');
greet('Hello', 'John', 'Good morning!');
  • 1: SyntaxError
  • 2: ['Hello', 'John', 'Hello John'], ['Hello', 'John', 'Good morning!']
Answer

Answer: 2 Since parameters defined earlier are available to later default parameters, this code snippet doesn't throw any error.


⬆ Back to Top

42. What is the output of below code

function outer(f = inner()) {
  function inner() { return 'Inner' }
}
outer();
  • 1: ReferenceError
  • 2: Inner
Answer

Answer: 1 The functions and variables declared in the function body cannot be referred from default value parameter initializers. If you still try to access, it throws a run-time ReferenceError(i.e, inner is not defined).


⬆ Back to Top

43. What is the output of below code

function myFun(x, y, ...manyMoreArgs) {
  console.log(manyMoreArgs)
}

myFun(1, 2, 3, 4, 5);
myFun(1, 2);
  • 1: [3, 4, 5], undefined
  • 2: SyntaxError
  • 3: [3, 4, 5], []
  • 4: [3, 4, 5], [undefined]
Answer

Answer: 3 The rest parameter is used to hold the remaining parameters of a function and it becomes an empty array if the argument is not provided.


⬆ Back to Top

44. What is the output of below code

const obj = {'key': 'value'};
const array = [...obj];
console.log(array);
  • 1: ['key', 'value']
  • 2: TypeError
  • 3: []
  • 4: ['key']
Answer

Answer: 2 Spread syntax can be applied only to iterable objects. By default, Objects are not iterable, but they become iterable when used in an Array, or with iterating functions such as map(), reduce(), and assign(). If you still try to do it, it still throws TypeError: obj is not iterable.


⬆ Back to Top

45. What is the output of below code

function* myGenFunc() {
    yield 1;
    yield 2;
    yield 3;
}
var myGenObj = new myGenFunc;
console.log(myGenObj.next().value);
  • 1: 1
  • 2: undefined
  • 3: SyntaxError
  • 4: TypeError
Answer

Answer: 4 Generators are not constructible type. But if you still proceed to do, there will be an error saying "TypeError: myGenFunc is not a constructor"


⬆ Back to Top

46. What is the output of below code


function* yieldAndReturn() {
  yield 1;
  return 2;
  yield 3;
}

var myGenObj = yieldAndReturn()
console.log(myGenObj.next());
console.log(myGenObj.next());
console.log(myGenObj.next());
  • 1: { value: 1, done: false }, { value: 2, done: true }, { value: undefined, done: true }
  • 2: { value: 1, done: false }, { value: 2, done: false }, { value: undefined, done: true }
  • 3: { value: 1, done: false }, { value: 2, done: true }, { value: 3, done: true }
  • 4: { value: 1, done: false }, { value: 2, done: false }, { value: 3, done: true }
Answer

Answer: 1 A return statement in a generator function will make the generator finish. If a value is returned, it will be set as the value property of the object and done property to true. When a generator is finished, subsequent next() calls return an object of this form: {value: undefined, done: true}.


⬆ Back to Top

47. What is the output of below code

const myGenerator = (function *(){
  yield 1;
  yield 2;
  yield 3;
})();
for (const value of myGenerator) {
  console.log(value);
  break;
}

for (const value of myGenerator) {
  console.log(value);
}
  • 1: 1,2,3 and 1,2,3
  • 2: 1,2,3 and 4,5,6
  • 3: 1 and 1
  • 4: 1
Answer

Answer: 4 The generator should not be re-used once the iterator is closed. i.e, Upon exiting a loop(on completion or using break & return), the generator is closed and trying to iterate over it again does not yield any more results. Hence, the second loop doesn't print any value.


⬆ Back to Top

48. What is the output of below code

const num = 0o38;
console.log(num);
  • 1: SyntaxError
  • 2: 38
Answer

Answer: 1 If you use an invalid number(outside of 0-7 range) in the octal literal, JavaScript will throw a SyntaxError. In ES5, it treats the octal literal as a decimal number.


⬆ Back to Top

49. What is the output of below code

const squareObj = new Square(10);
console.log(squareObj.area);

class Square {
  constructor(length) {
    this.length = length;
  }

  get area() {
    return this.length * this.length;
  }

  set area(value) {
    this.area = value;
  }
}
  • 1: 100
  • 2: ReferenceError
Answer

Answer: 2 Unlike function declarations, class declarations are not hoisted. i.e, First You need to declare your class and then access it, otherwise it will throw a ReferenceError "Uncaught ReferenceError: Square is not defined". Note: Class expressions also applies to the same hoisting restrictions of class declarations.


⬆ Back to Top

50. What is the output of below code

function Person() { }

Person.prototype.walk = function() {
  return this;
}

Person.run = function() {
  return this;
}

let user = new Person();
let walk = user.walk;
console.log(walk());

let run = Person.run;
console.log(run());
  • 1: undefined, undefined
  • 2: Person, Person
  • 3: SyntaxError
  • 4: Window, Window
Answer

Answer: 4 When a regular or prototype method is called without a value for this, the methods return an initial this value if the value is not undefined. Otherwise global window object will be returned. In our case, the initial this value is undefined so both methods return window objects.


⬆ Back to Top

51. What is the output of below code

class Vehicle {
  constructor(name) {
    this.name = name;
  }

  start() {
    console.log(`${this.name} vehicle started`);
  }
}

class Car extends Vehicle {
  start() {
    console.log(`${this.name} car started`);
    super.start();
  }
}

const car = new Car('BMW');
console.log(car.start());
  • 1: SyntaxError
  • 2: BMW vehicle started, BMW car started
  • 3: BMW car started, BMW vehicle started
  • 4: BMW car started, BMW car started
Answer

Answer: 3 The super keyword is used to call methods of a superclass. Unlike other languages the super invocation doesn't need to be a first statement. i.e, The statements will be executed in the same order of code.


⬆ Back to Top

52. What is the output of below code

const USER = {'age': 30};
USER.age = 25;
console.log(USER.age);
  • 1: 30
  • 2: 25
  • 3: Uncaught TypeError
  • 4: SyntaxError
Answer

Answer: 2 Even though we used constant variables, the content of it is an object and the object's contents (e.g properties) can be altered. Hence, the change is going to be valid in this case.


⬆ Back to Top

53. What is the output of below code

console.log('🙂' === '🙂');
  • 1: false
  • 2: true
Answer

Answer: 2 Emojis are unicodes and the unicode for smile symbol is "U+1F642". The unicode comparision of same emojies is equivalent to string comparison. Hence, the output is always true.


⬆ Back to Top

54. What is the output of below code?

console.log(typeof typeof typeof true);
  • 1: string
  • 2: boolean
  • 3: NaN
  • 4: number
Answer

Answer: 1 The typeof operator on any primitive returns a string value. So even if you apply the chain of typeof operators on the return value, it is always string.


⬆ Back to Top

55. What is the output of below code?

let zero = new Number(0);

if (zero) {
  console.log("If");
} else {
  console.log("Else");
}
  • 1: If
  • 2: Else
  • 3: NaN
  • 4: SyntaxError
Answer

Answer: 1 1. The type of operator on new Number always returns object. i.e, typeof new Number(0) --> object. 2. Objects are always truthy in if block Hence the above code block always goes to if section.


⬆ Back to Top

55. What is the output of below code in non strict mode?

let msg = "Good morning!!";

msg.name = "John"; 

console.log(msg.name);
  • 1: ""
  • 2: Error
  • 3: John
  • 4: Undefined
Answer

Answer: 4 It returns undefined for non-strict mode and returns Error for strict mode. In non-strict mode, the wrapper object is going to be created and get the mentioned property. But the object get disappeared after accessing the property in next line.


⬆ Back to Top

Did you find this article valuable?

Support CapsCode's Blog by becoming a sponsor. Any amount is appreciated!