DEV Community

Halil Can Ozcelik
Halil Can Ozcelik

Posted on

JavaScript Interview Coding Questions - 4

Continuing to questions… As I said in first blog, these are generally evaluation based code snippets.

  1. This one is about scope differences of Arrow & Regular function definitions.

    // 1. What will be logged? Why?
    const module1 = {
      x: 55,
      getX: function () {
        console.log('x:', this.x);
      }
    };
    
    const module2 = {
      x: 55,
      getX: () => {
        console.log('x:', this.x);
      }
    };
    
    (function() {
      this.x = 66;
      module1.getX();
      module2.getX();
    })();
    

    The console output will be following:

    x: 55
    x: 66
    

    Because this refers to wrapper object in regular function so this.x logs x property of wrapper module1 object in first example. On the other side, arrow functions don't bind their own scope, but inherit it from the parent one, which is Window or the global object in this case.

    You can test it in below:

  2. Let's examine same issue in a different example.

    // 2. What will be logged? Why?
    const message1 = {
      hello : 'Hello',
      names : ['Sue', 'Joe'],
      showMessage: function () {
        this.names.forEach(function(name) {
          console.log(`${this.hello} ${name}`);
        });
      }
    }
    message1.showMessage();
    
    const message2 = {
      hello : 'Hello',
      names : ['Sue', 'Joe'],
      showMessage: function () {
        this.names.forEach(name => {
          console.log(`${this.hello} ${name}`);
        });
      }
    }
    message2.showMessage();
    

    The console output will be following:

    undefined Sue
    undefined Joe
    Hello Sue
    Hello Joe
    

    In message1, the function inside this.names.forEach is defined as regular function, so this equals to the global object by default (Window in browsers, global in Node.js) and it has no hello property. this equals to undefined by default in strict mode!

    On the other hand, in message2, the function inside this.names.forEach is defined as arrow function. Arrow functions don't have own scope, so it equals to owner's (which is showMessage in this case) scope. The scope of showMessage is the wrapper object message2. For this reason, we can reach hello property of message2 by using this.hello.

    You can test it in below:

  3. This question is to evaluate knowledge about promises in JavaScript.

    const promiser = ms => new Promise((resolve, reject) => {
      setTimeout(() => { resolve('wait wait..') }, ms)
    });
    
    const timeout = new Promise((resolve, reject) => {
      setTimeout(() => { resolve('timeout!') }, 2000)
    });
    
    const race1 = Promise.race([promiser(1000), timeout]);
    const race2 = Promise.race([promiser(3000), timeout]);
    
    // What will be the output?
    race1.then(res => console.log('race1:', res))
      .catch(err => console.log('race1:',  err));
    
    // What will be the output?
    race2.then(res => console.log('race2:', res))
      .catch(err => console.log('race2:', err));
    

    The result will be below:

    race1: wait wait..
    race2: timeout!
    

    Promise.race() returns a winner promise which fulfills or rejects sooner. Our timeout promise is resolved in 2 seconds. The promiser is taking resolving time as parameter. In first race, it resolved in 1 second so wins the race, but in the second race it takes 3 seconds as parameter so timeout is resolved earlier.

    You can test it in below:

You can read the previous articles of this series from the links below:



Top comments (0)