7 Quick JavaScript Pop Quizzes With Explanations
Tags: javascript, tutorial, webdev
Published: 2019-10-31 08:08:40

---
title: 7 Quick JavaScript Pop Quizzes With Explanations
published: true
description: 7 Quick JavaScript Pop Quizzes With Explanations
tags: #javascript, #tutorial, #webdev
---

> originally published on [devinduct](https://devinduct.com/blogpost/49/7-quick-javascript-pop-quizzes-with-explanations)

## Introduction

I believe that learning new things and evaluating the things we know is useful to keep us on track, thus avoiding the situation where we feel outdated. In this article, we will go through some basics of JavaScript. Enjoy!

## 1. Declarations

Think about the following code, and try to answer what gets logged (and why) without reading the explanation below.

```js
// situation 1
console.log(person);
var person = 'John';

// situation 2
console.log(person);
let person = 'Phill';

// situation 3
console.log(person);
const person = 'Frank';

// situation 4
const person = 'Vanessa';
console.log(person);
person = 'Mike';
console.log(person);

// situation 5
var person = 'John';
let person = 'Mike';
console.log(person);

// situation 6
var person = 'John';
if (person) {
  let person = 'Mike';
  console.log(person);
}
console.log(person);
```
Explanation


> __Situation 1:__ The expected result here would be to see the text `John` written in the console, but surprisingly, we see `undefined` gets logged instead. Wonder why? 

Well, here we can see the classic JavaScript in action. This behavior is called __hoisting__. Under the hood, the language splits the variable declaration and value assignment into two pieces. The variables are moved to the top, declared with the value set to `undefined` (hoisted), regardlessly of where they were initially declared by a developer. It looks something like this:

```js
var person;
console.log(person);
person = 'John';
```

> __Situation 2:__ Here, the result will be a reference error.

`Uncaught ReferenceError: Cannot access 'person' before initialization`

The error text speaks for itself. Because we used the keyword `let`, our variable is hoisted but remained uninitialized, and the error gets thrown informing us that we are trying to access an uninitialized variable. The `let` keyword was introduced in ES6 enabling us to use block-scoped variables thus helping us prevent unintended behavior.

> __Situation 3:__ Here, we have the same error as in the __Situation 2__.

The difference is that we've used the keyword `const`, thus preventing re-assigning our variable after initialization. This keyword was also introduced in ES6.

> __Situation 4:__ In this case, we can see how the keyword `const` is useful and how it can save us from unintentionally re-assigning our variable. In our example, first, we will see `Vanessa` written in the console, and then a type error.

`Uncaught TypeError: Assignment to constant variable`

The usefulness of `const` variables grows exponentially with our codebase.

> __Situation 5:__ If a variable has already been defined inside a certain scope with the keyword `var`, trying to declare it again with the keyword `let` inside the same scope throws an error.

So, in our example, nothing will be logged and we will see a syntax error.

`Uncaught SyntaxError: Identifier 'person' has already been declared`

> __Situation 6:__ We have a function-scoped variable first and block-scoped variable second. In this case, it doesn't matter if they have the same name/identifier.

In the console, we should see `Mike` and `John` getting logged, in that order. Why?

Because the keyword `let` gives us the block-scoped variables, meaning that they only exist within the scope they are created, in this case within the `if...else` statement. The inner variable takes primate over the outer variable and this is the reason why we can use the same identifier.

## 2. Inheritance

Consider the following classes and try to answer what gets logged and why.

```js
class Person {
  constructor() {
    this.sayHello = () => {
      return 'Hello';
    }
  }

  sayBye() {
    return 'Bye';
  }
}

class Student extends Person {
  sayHello() {
    return 'Hello from Student';
  }
}

const student = new Student();
console.log(student.sayHello());
```
Explanation

> If you said `Hello` you were right!

__Why__: Each time we create a new `Student` instance, we set the `sayHello` property to it to be a `function` returning the string `Hello`. This is happening in the parent (`Person`) class constructor.

Classes are syntactical sugar in JavaScript, and under the hood, in our example, the `sayHello` method in the `Student` class is defined on the prototype chain. Considering that each time we create an instance of the `Student` class we set the `sayHello` property to that instance to be a `function` returning the string `Hello`, we never get to use the function defined on the prototype chain thus we will never see the message `Hello from Student` being logged.

## 3. Object Mutability

Consider the following situations and think of each section output:

```js
// situation 1
const user = {
  name: 'John',
  surname: 'Doe'
}

user = {
  name: 'Mike'
}

console.log(user);

// situation 2
const user = {
  name: 'John',
  surname: 'Doe'
}

user.name = 'Mike';
console.log(user.name);

// situation 3
const user = {
  name: 'John',
  surname: 'Doe'
}

const anotherUser = user;
anotherUser.name = 'Mike';
console.log(user.name);

// situation 4
const user = {
  name: 'John',
  surname: 'Doe',
  address: {
    street: 'My Street'
  }
}

Object.freeze(user);

user.name = 'Mike';
user.address.street = 'My Different Street';
console.log(user.name);
console.log(user.address.street);
```

Explanation

> __Situation 1:__ Here, as we learned in the previous section, we are trying to re-assign a `const` variable that is not permitted, therefore, we will get a type error

The result in our console will be the following text:

`Uncaught TypeError: Assignment to constant variable`

> __Situation 2:__ In this scenario, we have different behavior even though we are modifying the variable declared with the keyword `const`. The difference is that we are changing the object property and not its reference, and this is allowed on `const` object variables.

The result in the console should be the word `Mike`.

> __Situation 3:__ By assigning the `user` to `anotherUser` variable we are sharing the reference, or memory location if you like, between them. In other words, both of them will point to the same object in memory, therefore, changing the property on one object will reflect the change on the other.

The result in the console should be `Mike`.

> __Situation 4:__ Here, we are using `Object.freeze` method to provide the functionality that was lacking in the previous scenario (situation 3). By using this method, we can _freeze_ our object thus not allowing for its property values to change. But there is a catch. It will only do a shallow freeze, meaning that it will not protect the deep property updates. This is the reason why we are able to mutate the street property while the name property will remain unchanged.

The output in the console should be the words `John` and `My Different Street`, in that order.


## 4. Arrow Function

What will be logged and why after running the following snippet:

```js
const student = {
  school: 'My School',
  fullName: 'John Doe',
  printName: () => {
    console.log(this.fullName);
  },
  printSchool: function () {
    console.log(this.school);
  }
};

student.printName();
student.printSchool();
```
Explanation

The output in our console will be `undefined` and `My School`, in that order.

If you are coming from the old school, you will probably be familiar with the following syntax:

```js
var me = this;
// or
var self = this;

// ...
// ...
// somewhere deep...
// me.doSomething();
```

You can think of `me` or `self` variable as the parent scope accessible for every nested function created within.

When using arrow functions, this is done for us and we no longer need to store the `this` reference in order to have access to it somewhere deeper in our code. Arrow functions do not bind their own this, instead, they inherit the one from the parent scope and this is the reason why we have `undefined` logged after invoking the `printName` function.
## 5. Destructuring

Check out the destructuring below and think about what will be logged. Is the given syntax allowed or an error will be thrown?

```js
const rawUser = {
   name: 'John',
   surname: 'Doe',
   email: 'john@doe.com',
   displayName: 'SuperCoolJohn',
   joined: '2016-05-05',
   image: 'path-to-the-image',
   followers: 45
}

let user = {}, userDetails = {};
({ name: user.name, surname: user.surname, ...userDetails } = rawUser);

console.log(user);
console.log(userDetails); 
```
Explanation

Although a bit out of the box, the syntax above is allowed and it doesn't throw an error! Pretty neat, right?

Most of us are not accustomed to the right side of expression looking like that...I mean, only the left side should contain _dot syntax_...or not? :) 

All jokes to the side, the syntax above is powerful and enables us to easily split any object into two more specific ones as shown in the example above.

The console output is:

```js
// {name: "John", surname: "Doe"}
// {email: "john@doe.com", displayName: "SuperCoolJohn", joined: "2016-05-05", image: "path-to-the-image", followers: 45}
```

## 6. Async/Await

What will be logged after the following immediate function gets invoked?

```js
(async () => {
  let result = 'Some Data';

  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve('Some data retrieved from the server'), 2000);
  });

  result = await promise;
  console.log(result);
})();
```
Explanation

If you said `Some data retrieved from the server` after 2 seconds, you were right!

The code is paused until the promise gets resolved. After two seconds, it continues and logs the given text. This means that the JavaScript engine will literally wait until the asynchronous operation is completed. The `async/await` approach is, let's say, syntactic sugar to get the promise result. Some might say, a more readable way than `promise.then`.

## 7. The Return Statement

```js
const multiplyByTwo = (x) => {
    return
    {
        result: x * 2
    };
}
console.log(multiplyByTwo(2));  
```
Explanation

If you said `{result: 4}`, well, you were wrong. The output is `undefined`. But don't be so harsh on yourself, it bugged me too, considering that I write C# as well and this is not a problem there.

The code above will return `undefined` due to [Automatic Semicolon Insertion](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return#Automatic_Semicolon_Insertion) which says that __no line terminator is allowed between the return keyword and the expression__

The solution would be to fix our function and write it in one of the following ways:

```js
const multiplyByTwo = (x) => {
    return {
        result: x * 2
    };
}
```

or

```js
const multiplyByTwo = (x) => {
  return (
    {
      result: x * 2
    }
  );
}
```

## Conclusion

That's it for this session. I hope you liked it and if so, follow me on [twitter](https://twitter.com/protic_milos), or subscribe to [devinduct](https://devinduct.com/) to stay tuned.