Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A long list of (advanced) JavaScript questions, and their explanations ✨

License

NotificationsYou must be signed in to change notification settings

lydiahallie/javascript-questions

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JavaScript Questions

Note

This repo was created in 2019 and the questions provided here are therefore based on the JavaScript syntax and behavior at that time. Since JavaScript is a constantly evolving language, there are newer language features that are not covered by the questions here.


From basic to advanced: test how well you know JavaScript, refresh your knowledge a bit or prepare for your coding interview! 💪 🚀 I update this repo regularly with new questions. I added the answers in the **collapsed sections** below the questions, simply click on them to expand it. It's just for fun, good luck! ❤️

Feel free to reach out to me! 😊

Instagram ||Twitter ||LinkedIn ||Blog

Feel free to use them in a project! 😃 I wouldreally appreciate a reference to this repo, I create the questions and explanations (yes I'm sad lol) and the community helps me so much to maintain and improve it! 💪🏼 Thank you and have fun!
See 20 Available Translations 🇸🇦🇪🇬🇧🇦🇩🇪🇪🇸🇫🇷🇮🇩🇯🇵🇰🇷🇳🇱🇧🇷🇷🇺🇹🇭🇹🇷🇺🇦🇻🇳🇨🇳🇹🇼🇽🇰


1. What's the output?
functionsayHi(){console.log(name);console.log(age);varname='Lydia';letage=21;}sayHi();
  • A:Lydia andundefined
  • B:Lydia andReferenceError
  • C:ReferenceError and21
  • D:undefined andReferenceError
Answer

Answer: D

Within the function, we first declare thename variable with thevar keyword. This means that the variable gets hoisted (memory space is set up during the creation phase) with the default value ofundefined, until we actually get to the line where we define the variable. We haven't defined the variable yet on the line where we try to log thename variable, so it still holds the value ofundefined.

Variables with thelet keyword (andconst) are hoisted, but unlikevar, don't getinitialized. They are not accessible before the line we declare (initialize) them. This is called the "temporal dead zone". When we try to access the variables before they are declared, JavaScript throws aReferenceError.


2. What's the output?
for(vari=0;i<3;i++){setTimeout(()=>console.log(i),1);}for(leti=0;i<3;i++){setTimeout(()=>console.log(i),1);}
  • A:0 1 2 and0 1 2
  • B:0 1 2 and3 3 3
  • C:3 3 3 and0 1 2
Answer

Answer: C

Because of the event queue in JavaScript, thesetTimeout callback function is calledafter the loop has been executed. Since the variablei in the first loop was declared using thevar keyword, this value was global. During the loop, we incremented the value ofi by1 each time, using the unary operator++. By the time thesetTimeout callback function was invoked,i was equal to3 in the first example.

In the second loop, the variablei was declared using thelet keyword: variables declared with thelet (andconst) keyword are block-scoped (a block is anything between{ }). During each iteration,i will have a new value, and each value is scoped inside the loop.


3. What's the output?
constshape={radius:10,diameter(){returnthis.radius*2;},perimeter:()=>2*Math.PI*this.radius,};console.log(shape.diameter());console.log(shape.perimeter());
  • A:20 and62.83185307179586
  • B:20 andNaN
  • C:20 and63
  • D:NaN and63
Answer

Answer: B

Note that the value ofdiameter is a regular function, whereas the value ofperimeter is an arrow function.

With arrow functions, thethis keyword refers to its current surrounding scope, unlike regular functions! This means that when we callperimeter, it doesn't refer to the shape object, but to its surrounding scope (window for example).

Since there is no valueradius in the scope of the arrow function,this.radius returnsundefined which, when multiplied by2 * Math.PI, results inNaN.


4. What's the output?
+true;!'Lydia';
  • A:1 andfalse
  • B:false andNaN
  • C:false andfalse
Answer

Answer: A

The unary plus tries to convert an operand to a number.true is1, andfalse is0.

The string'Lydia' is a truthy value. What we're actually asking, is "Is this truthy value falsy?". This returnsfalse.


5. Which one is true?
constbird={size:'small',};constmouse={name:'Mickey',small:true,};
  • A:mouse.bird.size is not valid
  • B:mouse[bird.size] is not valid
  • C:mouse[bird["size"]] is not valid
  • D: All of them are valid
Answer

Answer: A

In JavaScript, all object keys are strings (unless it's a Symbol). Even though we might nottype them as strings, they are always converted into strings under the hood.

JavaScript interprets (or unboxes) statements. When we use bracket notation, it sees the first opening bracket[ and keeps going until it finds the closing bracket]. Only then, it will evaluate the statement.

mouse[bird.size]: First it evaluatesbird.size, which is"small".mouse["small"] returnstrue

However, with dot notation, this doesn't happen.mouse does not have a key calledbird, which means thatmouse.bird isundefined. Then, we ask for thesize using dot notation:mouse.bird.size. Sincemouse.bird isundefined, we're actually askingundefined.size. This isn't valid, and will throw an error similar toCannot read property "size" of undefined.


6. What's the output?
letc={greeting:'Hey!'};letd;d=c;c.greeting='Hello';console.log(d.greeting);
  • A:Hello
  • B:Hey!
  • C:undefined
  • D:ReferenceError
  • E:TypeError
Answer

Answer: A

In JavaScript, all objects interact byreference when setting them equal to each other.

First, variablec holds a value to an object. Later, we assignd with the same reference thatc has to the object.

When you change one object, you change all of them.


7. What's the output?
leta=3;letb=newNumber(3);letc=3;console.log(a==b);console.log(a===b);console.log(b===c);
  • A:truefalsetrue
  • B:falsefalsetrue
  • C:truefalsefalse
  • D:falsetruetrue
Answer

Answer: C

new Number() is a built-in function constructor. Although it looks like a number, it's not really a number: it has a bunch of extra features and is an object.

When we use the== operator (Equality operator), it only checks whether it has the samevalue. They both have the value of3, so it returnstrue.

However, when we use the=== operator (Strict equality operator), both valueand type should be the same. It's not:new Number() is not a number, it's anobject. Both returnfalse.


8. What's the output?
classChameleon{staticcolorChange(newColor){this.newColor=newColor;returnthis.newColor;}constructor({ newColor='green'}={}){this.newColor=newColor;}}constfreddie=newChameleon({newColor:'purple'});console.log(freddie.colorChange('orange'));
  • A:orange
  • B:purple
  • C:green
  • D:TypeError
Answer

Answer: D

ThecolorChange function is static. Static methods are designed to live only on the constructor in which they are created, and cannot be passed down to any children or called upon class instances. Sincefreddie is an instance of class Chameleon, the function cannot be called upon it. ATypeError is thrown.


9. What's the output?
letgreeting;greetign={};// Typo!console.log(greetign);
  • A:{}
  • B:ReferenceError: greetign is not defined
  • C:undefined
Answer

Answer: A

It logs the object, because we just created an empty object on the global object! When we mistypedgreeting asgreetign, the JS interpreter actually saw this as:

  1. global.greetign = {} in Node.js
  2. window.greetign = {},frames.greetign = {} andself.greetign in browsers.
  3. self.greetign in web workers.
  4. globalThis.greetign in all environments.

In order to avoid this, we can use"use strict". This makes sure that you have declared a variable before setting it equal to anything.


10. What happens when we do this?
functionbark(){console.log('Woof!');}bark.animal='dog';
  • A: Nothing, this is totally fine!
  • B:SyntaxError. You cannot add properties to a function this way.
  • C:"Woof" gets logged.
  • D:ReferenceError
Answer

Answer: A

This is possible in JavaScript, because functions are objects! (Everything besides primitive types are objects)

A function is a special type of object. The code you write yourself isn't the actual function. The function is an object with properties. This property is invocable.


11. What's the output?
functionPerson(firstName,lastName){this.firstName=firstName;this.lastName=lastName;}constmember=newPerson('Lydia','Hallie');Person.getFullName=function(){return`${this.firstName}${this.lastName}`;};console.log(member.getFullName());
  • A:TypeError
  • B:SyntaxError
  • C:Lydia Hallie
  • D:undefinedundefined
Answer

Answer: A

In JavaScript, functions are objects, and therefore, the methodgetFullName gets added to the constructor function object itself. For that reason, we can callPerson.getFullName(), butmember.getFullName throws aTypeError.

If you want a method to be available to all object instances, you have to add it to the prototype property:

Person.prototype.getFullName=function(){return`${this.firstName}${this.lastName}`;};


12. What's the output?
functionPerson(firstName,lastName){this.firstName=firstName;this.lastName=lastName;}constlydia=newPerson('Lydia','Hallie');constsarah=Person('Sarah','Smith');console.log(lydia);console.log(sarah);
  • A:Person {firstName: "Lydia", lastName: "Hallie"} andundefined
  • B:Person {firstName: "Lydia", lastName: "Hallie"} andPerson {firstName: "Sarah", lastName: "Smith"}
  • C:Person {firstName: "Lydia", lastName: "Hallie"} and{}
  • D:Person {firstName: "Lydia", lastName: "Hallie"} andReferenceError
Answer

Answer: A

Forsarah, we didn't use thenew keyword. When usingnew,this refers to the new empty object we create. However, if you don't addnew,this refers to theglobal object!

We said thatthis.firstName equals"Sarah" andthis.lastName equals"Smith". What we actually did, is definingglobal.firstName = 'Sarah' andglobal.lastName = 'Smith'.sarah itself is leftundefined, since we don't return a value from thePerson function.


13. What are the three phases of event propagation?
  • A: Target > Capturing > Bubbling
  • B: Bubbling > Target > Capturing
  • C: Target > Bubbling > Capturing
  • D: Capturing > Target > Bubbling
Answer

Answer: D

During thecapturing phase, the event goes through the ancestor elements down to the target element. It then reaches thetarget element, andbubbling begins.


14. All object have prototypes.
  • A: true
  • B: false
Answer

Answer: B

All objects have prototypes, except for thebase object. The base object is the object created by the user, or an object that is created using thenew keyword. The base object has access to some methods and properties, such as.toString. This is the reason why you can use built-in JavaScript methods! All of such methods are available on the prototype. Although JavaScript can't find it directly on your object, it goes down the prototype chain and finds it there, which makes it accessible for you.


15. What's the output?
functionsum(a,b){returna+b;}sum(1,'2');
  • A:NaN
  • B:TypeError
  • C:"12"
  • D:3
Answer

Answer: C

JavaScript is adynamically typed language: we don't specify what types certain variables are. Values can automatically be converted into another type without you knowing, which is calledimplicit type coercion.Coercion is converting from one type into another.

In this example, JavaScript converts the number1 into a string, in order for the function to make sense and return a value. During the addition of a numeric type (1) and a string type ('2'), the number is treated as a string. We can concatenate strings like"Hello" + "World", so what's happening here is"1" + "2" which returns"12".


16. What's the output?
letnumber=0;console.log(number++);console.log(++number);console.log(number);
  • A:112
  • B:122
  • C:022
  • D:012
Answer

Answer: C

Thepostfix unary operator++:

  1. Returns the value (this returns0)
  2. Increments the value (number is now1)

Theprefix unary operator++:

  1. Increments the value (number is now2)
  2. Returns the value (this returns2)

This returns0 2 2.


17. What's the output?
functiongetPersonInfo(one,two,three){console.log(one);console.log(two);console.log(three);}constperson='Lydia';constage=21;getPersonInfo`${person} is${age} years old`;
  • A:"Lydia"21["", " is ", " years old"]
  • B:["", " is ", " years old"]"Lydia"21
  • C:"Lydia"["", " is ", " years old"]21
Answer

Answer: B

If you use tagged template literals, the value of the first argument is always an array of the string values. The remaining arguments get the values of the passed expressions!


18. What's the output?
functioncheckAge(data){if(data==={age:18}){console.log('You are an adult!');}elseif(data=={age:18}){console.log('You are still an adult.');}else{console.log(`Hmm.. You don't have an age I guess`);}}checkAge({age:18});
  • A:You are an adult!
  • B:You are still an adult.
  • C:Hmm.. You don't have an age I guess
Answer

Answer: C

When testing equality, primitives are compared by theirvalue, while objects are compared by theirreference. JavaScript checks if the objects have a reference to the same location in memory.

The two objects that we are comparing don't have that: the object we passed as a parameter refers to a different location in memory than the object we used in order to check equality.

This is why both{ age: 18 } === { age: 18 } and{ age: 18 } == { age: 18 } returnfalse.


19. What's the output?
functiongetAge(...args){console.log(typeofargs);}getAge(21);
  • A:"number"
  • B:"array"
  • C:"object"
  • D:"NaN"
Answer

Answer: C

The rest parameter (...args) lets us "collect" all remaining arguments into an array. An array is an object, sotypeof args returns"object"


20. What's the output?
functiongetAge(){'use strict';age=21;console.log(age);}getAge();
  • A:21
  • B:undefined
  • C:ReferenceError
  • D:TypeError
Answer

Answer: C

With"use strict", you can make sure that you don't accidentally declare global variables. We never declared the variableage, and since we use"use strict", it will throw a reference error. If we didn't use"use strict", it would have worked, since the propertyage would have gotten added to the global object.


21. What's the value ofsum?
constsum=eval('10*10+5');
  • A:105
  • B:"105"
  • C:TypeError
  • D:"10*10+5"
Answer

Answer: A

eval evaluates code that's passed as a string. If it's an expression, like in this case, it evaluates the expression. The expression is10 * 10 + 5. This returns the number105.


22. How long is cool_secret accessible?
sessionStorage.setItem('cool_secret',123);
  • A: Forever, the data doesn't get lost.
  • B: When the user closes the tab.
  • C: When the user closes the entire browser, not only the tab.
  • D: When the user shuts off their computer.
Answer

Answer: B

The data stored insessionStorage is removed after closing thetab.

If you usedlocalStorage, the data would've been there forever, unless for examplelocalStorage.clear() is invoked.


23. What's the output?
varnum=8;varnum=10;console.log(num);
  • A:8
  • B:10
  • C:SyntaxError
  • D:ReferenceError
Answer

Answer: B

With thevar keyword, you can declare multiple variables with the same name. The variable will then hold the latest value.

You cannot do this withlet orconst since they're block-scoped and therefore can't be redeclared.


24. What's the output?
constobj={1:'a',2:'b',3:'c'};constset=newSet([1,2,3,4,5]);obj.hasOwnProperty('1');obj.hasOwnProperty(1);set.has('1');set.has(1);
  • A:falsetruefalsetrue
  • B:falsetruetruetrue
  • C:truetruefalsetrue
  • D:truetruetruetrue
Answer

Answer: C

All object keys (excluding Symbols) are strings under the hood, even if you don't type it yourself as a string. This is whyobj.hasOwnProperty('1') also returns true.

It doesn't work that way for a set. There is no'1' in our set:set.has('1') returnsfalse. It has the numeric type1,set.has(1) returnstrue.


25. What's the output?
constobj={a:'one',b:'two',a:'three'};console.log(obj);
  • A:{ a: "one", b: "two" }
  • B:{ b: "two", a: "three" }
  • C:{ a: "three", b: "two" }
  • D:SyntaxError
Answer

Answer: C

If you have two keys with the same name, the key will be replaced. It will still be in its first position, but with the last specified value.


26. The JavaScript global execution context creates two things for you: the global object, and the "this" keyword.
  • A: true
  • B: false
  • C: it depends
Answer

Answer: A

The base execution context is the global execution context: it's what's accessible everywhere in your code.


27. What's the output?
for(leti=1;i<5;i++){if(i===3)continue;console.log(i);}
  • A:12
  • B:123
  • C:124
  • D:134
Answer

Answer: C

Thecontinue statement skips an iteration if a certain condition returnstrue.


28. What's the output?
String.prototype.giveLydiaPizza=()=>{return'Just give Lydia pizza already!';};constname='Lydia';console.log(name.giveLydiaPizza())
  • A:"Just give Lydia pizza already!"
  • B:TypeError: not a function
  • C:SyntaxError
  • D:undefined
Answer

Answer: A

String is a built-in constructor, that we can add properties to. I just added a method to its prototype. Primitive strings are automatically converted into a string object, generated by the string prototype function. So, all strings (string objects) have access to that method!


29. What's the output?
consta={};constb={key:'b'};constc={key:'c'};a[b]=123;a[c]=456;console.log(a[b]);
  • A:123
  • B:456
  • C:undefined
  • D:ReferenceError
Answer

Answer: B

Object keys are automatically converted into strings. We are trying to set an object as a key to objecta, with the value of123.

However, when we stringify an object, it becomes"[object Object]". So what we are saying here, is thata["[object Object]"] = 123. Then, we can try to do the same again.c is another object that we are implicitly stringifying. So then,a["[object Object]"] = 456.

Then, we loga[b], which is actuallya["[object Object]"]. We just set that to456, so it returns456.


30. What's the output?
constfoo=()=>console.log('First');constbar=()=>setTimeout(()=>console.log('Second'));constbaz=()=>console.log('Third');bar();foo();baz();
  • A:FirstSecondThird
  • B:FirstThirdSecond
  • C:SecondFirstThird
  • D:SecondThirdFirst
Answer

Answer: B

We have asetTimeout function and invoked it first. Yet, it was logged last.

This is because in browsers, we don't just have the runtime engine, we also have something called aWebAPI. TheWebAPI gives us thesetTimeout function to start with, and for example the DOM.

After thecallback is pushed to the WebAPI, thesetTimeout function itself (but not the callback!) is popped off the stack.

Now,foo gets invoked, and"First" is being logged.

foo is popped off the stack, andbaz gets invoked."Third" gets logged.

The WebAPI can't just add stuff to the stack whenever it's ready. Instead, it pushes the callback function to something called thequeue.

This is where an event loop starts to work. Anevent loop looks at the stack and task queue. If the stack is empty, it takes the first thing on the queue and pushes it onto the stack.

bar gets invoked,"Second" gets logged, and it's popped off the stack.


31. What is the event.target when clicking the button?
<divonclick="console.log('first div')"><divonclick="console.log('second div')"><buttononclick="console.log('button')">      Click!</button></div></div>
  • A: Outerdiv
  • B: Innerdiv
  • C:button
  • D: An array of all nested elements.
Answer

Answer: C

The deepest nested element that caused the event is the target of the event. You can stop bubbling byevent.stopPropagation


32. When you click the paragraph, what's the logged output?
<divonclick="console.log('div')"><ponclick="console.log('p')">    Click here!</p></div>
  • A:pdiv
  • B:divp
  • C:p
  • D:div
Answer

Answer: A

If we clickp, we see two logs:p anddiv. During event propagation, there are 3 phases: capturing, targeting, and bubbling. By default, event handlers are executed in the bubbling phase (unless you setuseCapture totrue). It goes from the deepest nested element outwards.


33. What's the output?
constperson={name:'Lydia'};functionsayHi(age){return`${this.name} is${age}`;}console.log(sayHi.call(person,21));console.log(sayHi.bind(person,21));
  • A:undefined is 21Lydia is 21
  • B:functionfunction
  • C:Lydia is 21Lydia is 21
  • D:Lydia is 21function
Answer

Answer: D

With both, we can pass the object to which we want thethis keyword to refer to. However,.call is alsoexecuted immediately!

.bind. returns acopy of the function, but with a bound context! It is not executed immediately.


34. What's the output?
functionsayHi(){return(()=>0)();}console.log(typeofsayHi());
  • A:"object"
  • B:"number"
  • C:"function"
  • D:"undefined"
Answer

Answer: B

ThesayHi function returns the returned value of the immediately invoked function expression (IIFE). This function returned0, which is type"number".

FYI:typeof can return the following list of values:undefined,boolean,number,bigint,string,symbol,function andobject. Note thattypeof null returns"object".


35. Which of these values are falsy?
0;newNumber(0);('');(' ');newBoolean(false);undefined;
  • A:0,'',undefined
  • B:0,new Number(0),'',new Boolean(false),undefined
  • C:0,'',new Boolean(false),undefined
  • D: All of them are falsy
Answer

Answer: A

There are 8 falsy values:

  • undefined
  • null
  • NaN
  • false
  • '' (empty string)
  • 0
  • -0
  • 0n (BigInt(0))

Function constructors, likenew Number andnew Boolean are truthy.


36. What's the output?
console.log(typeoftypeof1);
  • A:"number"
  • B:"string"
  • C:"object"
  • D:"undefined"
Answer

Answer: B

typeof 1 returns"number".typeof "number" returns"string"


37. What's the output?
constnumbers=[1,2,3];numbers[10]=11;console.log(numbers);
  • A:[1, 2, 3, null x 7, 11]
  • B:[1, 2, 3, 11]
  • C:[1, 2, 3, empty x 7, 11]
  • D:SyntaxError
Answer

Answer: C

When you set a value to an element in an array that exceeds the length of the array, JavaScript creates something called "empty slots". These actually have the value ofundefined, but you will see something like:

[1, 2, 3, empty x 7, 11]

depending on where you run it (it's different for every browser, node, etc.)


38. What's the output?
(()=>{letx,y;try{thrownewError();}catch(x){(x=1),(y=2);console.log(x);}console.log(x);console.log(y);})();
  • A:1undefined2
  • B:undefinedundefinedundefined
  • C:112
  • D:1undefinedundefined
Answer

Answer: A

Thecatch block receives the argumentx. This is not the samex as the variable when we pass arguments. This variablex is block-scoped.

Later, we set this block-scoped variable equal to1, and set the value of the variabley. Now, we log the block-scoped variablex, which is equal to1.

Outside of thecatch block,x is stillundefined, andy is2. When we want toconsole.log(x) outside of thecatch block, it returnsundefined, andy returns2.


39. Everything in JavaScript is either a...
  • A: primitive or object
  • B: function or object
  • C: trick question! only objects
  • D: number or object
Answer

Answer: A

JavaScript only has primitive types and objects.

Primitive types areboolean,null,undefined,bigint,number,string, andsymbol.

What differentiates a primitive from an object is that primitives do not have any properties or methods; however, you'll note that'foo'.toUpperCase() evaluates to'FOO' and does not result in aTypeError. This is because when you try to access a property or method on a primitive like a string, JavaScript will implicitly wrap the primitive type using one of the wrapper classes, i.e.String, and then immediately discard the wrapper after the expression evaluates. All primitives except fornull andundefined exhibit this behavior.


40. What's the output?
[[0,1],[2,3]].reduce((acc,cur)=>{returnacc.concat(cur);},[1,2],);
  • A:[0, 1, 2, 3, 1, 2]
  • B:[6, 1, 2]
  • C:[1, 2, 0, 1, 2, 3]
  • D:[1, 2, 6]
Answer

Answer: C

[1, 2] is our initial value. This is the value we start with, and the value of the very firstacc. During the first round,acc is[1,2], andcur is[0, 1]. We concatenate them, which results in[1, 2, 0, 1].

Then,[1, 2, 0, 1] isacc and[2, 3] iscur. We concatenate them, and get[1, 2, 0, 1, 2, 3]


41. What's the output?
!!null;!!'';!!1;
  • A:falsetruefalse
  • B:falsefalsetrue
  • C:falsetruetrue
  • D:truetruefalse
Answer

Answer: B

null is falsy.!null returnstrue.!true returnsfalse.

"" is falsy.!"" returnstrue.!true returnsfalse.

1 is truthy.!1 returnsfalse.!false returnstrue.


42. What does thesetInterval method return in the browser?
setInterval(()=>console.log('Hi'),1000);
  • A: a unique id
  • B: the amount of milliseconds specified
  • C: the passed function
  • D:undefined
Answer

Answer: A

It returns a unique id. This id can be used to clear that interval with theclearInterval() function.


43. What does this return?
[...'Lydia'];
  • A:["L", "y", "d", "i", "a"]
  • B:["Lydia"]
  • C:[[], "Lydia"]
  • D:[["L", "y", "d", "i", "a"]]
Answer

Answer: A

A string is an iterable. The spread operator maps every character of an iterable to one element.


44. What's the output?
function*generator(i){yieldi;yieldi*2;}constgen=generator(10);console.log(gen.next().value);console.log(gen.next().value);
  • A:[0, 10], [10, 20]
  • B:20, 20
  • C:10, 20
  • D:0, 10 and 10, 20
Answer

Answer: C

Regular functions cannot be stopped mid-way after invocation. However, a generator function can be "stopped" midway, and later continue from where it stopped. Every time a generator function encounters ayield keyword, the function yields the value specified after it. Note that the generator function in that case doesn’treturn the value, ityields the value.

First, we initialize the generator function withi equal to10. We invoke the generator function using thenext() method. The first time we invoke the generator function,i is equal to10. It encounters the firstyield keyword: it yields the value ofi. The generator is now "paused", and10 gets logged.

Then, we invoke the function again with thenext() method. It starts to continue where it stopped previously, still withi equal to10. Now, it encounters the nextyield keyword, and yieldsi * 2.i is equal to10, so it returns10 * 2, which is20. This results in10, 20.


45. What does this return?
constfirstPromise=newPromise((res,rej)=>{setTimeout(res,500,'one');});constsecondPromise=newPromise((res,rej)=>{setTimeout(res,100,'two');});Promise.race([firstPromise,secondPromise]).then(res=>console.log(res));
  • A:"one"
  • B:"two"
  • C:"two" "one"
  • D:"one" "two"
Answer

Answer: B

When we pass multiple promises to thePromise.race method, it resolves/rejects thefirst promise that resolves/rejects. To thesetTimeout method, we pass a timer: 500ms for the first promise (firstPromise), and 100ms for the second promise (secondPromise). This means that thesecondPromise resolves first with the value of'two'.res now holds the value of'two', which gets logged.


46. What's the output?
letperson={name:'Lydia'};constmembers=[person];person=null;console.log(members);
  • A:null
  • B:[null]
  • C:[{}]
  • D:[{ name: "Lydia" }]
Answer

Answer: D

First, we declare a variableperson with the value of an object that has aname property.

Then, we declare a variable calledmembers. We set the first element of that array equal to the value of theperson variable. Objects interact byreference when setting them equal to each other. When you assign a reference from one variable to another, you make acopy of that reference. (note that they don't have thesame reference!)

Then, we set the variableperson equal tonull.

We are only modifying the value of theperson variable, and not the first element in the array, since that element has a different (copied) reference to the object. The first element inmembers still holds its reference to the original object. When we log themembers array, the first element still holds the value of the object, which gets logged.


47. What's the output?
constperson={name:'Lydia',age:21,};for(constiteminperson){console.log(item);}
  • A:{ name: "Lydia" }, { age: 21 }
  • B:"name", "age"
  • C:"Lydia", 21
  • D:["name", "Lydia"], ["age", 21]
Answer

Answer: B

With afor-in loop, we can iterate through object keys, in this casename andage. Under the hood, object keys are strings (if they're not a Symbol). On every loop, we set the value ofitem equal to the current key it’s iterating over. First,item is equal toname, and gets logged. Then,item is equal toage, which gets logged.


48. What's the output?
console.log(3+4+'5');
  • A:"345"
  • B:"75"
  • C:12
  • D:"12"
Answer

Answer: B

Operator associativity is the order in which the compiler evaluates the expressions, either left-to-right or right-to-left. This only happens if all operators have thesame precedence. We only have one type of operator:+. For addition, the associativity is left-to-right.

3 + 4 gets evaluated first. This results in the number7.

7 + '5' results in"75" because of coercion. JavaScript converts the number7 into a string, see question 15. We can concatenate two strings using the+operator."7" + "5" results in"75".


49. What's the value ofnum?
constnum=parseInt('7*6',10);
  • A:42
  • B:"42"
  • C:7
  • D:NaN
Answer

Answer: C

Only the first number in the string is returned. Based on theradix (the second argument in order to specify what type of number we want to parse it to: base 10, hexadecimal, octal, binary, etc.), theparseInt checks whether the characters in the string are valid. Once it encounters a character that isn't a valid number in the radix, it stops parsing and ignores the following characters.

* is not a valid number. It only parses"7" into the decimal7.num now holds the value of7.


50. What's the output?
[1,2,3].map(num=>{if(typeofnum==='number')return;returnnum*2;});
  • A:[]
  • B:[null, null, null]
  • C:[undefined, undefined, undefined]
  • D:[ 3 x empty ]
Answer

Answer: C

When mapping over the array, the value ofnum is equal to the element it’s currently looping over. In this case, the elements are numbers, so the condition of the if statementtypeof num === "number" returnstrue. The map function creates a new array and inserts the values returned from the function.

However, we don’t return a value. When we don’t return a value from the function, the function returnsundefined. For every element in the array, the function block gets called, so for each element we returnundefined.


51. What's the output?
functiongetInfo(member,year){member.name='Lydia';year='1998';}constperson={name:'Sarah'};constbirthYear='1997';getInfo(person,birthYear);console.log(person,birthYear);
  • A:{ name: "Lydia" }, "1997"
  • B:{ name: "Sarah" }, "1998"
  • C:{ name: "Lydia" }, "1998"
  • D:{ name: "Sarah" }, "1997"
Answer

Answer: A

Arguments are passed byvalue, unless their value is an object, then they're passed byreference.birthYear is passed by value, since it's a string, not an object. When we pass arguments by value, acopy of that value is created (see question 46).

The variablebirthYear has a reference to the value"1997". The argumentyear also has a reference to the value"1997", but it's not the same value asbirthYear has a reference to. When we update the value ofyear by settingyear equal to"1998", we are only updating the value ofyear.birthYear is still equal to"1997".

The value ofperson is an object. The argumentmember has a (copied) reference to thesame object. When we modify a property of the objectmember has a reference to, the value ofperson will also be modified, since they both have a reference to the same object.person'sname property is now equal to the value"Lydia"


52. What's the output?
functiongreeting(){throw'Hello world!';}functionsayHi(){try{constdata=greeting();console.log('It worked!',data);}catch(e){console.log('Oh no an error:',e);}}sayHi();
  • A:It worked! Hello world!
  • B:Oh no an error: undefined
  • C:SyntaxError: can only throw Error objects
  • D:Oh no an error: Hello world!
Answer

Answer: D

With thethrow statement, we can create custom errors. With this statement, you can throw exceptions. An exception can be astring, anumber, aboolean or anobject. In this case, our exception is the string'Hello world!'.

With thecatch statement, we can specify what to do if an exception is thrown in thetry block. An exception is thrown: the string'Hello world!'.e is now equal to that string, which we log. This results in'Oh an error: Hello world!'.


53. What's the output?
functionCar(){this.make='Lamborghini';return{make:'Maserati'};}constmyCar=newCar();console.log(myCar.make);
  • A:"Lamborghini"
  • B:"Maserati"
  • C:ReferenceError
  • D:TypeError
Answer

Answer: B

When a constructor function is called with thenew keyword, it creates an object and sets thethis keyword to refer to that object. By default, if the constructor function doesn't explicitly return anything, it will return the newly created object.

In this case, the constructor functionCar explicitly returns a new object withmake set to"Maserati", which overrides the default behavior. Therefore, whennew Car() is called, thereturned object is assigned tomyCar, resulting in the output being"Maserati" whenmyCar.make is accessed.


54. What's the output?
(()=>{letx=(y=10);})();console.log(typeofx);console.log(typeofy);
  • A:"undefined", "number"
  • B:"number", "number"
  • C:"object", "number"
  • D:"number", "undefined"
Answer

Answer: A

let x = (y = 10); is actually shorthand for:

y=10;letx=y;

When we sety equal to10, we actually add a propertyy to the global object (window in the browser,global in Node). In a browser,window.y is now equal to10.

Then, we declare a variablex with the value ofy, which is10. Variables declared with thelet keyword areblock scoped, they are only defined within the block they're declared in; the immediately invoked function expression (IIFE) in this case. When we use thetypeof operator, the operandx is not defined: we are trying to accessx outside of the block it's declared in. This means thatx is not defined. Values who haven't been assigned a value or declared are of type"undefined".console.log(typeof x) returns"undefined".

However, we created a global variabley when settingy equal to10. This value is accessible anywhere in our code.y is defined, and holds a value of type"number".console.log(typeof y) returns"number".


55. What's the output?
classDog{constructor(name){this.name=name;}}Dog.prototype.bark=function(){console.log(`Woof I am${this.name}`);};constpet=newDog('Mara');pet.bark();deleteDog.prototype.bark;pet.bark();
  • A:"Woof I am Mara",TypeError
  • B:"Woof I am Mara","Woof I am Mara"
  • C:"Woof I am Mara",undefined
  • D:TypeError,TypeError
Answer

Answer: A

We can delete properties from objects using thedelete keyword, also on the prototype. By deleting a property on the prototype, it is not available anymore in the prototype chain. In this case, thebark function is not available anymore on the prototype afterdelete Dog.prototype.bark, yet we still try to access it.

When we try to invoke something that is not a function, aTypeError is thrown. In this caseTypeError: pet.bark is not a function, sincepet.bark isundefined.


56. What's the output?
constset=newSet([1,1,2,3,4]);console.log(set);
  • A:[1, 1, 2, 3, 4]
  • B:[1, 2, 3, 4]
  • C:{1, 1, 2, 3, 4}
  • D:{1, 2, 3, 4}
Answer

Answer: D

TheSet object is a collection ofunique values: a value can only occur once in a set.

We passed the iterable[1, 1, 2, 3, 4] with a duplicate value1. Since we cannot have two of the same values in a set, one of them is removed. This results in{1, 2, 3, 4}.


57. What's the output?
// counter.jsletcounter=10;exportdefaultcounter;
// index.jsimportmyCounterfrom'./counter';myCounter+=1;console.log(myCounter);
  • A:10
  • B:11
  • C:Error
  • D:NaN
Answer

Answer: C

An imported module isread-only: you cannot modify the imported module. Only the module that exports them can change its value.

When we try to increment the value ofmyCounter, it throws an error:myCounter is read-only and cannot be modified.


58. What's the output?
constname='Lydia';age=21;console.log(deletename);console.log(deleteage);
  • A:false,true
  • B:"Lydia",21
  • C:true,true
  • D:undefined,undefined
Answer

Answer: A

Thedelete operator returns a boolean value:true on a successful deletion, else it'll returnfalse. However, variables declared with thevar,const, orlet keywords cannot be deleted using thedelete operator.

Thename variable was declared with aconst keyword, so its deletion is not successful:false is returned. When we setage equal to21, we actually added a property calledage to the global object. You can successfully delete properties from objects this way, also the global object, sodelete age returnstrue.


59. What's the output?
constnumbers=[1,2,3,4,5];const[y]=numbers;console.log(y);
  • A:[[1, 2, 3, 4, 5]]
  • B:[1, 2, 3, 4, 5]
  • C:1
  • D:[1]
Answer

Answer: C

We can unpack values from arrays or properties from objects through destructuring. For example:

[a,b]=[1,2];

The value ofa is now1, and the value ofb is now2. What we actually did in the question, is:

[y]=[1,2,3,4,5];

This means that the value ofy is equal to the first value in the array, which is the number1. When we logy,1 is returned.


60. What's the output?
constuser={name:'Lydia',age:21};constadmin={admin:true, ...user};console.log(admin);
  • A:{ admin: true, user: { name: "Lydia", age: 21 } }
  • B:{ admin: true, name: "Lydia", age: 21 }
  • C:{ admin: true, user: ["Lydia", 21] }
  • D:{ admin: true }
Answer

Answer: B

It's possible to combine objects using the spread operator.... It lets you create copies of the key/value pairs of one object, and add them to another object. In this case, we create copies of theuser object, and add them to theadmin object. Theadmin object now contains the copied key/value pairs, which results in{ admin: true, name: "Lydia", age: 21 }.


61. What's the output?
constperson={name:'Lydia'};Object.defineProperty(person,'age',{value:21});console.log(person);console.log(Object.keys(person));
  • A:{ name: "Lydia", age: 21 },["name", "age"]
  • B:{ name: "Lydia", age: 21 },["name"]
  • C:{ name: "Lydia"},["name", "age"]
  • D:{ name: "Lydia"},["age"]
Answer

Answer: B

With thedefineProperty method, we can add new properties to an object, or modify existing ones. When we add a property to an object using thedefineProperty method, they are by defaultnot enumerable. TheObject.keys method returns allenumerable property names from an object, in this case only"name".

Properties added using thedefineProperty method are immutable by default. You can override this behavior using thewritable,configurable andenumerable properties. This way, thedefineProperty method gives you a lot more control over the properties you're adding to an object.


62. What's the output?
constsettings={username:'lydiahallie',level:19,health:90,};constdata=JSON.stringify(settings,['level','health']);console.log(data);
  • A:"{"level":19, "health":90}"
  • B:"{"username": "lydiahallie"}"
  • C:"["level", "health"]"
  • D:"{"username": "lydiahallie", "level":19, "health":90}"
Answer

Answer: A

The second argument ofJSON.stringify is thereplacer. The replacer can either be a function or an array, and lets you control what and how the values should be stringified.

If the replacer is anarray, only the property names included in the array will be added to the JSON string. In this case, only the properties with the names"level" and"health" are included,"username" is excluded.data is now equal to"{"level":19, "health":90}".

If the replacer is afunction, this function gets called on every property in the object you're stringifying. The value returned from this function will be the value of the property when it's added to the JSON string. If the value isundefined, this property is excluded from the JSON string.


63. What's the output?
letnum=10;constincreaseNumber=()=>num++;constincreasePassedNumber=number=>number++;constnum1=increaseNumber();constnum2=increasePassedNumber(num1);console.log(num1);console.log(num2);
  • A:10,10
  • B:10,11
  • C:11,11
  • D:11,12
Answer

Answer: A

The unary operator++first returns the value of the operand,then increments the value of the operand. The value ofnum1 is10, since theincreaseNumber function first returns the value ofnum, which is10, and only increments the value ofnum afterward.

num2 is10, since we passednum1 to theincreasePassedNumber.number is equal to10(the value ofnum1). Again, the unary operator++first returns the value of the operand,then increments the value of the operand. The value ofnumber is10, sonum2 is equal to10.


64. What's the output?
constvalue={number:10};constmultiply=(x={ ...value})=>{console.log((x.number*=2));};multiply();multiply();multiply(value);multiply(value);
  • A:20,40,80,160
  • B:20,40,20,40
  • C:20,20,20,40
  • D:NaN,NaN,20,40
Answer

Answer: C

In ES6, we can initialize parameters with a default value. The value of the parameter will be the default value, if no other value has been passed to the function, or if the value of the parameter is"undefined". In this case, we spread the properties of thevalue object into a new object, sox has the default value of{ number: 10 }.

The default argument is evaluated atcall time! Every time we call the function, anew object is created. We invoke themultiply function the first two times without passing a value:x has the default value of{ number: 10 }. We then log the multiplied value of that number, which is20.

The third time we invoke multiply, we do pass an argument: the object calledvalue. The*= operator is actually shorthand forx.number = x.number * 2: we modify the value ofx.number, and log the multiplied value20.

The fourth time, we pass thevalue object again.x.number was previously modified to20, sox.number *= 2 logs40.


65. What's the output?
[1,2,3,4].reduce((x,y)=>console.log(x,y));
  • A:12 and33 and64
  • B:12 and23 and34
  • C:1undefined and2undefined and3undefined and4undefined
  • D:12 andundefined3 andundefined4
Answer

Answer: D

The first argument that thereduce method receives is theaccumulator,x in this case. The second argument is thecurrent value,y. With the reduce method, we execute a callback function on every element in the array, which could ultimately result in one single value.

In this example, we are not returning any values, we are simply logging the values of the accumulator and the current value.

The value of the accumulator is equal to the previously returned value of the callback function. If you don't pass the optionalinitialValue argument to thereduce method, the accumulator is equal to the first element on the first call.

On the first call, the accumulator (x) is1, and the current value (y) is2. We don't return from the callback function, we log the accumulator, and the current values:1 and2 get logged.

If you don't return a value from a function, it returnsundefined. On the next call, the accumulator isundefined, and the current value is3.undefined and3 get logged.

On the fourth call, we again don't return from the callback function. The accumulator is againundefined, and the current value is4.undefined and4 get logged.


66. With which constructor can we successfully extend theDog class?
classDog{constructor(name){this.name=name;}};classLabradorextendsDog{// 1constructor(name,size){this.size=size;}// 2constructor(name,size){super(name);this.size=size;}// 3constructor(size){super(name);this.size=size;}// 4constructor(name,size){this.name=name;this.size=size;}};
  • A: 1
  • B: 2
  • C: 3
  • D: 4
Answer

Answer: B

In a derived class, you cannot access thethis keyword before callingsuper. If you try to do that, it will throw a ReferenceError: 1 and 4 would throw a reference error.

With thesuper keyword, we call that parent class's constructor with the given arguments. The parent's constructor receives thename argument, so we need to passname tosuper.

TheLabrador class receives two arguments,name since it extendsDog, andsize as an extra property on theLabrador class. They both need to be passed to the constructor function onLabrador, which is done correctly using constructor 2.


67. What's the output?
// index.jsconsole.log('running index.js');import{sum}from'./sum.js';console.log(sum(1,2));// sum.jsconsole.log('running sum.js');exportconstsum=(a,b)=>a+b;
  • A:running index.js,running sum.js,3
  • B:running sum.js,running index.js,3
  • C:running sum.js,3,running index.js
  • D:running index.js,undefined,running sum.js
Answer

Answer: B

With theimport keyword, all imported modules arepre-parsed. This means that the imported modules get runfirst, and the code in the file that imports the module gets executedafter.

This is a difference betweenrequire() in CommonJS andimport! Withrequire(), you can load dependencies on demand while the code is being run. If we had usedrequire instead ofimport,running index.js,running sum.js,3 would have been logged to the console.


68. What's the output?
console.log(Number(2)===Number(2));console.log(Boolean(false)===Boolean(false));console.log(Symbol('foo')===Symbol('foo'));
  • A:true,true,false
  • B:false,true,false
  • C:true,false,true
  • D:true,true,true
Answer

Answer: A

Every Symbol is entirely unique. The purpose of the argument passed to the Symbol is to give the Symbol a description. The value of the Symbol is not dependent on the passed argument. As we test equality, we are creating two entirely new symbols: the firstSymbol('foo'), and the secondSymbol('foo'). These two values are unique and not equal to each other,Symbol('foo') === Symbol('foo') returnsfalse.


69. What's the output?
constname='Lydia Hallie';console.log(name.padStart(13));console.log(name.padStart(2));
  • A:"Lydia Hallie","Lydia Hallie"
  • B:" Lydia Hallie"," Lydia Hallie" ("[13x whitespace]Lydia Hallie","[2x whitespace]Lydia Hallie")
  • C:" Lydia Hallie","Lydia Hallie" ("[1x whitespace]Lydia Hallie","Lydia Hallie")
  • D:"Lydia Hallie","Lyd",
Answer

Answer: C

With thepadStart method, we can add padding to the beginning of a string. The value passed to this method is thetotal length of the string together with the padding. The string"Lydia Hallie" has a length of12.name.padStart(13) inserts 1 space at the start of the string, because 12 + 1 is 13.

If the argument passed to thepadStart method is smaller than the length of the array, no padding will be added.


70. What's the output?
console.log('🥑'+'💻');
  • A:"🥑💻"
  • B:257548
  • C: A string containing their code points
  • D: Error
Answer

Answer: A

With the+ operator, you can concatenate strings. In this case, we are concatenating the string"🥑" with the string"💻", resulting in"🥑💻".


71. How can we log the values that are commented out after the console.log statement?
function*startGame(){constanswer=yield'Do you love JavaScript?';if(answer!=='Yes'){return"Oh wow... Guess we're done here";}return'JavaScript loves you back ❤️';}constgame=startGame();console.log(/* 1 */);// Do you love JavaScript?console.log(/* 2 */);// JavaScript loves you back ❤️
  • A:game.next("Yes").value andgame.next().value
  • B:game.next.value("Yes") andgame.next.value()
  • C:game.next().value andgame.next("Yes").value
  • D:game.next.value() andgame.next.value("Yes")
Answer

Answer: C

A generator function "pauses" its execution when it sees theyield keyword. First, we have to let the function yield the string "Do you love JavaScript?", which can be done by callinggame.next().value.

Every line is executed, until it finds the firstyield keyword. There is ayield keyword on the first line within the function: the execution stops with the first yield!This means that the variableanswer is not defined yet!

When we callgame.next("Yes").value, the previousyield is replaced with the value of the parameters passed to thenext() function,"Yes" in this case. The value of the variableanswer is now equal to"Yes". The condition of the if-statement returnsfalse, andJavaScript loves you back ❤️ gets logged.


72. What's the output?
console.log(String.raw`Hello\nworld`);
  • A:Hello world!
  • B:Hello
         world
  • C:Hello\nworld
  • D:Hello\n
         world
Answer

Answer: C

String.raw returns a string where the escapes (\n,\v,\t etc.) are ignored! Backslashes can be an issue since you could end up with something like:

const path = `C:\Documents\Projects\table.html`

Which would result in:

"C:DocumentsProjects able.html"

WithString.raw, it would simply ignore the escape and print:

C:\Documents\Projects\table.html

In this case, the string isHello\nworld, which gets logged.


73. What's the output?
asyncfunctiongetData(){returnawaitPromise.resolve('I made it!');}constdata=getData();console.log(data);
  • A:"I made it!"
  • B:Promise {<resolved>: "I made it!"}
  • C:Promise {<pending>}
  • D:undefined
Answer

Answer: C

An async function always returns a promise. Theawait still has to wait for the promise to resolve: a pending promise gets returned when we callgetData() in order to setdata equal to it.

If we wanted to get access to the resolved value"I made it", we could have used the.then() method ondata:

data.then(res => console.log(res))

This would've logged"I made it!"


74. What's the output?
functionaddToList(item,list){returnlist.push(item);}constresult=addToList('apple',['banana']);console.log(result);
  • A:['apple', 'banana']
  • B:2
  • C:true
  • D:undefined
Answer

Answer: B

The.push() method returns thelength of the new array! Previously, the array contained one element (the string"banana") and had a length of1. After adding the string"apple" to the array, the array contains two elements, and has a length of2. This gets returned from theaddToList function.

Thepush method modifies the original array. If you wanted to return thearray from the function rather than thelength of the array, you should have returnedlist after pushingitem to it.


75. What's the output?
constbox={x:10,y:20};Object.freeze(box);constshape=box;shape.x=100;console.log(shape);
  • A:{ x: 100, y: 20 }
  • B:{ x: 10, y: 20 }
  • C:{ x: 100 }
  • D:ReferenceError
Answer

Answer: B

Object.freeze makes it impossible to add, remove, or modify properties of an object (unless the property's value is another object).

When we create the variableshape and set it equal to the frozen objectbox,shape also refers to a frozen object. You can check whether an object is frozen by usingObject.isFrozen. In this case,Object.isFrozen(shape) would return true, since the variableshape has a reference to a frozen object.

Sinceshape is frozen, and since the value ofx is not an object, we cannot modify the propertyx.x is still equal to10, and{ x: 10, y: 20 } gets logged.


76. What's the output?
const{firstName:myName}={firstName:'Lydia'};console.log(firstName);
  • A:"Lydia"
  • B:"myName"
  • C:undefined
  • D:ReferenceError
Answer

Answer: D

By usingdestructuring assignment syntax we can unpack values from arrays, or properties from objects, into distinct variables:

const{ firstName}={firstName:'Lydia'};// ES5 version:// var firstName = { firstName: 'Lydia' }.firstName;console.log(firstName);// "Lydia"

Also, a property can be unpacked from an object and assigned to a variable with a different name than the object property:

const{firstName:myName}={firstName:'Lydia'};// ES5 version:// var myName = { firstName: 'Lydia' }.firstName;console.log(myName);// "Lydia"console.log(firstName);// Uncaught ReferenceError: firstName is not defined

Therefore,firstName does not exist as a variable, thus attempting to access its value will raise aReferenceError.

Note: Be aware of theglobal scope properties:

const{name:myName}={name:'Lydia'};console.log(myName);// "lydia"console.log(name);// "" ----- Browser e.g. Chromeconsole.log(name);// ReferenceError: name is not defined  ----- NodeJS

Whenever Javascript is unable to find a variable within thecurrent scope, it climbs up theScope chain and searches for it and if it reaches the top-level scope, akaGlobal scope, and still doesn't find it, it will throw aReferenceError.

  • InBrowsers such asChrome,name is adeprecated global scope property. In this example, the code is running insideglobal scope and there is no user-defined local variable forname, therefore it searches the predefinedvariables/properties in the global scope which is in the case of browsers, it searches throughwindow object and it will extract thewindow.name value which is equal to anempty string.

  • InNodeJS, there is no such property on theglobal object, thus attempting to access a non-existent variable will raise aReferenceError.


77. Is this a pure function?
functionsum(a,b){returna+b;}
  • A: Yes
  • B: No
Answer

Answer: A

A pure function is a function thatalways returns the same result, if the same arguments are passed.

Thesum function always returns the same result. If we pass1 and2, it willalways return3 without side effects. If we pass5 and10, it willalways return15, and so on. This is the definition of a pure function.


78. What is the output?
constadd=()=>{constcache={};returnnum=>{if(numincache){return`From cache!${cache[num]}`;}else{constresult=num+10;cache[num]=result;return`Calculated!${result}`;}};};constaddFunction=add();console.log(addFunction(10));console.log(addFunction(10));console.log(addFunction(5*2));
  • A:Calculated! 20Calculated! 20Calculated! 20
  • B:Calculated! 20From cache! 20Calculated! 20
  • C:Calculated! 20From cache! 20From cache! 20
  • D:Calculated! 20From cache! 20Error
Answer

Answer: C

Theadd function is amemoized function. With memoization, we can cache the results of a function in order to speed up its execution. In this case, we create acache object that stores the previously returned values.

If we call theaddFunction function again with the same argument, it first checks whether it has already gotten that value in its cache. If that's the case, the cache value will be returned, which saves execution time. Otherwise, if it's not cached, it will calculate the value and store it afterward.

We call theaddFunction function three times with the same value: on the first invocation, the value of the function whennum is equal to10 isn't cached yet. The condition of the if-statementnum in cache returnsfalse, and the else block gets executed:Calculated! 20 gets logged, and the value of the result gets added to the cache object.cache now looks like{ 10: 20 }.

The second time, thecache object contains the value that gets returned for10. The condition of the if-statementnum in cache returnstrue, and'From cache! 20' gets logged.

The third time, we pass5 * 2 to the function which gets evaluated to10. Thecache object contains the value that gets returned for10. The condition of the if-statementnum in cache returnstrue, and'From cache! 20' gets logged.


79. What is the output?
constmyLifeSummedUp=['☕','💻','🍷','🍫'];for(letiteminmyLifeSummedUp){console.log(item);}for(letitemofmyLifeSummedUp){console.log(item);}
  • A:0123 and"☕""💻""🍷""🍫"
  • B:"☕""💻""🍷""🍫" and"☕""💻""🍷""🍫"
  • C:"☕""💻""🍷""🍫" and0123
  • D:0123 and{0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}
Answer

Answer: A

With afor-in loop, we can iterate overenumerable properties. In an array, the enumerable properties are the "keys" of array elements, which are actually their indexes. You could see an array as:

{0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}

Where the keys are the enumerable properties.0123 get logged.

With afor-of loop, we can iterate overiterables. An array is an iterable. When we iterate over the array, the variable "item" is equal to the element it's currently iterating over,"☕""💻""🍷""🍫" get logged.


80. What is the output?
constlist=[1+2,1*2,1/2];console.log(list);
  • A:["1 + 2", "1 * 2", "1 / 2"]
  • B:["12", 2, 0.5]
  • C:[3, 2, 0.5]
  • D:[1, 1, 1]
Answer

Answer: C

Array elements can hold any value. Numbers, strings, objects, other arrays, null, boolean values, undefined, and other expressions such as dates, functions, and calculations.

The element will be equal to the returned value.1 + 2 returns3,1 * 2 returns2, and1 / 2 returns0.5.


81. What is the output?
functionsayHi(name){return`Hi there,${name}`;}console.log(sayHi());
  • A:Hi there,
  • B:Hi there, undefined
  • C:Hi there, null
  • D:ReferenceError
Answer

Answer: B

By default, arguments have the value ofundefined, unless a value has been passed to the function. In this case, we didn't pass a value for thename argument.name is equal toundefined which gets logged.

In ES6, we can overwrite this defaultundefined value with default parameters. For example:

function sayHi(name = "Lydia") { ... }

In this case, if we didn't pass a value or if we passedundefined,name would always be equal to the stringLydia


82. What is the output?
varstatus='😎';setTimeout(()=>{conststatus='😍';constdata={status:'🥑',getStatus(){returnthis.status;},};console.log(data.getStatus());console.log(data.getStatus.call(this));},0);
  • A:"🥑" and"😍"
  • B:"🥑" and"😎"
  • C:"😍" and"😎"
  • D:"😎" and"😎"
Answer

Answer: B

The value of thethis keyword is dependent on where you use it. In amethod, like thegetStatus method, thethis keyword refers tothe object that the method belongs to. The method belongs to thedata object, sothis refers to thedata object. When we logthis.status, thestatus property on thedata object gets logged, which is"🥑".

With thecall method, we can change the object to which thethis keyword refers. Infunctions, thethis keyword refers to thethe object that the function belongs to. We declared thesetTimeout function on theglobal object, so within thesetTimeout function, thethis keyword refers to theglobal object. On the global object, there is a variable calledstatus with the value of"😎". When loggingthis.status,"😎" gets logged.


83. What is the output?
constperson={name:'Lydia',age:21,};letcity=person.city;city='Amsterdam';console.log(person);
  • A:{ name: "Lydia", age: 21 }
  • B:{ name: "Lydia", age: 21, city: "Amsterdam" }
  • C:{ name: "Lydia", age: 21, city: undefined }
  • D:"Amsterdam"
Answer

Answer: A

We set the variablecity equal to the value of the property calledcity on theperson object. There is no property on this object calledcity, so the variablecity has the value ofundefined.

Note that we arenot referencing theperson object itself! We simply set the variablecity equal to the current value of thecity property on theperson object.

Then, we setcity equal to the string"Amsterdam". This doesn't change the person object: there is no reference to that object.

When logging theperson object, the unmodified object gets returned.


84. What is the output?
functioncheckAge(age){if(age<18){constmessage="Sorry, you're too young.";}else{constmessage="Yay! You're old enough!";}returnmessage;}console.log(checkAge(21));
  • A:"Sorry, you're too young."
  • B:"Yay! You're old enough!"
  • C:ReferenceError
  • D:undefined
Answer

Answer: C

Variables with theconst andlet keywords areblock-scoped. A block is anything between curly brackets ({ }). In this case, the curly brackets of the if/else statements. You cannot reference a variable outside of the block it's declared in, a ReferenceError gets thrown.


85. What kind of information would get logged?
fetch('https://www.website.com/api/user/1').then(res=>res.json()).then(res=>console.log(res));
  • A: The result of thefetch method.
  • B: The result of the second invocation of thefetch method.
  • C: The result of the callback in the previous.then().
  • D: It would always be undefined.
Answer

Answer: C

The value ofres in the second.then is equal to the returned value of the previous.then. You can keep chaining.thens like this, where the value is passed to the next handler.


86. Which option is a way to sethasName equal totrue, provided you cannot passtrue as an argument?
functiongetName(name){consthasName=//}
  • A:!!name
  • B:name
  • C:new Boolean(name)
  • D:name.length
Answer

Answer: A

With!!name, we determine whether the value ofname is truthy or falsy. If the name is truthy, which we want to test for,!name returnsfalse.!false (which is what!!name practically is) returnstrue.

By settinghasName equal toname, you sethasName equal to whatever value you passed to thegetName function, not the boolean valuetrue.

new Boolean(true) returns an object wrapper, not the boolean value itself.

name.length returns the length of the passed argument, not whether it'strue.


87. What's the output?
console.log('I want pizza'[0]);
  • A:"""
  • B:"I"
  • C:SyntaxError
  • D:undefined
Answer

Answer: B

In order to get a character at a specific index of a string, you can use bracket notation. The first character in the string has index 0, and so on. In this case, we want to get the element with index 0, the character"I', which gets logged.

Note that this method is not supported in IE7 and below. In that case, use.charAt().


88. What's the output?
functionsum(num1,num2=num1){console.log(num1+num2);}sum(10);
  • A:NaN
  • B:20
  • C:ReferenceError
  • D:undefined
Answer

Answer: B

You can set a default parameter's value equal to another parameter of the function, as long as they've been definedbefore the default parameter. We pass the value10 to thesum function. If thesum function only receives 1 argument, it means that the value fornum2 is not passed, and the value ofnum1 is equal to the passed value10 in this case. The default value ofnum2 is the value ofnum1, which is10.num1 + num2 returns20.

If you're trying to set a default parameter's value equal to a parameter that is definedafter (to the right), the parameter's value hasn't been initialized yet, which will throw an error.


89. What's the output?
// module.jsexportdefault()=>'Hello world';exportconstname='Lydia';// index.jsimport*asdatafrom'./module';console.log(data);
  • A:{ default: function default(), name: "Lydia" }
  • B:{ default: function default() }
  • C:{ default: "Hello world", name: "Lydia" }
  • D: Global object ofmodule.js
Answer

Answer: A

With theimport * as name syntax, we importall exports from themodule.js file into theindex.js file as a new object calleddata is created. In themodule.js file, there are two exports: the default export, and a named export. The default export is a function that returns the string"Hello World", and the named export is a variable calledname which has the value of the string"Lydia".

Thedata object has adefault property for the default export, other properties have the names of the named exports and their corresponding values.


90. What's the output?
classPerson{constructor(name){this.name=name;}}constmember=newPerson('John');console.log(typeofmember);
  • A:"class"
  • B:"function"
  • C:"object"
  • D:"string"
Answer

Answer: C

Classes are syntactical sugar for function constructors. The equivalent of thePerson class as a function constructor would be:

functionPerson(name){this.name=name;}

Calling a function constructor withnew results in the creation of an instance ofPerson,typeof keyword returns"object" for an instance.typeof member returns"object".


91. What's the output?
letnewList=[1,2,3].push(4);console.log(newList.push(5));
  • A:[1, 2, 3, 4, 5]
  • B:[1, 2, 3, 5]
  • C:[1, 2, 3, 4]
  • D:Error
Answer

Answer: D

The.push method returns thenew length of the array, not the array itself! By settingnewList equal to[1, 2, 3].push(4), we setnewList equal to the new length of the array:4.

Then, we try to use the.push method onnewList. SincenewList is the numerical value4, we cannot use the.push method: a TypeError is thrown.


92. What's the output?
functiongiveLydiaPizza(){return'Here is pizza!';}constgiveLydiaChocolate=()=>"Here's chocolate... now go hit the gym already.";console.log(giveLydiaPizza.prototype);console.log(giveLydiaChocolate.prototype);
  • A:{ constructor: ...}{ constructor: ...}
  • B:{}{ constructor: ...}
  • C:{ constructor: ...}{}
  • D:{ constructor: ...}undefined
Answer

Answer: D

Regular functions, such as thegiveLydiaPizza function, have aprototype property, which is an object (prototype object) with aconstructor property. Arrow functions however, such as thegiveLydiaChocolate function, do not have thisprototype property.undefined gets returned when trying to access theprototype property usinggiveLydiaChocolate.prototype.


93. What's the output?
constperson={name:'Lydia',age:21,};for(const[x,y]ofObject.entries(person)){console.log(x,y);}
  • A:nameLydia andage21
  • B:["name", "Lydia"] and["age", 21]
  • C:["name", "age"] andundefined
  • D:Error
Answer

Answer: A

Object.entries(person) returns an array of nested arrays, containing the keys and objects:

[ [ 'name', 'Lydia' ], [ 'age', 21 ] ]

Using thefor-of loop, we can iterate over each element in the array, the subarrays in this case. We can destructure the subarrays instantly in the for-of loop, usingconst [x, y].x is equal to the first element in the subarray,y is equal to the second element in the subarray.

The first subarray is[ "name", "Lydia" ], withx equal to"name", andy equal to"Lydia", which get logged.The second subarray is[ "age", 21 ], withx equal to"age", andy equal to21, which get logged.


94. What's the output?
functiongetItems(fruitList, ...args,favoriteFruit){return[...fruitList, ...args,favoriteFruit]}getItems(["banana","apple"],"pear","orange")
  • A:["banana", "apple", "pear", "orange"]
  • B:[["banana", "apple"], "pear", "orange"]
  • C:["banana", "apple", ["pear"], "orange"]
  • D:SyntaxError
Answer

Answer: D

...args is a rest parameter. The rest parameter's value is an array containing all remaining arguments,and can only be the last parameter! In this example, the rest parameter was the second parameter. This is not possible, and will throw a syntax error.

functiongetItems(fruitList,favoriteFruit, ...args){return[...fruitList, ...args,favoriteFruit];}getItems(['banana','apple'],'pear','orange');

The above example works. This returns the array[ 'banana', 'apple', 'orange', 'pear' ]


95. What's the output?
functionnums(a,b){if(a>b)console.log('a is bigger');elseconsole.log('b is bigger');returna+b;}console.log(nums(4,2));console.log(nums(1,2));
  • A:a is bigger,6 andb is bigger,3
  • B:a is bigger,undefined andb is bigger,undefined
  • C:undefined andundefined
  • D:SyntaxError
Answer

Answer: B

In JavaScript, we don'thave to write the semicolon (;) explicitly, however the JavaScript engine still adds them after statements. This is calledAutomatic Semicolon Insertion. A statement can for example be variables, or keywords likethrow,return,break, etc.

Here, we wrote areturn statement, and another valuea + b on anew line. However, since it's a new line, the engine doesn't know that it's actually the value that we wanted to return. Instead, it automatically added a semicolon afterreturn. You could see this as:

return;a+b;

This means thata + b is never reached, since a function stops running after thereturn keyword. If no value gets returned, like here, the function returnsundefined. Note that there is no automatic insertion afterif/else statements!


96. What's the output?
classPerson{constructor(){this.name='Lydia';}}Person=classAnotherPerson{constructor(){this.name='Sarah';}};constmember=newPerson();console.log(member.name);
  • A:"Lydia"
  • B:"Sarah"
  • C:Error: cannot redeclare Person
  • D:SyntaxError
Answer

Answer: B

We can set classes equal to other classes/function constructors. In this case, we setPerson equal toAnotherPerson. The name on this constructor isSarah, so the name property on the newPerson instancemember is"Sarah".


97. What's the output?
constinfo={[Symbol('a')]:'b',};console.log(info);console.log(Object.keys(info));
  • A:{Symbol('a'): 'b'} and["{Symbol('a')"]
  • B:{} and[]
  • C:{ a: "b" } and["a"]
  • D:{Symbol('a'): 'b'} and[]
Answer

Answer: D

A Symbol is notenumerable. The Object.keys method returns allenumerable key properties on an object. The Symbol won't be visible, and an empty array is returned. When logging the entire object, all properties will be visible, even non-enumerable ones.

This is one of the many qualities of a symbol: besides representing an entirely unique value (which prevents accidental name collision on objects, for example when working with 2 libraries that want to add properties to the same object), you can also "hide" properties on objects this way (although not entirely. You can still access symbols using theObject.getOwnPropertySymbols() method).


98. What's the output?
constgetList=([x, ...y])=>[x,y]constgetUser=user=>{name:user.name,age:user.age}constlist=[1,2,3,4]constuser={name:"Lydia",age:21}console.log(getList(list))console.log(getUser(user))
  • A:[1, [2, 3, 4]] andSyntaxError
  • B:[1, [2, 3, 4]] and{ name: "Lydia", age: 21 }
  • C:[1, 2, 3, 4] and{ name: "Lydia", age: 21 }
  • D:Error and{ name: "Lydia", age: 21 }
Answer

Answer: A

ThegetList function receives an array as its argument. Between the parentheses of thegetList function, we destructure this array right away. You could see this as:

[x, ...y] = [1, 2, 3, 4]

With the rest parameter...y, we put all "remaining" arguments in an array. The remaining arguments are2,3 and4 in this case. The value ofy is an array, containing all the rest parameters. The value ofx is equal to1 in this case, so when we log[x, y],[1, [2, 3, 4]] gets logged.

ThegetUser function receives an object. With arrow functions, we don'thave to write curly brackets if we just return one value. However, if you want to instantly return anobject from an arrow function, you have to write it between parentheses, otherwise everything between the two braces will be interpreted as a block statement. In this case the code between the braces is not a valid JavaScript code, so aSyntaxError gets thrown.

The following function would have returned an object:

const getUser = user => ({ name: user.name, age: user.age })


99. What's the output?
constname='Lydia';console.log(name());
  • A:SyntaxError
  • B:ReferenceError
  • C:TypeError
  • D:undefined
Answer

Answer: C

The variablename holds the value of a string, which is not a function, and thus cannot be invoked.

TypeErrors get thrown when a value is not of the expected type. JavaScript expectedname to be a function since we're trying to invoke it. It was a string however, so a TypeError gets thrown: name is not a function!

SyntaxErrors get thrown when you've written something that isn't valid JavaScript, for example when you've written the wordreturn asretrun.ReferenceErrors get thrown when JavaScript isn't able to find a reference to a value that you're trying to access.


100. What's the value of output?
// 🎉✨ This is my 100th question! ✨🎉constoutput=`${[]&&'Im'}possible!You should${''&&`n't`} see a therapist after so much JavaScript lol`;
  • A:possible! You should see a therapist after so much JavaScript lol
  • B:Impossible! You should see a therapist after so much JavaScript lol
  • C:possible! You shouldn't see a therapist after so much JavaScript lol
  • D:Impossible! You shouldn't see a therapist after so much JavaScript lol
Answer

Answer: B

[] is a truthy value. With the&& operator, the right-hand value will be returned if the left-hand value is a truthy value. In this case, the left-hand value[] is a truthy value, so"Im' gets returned.

"" is a falsy value. If the left-hand value is falsy, nothing gets returned.n't doesn't get returned.


101. What's the value of output?
constone=false||{}||null;consttwo=null||false||'';constthree=[]||0||true;console.log(one,two,three);
  • A:falsenull[]
  • B:null""true
  • C:{}""[]
  • D:nullnulltrue
Answer

Answer: C

With the|| operator, we can return the first truthy operand. If all values are falsy, the last operand gets returned.

(false || {} || null): the empty object{} is a truthy value. This is the first (and only) truthy value, which gets returned.one is equal to{}.

(null || false || ""): all operands are falsy values. This means that the last operand,"" gets returned.two is equal to"".

([] || 0 || ""): the empty array[] is a truthy value. This is the first truthy value, which gets returned.three is equal to[].


102. What's the value of output?
constmyPromise=()=>Promise.resolve('I have resolved!');functionfirstFunction(){myPromise().then(res=>console.log(res));console.log('second');}asyncfunctionsecondFunction(){console.log(awaitmyPromise());console.log('second');}firstFunction();secondFunction();
  • A:I have resolved!,second andI have resolved!,second
  • B:second,I have resolved! andsecond,I have resolved!
  • C:I have resolved!,second andsecond,I have resolved!
  • D:second,I have resolved! andI have resolved!,second
Answer

Answer: D

With a promise, we basically sayI want to execute this function, but I'll put it aside for now while it's running since this might take a while. Only when a certain value is resolved (or rejected), and when the call stack is empty, I want to use this value.

We can get this value with both.then and theawait keywords in anasync function. Although we can get a promise's value with both.then andawait, they work a bit differently.

In thefirstFunction, we (sort of) put the myPromise function aside while it was running, but continued running the other code, which isconsole.log('second') in this case. Then, the function resolved with the stringI have resolved, which then got logged after it saw that the callstack was empty.

With the await keyword insecondFunction, we literally pause the execution of an async function until the value has been resolved before moving to the next line.

This means that it waited for themyPromise to resolve with the valueI have resolved, and only once that happened, we moved to the next line:second got logged.


103. What's the value of output?
constset=newSet();set.add(1);set.add('Lydia');set.add({name:'Lydia'});for(letitemofset){console.log(item+2);}
  • A:3,NaN,NaN
  • B:3,7,NaN
  • C:3,Lydia2,[object Object]2
  • D:"12",Lydia2,[object Object]2
Answer

Answer: C

The+ operator is not only used for adding numerical values, but we can also use it to concatenate strings. Whenever the JavaScript engine sees that one or more values are not a number, it coerces the number into a string.

The first one is1, which is a numerical value.1 + 2 returns the number 3.

However, the second one is a string"Lydia"."Lydia" is a string and2 is a number:2 gets coerced into a string."Lydia" and"2" get concatenated, which results in the string"Lydia2".

{ name: "Lydia" } is an object. Neither a number nor an object is a string, so it stringifies both. Whenever we stringify a regular object, it becomes"[object Object]"."[object Object]" concatenated with"2" becomes"[object Object]2".


104. What's its value?
Promise.resolve(5);
  • A:5
  • B:Promise {<pending>: 5}
  • C:Promise {<fulfilled>: 5}
  • D:Error
Answer

Answer: C

We can pass any type of value we want toPromise.resolve, either a promise or a non-promise. The method itself returns a promise with the resolved value (<fulfilled>). If you pass a regular function, it'll be a resolved promise with a regular value. If you pass a promise, it'll be a resolved promise with the resolved value of that passed promise.

In this case, we just passed the numerical value5. It returns a resolved promise with the value5.


105. What's its value?
functioncompareMembers(person1,person2=person){if(person1!==person2){console.log('Not the same!');}else{console.log('They are the same!');}}constperson={name:'Lydia'};compareMembers(person);
  • A:Not the same!
  • B:They are the same!
  • C:ReferenceError
  • D:SyntaxError
Answer

Answer: B

Objects are passed by reference. When we check objects for strict equality (===), we're comparing their references.

We set the default value forperson2 equal to theperson object, and passed theperson object as the value forperson1.

This means that both values have a reference to the same spot in memory, thus they are equal.

The code block in theelse statement gets run, andThey are the same! gets logged.


106. What's its value?
constcolorConfig={red:true,blue:false,green:true,black:true,yellow:false,};constcolors=['pink','red','blue'];console.log(colorConfig.colors[1]);
  • A:true
  • B:false
  • C:undefined
  • D:TypeError
Answer

Answer: D

In JavaScript, we have two ways to access properties on an object: bracket notation, or dot notation. In this example, we use dot notation (colorConfig.colors) instead of bracket notation (colorConfig["colors"]).

With dot notation, JavaScript tries to find the property on the object with that exact name. In this example, JavaScript tries to find a property calledcolors on thecolorConfig object. There is no property calledcolors, so this returnsundefined. Then, we try to access the value of the first element by using[1]. We cannot do this on a value that'sundefined, so it throws aTypeError:Cannot read property '1' of undefined.

JavaScript interprets (or unboxes) statements. When we use bracket notation, it sees the first opening bracket[ and keeps going until it finds the closing bracket]. Only then, it will evaluate the statement. If we would've usedcolorConfig[colors[1]], it would have returned the value of thered property on thecolorConfig object.


107. What's its value?
console.log('❤️'==='❤️');
  • A:true
  • B:false
Answer

Answer: A

Under the hood, emojis are unicodes. The unicodes for the heart emoji is"U+2764 U+FE0F". These are always the same for the same emojis, so we're comparing two equal strings to each other, which returns true.


108. Which of these methods modifies the original array?
constemojis=['✨','🥑','😍'];emojis.map(x=>x+'✨');emojis.filter(x=>x!=='🥑');emojis.find(x=>x!=='🥑');emojis.reduce((acc,cur)=>acc+'✨');emojis.slice(1,2,'✨');emojis.splice(1,2,'✨');
  • A:All of them
  • B:mapreduceslicesplice
  • C:mapslicesplice
  • D:splice
Answer

Answer: D

Withsplice method, we modify the original array by deleting, replacing or adding elements. In this case, we removed 2 items from index 1 (we removed'🥑' and'😍') and added the ✨ emoji instead.

map,filter andslice return a new array,find returns an element, andreduce returns a reduced value.


109. What's the output?
constfood=['🍕','🍫','🥑','🍔'];constinfo={favoriteFood:food[0]};info.favoriteFood='🍝';console.log(food);
  • A:['🍕', '🍫', '🥑', '🍔']
  • B:['🍝', '🍫', '🥑', '🍔']
  • C:['🍝', '🍕', '🍫', '🥑', '🍔']
  • D:ReferenceError
Answer

Answer: A

We set the value of thefavoriteFood property on theinfo object equal to the string with the pizza emoji,'🍕'. A string is a primitive data type. In JavaScript, primitive data types don't interact by reference.

In JavaScript, primitive data types (everything that's not an object) interact byvalue. In this case, we set the value of thefavoriteFood property on theinfo object equal to the value of the first element in thefood array, the string with the pizza emoji in this case ('🍕'). A string is a primitive data type, and interact by value (see myblogpost if you're interested in learning more)

Then, we change the value of thefavoriteFood property on theinfo object. Thefood array hasn't changed, since the value offavoriteFood was merely acopy of the value of the first element in the array, and doesn't have a reference to the same spot in memory as the element onfood[0]. When we log food, it's still the original array,['🍕', '🍫', '🥑', '🍔'].


110. What does this method do?
JSON.parse();
  • A: Parses JSON to a JavaScript value
  • B: Parses a JavaScript object to JSON
  • C: Parses any JavaScript value to JSON
  • D: Parses JSON to a JavaScript object only
Answer

Answer: A

With theJSON.parse() method, we can parse JSON string to a JavaScript value.

// Stringifying a number into valid JSON, then parsing the JSON string to a JavaScript value:constjsonNumber=JSON.stringify(4);// '4'JSON.parse(jsonNumber);// 4// Stringifying an array value into valid JSON, then parsing the JSON string to a JavaScript value:constjsonArray=JSON.stringify([1,2,3]);// '[1, 2, 3]'JSON.parse(jsonArray);// [1, 2, 3]// Stringifying an object  into valid JSON, then parsing the JSON string to a JavaScript value:constjsonArray=JSON.stringify({name:'Lydia'});// '{"name":"Lydia"}'JSON.parse(jsonArray);// { name: 'Lydia' }


111. What's the output?
letname='Lydia';functiongetName(){console.log(name);letname='Sarah';}getName();
  • A: Lydia
  • B: Sarah
  • C:undefined
  • D:ReferenceError
Answer

Answer: D

Each function has its ownexecution context (orscope). ThegetName function first looks within its own context (scope) to see if it contains the variablename we're trying to access. In this case, thegetName function contains its ownname variable: we declare the variablename with thelet keyword, and with the value of'Sarah'.

Variables with thelet keyword (andconst) are hoisted, but unlikevar, don't getinitialized. They are not accessible before the line we declare (initialize) them. This is called the "temporal dead zone". When we try to access the variables before they are declared, JavaScript throws aReferenceError.

If we wouldn't have declared thename variable within thegetName function, the javascript engine would've looked down thescope chain. The outer scope has a variable calledname with the value ofLydia. In that case, it would've loggedLydia.

letname='Lydia';functiongetName(){console.log(name);}getName();// Lydia


112. What's the output?
function*generatorOne(){yield['a','b','c'];}function*generatorTwo(){yield*['a','b','c'];}constone=generatorOne();consttwo=generatorTwo();console.log(one.next().value);console.log(two.next().value);
  • A:a anda
  • B:a andundefined
  • C:['a', 'b', 'c'] anda
  • D:a and['a', 'b', 'c']
Answer

Answer: C

With theyield keyword, weyield values in a generator function. With theyield* keyword, we can yield values from another generator function, or iterable object (for example an array).

IngeneratorOne, we yield the entire array['a', 'b', 'c'] using theyield keyword. The value ofvalue property on the object returned by thenext method onone (one.next().value) is equal to the entire array['a', 'b', 'c'].

console.log(one.next().value);// ['a', 'b', 'c']console.log(one.next().value);// undefined

IngeneratorTwo, we use theyield* keyword. This means that the first yielded value oftwo, is equal to the first yielded value in the iterator. The iterator is the array['a', 'b', 'c']. The first yielded value isa, so the first time we calltwo.next().value,a is returned.

console.log(two.next().value);// 'a'console.log(two.next().value);// 'b'console.log(two.next().value);// 'c'console.log(two.next().value);// undefined


113. What's the output?
console.log(`${(x=>x)('I love')} to program`);
  • A:I love to program
  • B:undefined to program
  • C:${(x => x)('I love') to program
  • D:TypeError
Answer

Answer: A

Expressions within template literals are evaluated first. This means that the string will contain the returned value of the expression, the immediately invoked function(x => x)('I love') in this case. We pass the value'I love' as an argument to thex => x arrow function.x is equal to'I love', which gets returned. This results inI love to program.


114. What will happen?
letconfig={alert:setInterval(()=>{console.log('Alert!');},1000),};config=null;
  • A: ThesetInterval callback won't be invoked
  • B: ThesetInterval callback gets invoked once
  • C: ThesetInterval callback will still be called every second
  • D: We never invokedconfig.alert(), config isnull
Answer

Answer: C

Normally when we set objects equal tonull, those objects getgarbage collected as there is no reference anymore to that object. However, since the callback function withinsetInterval is an arrow function (thus bound to theconfig object), the callback function still holds a reference to theconfig object.As long as there is a reference, the object won't get garbage collected.Since this is an interval, settingconfig tonull ordelete-ingconfig.alert won't garbage-collect the interval, so the interval will still be called.It should be cleared withclearInterval(config.alert) to remove it from memory.Since it was not cleared, thesetInterval callback function will still get invoked every 1000ms (1s).


115. Which method(s) will return the value'Hello world!'?
constmyMap=newMap();constmyFunc=()=>'greeting';myMap.set(myFunc,'Hello world!');//1myMap.get('greeting');//2myMap.get(myFunc);//3myMap.get(()=>'greeting');
  • A: 1
  • B: 2
  • C: 2 and 3
  • D: All of them
Answer

Answer: B

When adding a key/value pair using theset method, the key will be the value of the first argument passed to theset function, and the value will be the second argument passed to theset function. The key is thefunction() => 'greeting' in this case, and the value'Hello world'.myMap is now{ () => 'greeting' => 'Hello world!' }.

1 is wrong, since the key is not'greeting' but() => 'greeting'.3 is wrong, since we're creating a new function by passing it as a parameter to theget method. Object interacts byreference. Functions are objects, which is why two functions are never strictly equal, even if they are identical: they have a reference to a different spot in memory.


116. What's the output?
constperson={name:'Lydia',age:21,};constchangeAge=(x={ ...person})=>(x.age+=1);constchangeAgeAndName=(x={ ...person})=>{x.age+=1;x.name='Sarah';};changeAge(person);changeAgeAndName();console.log(person);
  • A:{name: "Sarah", age: 22}
  • B:{name: "Sarah", age: 23}
  • C:{name: "Lydia", age: 22}
  • D:{name: "Lydia", age: 23}
Answer

Answer: C

Both thechangeAge andchangeAgeAndName functions have a default parameter, namely anewly created object{ ...person }. This object has copies of all the key/values in theperson object.

First, we invoke thechangeAge function and pass theperson object as its argument. This function increases the value of theage property by 1.person is now{ name: "Lydia", age: 22 }.

Then, we invoke thechangeAgeAndName function, however we don't pass a parameter. Instead, the value ofx is equal to anew object:{ ...person }. Since it's a new object, it doesn't affect the values of the properties on theperson object.person is still equal to{ name: "Lydia", age: 22 }.


117. Which of the following options will return6?
functionsumValues(x,y,z){returnx+y+z;}
  • A:sumValues([...1, 2, 3])
  • B:sumValues([...[1, 2, 3]])
  • C:sumValues(...[1, 2, 3])
  • D:sumValues([1, 2, 3])
Answer

Answer: C

With the spread operator..., we canspread iterables to individual elements. ThesumValues function receives three arguments:x,y andz....[1, 2, 3] will result in1, 2, 3, which we pass to thesumValues function.


118. What's the output?
letnum=1;constlist=['🥳','🤠','🥰','🤪'];console.log(list[(num+=1)]);
  • A:🤠
  • B:🥰
  • C:SyntaxError
  • D:ReferenceError
Answer

Answer: B

With the+= operator, we're incrementing the value ofnum by1.num had the initial value1, so1 + 1 is2. The item on the second index in thelist array is 🥰,console.log(list[2]) prints 🥰.


119. What's the output?
constperson={firstName:'Lydia',lastName:'Hallie',pet:{name:'Mara',breed:'Dutch Tulip Hound',},getFullName(){return`${this.firstName}${this.lastName}`;},};console.log(person.pet?.name);console.log(person.pet?.family?.name);console.log(person.getFullName?.());console.log(member.getLastName?.());
  • A:undefinedundefinedundefinedundefined
  • B:MaraundefinedLydia HallieReferenceError
  • C:MaranullLydia Hallienull
  • D:nullReferenceErrornullReferenceError
Answer

Answer: B

With the optional chaining operator?., we no longer have to explicitly check whether the deeper nested values are valid or not. If we're trying to access a property on anundefined ornull value (nullish), the expression short-circuits and returnsundefined.

person.pet?.name:person has a property namedpet:person.pet is not nullish. It has a property calledname, and returnsMara.person.pet?.family?.name:person has a property namedpet:person.pet is not nullish.pet doesnot have a property calledfamily,person.pet.family is nullish. The expression returnsundefined.person.getFullName?.():person has a property namedgetFullName:person.getFullName() is not nullish and can get invoked, which returnsLydia Hallie.member.getLastName?.(): variablemember is non-existent therefore aReferenceError gets thrown!


120. What's the output?
constgroceries=['banana','apple','peanuts'];if(groceries.indexOf('banana')){console.log('We have to buy bananas!');}else{console.log(`We don't have to buy bananas!`);}
  • A: We have to buy bananas!
  • B: We don't have to buy bananas
  • C:undefined
  • D:1
Answer

Answer: B

We passed the conditiongroceries.indexOf("banana") to the if-statement.groceries.indexOf("banana") returns0, which is a falsy value. Since the condition in the if-statement is falsy, the code in theelse block runs, andWe don't have to buy bananas! gets logged.


121. What's the output?
constconfig={languages:[],setlanguage(lang){returnthis.languages.push(lang);},};console.log(config.language);
  • A:function language(lang) { this.languages.push(lang }
  • B:0
  • C:[]
  • D:undefined
Answer

Answer: D

Thelanguage method is asetter. Setters don't hold an actual value, their purpose is tomodify properties. When calling asetter method,undefined gets returned.


122. What's the output?
constname='Lydia Hallie';console.log(!typeofname==='object');console.log(!typeofname==='string');
  • A:falsetrue
  • B:truefalse
  • C:falsefalse
  • D:truetrue
Answer

Answer: C

typeof name returns"string". The string"string" is a truthy value, so!typeof name returns the boolean valuefalse.false === "object" andfalse === "string" both returnfalse.

(If we wanted to check whether the type was (un)equal to a certain type, we should've written!== instead of!typeof)


123. What's the output?
constadd=x=>y=>z=>{console.log(x,y,z);returnx+y+z;};add(4)(5)(6);
  • A:456
  • B:654
  • C:4functionfunction
  • D:undefinedundefined6
Answer

Answer: A

Theadd function returns an arrow function, which returns an arrow function, which returns an arrow function (still with me?). The first function receives an argumentx with the value of4. We invoke the second function, which receives an argumenty with the value5. Then we invoke the third function, which receives an argumentz with the value6. When we're trying to access the valuex,y andz within the last arrow function, the JS engine goes up the scope chain in order to find the values forx andy accordingly. This returns456.


124. What's the output?
asyncfunction*range(start,end){for(leti=start;i<=end;i++){yieldPromise.resolve(i);}}(async()=>{constgen=range(1,3);forawait(constitemofgen){console.log(item);}})();
  • A:Promise {1}Promise {2}Promise {3}
  • B:Promise {<pending>}Promise {<pending>}Promise {<pending>}
  • C:123
  • D:undefinedundefinedundefined
Answer

Answer: C

The generator functionrange returns an async object with promises for each item in the range we pass:Promise{1},Promise{2},Promise{3}. We set the variablegen equal to the async object, after which we loop over it using afor await ... of loop. We set the variableitem equal to the returned Promise values: firstPromise{1}, thenPromise{2}, thenPromise{3}. Since we'reawaiting the value ofitem, the resolved promise, the resolvedvalues of the promises get returned:1,2, then3.


125. What's the output?
constmyFunc=({ x, y, z})=>{console.log(x,y,z);};myFunc(1,2,3);
  • A:123
  • B:{1: 1}{2: 2}{3: 3}
  • C:{ 1: undefined }undefinedundefined
  • D:undefinedundefinedundefined
Answer

Answer: D

myFunc expects an object with propertiesx,y andz as its argument. Since we're only passing three separate numeric values (1, 2, 3) instead of one object with propertiesx,y andz ({x: 1, y: 2, z: 3}),x,y andz have their default value ofundefined.


126. What's the output?
functiongetFine(speed,amount){constformattedSpeed=newIntl.NumberFormat('en-US',{style:'unit',unit:'mile-per-hour'}).format(speed);constformattedAmount=newIntl.NumberFormat('en-US',{style:'currency',currency:'USD'}).format(amount);return`The driver drove${formattedSpeed} and has to pay${formattedAmount}`;}console.log(getFine(130,300))
  • A: The driver drove 130 and has to pay 300
  • B: The driver drove 130 mph and has to pay $300.00
  • C: The driver drove undefined and has to pay undefined
  • D: The driver drove 130.00 and has to pay 300.00
Answer

Answer: B

With theIntl.NumberFormat method, we can format numeric values to any locale. We format the numeric value130 to theen-US locale as aunit inmile-per-hour, which results in130 mph. The numeric value300 to theen-US locale as acurrency inUSD results in$300.00.


127. What's the output?
constspookyItems=['👻','🎃','🕸'];({item:spookyItems[3]}={item:'💀'});console.log(spookyItems);
  • A:["👻", "🎃", "🕸"]
  • B:["👻", "🎃", "🕸", "💀"]
  • C:["👻", "🎃", "🕸", { item: "💀" }]
  • D:["👻", "🎃", "🕸", "[object Object]"]
Answer

Answer: B

By destructuring objects, we can unpack values from the right-hand object, and assign the unpacked value to the value of the same property name on the left-hand object. In this case, we're assigning the value "💀" tospookyItems[3]. This means that we're modifying thespookyItems array, we're adding the "💀" to it. When loggingspookyItems,["👻", "🎃", "🕸", "💀"] gets logged.


128. What's the output?
constname='Lydia Hallie';constage=21;console.log(Number.isNaN(name));console.log(Number.isNaN(age));console.log(isNaN(name));console.log(isNaN(age));
  • A:truefalsetruefalse
  • B:truefalsefalsefalse
  • C:falsefalsetruefalse
  • D:falsetruefalsetrue
Answer

Answer: C

With theNumber.isNaN method, you can check if the value you pass is anumeric value and equal toNaN.name is not a numeric value, soNumber.isNaN(name) returnsfalse.age is a numeric value, but is not equal toNaN, soNumber.isNaN(age) returnsfalse.

With theisNaN method, you can check if the value you pass is not a number.name is not a number, soisNaN(name) returns true.age is a number, soisNaN(age) returnsfalse.


129. What's the output?
constrandomValue=21;functiongetInfo(){console.log(typeofrandomValue);constrandomValue='Lydia Hallie';}getInfo();
  • A:"number"
  • B:"string"
  • C:undefined
  • D:ReferenceError
Answer

Answer: D

Variables declared with theconst keyword are not referenceable before their initialization: this is called thetemporal dead zone. In thegetInfo function, the variablerandomValue is scoped in the functional scope ofgetInfo. On the line where we want to log the value oftypeof randomValue, the variablerandomValue isn't initialized yet: aReferenceError gets thrown! The engine didn't go down the scope chain since we declared the variablerandomValue in thegetInfo function.


130. What's the output?
constmyPromise=Promise.resolve('Woah some cool data');(async()=>{try{console.log(awaitmyPromise);}catch{thrownewError(`Oops didn't work`);}finally{console.log('Oh finally!');}})();
  • A:Woah some cool data
  • B:Oh finally!
  • C:Woah some cool dataOh finally!
  • D:Oops didn't workOh finally!
Answer

Answer: C

In thetry block, we're logging the awaited value of themyPromise variable:"Woah some cool data". Since no errors were thrown in thetry block, the code in thecatch block doesn't run. The code in thefinally blockalways runs,"Oh finally!" gets logged.


131. What's the output?
constemojis=['🥑',['✨','✨',['🍕','🍕']]];console.log(emojis.flat(1));
  • A:['🥑', ['✨', '✨', ['🍕', '🍕']]]
  • B:['🥑', '✨', '✨', ['🍕', '🍕']]
  • C:['🥑', ['✨', '✨', '🍕', '🍕']]
  • D:['🥑', '✨', '✨', '🍕', '🍕']
Answer

Answer: B

With theflat method, we can create a new, flattened array. The depth of the flattened array depends on the value that we pass. In this case, we passed the value1 (which we didn't have to, that's the default value), meaning that only the arrays on the first depth will be concatenated.['🥑'] and['✨', '✨', ['🍕', '🍕']] in this case. Concatenating these two arrays results in['🥑', '✨', '✨', ['🍕', '🍕']].


132. What's the output?
classCounter{constructor(){this.count=0;}increment(){this.count++;}}constcounterOne=newCounter();counterOne.increment();counterOne.increment();constcounterTwo=counterOne;counterTwo.increment();console.log(counterOne.count);
  • A:0
  • B:1
  • C:2
  • D:3
Answer

Answer: D

counterOne is an instance of theCounter class. The counter class contains acount property on its constructor, and anincrement method. First, we invoked theincrement method twice by callingcounterOne.increment(). Currently,counterOne.count is2.

Then, we create a new variablecounterTwo, and set it equal tocounterOne. Since objects interact by reference, we're just creating a new reference to the same spot in memory thatcounterOne points to. Since it has the same spot in memory, any changes made to the object thatcounterTwo has a reference to, also apply tocounterOne. Currently,counterTwo.count is2.

We invokecounterTwo.increment(), which setscount to3. Then, we log the count oncounterOne, which logs3.


133. What's the output?
constmyPromise=Promise.resolve(Promise.resolve('Promise'));functionfuncOne(){setTimeout(()=>console.log('Timeout 1!'),0);myPromise.then(res=>res).then(res=>console.log(`${res} 1!`));console.log('Last line 1!');}asyncfunctionfuncTwo(){constres=awaitmyPromise;console.log(`${res} 2!`)setTimeout(()=>console.log('Timeout 2!'),0);console.log('Last line 2!');}funcOne();funcTwo();
  • A:Promise 1! Last line 1! Promise 2! Last line 2! Timeout 1! Timeout 2!
  • B:Last line 1! Timeout 1! Promise 1! Last line 2! Promise2! Timeout 2!
  • C:Last line 1! Promise 2! Last line 2! Promise 1! Timeout 1! Timeout 2!
  • D:Timeout 1! Promise 1! Last line 1! Promise 2! Timeout 2! Last line 2!
Answer

Answer: C

First, we invokefuncOne. On the first line offuncOne, we call theasynchronoussetTimeout function, from which the callback is sent to the Web API. (see my article on the event loophere.)

Then we call themyPromise promise, which is anasynchronous operation. Pay attention, that now only the first then clause was added to the microtask queue.

Both the promise and the timeout are asynchronous operations, the function keeps on running while it's busy completing the promise and handling thesetTimeout callback. This means thatLast line 1! gets logged first, since this is not an asynchonous operation.

Since the callstack is not empty yet, thesetTimeout function and promise infuncOne cannot get added to the callstack yet.

InfuncTwo, the variableres getsPromise becausePromise.resolve(Promise.resolve('Promise')) is equivalent toPromise.resolve('Promise') since resolving a promise just resolves it's value. Theawait in this line stops the execution of the function until it receives the resolution of the promise and then keeps on running synchronously until completion, soPromise 2! and thenLast line 2! are logged and thesetTimeout is sent to the Web API. If the first then clause infuncOne had its own log statement, it would be printed beforePromise 2!. Howewer, it executed silently and put the second then clause in microtask queue. So, the second clause will be printed afterPromise 2!.

Then the call stack is empty. Promises aremicrotasks so they are resolved first when the call stack is empty soPromise 1! gets to be logged.

Now, sincefuncTwo popped off the call stack, the call stack is empty. The callbacks waiting in the queue (() => console.log("Timeout 1!") fromfuncOne, and() => console.log("Timeout 2!") fromfuncTwo) get added to the call stack one by one. The first callback logsTimeout 1!, and gets popped off the stack. Then, the second callback logsTimeout 2!, and gets popped off the stack.


134. How can we invokesum insum.js fromindex.js?
// sum.jsexportdefaultfunctionsum(x){returnx+x;}// index.jsimport*assumfrom'./sum';
  • A:sum(4)
  • B:sum.sum(4)
  • C:sum.default(4)
  • D: Default aren't imported with*, only named exports
Answer

Answer: C

With the asterisk*, we import all exported values from that file, both default and named. If we had the following file:

// info.jsexportconstname='Lydia';exportconstage=21;exportdefault'I love JavaScript';// index.jsimport*asinfofrom'./info';console.log(info);

The following would get logged:

{default:"I love JavaScript",name:"Lydia",age:21}

For thesum example, it means that the imported valuesum looks like this:

{default:functionsum(x){returnx+x}}

We can invoke this function, by callingsum.default


135. What's the output?
consthandler={set:()=>console.log('Added a new property!'),get:()=>console.log('Accessed a property!'),};constperson=newProxy({},handler);person.name='Lydia';person.name;
  • A:Added a new property!
  • B:Accessed a property!
  • C:Added a new property!Accessed a property!
  • D: Nothing gets logged
Answer

Answer: C

With a Proxy object, we can add custom behavior to an object that we pass to it as the second argument. In this case, we pass thehandler object which contains two properties:set andget.set gets invoked whenever weset property values, andget gets invoked whenever weget (access) property values.

The first argument is an empty object{}, which is the value ofperson. To this object, the custom behavior specified in thehandler object gets added. If we add a property to theperson object,set will get invoked. If we access a property on theperson object,get gets invoked.

First, we added a new propertyname to the proxy object (person.name = "Lydia").set gets invoked, and logs"Added a new property!".

Then, we access a property value on the proxy object, and theget property on the handler object is invoked."Accessed a property!" gets logged.


136. Which of the following will modify theperson object?
constperson={name:'Lydia Hallie'};Object.seal(person);
  • A:person.name = "Evan Bacon"
  • B:person.age = 21
  • C:delete person.name
  • D:Object.assign(person, { age: 21 })
Answer

Answer: A

WithObject.seal we can prevent new properties from beingadded, or existing properties to beremoved.

However, you can still modify the value of existing properties.


137. Which of the following will modify theperson object?
constperson={name:'Lydia Hallie',address:{street:'100 Main St',},};Object.freeze(person);
  • A:person.name = "Evan Bacon"
  • B:delete person.address
  • C:person.address.street = "101 Main St"
  • D:person.pet = { name: "Mara" }
Answer

Answer: C

TheObject.freeze methodfreezes an object. No properties can be added, modified, or removed.

However, it onlyshallowly freezes the object, meaning that onlydirect properties on the object are frozen. If the property is another object, likeaddress in this case, the properties on that object aren't frozen, and can be modified.


138. What's the output?
constadd=x=>x+x;functionmyFunc(num=2,value=add(num)){console.log(num,value);}myFunc();myFunc(3);
  • A:24 and36
  • B:2NaN and3NaN
  • C:2Error and36
  • D:24 and3Error
Answer

Answer: A

First, we invokedmyFunc() without passing any arguments. Since we didn't pass arguments,num andvalue got their default values: num is2, andvalue is the returned value of the functionadd. To theadd function, we passnum as an argument, which had the value of2.add returns4, which is the value ofvalue.

Then, we invokedmyFunc(3) and passed the value3 as the value for the argumentnum. We didn't pass an argument forvalue. Since we didn't pass a value for thevalue argument, it got the default value: the returned value of theadd function. Toadd, we passnum, which has the value of3.add returns6, which is the value ofvalue.


139. What's the output?
classCounter{  #number=10increment(){this.#number++}getNum(){returnthis.#number}}constcounter=newCounter()counter.increment()console.log(counter.#number)
  • A:10
  • B:11
  • C:undefined
  • D:SyntaxError
Answer

Answer: D

In ES2020, we can add private variables in classes by using the#. We cannot access these variables outside of the class. When we try to logcounter.#number, a SyntaxError gets thrown: we cannot access it outside theCounter class!


140. What's missing?
constteams=[{name:'Team 1',members:['Paul','Lisa']},{name:'Team 2',members:['Laura','Tim']},];function*getMembers(members){for(leti=0;i<members.length;i++){yieldmembers[i];}}function*getTeams(teams){for(leti=0;i<teams.length;i++){// ✨ SOMETHING IS MISSING HERE ✨}}constobj=getTeams(teams);obj.next();// { value: "Paul", done: false }obj.next();// { value: "Lisa", done: false }
  • A:yield getMembers(teams[i].members)
  • B:yield* getMembers(teams[i].members)
  • C:return getMembers(teams[i].members)
  • D:return yield getMembers(teams[i].members)
Answer

Answer: B

In order to iterate over themembers in each element in theteams array, we need to passteams[i].members to thegetMembers generator function. The generator function returns a generator object. In order to iterate over each element in this generator object, we need to useyield*.

If we would've writtenyield,return yield, orreturn, the entire generator function would've gotten returned the first time we called thenext method.


141. What's the output?
constperson={name:'Lydia Hallie',hobbies:['coding'],};functionaddHobby(hobby,hobbies=person.hobbies){hobbies.push(hobby);returnhobbies;}addHobby('running',[]);addHobby('dancing');addHobby('baking',person.hobbies);console.log(person.hobbies);
  • A:["coding"]
  • B:["coding", "dancing"]
  • C:["coding", "dancing", "baking"]
  • D:["coding", "running", "dancing", "baking"]
Answer

Answer: C

TheaddHobby function receives two arguments,hobby andhobbies with the default value of thehobbies array on theperson object.

First, we invoke theaddHobby function, and pass"running" as the value forhobby and an empty array as the value forhobbies. Since we pass an empty array as the value forhobbies,"running" gets added to this empty array.

Then, we invoke theaddHobby function, and pass"dancing" as the value forhobby. We didn't pass a value forhobbies, so it gets the default value, thehobbies property on theperson object. We push the hobbydancing to theperson.hobbies array.

Last, we invoke theaddHobby function, and pass"baking" as the value forhobby, and theperson.hobbies array as the value forhobbies. We push the hobbybaking to theperson.hobbies array.

After pushingdancing andbaking, the value ofperson.hobbies is["coding", "dancing", "baking"]


142. What's the output?
classBird{constructor(){console.log("I'm a bird. 🦢");}}classFlamingoextendsBird{constructor(){console.log("I'm pink. 🌸");super();}}constpet=newFlamingo();
  • A:I'm pink. 🌸
  • B:I'm pink. 🌸I'm a bird. 🦢
  • C:I'm a bird. 🦢I'm pink. 🌸
  • D: Nothing, we didn't call any method
Answer

Answer: B

We create the variablepet which is an instance of theFlamingo class. When we instantiate this instance, theconstructor onFlamingo gets called. First,"I'm pink. 🌸" gets logged, after which we callsuper().super() calls the constructor of the parent class,Bird. The constructor inBird gets called, and logs"I'm a bird. 🦢".


143. Which of the options result(s) in an error?
constemojis=['🎄','🎅🏼','🎁','⭐'];/* 1 */emojis.push('🦌');/* 2 */emojis.splice(0,2);/* 3 */emojis=[...emojis,'🥂'];/* 4 */emojis.length=0;
  • A: 1
  • B: 1 and 2
  • C: 3 and 4
  • D: 3
Answer

Answer: D

Theconst keyword simply means we cannotredeclare the value of that variable, it'sread-only. However, the value itself isn't immutable. The properties on theemojis array can be modified, for example by pushing new values, splicing them, or setting the length of the array to 0.


144. What do we need to add to theperson object to get["Lydia Hallie", 21] as the output of[...person]?
constperson={name:"Lydia Hallie",age:21}[...person]// ["Lydia Hallie", 21]
  • A: Nothing, object are iterable by default
  • B:*[Symbol.iterator]() { for (let x in this) yield* this[x] }
  • C:*[Symbol.iterator]() { yield* Object.values(this) }
  • D:*[Symbol.iterator]() { for (let x in this) yield this }
Answer

Answer: C

Objects aren't iterable by default. An iterable is an iterable if the iterator protocol is present. We can add this manually by adding the iterator symbol[Symbol.iterator], which has to return a generator object, for example by making it a generator function*[Symbol.iterator]() {}. This generator function has to yield theObject.values of theperson object if we want it to return the array["Lydia Hallie", 21]:yield* Object.values(this).


145. What's the output?
letcount=0;constnums=[0,1,2,3];nums.forEach(num=>{if(num)count+=1})console.log(count)
  • A: 1
  • B: 2
  • C: 3
  • D: 4
Answer

Answer: C

Theif condition within theforEach loop checks whether the value ofnum is truthy or falsy. Since the first number in thenums array is0, a falsy value, theif statement's code block won't be executed.count only gets incremented for the other 3 numbers in thenums array,1,2 and3. Sincecount gets incremented by1 3 times, the value ofcount is3.


146. What's the output?
functiongetFruit(fruits){console.log(fruits?.[1]?.[1])}getFruit([['🍊','🍌'],['🍍']])getFruit()getFruit([['🍍'],['🍊','🍌']])
  • A:null,undefined, 🍌
  • B:[],null, 🍌
  • C:[],[], 🍌
  • D:undefined,undefined, 🍌
Answer

Answer: D

The? allows us to optionally access deeper nested properties within objects. We're trying to log the item on index1 within the subarray that's on index1 of thefruits array. If the subarray on index1 in thefruits array doesn't exist, it'll simply returnundefined. If the subarray on index1 in thefruits array exists, but this subarray doesn't have an item on its1 index, it'll also returnundefined.

First, we're trying to log the second item in the['🍍'] subarray of[['🍊', '🍌'], ['🍍']]. This subarray only contains one item, which means there is no item on index1, and returnsundefined.

Then, we're invoking thegetFruits function without passing a value as an argument, which means thatfruits has a value ofundefined by default. Since we're conditionally chaining the item on index1 offruits, it returnsundefined since this item on index1 does not exist.

Lastly, we're trying to log the second item in the['🍊', '🍌'] subarray of['🍍'], ['🍊', '🍌']. The item on index1 within this subarray is🍌, which gets logged.


147. What's the output?
classCalc{constructor(){this.count=0}increase(){this.count++}}constcalc=newCalc()newCalc().increase()console.log(calc.count)
  • A:0
  • B:1
  • C:undefined
  • D:ReferenceError
Answer

Answer: A

We set the variablecalc equal to a new instance of theCalc class. Then, we instantiate a new instance ofCalc, and invoke theincrease method on this instance. Since the count property is within the constructor of theCalc class, the count property is not shared on the prototype ofCalc. This means that the value of count has not been updated for the instance calc points to, count is still0.


148. What's the output?
constuser={email:"e@mail.com",password:"12345"}constupdateUser=({ email, password})=>{if(email){Object.assign(user,{ email})}if(password){user.password=password}returnuser}constupdatedUser=updateUser({email:"new@email.com"})console.log(updatedUser===user)
  • A:false
  • B:true
  • C:TypeError
  • D:ReferenceError
Answer

Answer: B

TheupdateUser function updates the values of theemail andpassword properties on user, if their values are passed to the function, after which the function returns theuser object. The returned value of theupdateUser function is theuser object, which means that the value of updatedUser is a reference to the sameuser object thatuser points to.updatedUser === user equalstrue.


149. What's the output?
constfruit=['🍌','🍊','🍎']fruit.slice(0,1)fruit.splice(0,1)fruit.unshift('🍇')console.log(fruit)
  • A:['🍌', '🍊', '🍎']
  • B:['🍊', '🍎']
  • C:['🍇', '🍊', '🍎']
  • D:['🍇', '🍌', '🍊', '🍎']
Answer

Answer: C

First, we invoke theslice method on the fruit array. The slice method does not modify the original array, but returns the value that it sliced off the array: the banana emoji.Then, we invoke thesplice method on the fruit array. The splice method does modify the original array, which means that the fruit array now consists of['🍊', '🍎'].At last, we invoke theunshift method on thefruit array, which modifies the original array by adding the provided value, ‘🍇’ in this case, as the first element in the array. The fruit array now consists of['🍇', '🍊', '🍎'].


150. What's the output?
constanimals={};letdog={emoji:'🐶'}letcat={emoji:'🐈'}animals[dog]={ ...dog,name:"Mara"}animals[cat]={ ...cat,name:"Sara"}console.log(animals[dog])
  • A:{ emoji: "🐶", name: "Mara" }
  • B:{ emoji: "🐈", name: "Sara" }
  • C:undefined
  • D:ReferenceError
Answer

Answer: B

Object keys are converted to strings.

Since the value ofdog is an object,animals[dog] actually means that we’re creating a new property called"[object Object]" equal to the new object.animals["[object Object]"] is now equal to{ emoji: "🐶", name: "Mara"}.

cat is also an object, which means thatanimals[cat] actually means that we’re overwriting the value ofanimals["[object Object]"] with the new cat properties.

Logginganimals[dog], or actuallyanimals["[object Object]"] since converting thedog object to a string results"[object Object]", returns the{ emoji: "🐈", name: "Sara" }.


151. What's the output?
constuser={email:"my@email.com",updateEmail:email=>{this.email=email}}user.updateEmail("new@email.com")console.log(user.email)
  • A:my@email.com
  • B:new@email.com
  • C:undefined
  • D:ReferenceError
Answer

Answer: A

TheupdateEmail function is an arrow function, and is not bound to theuser object. This means that thethis keyword is not referring to theuser object, but refers to the global scope in this case. The value ofemail within theuser object does not get updated. When logging the value ofuser.email, the original value ofmy@email.com gets returned.


152. What's the output?
constpromise1=Promise.resolve('First')constpromise2=Promise.resolve('Second')constpromise3=Promise.reject('Third')constpromise4=Promise.resolve('Fourth')construnPromises=async()=>{constres1=awaitPromise.all([promise1,promise2])constres2=awaitPromise.all([promise3,promise4])return[res1,res2]}runPromises().then(res=>console.log(res)).catch(err=>console.log(err))
  • A:[['First', 'Second'], ['Fourth']]
  • B:[['First', 'Second'], ['Third', 'Fourth']]
  • C:[['First', 'Second']]
  • D:'Third'
Answer

Answer: D

ThePromise.all method runs the passed promises in parallel. If one promise fails, thePromise.all methodrejects with the value of the rejected promise. In this case,promise3 is rejected with the value"Third". We’re catching the rejected value in the chainedcatch method on therunPromises invocation to catch any errors within therunPromises function. Only"Third" gets logged, sincepromise3 is rejected with this value.


153. What should the value ofmethod be to log{ name: "Lydia", age: 22 }?
constkeys=["name","age"]constvalues=["Lydia",22]constmethod=/* ?? */Object[method](keys.map((_,i)=>{return[keys[i],values[i]]}))// { name: "Lydia", age: 22 }
  • A:entries
  • B:values
  • C:fromEntries
  • D:forEach
Answer

Answer: C

ThefromEntries method turns a 2d array into an object. The first element in each subarray will be the key, and the second element in each subarray will be the value. In this case, we’re mapping over thekeys array, which returns an array that the first element is the item on the key array on the current index, and the second element is the item of the values array on the current index.

This creates an array of subarrays containing the correct keys and values, which results in{ name: "Lydia", age: 22 }


154. What's the output?
constcreateMember=({ email, address={}})=>{constvalidEmail=/.+\@.+\..+/.test(email)if(!validEmail)thrownewError("Valid email pls")return{email,address:address ?address :null}}constmember=createMember({email:"my@email.com"})console.log(member)
  • A:{ email: "my@email.com", address: null }
  • B:{ email: "my@email.com" }
  • C:{ email: "my@email.com", address: {} }
  • D:{ email: "my@email.com", address: undefined }
Answer

Answer: C

The default value ofaddress is an empty object{}. When we set the variablemember equal to the object returned by thecreateMember function, we didn't pass a value for the address, which means that the value of the address is the default empty object{}. An empty object is a truthy value, which means that the condition of theaddress ? address : null conditional returnstrue. The value of the address is the empty object{}.


155. What's the output?
letrandomValue={name:"Lydia"}randomValue=23if(!typeofrandomValue==="string"){console.log("It's not a string!")}else{console.log("Yay it's a string!")}
  • A:It's not a string!
  • B:Yay it's a string!
  • C:TypeError
  • D:undefined
Answer

Answer: B

The condition within theif statement checks whether the value of!typeof randomValue is equal to"string". The! operator converts the value to a boolean value. If the value is truthy, the returned value will befalse, if the value is falsy, the returned value will betrue. In this case, the returned value oftypeof randomValue is the truthy value"number", meaning that the value of!typeof randomValue is the boolean valuefalse.

!typeof randomValue === "string" always returns false, since we're actually checkingfalse === "string". Since the condition returnedfalse, the code block of theelse statement gets run, andYay it's a string! gets logged.

About

A long list of (advanced) JavaScript questions, and their explanations ✨

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp