Tricky JavaScript Questions
Tags: javascript, career, webdev, interview
Published: 2020-10-07 10:02:03

As part of my journey to become a better JavaScript programmer, I need to dive deep into JavaScript foundations. In this article, I'll show you mind-boggling questions (for me, it was mind-boggling, I hope for you as well) that we can learn some of the concepts behind these questions.

Before we start, I want to mention some of the resources I used for writing this article, and I highly recommend you to use them as well:
1. [70 JavaScript Interview Questions](https://dev.to/macmacky/70-javascript-interview-questions-5gfi) - Excellent article 
that you can learn a lot about JavaScript foundations.
2. [What Makes Javascript Weird...and AWESOME](https://www.youtube.com/playlist?list=PLoYCgNOIyGABI011EYc-avPOsk1YsMUe_) - I found this Youtube playlist, In my opinion, the explanations are very understandable, and he shows visual code examples.
3. [What the heck is the event loop anyway? | Philip Roberts | JSConf EU](https://youtu.be/8aGhZQkoFbQ) - One of the most famous JavaScript videos recently. He explains how JavaScript works "Behind the scenes" (how the event loop works).

Of course, this is only some of the resources on the subject. There are many other resources to learn from.

So are you ready to get your mind blow away (from JavaScript question)?

![Alt Text](https://media.giphy.com/media/2AsEweF761Dji/giphy.gif)

## Questions

**Notice 1!**: To each question, there is an answer with an explanation (link below each item).
**Notice 2!**: If you run the questions on the console, remember that some of the variables are repeating themselves, so do refresh from question to question.
**Notice 3!**: For each question think what will be the output.
<a name="Question-1"></a>
{% details Question 1 %} 
```javascript
var a = 1
function foo(){
 var a = 2
 console.log(a)
}
foo()
console.log(a);
```
{% enddetails %}
[Go to answer 1](#Answer-1)
<a name="Question-2"></a>
{% details Question 2 %}
```javascript
function foo(){
    a = 2
  }
  foo()
  console.log(a);
```
{% enddetails %}
[Go to answer 2](#Answer-2)
<a name="Question-3"></a>
{% details Question 3 %}
```javascript
var answer = 0;

const baseValue = value => multipleValue => value * multipleValue;

const multiple = baseValue(2);
answer = multiple(5);
console.log(answer);
```
{% enddetails %}
[Go to answer 3](#Answer-3)
<a name="Question-4"></a>
{% details Question 4 %}
```javascript
function outerFunc(outerParam) {
  function innerFunc(innerParam) {
     outerParam["b"] = innerParam;
  }
  return innerFunc;
}

const obj = {a:1}
const example = outerFunc(obj);
const answer = example(2)
console.log(obj);
```
{% enddetails %}
[Go to answer 4](#Answer-4)
<a name="Question-5"></a>
{% details Question 5 %}
```javascript
let arr =[1,2]
function test(array){
  array.push(3)
}
test(arr)
console.log(arr)
```
{% enddetails %}
[Go to answer 5](#Answer-5)
<a name="Question-6"></a>
{% details Question 6 %}
```javascript
let arr =[1,2]
function test(array){
  array.push(3)
}
test([...arr])
console.log(arr)
```
{% enddetails %}
[Go to answer 6](#Answer-6)
<a name="Question-7"></a>
{% details Question 7 %}
```javascript
let arr =[1,2]
function test(array){
  array = [1,2,3]
}
test(arr)
console.log(arr)
```
{% enddetails %}
[Go to answer 7](#Answer-7)
<a name="Question-8"></a>
{% details Question 8 %}
```javascript
const carDetails = {
    name: "Tomer",
    getName(){
       return this.name;
    },
  };
  var name = "Joe";
  var getCarName = carDetails.getName;
  console.log(getCarName());
```
{% enddetails %}
[Go to answer 8](#Answer-8)
<a name="Question-9"></a>
{% details Question 9 %}
```javascript
console.log(a)
console.log(b)
var a = 2
let b = 2
```
{% enddetails %}
[Go to answer 9](#Answer-9)
<a name="Question-10"></a>
{% details Question 10 %}
```javascript
a()
function a(){
    console.log("a")
}
b();
var b =function(){
    console.log("b")
}
```
{% enddetails %}
[Go to answer 10](#Answer-10)
## Answers
<a name="Answer-1"></a>
### Answer To Question 1 
I think the answer is pretty straightforward. If you said `2` and `1`, you are correct. This question is about **Scope**. In JavaScript, there are two types of scopes: **Global Scope and Local Scope**, variables declared within a JavaScript function become local, and variables declared outside of the function become global. 
The `var a = 1` declared out of the function and saved in global memory. The `var a = 2` declared inside the function and saved in local memory. **it's a different place in memory** (even if they have the same name).

[Back to question 1](#Question-1)
<a name="Answer-2"></a>
### Answer To Question 2
If you said `a is not defined,` you have healthy thinking, but the **answer is `2`**. This is why JavaScript is a unique language. According to the logic we talked about in the previous question, the variables should be in local scope, **But, if you pay attention, the variables didn't declare (without `var`, `let`, `const`). When we do assignments without declarations in JavaSacript (`a=2`), the compiler will save the variable in the global scope**. FYI, we can fix this behavior by add `"use strict"`.

[Back to question 2](#Question-2)
<a name="Answer-3"></a>
### Answer To Question 3
The answer is `10`. This question is about **Closures**. In simple words - Closures are functions that return another function, and the inner function has access to the outer variables function (You can read more [here](https://www.tutorialsteacher.com/javascript/closure-in-javascript)). We can look at Closures like Global scope (outer function) and Local scope (inner function) that leaves inside the local scope (`baseValue`). Like regular Scope in JavaScript, the Local scope has access to Global Scope. For that reason, the compiler can know what is `value`. 
FYI, This doesn't seem like a "conservative" Closure example because it's writing in ES5 syntax (arrow function). The "conservative" looks like:
```javascript
var answer = 0;

function baseValue(value){
   return function(multipleValue){
      return value * multipleValue;
   }
}

const multiple = baseValue(2);
answer = multiple(5);
console.log(answer);
```

[Back to question 3](#Question-3)
<a name="Answer-4"></a>
### Answer To Question 4
The answer is `{a: 1,b: 2}`. After the previous question, we can recognize it's a Closure, but this question is also about **References**. In JavaScript, **there are two kinds of variables types: primitives variables (strings, numbers, and booleans) and References variables (arrays and objects).** Primitives variables save in memory in their values, and references save in memory as virtual id. For that reason, when we pass the object from function to function, we actually pass the virtual id. In our case, the compiler saved the `obj` and saw we call the reference again by `outerParam["b"] = innerParam.` Hence, he added to the object key `b` and value `2` (value of innerParam).
In the case of  primitives variables like:
```javascript
function outerFunc(outerParam) {
  function innerFunc(innerParam) {
     outerParam = innerParam;
  }
  return innerFunc;
}

const num = 1
const example = outerFunc(num);
const answer = example(2)
console.log(num);
```
The `num` will still be `1` (but the outerParam will be 2).

[Back to question 4](#Question-4)
<a name="Answer-5"></a>
### Answer To Question 5
The answer is `[1,2,3]`, arrays are References (full explanation in the previous answer).

[Back to question 5](#Question-5)
<a name="Answer-6"></a>
### Answer To Question 6
The answer is `[1,2]`. I used the ES6 "Spread Operator,"  it's basically the same do `test([1,2,3])`. In this way, we created a new array (new reference) and `arr` reference saved in different id - **we didn't change the reference just added another one**.

[Back to question 6](#Question-6)
<a name="Answer-7"></a>
### Answer To Question 7
The answer is `[1,2]`. I know that after all the explanations on references, it seems weird. Still, there is a good reason for it, **The `=` Operator creates a new reference** (you can look in [this discussion](https://stackoverflow.com/questions/44397580/does-array-assignment-create-a-new-reference) for more information), The `array` exist in the local scope and don't influence the global variables in this case. 
If the code was like:
```javascript
let arr =[1,2]
function test(array){
  arr = [1,2,3]
}
test(arr)
console.log(arr)
```
The answer was `[1,2,3]` because, in this case, **we replaced the global variable (`arr`) with a new reference.**

[Back to question 7](#Question-7)
<a name="Answer-8"></a>
### Answer To Question 8
The answer is `Joe`. The question's subject is "Context"(`this`). In JavaScript, **`this` is the object that is called to the function**. When we do `var getCarName = carDetails.getName;` we store the function in the global scope, So this will be `Window,` and because we set `name` in the global scope (window), the output will be `Joe` (same as window.name). This is JavaScript's default behavior. If you want to change this behavior, you can use: bind, apply, call, and arrow functions.

[Back to question 8](#Question-8)
<a name="Answer-9"></a>
### Answer To Question 9
If you said `undefined` and `b is not defined` (error), congratulation, you know **Hoisting**. In simple words, hoisting is the way the compiler defines the variables. When the function executes, **the compiler looks for variables declaration, and if the variable were declared, it would hoist it to the top.** it's the same as:
```javascript
var a;
console.log(a)
a = 2
```
**It only works on `var`**. `let` and `const` **is not** "hoisting" variables. This is why we will see the error: `b is not defined.`

[Back to question 9](#Question-9)
<a name="Answer-10"></a>
### Answer To Question 10
The answer is `a` and `b is not a function` (error). This is a very wried part of JavaScript (in my point of view) - **functions are hoisted as well.** If you read the last answer, you will understand that `var` is also hoisted, **but it doesn't matter what will be after the `=` operator. In the hoisting stage, he will always be `undefined`**. So when we do `b()`, it's the same as `undefined().`

[Back to question 10](#Question-10)

Thank you for reading this article. I hope you enjoyed and learned new things. If you have any questions or suggestions, please leave a comment.