A JavaScript Quiz — Explained

In this story, I am going to explain the 14 questions that appeared in the quiz http://perfectionkills.com/javascript-quiz/.

Do the quiz first. Then read this story.

Table Of Contents

  1. Questions
  2. Finally: Thank You!

#Questions

#Q1

(function () {
    return typeof arguments;
})();

Here, an IIFE (Immediately-Invoked Function Expression) is defined. IIFE means, the function will invoke immediately.

“arguments” is an array that holds all the arguments of the function. In this case, the function returns typeof arguments. Everyone knows it, type of an array is “object”.

#Q2

var f = function g() {
    return 23;
};
typeof g();

Here, a variable named f is defined. And its value is set to a function named g. We have to note one thing. g is defined but then assigned to f. So, g is undefined now.

So running g() will throw an error.

#Q3

(function (x) {
    delete x;
    return x;
})(1);

Here, again we encounter another IIFE. In this function, the “delete” keyword is used with the parameter x. But

delete is only effective on an object’s properties.
MDN(@)

So, the “delete” operator stays silent here and 1 is returned as x’s value.

#Q4

var y = 1,
    x = (y = typeof x);
x;

Here, y is defined and set to 1. Then x, y is set to the type of x. It is executed from right to left. That means x is undefined in the “typeof x” statement. So typeof undefined is “undefined” and that will be set to y. What about x then? x’s value is also undefined.

Because,

The assignment operation evaluates to the assigned value.
MDN(@)

#Q5 (My favorite one)

(function f(f) {
    return typeof f();
})(function () {
    return 1;
});

Here, another IIFE. A function f is defined. f expects a parameter named f. To avoid confusion, I will refer to the function f as $f and the parameter f as _f. Then in the second line, the function is returning the typeof f().

But, What does f() mean? $f or _f ?. Variables are searched in the local scope first. If it's not defined in the local scope, then the parent scope is searched. This search is continued until the variable is found or there is no parent scope.

So in this case, _f is available in the local scope (scope under $f). So, _f is called.

What is _f? _f is the first parameter passed to the function $f. In this case, it's the function that returns 1. So, _f() is 1. typeof 1 is "number". We all know that.

#Q6

var foo = {
    bar: function () {
        return this.baz;
    },
    baz: 1,
};
(function () {
    return typeof arguments[0]();
})(foo.bar);

IIFE again. Here a variable named foo is defined and set to that object.

The object (foo) has 2 keys bar & baz. baz is 1. bar is a function that returns baz. In this case, 1. (this points to the object foo).

Then comes the IIFE. The function returns the type of the value returned by its (first argument) function. The first argument is foo.bar. foo.bar returns this.baz. What does this mean here? Does it point to foo or something else?

this keyword is a tricky one. I am not going to even try to explain it. To be honest, I don't understand it enough either. I just think of it as the "parent context". If the function is called normally, it points to globalThis. If it is called as a method of an object, this points to the object. To learn more about this in JavaScript, take a look at the Reference page of this on MDN.

Here, arguments[0] is called normally. So, this points to globalThis now. Whether it is window or global, baz is not defined. Hence, it returns undefined. Finally, the IIFE returns "undefined".

#Q7

var foo = {
    bar: function () {
        return this.baz;
    },
    baz: 1,
};
typeof (f = foo.bar)();

This question is also like the previous one. foo is defined with the same value as of #6.

Here, a variable named f gets defined and set to foo.bar. As I have mentioned for #4, we know that, (f = foo.bar) evaluates to f. Now f wil be executed.

f is being called from the global context. Thus, inside f, this is globalThis. globalThis.baz is undefined. So again, the typeof undefined is “undefined”.

#Q8

var f = (function f() {
    return "1";
},
function g() {
    return 2;
})();
typeof f;

The comma operator is used here. Never heard of the comma operator?

The comma operator (,) evaluates each of its operands (from left to right) and returns the value of the last operand.
MDN(@)

As of MDN’s statement, the comma operator evaluates each operand and returns the rightmost value. In this case, g is the rightmost value. So the value of the variable f is the return value of function g. g returns 2. So f is 2. Therefore typeof f is “number”.

#Q9

var x = 1;
if (function f() {}) {
    x += typeof f;
}
x;

In this question, we have to find the value of x at the end. When x is defined, it is 1. Then there is an if block. It checks if “function f() {}” is truthy.

In JavaScript, a truthy value is a value that is considered true when encountered in a Boolean context. All values are truthy unless they are defined as falsy (i.e., except for false, 0, -0, 0n, "", null, undefined, and NaN).
MDN(@)

So, the function is truthy. Now, typeof f gets added to x. Is that "function"? That's what I thought, at first. But turns out it's not.

The Identifier in a FunctionExpression can be referenced from inside the FunctionExpression's FunctionBody to allow the function to call itself recursively. However, unlike in a FunctionDeclaration, the Identifier in a FunctionExpression cannot be referenced from and does not affect the scope enclosing the FunctionExpression.
ECMAScript Specification(@)

If you don't understand (which is totally fine),
If the function is defined in the condition of if block, it's a FunctionExpression. The Identifier in the expression (which is the function name, in this case, f), cannot be the referenced from that scope.

This means, variable f is undefined inside the if block.

#Q10 (Easiest in my opinion)

var x = [typeof x, typeof y][1];
typeof typeof x;

x is defined as the typeof y. y is, obviously undefined. So, x is "undefined".

typeof x is string. typeof "string", is again, "string".

#Q11

(function (foo) {
    return typeof foo.bar;
})({ foo: { bar: 1 } });

Another IIFE!

Inside the function, foo is equal to { foo: { bar: 1 }}. foo.bar is obviously undefined. typeof undefined is, again, "undefined"

I don't feel like this question is good enough to be put in this quiz.

#Q12

(function f() {
    function f() {
        return 1;
    }
    return f();
    function f() {
        return 2;
    }
})();

IIFE again. Here a function named “f” is defined (which I will refer to as f1). Inside the function, two functions are defined with the same name “f”. The first function (which I will refer to as f2) returns 1. The second function (which I will refer to as f3) returns 2.

Generally, JavaScript is interpreted. It is read and executed line by line, from top to bottom. Based on this fact, you might have thought that the declaration of f3 is unreachable, because, f1 returns early. And the return value would be f2(). But that's not the case here.

There is a thing called, "Function Hoisting".

Function declarations in JavaScript are hoisted to the top of the enclosing function or global scope.
MDN(@)

Because of this, f3 gets put after the f2 and before the return statement. Now, when the interpreter start executing the code, f (inside the f1's scope), is set to f2 and then gets overridden by the f3. That's why f() returns 2.

#Q13

function f() {
    return f;
}
new f() instanceof f;
The instanceof operator tests whether the prototype property of a constructor appears anywhere in the prototype chain of an object.
MDN(@)

I didn’t understand it. Explain it to me, please.

#Q14

with (function (x, undefined) {}) length;

If you didn’t understand the with statement, see below.

The with statement extends the scope chain for a statement.
MDN(@)

We can think the question like this (function(x, undefined)).length

It evaluates the function’s length. But what does Function.length return?

The length property indicates the number of parameters expected by the function.
MDN(@)

In this case, The function expects 2 parameters. So the length property returns 2.

#Finally: Thank You!

I hope you find this explanation useful. Let me know if you have got any feedback.