From 4858b8b3d124dc33ab599f81b3ac946ff90d850d Mon Sep 17 00:00:00 2001
From: Gabriel Sroka
#### Answer: D
-With the `throw` statement, we can create custom errors. With this statement, you can throw exceptions. An exception can be a string, a number, a boolean or an object. In this case, our exception is the string `'Hello world'`.
+With the `throw` statement, we can create custom errors. With this statement, you can throw exceptions. An exception can be a string, a number, a boolean or an object. In this case, our exception is the string `'Hello world!'`.
-With the `catch` statement, we can specify what to do if an exception is thrown in the `try` 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'`.
+With the `catch` statement, we can specify what to do if an exception is thrown in the `try` 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!'`.
Answer
+✨✉이메일 업데이트 구독 ✉✨
+
+사용 가능한 언어 목록:
* [English](./README.md)
* [العربية](./README_AR.md)
* [اللغة العامية - Egyptian Arabic](./README_ar-EG.md)
-* [Bosanski](./README-bs_BS.md)
-* [Deutsch](./README-de_DE.md)
+* [Bosanski](./README-bs_BS.md)
+* [Deutsch](./README-de_DE.md)
* [Español](./README-ES.md)
-* [日本語](./README-ja_JA.md)
-* [Português Brasil](./README_pt_BR.md)
-* [Русский](./README_ru-RU.md)
-* [Українська мова](./README-ua_UA.md)
+* [Français](./README_fr-FR.md)
+* [日本語](./README-ja_JA.md)
+* [한국어](./README-ko_KR.md)
+* [Português Brasil](./README_pt_BR.md)
+* [Русский](./README_ru-RU.md)
+* [Українська мова](./README-ua_UA.md)
* [Tiếng Việt](./README-vi.md)
* [中文版本](./README-zh_CN.md)
* [Türkçe](./README-tr_TR.md)
@@ -604,7 +610,7 @@ getAge(21);
#### 정답: C
-스프레드 연산자 (`...args`.)는 인수를 가진 배열을 리턴해요. 배열은 객체이므로, `typeof args`는 `"object"`를 리턴해요.
+rest 파라미터 (`...args`.)는 모든 남아있는 인수들을 하나의 배열로 "집합" 해요. 배열은 객체이므로, `typeof args`는 `"object"`를 리턴해요.
+ +#### Answer: A + +With a _for-in_ loop, we can iterate over **enumerable** 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. `0` `1` `2` `3` get logged. + +With a _for-of_ loop, we can iterate over **iterables**. 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. + +
++ +#### 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` returns `3`, `1 * 2` returns `2`, and `1 / 2` returns `0.5`. + +
++ +#### Answer: B + +By default, arguments have the value of `undefined`, unless a value has been passed to the function. In this case, we didn't pass a value for the `name` argument. `name` is equal to `undefined` which gets logged. + +In ES6, we can overwrite this default `undefined` value with default parameters. For example: + +`function sayHi(name = "Lydia") { ... }` + +In this case, if we didn't pass a value or if we passed `undefined`, `name` would always be equal to the string `Lydia` + +
++ +#### Answer: B + +The value of the `this` keyword is dependent on where you use it. In a **method**, like the `getStatus` method, the `this` keyword refers to _the object that the method belongs to_. The method belongs to the `data` object, so `this` refers to the `data` object. When we log `this.status`, the `status` property on the `data` object gets logged, which is `"🥑"`. + +With the `call` method, we can change the object to which the `this` keyword refers. In **functions**, the `this` keyword refers to the _the object that the function belongs to_. We declared the `setTimeout` function on the _global object_, so within the `setTimeout` function, the `this` keyword refers to the _global object_. On the global object, there is a variable called _status_ with the value of `"😎"`. When logging `this.status`, `"😎"` gets logged. + + +
++ +#### Answer: A + +We set the variable `city` equal to the value of the property called `city` on the `person` object. There is no property on this object called `city`, so the variable `city` has the value of `undefined`. + +Note that we are _not_ referencing the `person` object itself! We simply set the variable `city` equal to the current value of the `city` property on the `person` object. + +Then, we set `city` equal to the string `"Amsterdam"`. This doesn't change the person object: there is no reference to that object. + +When logging the `person` object, the unmodified object gets returned. + +
++ +#### Answer: C + +Variables with the `const` and `let` keyword are _block-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. + +
++ +#### Answer: C + +The value of `res` in the second `.then` is equal to the returned value of the previous `.then`. You can keep chaining `.then`s like this, where the value is passed to the next handler. + +
++ +#### Answer: A + +With `!!name`, we determine whether the value of `name` is truthy or falsey. If name is truthy, which we want to test for, `!name` returns `false`. `!false` (which is what `!!name` practically is) returns `true`. + +By setting `hasName` equal to `name`, you set `hasName` equal to whatever value you passed to the `getName` function, not the boolean value `true`. + +`new Boolean(true)` returns an object wrapper, not the boolean value itself. + +`name.length` returns the length of the passed argument, not whether it's `true`. + +
+
@@ -1503,7 +1503,7 @@ const num = parseInt("7*6", 10);
[1, 2, 3].map(num => {
if (typeof num === "number") return;
return num * 2;
-});
+ });
```
- A: `[]`
@@ -2011,10 +2011,10 @@ ES6에서는, 기본값으로 파라미터를 초기화할 수 있어요. 함수
[1, 2, 3, 4].reduce((x, y) => console.log(x, y));
```
-- A: `1` `2` and `3` `3` and `6` `4`
-- B: `1` `2` and `2` `3` and `3` `4`
-- C: `1` `undefined` and `2` `undefined` and `3` `undefined` and `4` `undefined`
-- D: `1` `2` and `undefined` `3` and `undefined` `4`
+- A: `1` `2` 그리고 `3` `3` 그리고 `6` `4`
+- B: `1` `2` 그리고 `2` `3` 그리고 `3` `4`
+- C: `1` `undefined` 그리고 `2` `undefined` 그리고 `3` `undefined` 그리고 `4` `undefined`
+- D: `1` `2` 그리고 `undefined` `3` 그리고 `undefined` `4`
@@ -2470,48 +2470,48 @@ console.log(addFunction(5 * 2));
---
-###### 79. What is the output?
+###### 79. 무엇이 출력 될까요?
```javascript
const myLifeSummedUp = ["☕", "💻", "🍷", "🍫"]
for (let item in myLifeSummedUp) {
- console.log(item)
+ console.log(item);
}
for (let item of myLifeSummedUp) {
- console.log(item)
+ console.log(item);
}
```
-- A: `0` `1` `2` `3` and `"☕"` ` "💻"` `"🍷"` `"🍫"`
-- B: `"☕"` ` "💻"` `"🍷"` `"🍫"` and `"☕"` ` "💻"` `"🍷"` `"🍫"`
-- C: `"☕"` ` "💻"` `"🍷"` `"🍫"` and `0` `1` `2` `3`
-- D: `0` `1` `2` `3` and `{0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}`
+- A: `0` `1` `2` `3` 그리고 `"☕"` ` "💻"` `"🍷"` `"🍫"`
+- B: `"☕"` ` "💻"` `"🍷"` `"🍫"` 그리고 `"☕"` ` "💻"` `"🍷"` `"🍫"`
+- C: `"☕"` ` "💻"` `"🍷"` `"🍫"` 그리고 `0` `1` `2` `3`
+- D: `0` `1` `2` `3` 그리고 `{0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}`
-
#### Answer: A
-With a _for-in_ loop, we can iterate over **enumerable** properties. In an array, the enumerable properties are the "keys" of array elements, which are actually their indexes. You could see an array as:
+_for-in_ 루프에서는, **열거 가능한** 속성들에 대해 반복 할 수 있어요. 배열에서, 열거 가능한 속성들은 배열 요소들의 "키"이고, 실제로는 그들의 인덱스죠. 배열을 다음과 같이 볼 수 있어요:
`{0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}`
-Where the keys are the enumerable properties. `0` `1` `2` `3` get logged.
+여기서 키는 열거 가능한 속성이에요. `0` `1` `2` `3`이 출력되죠.
-With a _for-of_ loop, we can iterate over **iterables**. 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.
+_for-of_ 루프에서는, **반복 가능한** 속성을 가진 요소에 대해 반복 할 수 있어요. 배열은 반복 가능해요. 배열을 반복할 때, "item" 변수는 현재 반복중인 요소로, `"☕"` ` "💻"` `"🍷"` `"🍫"`이 출력돼요.
#### 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.
+배열 요소들은 모든 값을 포함 할 수 있어요. Numbers, strings, objects, 다른 arrays, null, boolean 값, undefined, 그리고 자료형, 함수, 연산자와 같은 표현식들
-The element will be equal to the returned value. `1 + 2` returns `3`, `1 * 2` returns `2`, and `1 / 2` returns `0.5`.
+요소는 리턴된 값과 같아질 거예요. `1 + 2`는 `3`을 리턴하고, `1 * 2`는 `2`를 리턴하고, `1 / 2` 는 `0.5`을 리턴해요.
#### Answer: B
-By default, arguments have the value of `undefined`, unless a value has been passed to the function. In this case, we didn't pass a value for the `name` argument. `name` is equal to `undefined` which gets logged.
+기본값으로, 함수에 값이 전달되지 않으면, 인수는 `undefined` 값을 가져요. 이 경우, `name` 인수를 위한 값을 전달하지 않았어요. `name`은 `undefined`로 출력돼요.
-In ES6, we can overwrite this default `undefined` value with default parameters. For example:
+ES6에서, 기본값 `undefined` 값을 기본값 파라미터로 덮어쓸 수 있어요. 예를 들면:
`function sayHi(name = "Lydia") { ... }`
-In this case, if we didn't pass a value or if we passed `undefined`, `name` would always be equal to the string `Lydia`
+이 경우, 값을 전달하지 않거나 `undefined`를 전달하면, `name`은 항상 문자열 `Lydia`가 될 거예요.
#### Answer: B
-The value of the `this` keyword is dependent on where you use it. In a **method**, like the `getStatus` method, the `this` keyword refers to _the object that the method belongs to_. The method belongs to the `data` object, so `this` refers to the `data` object. When we log `this.status`, the `status` property on the `data` object gets logged, which is `"🥑"`.
-
-With the `call` method, we can change the object to which the `this` keyword refers. In **functions**, the `this` keyword refers to the _the object that the function belongs to_. We declared the `setTimeout` function on the _global object_, so within the `setTimeout` function, the `this` keyword refers to the _global object_. On the global object, there is a variable called _status_ with the value of `"😎"`. When logging `this.status`, `"😎"` gets logged.
+`this`키워드의 값은 사용하는 곳에 따라 달라요. **메소드**에서 `getStatus`메소드 처럼, `this`키워드는 _메소드가 속한 객체_ 를 참조해요. 이 메소드는 `data` 객체에 속해 있어, `this`는 `data`객체를 참조해요. `this.status`를 출력할 때, `data`객체의 `status` 속성 `"🥑"`이 출력돼요.
+`call` 메소드에서는, `this` 키워드가 참조하는 객체를 바꿀 수 있어요. **함수**에서, `this` 키워드는 _함수가 속한 객체_ 를 참조해요. `setTimeout` 함수를 _전역 객체_ 에 선언했고, `setTimeout` 함수 안에서, `this`키워드는 _전역 객체_ 를 참조해요. 전역 객체에서, 변수는 `"😎"`값을 가진 _status_ 를 부르죠. `this.status`를 출력하면, `"😎"`이 출력돼요.
#### Answer: A
-We set the variable `city` equal to the value of the property called `city` on the `person` object. There is no property on this object called `city`, so the variable `city` has the value of `undefined`.
+`city` 변수를 `person` rorcpdml `city`라고 불리는 속성 값으로 설정 했어요. 이 객체에서는 `city`라고 불리는 속성이 없기 때문에, `city`는 `undefined`의 값을 가져요.
-Note that we are _not_ referencing the `person` object itself! We simply set the variable `city` equal to the current value of the `city` property on the `person` object.
+`person`객체 자체를 참조 _하지않는_ 다는 걸 참고해요! 변수 `city`는 `person` 객체의 `city` 현재 속성 값으로 설정 했을 뿐이죠.
-Then, we set `city` equal to the string `"Amsterdam"`. This doesn't change the person object: there is no reference to that object.
+그러므로, 우리는 `city`를 문자열 `"Amsterdam"`로 설정 했어요. 이건 person 객체를 바꾸지 않아요: 여기서 객체를 참조하는 건 없어요.
-When logging the `person` object, the unmodified object gets returned.
+`person`객체를 출력할 때, 수정되지 않은 객체가 리턴 받아요.
#### Answer: C
-Variables with the `const` and `let` keyword are _block-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.
+`const`와 `let` 키워드를 사용한 변수는 _블록-스코프_ 예요. 블록은 중괄호 (`{ }`) 사이에 있는 것이죠. 이 경우, if/else 표현식의 중괄호를 의미해요. 블록 안에 선언된 건 블록 밖의 변수들을 참조하지 못해, ReferenceError를 던져요.
#### Answer: C
-The value of `res` in the second `.then` is equal to the returned value of the previous `.then`. You can keep chaining `.then`s like this, where the value is passed to the next handler.
+두번째 `.then`에서의 `res`의 값은 이전`.then`에서 리턴된 값이에요. 이것 처럼 `.then`을 계속해서 연결할 수 있고, 값은 계속해서 다음 핸들러로 전달 돼요.
#### Answer: A
-With `!!name`, we determine whether the value of `name` is truthy or falsey. If name is truthy, which we want to test for, `!name` returns `false`. `!false` (which is what `!!name` practically is) returns `true`.
+`!!name`에서, 우리는 `name`의 값이 참 같은지 거짓 같은지 결정해요. 만약 테스트 하려는 name이 참 같다면, `!name`은 `false`를 리턴해요. `!false` (실제로는 `!!name`)는 `true`를 리턴해요.
-By setting `hasName` equal to `name`, you set `hasName` equal to whatever value you passed to the `getName` function, not the boolean value `true`.
+`hasName`을 `name`으로 설정하면, `hasName`은 불린 값 `true`가 아니라, `getName` 함수에 전달된 값으로 설정해요.
-`new Boolean(true)` returns an object wrapper, not the boolean value itself.
+`new Boolean(true)`은 불린 값 자체가 아닌, 감싼 객체를 리턴해요.
-`name.length` returns the length of the passed argument, not whether it's `true`.
+`name.length`은 그것의 `true`의 여부가 아닌, 전달된 인수의 길이를 리턴해요.
From 91b1a158d519513d74789627ca852227ce7d9278 Mon Sep 17 00:00:00 2001
From: Alexander Ivanov
+
+#### Ответ: B
+
+В JavaScript мы _не должны_ явно указывать точку с запятой (`;`), однако движок JavaScript все равно добавляет их после операторов. Это называется **автоматической вставкой точек с запятой**. Например, оператором могут быть переменные или ключевые слова, такие как `throw`, `return`, `break` и т.д.
+
+Здесь мы написали инструкцию `return` и другое значение `a + b` в новой строке. Однако, поскольку это новая линия, движок не знает, что это на самом деле значение, которое мы хотели бы вернуть. Вместо этого он автоматически добавляет точку с запятой после `return`. Вы можете увидеть это как:
+
+```javascript
+ return;
+ a + b
+```
+
+Это означает, что `a + b` никогда не достигается, так как функция перестает выполняться после ключевого слова `return`. Если значение не возвращается, как здесь, функция возвращает значение `undefined`. Обратите внимание, что после операторов `if / else` автоматической вставки нет!
+
+
+
+#### Ответ: B
+
+Мы можем установить классы равными другим классам/конструкторам функций. В этом случае мы устанавливаем `Person` равным `AnotherPerson`. Свойство `name` этого конструктора - `Sarah`, поэтому свойство `name` для нового экземпляра класса `Person` `member` - это `Sarah`.
+
+
+
+#### Ответ: D
+
+`Symbol` не является _перечисляемый_. Метод `Object.keys` возвращает все _перечисляемые_ свойства ключа для объекта. `Symbol` не просматривается таким образом, и возвращается пустой массив. При регистрации всего объекта будут видны все свойства, даже не перечисляемые.
+
+Это одно из многих качеств символа: помимо представления совершенно уникального значения (которое предотвращает случайное столкновение имен в объектах, например, при работе с 2 библиотеками, которые хотят добавить свойства к одному и тому же объекту), вы также можете "скрыть" свойства объектов таким образом (хотя и не полностью. Вы можете получить доступ к символам, используя метод `Object.getOwnPropertySymbols()`).
+
+
+
+#### Ответ: A
+The `getList` function receives an array as its argument. Between the parentheses of the `getList` function, we destructure this array right away. You could see this as:
+Функция `getList` получает массив в качестве аргумента. Между скобками функции `getList` мы сразу же деструктурируем этот массив. Вы можете увидеть это как:
+
+ `[x, ...y] = [1, 2, 3, 4]`
+
+С помощью оставшихся параметров `... y` мы помещаем все "оставшиеся" аргументы в массив. Остальные аргументы - это `2`, `3` и `4` в этом случае. Значение `y` является массивом, содержащим все остальные параметры. В этом случае значение `x` равно `1`, поэтому, мы видим в логе `[x, y]`, `[1, [2, 3, 4]]`.
+
+Функция `getUser` получает объект. В случае функций со стрелками мы не можем писать фигурные скобки, если мы просто возвращаем одно значение. Однако, если вы хотите вернуть _объект_ из стрелочной функции, вы должны написать его в скобках, в противном случае никакое значение не возвращается! Следующая функция вернула бы объект:
+
+```const getUser = user => ({ name: user.name, age: user.age })```
+
+Поскольку в этом случае значение не возвращается, функция возвращает значение `undefined`.
+
+
+
+#### Ответ: C
+
+Переменная `name` содержит значение строки, которая не является функцией, поэтому не может вызываться.
+
+Ошибки типа выдаются, когда значение не соответствует ожидаемому типу. JavaScript ожидал, что `name` будет функцией, так как мы пытаемся вызвать ее. Однако это была строка, поэтому выдается ошибка TypeError: name не является функцией!
+
+Синтаксические ошибки генерируются, когда вы написали что-то, что не является допустимым JavaScript, например, когда вы написали слово `return` как `retrun`.
+ReferenceErrors генерируется, когда JavaScript не может найти ссылку на значение, к которому вы пытаетесь получить доступ.
+
+
+
+#### Ответ: B
+
+`[]` - истинное значение. С оператором `&&` будет возвращено правое значение, если левое значение является истинным значением. В этом случае левое значение `[]` является истинным значением, поэтому возвращается `'Im'`.
+
+`""` - ложное значение. Если левое значение ложно, ничего не возвращается. `n't` не возвращается.
+
+
+
+#### Ответ: C
+
+С помощью оператора `||` мы можем вернуть первый истинный операнд. Если все значения ложны, последний операнд возвращается.
+
+`(false || {} || null)`: пустой объект `{}` является истинным значением. Это первое (и единственное) истинное значение, которое возвращается. `one` содержит `{}`.
+
+`(null || false ||" ")`: все операнды являются ложными значениями. Это означает, что прошедший операнд `""` возвращается. `two` содержит `""`.
+
+`([] || 0 ||" ")`: пустой массив `[]` является истинным значением. Это первое истинное значение, которое возвращается. `three` присвоено `[]`.
+
+
@@ -2788,11 +2788,11 @@ sum(10)
###### 89. Какой будет вывод?
```javascript
-// module.js
+// module.js
export default () => "Hello world"
export const name = "Lydia"
-// index.js
+// index.js
import * as data from "./module"
console.log(data)
@@ -2895,8 +2895,8 @@ console.log(giveLydiaPizza.prototype)
console.log(giveLydiaChocolate.prototype)
```
-- A: `{ constructor: ...}` `{ constructor: ...}`
-- B: `{}` `{ constructor: ...}`
+- A: `{ constructor: ...}` `{ constructor: ...}`
+- B: `{}` `{ constructor: ...}`
- C: `{ constructor: ...}` `{}`
- D: `{ constructor: ...}` `undefined`
@@ -2926,7 +2926,7 @@ for (const [x, y] of Object.entries(person)) {
```
- A: `name` `Lydia` and `age` `21`
-- B: `["name", "Lydia"]` and `["age", 21]`
+- B: `["name", "Lydia"]` and `["age", 21]`
- C: `["name", "age"]` and `undefined`
- D: `Error`
@@ -2937,7 +2937,7 @@ for (const [x, y] of Object.entries(person)) {
`Object.entries (person)` возвращает массив вложенных массивов, содержащий ключи и объекты:
-`[ [ 'name', 'Lydia' ], [ 'age', 21 ] ]`
+`[ [ 'name', 'Lydia' ], [ 'age', 21 ] ]`
Используя цикл `for-of`, мы можем перебирать каждый элемент массива, в данном случае подмассивы. Мы можем мгновенно деструктурировать подмассивы в цикле for, используя `const [x, y]`. `x` равен первому элементу в подмассиве, `y` равен второму элементу в подмассиве.
@@ -2960,7 +2960,7 @@ getItems(["banana", "apple"], "pear", "orange")
```
- A: `["banana", "apple", "pear", "orange"]`
-- B: `[["banana", "apple"], "pear", "orange"]`
+- B: `[["banana", "apple"], "pear", "orange"]`
- C: `["banana", "apple", ["pear"], "orange"]`
- D: `SyntaxError`
@@ -2992,9 +2992,9 @@ function nums(a, b) {
if
(a > b)
console.log('a is bigger')
- else
+ else
console.log('b is bigger')
- return
+ return
a + b
}
From 4bbfcdfc08fc6607d304b7c765de6beee7a3cd2a Mon Sep 17 00:00:00 2001
From: Alexander Ivanov
+
+#### Cevap: B
+
+JavaScript'te, noktalı virgülü (`;`) özellikle yazmak _zorunda değiliz_, ancak JavaScript motoru ifadelerden sonra noktalı virgül eklemektedir. bu **Automatic Semicolon Insertion**, **Otomatik Noktalı Virgül Ekleme**, olarak adlandırılır. İfade, örneğin, değişkenler ya da `throw`, `return`, `break`, vb. gibi anahtar kelimeler olabilir.
+
+Burada, bir `return` ifadesi yazdık, ve _yeni bir satırda_ başka bir değer olarak `a + b`. Ancak, `a + b` yeni satırda olduğundan, JavaScript motoru onun aslında bizim döndürmek istediğimiz değer olduğunu bilmiyor. Onun yerine, `return`'den sonra otomatik olarak noktalı virgül ekliyor. Şöyle düşünebilirsiniz:
+
+```javascript
+ return;
+ a + b
+```
+
+Fonksiyon `return` anahtar kelimesinden sonra çalışmayı durduracağından, `a + b` asla ulaşılamaz demektir. Eğer hiçbir değer döndürülmezse, fonksiyon `undefined` döndürür. Dikkat etmeniz gereken, `if/else` ifadelerinden sonra otomatik ekleme yapılmadığıdır!
+
+
+
+#### Cevap: B
+
+Sınıfları diğer sınıf/fonksiyon yapıcılara eşitleyebiliriz. Bu örnekte, `Person`'ı `AnotherPerson`'a eşitliyoruz. Bu yapıcıdaki `name` `Sarah`'dır, yani `Person` instance'ı olan `member` üzerindeki `name` özelliği `"Sarah"`'tır.
+
+
+
+#### Cevap: D
+
+A Symbol is not _enumerable_. The Object.keys method returns all _enumerable_ 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 the `Object.getOwnPropertySymbols()` method).
+
+
+
+#### Cevap: A
+
+The `getList` function receives an array as its argument. Between the parentheses of the `getList` 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 are `2`, `3` and `4` in this case. The value of `y` is an array, containig all the rest parameters. The value of `x` is equal to `1` in this case, so when we log `[x, y]`, `[1, [2, 3, 4]]` gets logged.
+
+ The `getUser` function receives an object. With arrow functions, we don't _have_ to write curly brackets if we just return one value. However, if you want to return an _object_ from an arrow function, you have to write it between parentheses, otherwise no value gets returned! The following function would have returned an object:
+
+```const getUser = user => ({ name: user.name, age: user.age })```
+
+Since no value gets returned in this case, the function returns `undefined`.
+
+
+
+#### Cevap: C
+
+The variable `name` holds the value of a string, which is not a function, thus cannot invoke.
+
+TypeErrors get thrown wehn a value is not of the expected type. JavaScript expected `name` 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 word `return` as `retrun`.
+ReferenceErrors get thrown when JavaScript isn't able to find a reference to a value that you're trying to access.
+
+
+
+#### Cevap: 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.
+
+
+
+#### Cevap: 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 past 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 `[]`.
+
+
#### Cevap: D
-A Symbol is not _enumerable_. The Object.keys method returns all _enumerable_ 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.
+Symbol _sayılabilir_, "_enumerable_" değildir. Object.keys methodu nesne üzerindeki tüm _sayılabilir_ özellikleri döndürür. Symbol gizli kalır ve boş bir dizi döndürülür. Tüm nesne loglandığı zaman, bütün özellikler görülebilir, sayılabilir olmayanlar bile.
-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 the `Object.getOwnPropertySymbols()` method).
+Bu symbol'ün birçok özelliğinden birisidir: tamamen benzersiz bir değer temsil etmenin yanında (ki nesneler üzerindeki kazara isim çakışmasını önler, örneğin aynı nesneye özellikler eklemek isteyen 2 kütüphaneyle çalışırken), ayrıca bu yolla nesne üzerindeki özellikleri "saklayabilirsiniz" (gerçi tamamen değil. `Object.getOwnPropertySymbols()` methodunu kullanarak symbol'lere hala erişebilirsiniz).
#### Cevap: A
-The `getList` function receives an array as its argument. Between the parentheses of the `getList` function, we destructure this array right away. You could see this as:
+`getList` fonksiyonu argüman olarak bir dizi alır. `getList` fonksiyonunun parentezleri arasında, bu diziyi anında parçalıyoruz. Şu şekilde görebilirsiniz:
`[x, ...y] = [1, 2, 3, 4]`
- With the rest parameter `...y`, we put all "remaining" arguments in an array. The remaining arguments are `2`, `3` and `4` in this case. The value of `y` is an array, containig all the rest parameters. The value of `x` is equal to `1` in this case, so when we log `[x, y]`, `[1, [2, 3, 4]]` gets logged.
+ `...y` rest parametresi ile, dizi içinde "geriye kalan" tüm argümanları topluyoruz. Geriye kalan argümanlar `2`, `3`, ve `4` bu durumda. `y`'nin değeri tüm rest parametleri içeren bir dizi. `x`'in değeri `1`'a eşit, yani `[x, y]` logladığımız zaman, `[1, [2, 3, 4]]` loglanır.
- The `getUser` function receives an object. With arrow functions, we don't _have_ to write curly brackets if we just return one value. However, if you want to return an _object_ from an arrow function, you have to write it between parentheses, otherwise no value gets returned! The following function would have returned an object:
+ `getUser` fonksiyonu bir nesne alıyor. Ok fonksiyonlar ile, eğer sadece bir değer döndürmek istiyorsak süslü parentezleri yazmak _zorunda değiliz._ Ancak, bir ok fonksiyondan bir _nesne_ döndürmek istiyorsanız, parentezler arasında yazmak zorundasınız, aksi halde değer döndürülmez! Aşağıdaki fonksiyon bir nesne döndürecektir:
```const getUser = user => ({ name: user.name, age: user.age })```
-Since no value gets returned in this case, the function returns `undefined`.
+Bu örnekte değer döndürülmediği için, fonksiyon `undefined` döndürür.
정답
Answer
+정답
Answer
+정답
Answer
+정답
Answer
+정답
Answer
+정답
Answer
+정답
Answer
+정답
Answer
+정답
Ответ
Ответ
+Ответ
+Ответ
+Ответ
+Ответ
+Ответ
+Ответ
+Ответ
Cevap
+Cevap
+Cevap
+Cevap
+Cevap
+Cevap
+Cevap
+Cevap
Cevap
+ +#### Đáp án: C + +Trong ES6 thì chúng ta có thể khởi tạo tham số với giá trị mặc định. Giá trị của tham số sẽ là giá trị mặc định nếu ta không truyền gì vào hàm, hoặc khi giá trị truyền vào là `"undefined"`. Trong trường hợp này, ta dùng `spread operator` (toán tử mở rộng) để biến `value` thành một object mới, do đó `x` sẽ có giá trị mặc định là `{ number: 10 }`. + +Chú ý một điều là đối số sẽ được xét giá trị tại _call time_! Có nghĩa là mỗi khi chúng ta gọi hàm, một _object mới_ sẽ được tạo ra. Chúng ta gọi hàm `multiply` hai lần mà không truyền vào đối số nào cả: `x` sẽ nhận giá trị mặc định `{ number: 10 }`. Sau đó chúng ta sẽ ghi ra giá trị là `20`. + +Lần gọi thứ ba chúng ta truyền vào một đối số: chính là `value`. Toán tử `*=` chính là cách viết gọn của `x.number = x.number * 2`: chúng ta thay đổi giá trị của `x.number`, và ghi ra giá trị `20`. + +Tại lần gọi thứ tư, chúng ta truyền vào `value` một lần nữa. `x.number` trước đó đã bị thay đổi thành `20`, nên `x.number *= 2` sẽ ghi ra `40`. + +
++ +#### Đáp án: D + +Đối số đầu tiên của hàm `reduce` chính là _accumulator_ (tổng tích lũy), trong trường hợp này là `x`. Đối số thứ 2 chính là _giá trị hiện tại_, tức `y`. Với hàm reduce, ta sẽ gọi callback trên mỗi phần tử của mảng, cứ vậy cho tới khi ra đến một giá trị cuối cùng. + +Trong trường hợp này, chúng ta không trả về bất cứ giá trị nào cả, mà đơn thuần chỉ là ghi ra giá trị của _tổng tích lũy_ và _giá trị hiện tại_ mà thôi. + +Giá trị của tổng tích lũy chính là giá trị được hàm callback trả về tại vòng lặp trước đó. Nếu ta không đặt giá trị khởi tạo cho đối số trong hàm `reduce`, thì tổng tích lũy sẽ chính bằng giá trị đầu tiên tại lời gọi đầu tiên. + +Trong lời gọi đầu tiên, tổng tích lũy (`x`) là `1`, và giá trị hiện tại (`y`) là `2`. Chúng ta không trả về giá trị cho hàm callback, mà đơn thuần chỉ ghi chúng ta, vậy nên `1` và `2` được ghi ra. + +Nếu ta không trả về giá trị trong một function, thì nó sẽ mặc định trả về là `undefined`. Do đó trong lời gọi tiếp theo tổng tích lũy sẽ là `undefined`, và giá trị hiện tại là `3`. `undefined` và `3` sẽ được ghi ra. + +Tiếp tục như vậy, trong lời gọi thứ tư thì tổng tích lũy sẽ vẫn là `undefined`, giá trị hiện tại là `4`. `undefined` và `4` sẽ được ghi ra. +
++ +#### Đáp án: B + +Trong class dẫn xuất, ta không thể truy cập từ khóa `this` trước khi gọi `super`. Nếu bạn chạy thử, nó sẽ throw ra một `ReferenceError`, do đó 1 và 4 sẽ throw ra reference error. + +Với việc gọi `super`, chúng ta đã gọi hàm constructor của class cha với tham số truyền vào. Trong trường hợp này, class cha nhận `name` làm đối số trong constructor, do đó chúng cần đưa `name` vào hàm `super`. + +`Labrador` class nhận vào hai đối số, `name` vì nó kế thừa `Dog`, và `size` - một thuộc tính của `Labrador` class. Cả hai đều cần thiết để đưa vào trong constructor của class `Labrador`, do đó cách khởi tạo đúng là 2. +
++ +#### Đáp án: B + +Với `import`, tất cả các module import vào đều sẽ được _pre-parsed_ (đánh giá trước). Có nghĩa là những module được import vào sẽ được _chạy trước_, còn code trong file sẽ _chạy sau_. + +Đó chính là điều khác biệt giữa `require()` trong CommonJS và `import`! Với `require()`, ta có thể load các dependencies tại bất cứ khi nào ta cần. Nếu ta sử dụng `require` thay thế cho `import` thì `running index.js`, `running sum.js`, `3` sẽ được ghi ra. + +
++ +#### Đáp án: A + +Mỗi Symbol là một thứ hoàn toàn khác biệt. Giá trị truyền vào làm đối số trong Symbol chỉ đơn thuần là phần giải thích cho Symbol đó mà thôi, và nó không liên quan gì tới giá trị của Symbol đó cả. Chúng ta kiểm tra tính bằng nhau của hai Symbol hoàn toàn khác biệt: `Symbol('foo')` thứ nhất, và `Symbol('foo')` thứ hai. Mỗi giá trị đều là riêng biệt và duy nhất, nên `Symbol('foo') === Symbol('foo')` sẽ trả về `false`. + +
++ +#### Đáp án: C + +Với hàm `padStart` chúng ta có thể thêm vào khoảng trắng đằng trước mỗi chuỗi. Giá trị đưa vào trong hàm là _tổng độ dài_ của chuỗi sau khi thêm vào khoảng trắng. Chuỗi `"Lydia Hallie"` có độ dài là `12` nên `name.padStart(13)` sẽ thêm vào một khoảng trắng đằng trước chuỗi. + +Nếu đối số truyền vào cho hàm `padStart` nhỏ hơn độ dài của chuỗi, không có khoảng trắng nào được thêm vào. + +
++ +#### Đáp án: A + +Với phép toán `+`, ta có thể nối các xâu chuỗi. Trong trường hợp này, ta nối chuỗi `"🥑"` với chuỗi `"💻"`, kết quả tạo ra `"🥑💻"`. + +
++ +#### Đáp án: C + +Một _generator_ sẽ "tạm dừng" khi nhìn thấy từ khóa `yield`. Đầu tiên ra sẽ đưa ra chuỗi "Do you love JavaScript?", bằng cách gọi `game.next().value`. + +Chương trình sẽ chạy từng dòng, cho tới khi nó tìm thấy từ khóa `yield`. Có một từ khóa `yield` tại dòng đầu tiên của hàm: chương trình sẽ dừng tại đâ! _Điều đó có nghĩa là biến `answer` chưa hề được định nghĩa!_ + +Khi ta gọi `game.next("Yes").value`, `yield` trước đó sẽ được thay thế bởi giá trị được truyền vào hàm `next()`, trong trường hợp này là`"Yes"`. Theo đó giá trị của biến `answer` giờ sẽ là `"Yes"`. Điều kiện if sẽ trả về `false`, và `JavaScript loves you back ❤️` sẽ được ghi ra. + +
++ +#### Đáp án: C + +`String.raw` trả về chuỗi nguyên bản, các ký tự (`\n`, `\v`, `\t` etc.) sẽ vẫn là nguyên bản và không biến thành xuống dòng hay khoảng trắng! Nếu ta không để là chuỗi nguyên bản, sẽ có trường hợp xảy ra lỗi không mong muốn, ví dụ với đường dẫn: + +`` const path = `C:\Documents\Projects\table.html` `` + +Sẽ cho ta chuỗi là: + +`"C:DocumentsProjects able.html"` + +Với `String.raw`, nó sẽ trả về là: + +`C:\Documents\Projects\table.html` + +Do đó, trong trường hợp này `Hello\nworld` sẽ được ghi ra. + +
++ +#### Đáp án: C + +Một hàm `async` luôn luôn trả về một `promise`. `await` sẽ chờ cho tới khi promise đó được hoàn thành: một pending promise sẽ được trả về khi ta gọi `getData()` bằng cách gán nó cho biến `data`. + +Nếu ta muốn truy cập giá trị đã hoàn thành của promise, trong trường hợp này là `"I made it"`, ta có thể sử dụng hàm `.then()` ngay sau `data` như sau: + +`data.then(res => console.log(res))` + +Khi này nó sẽ ghi ra `"I made it!"` + +
++ +#### Đáp án: B + +Hàm `.push()` trả về _độ dài_ của mảng mới! Trước đó, mảng chỉ hồm một phần tử là `"banana"` và có độ dài là `1`. Sau khi thêm chuỗi `"apple"` vào mảng, mảng lúc này có hai chuỗi và có độ dài là `2`. Do đó hàm `addToList` sẽ trả về 2. + +Hàm `push` sẽ thay đổi chính bản thân mảng truyền vào. Do đó nếu chúng ta muốn trả về _mảng_ thay vì chỉ trả về _độ dài_, chúng ta nên trả về trực tiếp mảng `list` sau khi đã thêm `item` vào đó. + +
++ +#### Đáp án: B + +`Object.freeze` khiến cho chúng ta không thể thêm vào, xóa đi hay thay đổi bất kì thuộc tính nào của object (trừ phi giá trị của thuộc tính lại chính là một object khác). + +Khi chúng ta tạo ra biến `shape` và set cho nó giá trị bằng với một object đã được đóng băng là `box`, thì `shape` cũng sẽ trỏ tới một object đã được đóng băng. Ta có thể check một object có đang bị đóng băng hay không bằng `Object.isFrozen`. Trong trường hợp này, `Object.isFrozen(shape)` trả về true, vì `shape` đang trỏ tới một object bị đóng băng. + +Do đó, cộng với việc `x` không phải là object, ta sẽ không thể thay đổi giá trị của `x`. `x` sẽ vẫn là `10`, và `{ x: 10, y: 20 }` được ghi ra. + +
++ +#### Đáp án: D + +Khi ta tiến hành unpack giá trị `name` từ object ở phía bên phải, ta đã gán giá trị `"Lydia"` của nó cho biến có tên là `myName`. + +Với cú pháp `{ name: myName }`, chúng ta muốn khai báo một biến `myName` với giá trị là giá trị của thuộc tính `name` trong object phía bên phải. + +Do `name` chưa được định nghĩa, nên ghi log ra, nó sẽ throw ra một ReferenceError. + +
++ +#### Đáp án: A + +Một hàm được gọi là _pure function_ khi nó luôn luôn trả về một giá trị giống nhau, nếu đối số đưa vào là giống nhau. + +Hàm `sum` luôn trả về giá trị giống nhau. Nếu ta đưa vào `1` và `2`, nó sẽ _luôn_ trả về `3`. Nếu ta đưa vào `5` và `10`, nó _luôn_ trả về `15`. Cứ như vậy, đây là một _pure function_. + +
++ +#### Đáp án: C + +Hàm `add` chính là một hàm _memoized_ (hàm có nhớ). Với việc có nhớ, chúng ta có thể cache lại kết quả của function để tăng tốc độ tính toán lên. Trong trường hợp này, chúng ta tạo ra một `cache` object để lưu trữ những kết quả tính toán trước đó. + +Mỗi lần chúng ta gọi hàm `addFunction` với đối số giống nhau, đầu tiên nó sẽ check xem đối số đó có tồn tại trong cache hay không. Nếu có, giá trị trong cache sẽ được trả về luôn, tiết kiệm thời gian tính toán. Còn nếu không thì nó sẽ tiến hành tính toán kết quả và tiếp tục lưu vào cache. + +Chúng ta gọi hàm `addFunction` ba lần với cùng một đối số: trong lần gọi đầu tiên, giá trị của `num` là `10` và chưa có mặt trong cache. Do đó `num in cache` trả về `false`, và sẽ chạy vào else block: `Calculated! 20` sẽ được ghi ra, và 10 sẽ được đưa vào cạche. `cache` khi này sẽ là `{ 10: 20 }`. + +Tại lần gọi thứ hai, `cache` object đã có giá trị `10`. `num in cache` trả về `true`, và `'From cache! 20'` được ghi ra. + +Tại lần gọi thứ ba, ta đưa vào `5 * 2`, tức `10` vào hàm. Tiếp tục giống như trên, `'From cache! 20'` sẽ được ghi ra. + +
++ +#### Đáp án: A + +Với vòng lặp _for-in_, chúng ta có thể duyệt qua các thuộc tính **enumerable** của object. Với mảng, thuộc tính enumerable chính là các "key" của mảng, hay chính là các index của mảng đó. Ta có thể coi mảng như là: + +`{0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}` + +Do đó `0` `1` `2` `3` được ghi ra. + +Với vòng lặp _for-of_, chúng ta sẽ duyệt qua các phần tử của một **iterable**. Một mảng chính là một iterable. Khi chúng ta duyệt qua mảng, biến "item" chính là phần tử mà nó đang duyệt qua, do đó `"☕"` ` "💻"` `"🍷"` `"🍫"` được ghi ra. + +
++ +#### Đáp án: C + +Mảng có thể nhận bất cứ giá trị nào. Số, chuỗi, objects, mảng khác, null, boolean, undefined, và nhiều dạng biểu thức nữa như ngày tháng, hàm, và các tính toán. + +Giá trị của phần tử chính là giá trị trả về. `1 + 2` trả về `3`, `1 * 2` trả về `2`, và `1 / 2` trả về `0.5`. + +
++ +#### Đáp án: B + +Mặc định, đối số sẽ có giá trị là `undefined`, trừ phi ta gán giá trị cho nó khi đưa vào hàm. Trong trường hợp này, ta không đưa vào giá trị nào cho đối số `name` cả. Do đó `name` sẽ là `undefined` và được ghi ra. + +Với cú pháp ES6, ta có thể thay đổi giá trị mặc định `undefined` bằng một giá trị mặc định khác. Ví dụ: + +`function sayHi(name = "Lydia") { ... }` + +Trong trường hợp này, nếu ta không đưa giá trị nào vào hoặc đưa vào `undefined`, `name` cũng sẽ nhận giá trị mặc định là `Lydia`. + +
++ +#### Đáp án: B + +Giá trị của `this` phụ thuộc vào vị trí mà nó được gọi. Trong một **phương thức**, ví dụ `getStatus`, `this` trỏ tới _object chứa phương thức đó_. Phương thức này thuộc `data` object, do đó `this` trỏ tới `data` object. Khi chúng ta gọi `this.status` thì thuộc tính `status` của `data` sẽ được ghi ra, chính là `"🥑"`. + +Với phương thức `call`, chúng ta thay đổi tham chiếu mà `this` trỏ tới. Trong **hàm**, từ khóa `this` trỏ tới _object chứa hàm đó_. Chúng ta khai báo hàm `setTimeout` trong _global object_, do đó bên trong hàm `setTimeout` thì `this` sẽ trỏ tới _global object_. Tại biến global object, có một biến _status_ với giá trị `"😎"`. Do đó khi gọi `this.status`, `"😎"` sẽ được ghi ra. + +
++ +#### Đáp án: A + +Chúng ta set biến `city` bằng với giá trị của thuộc tính `city` của object `person`. Nhưng object này không có thuộc tính nào là `city` cả, nên giá trị của biến `city` sẽ là `undefined`. + +Chú ý là chúng ta _không tham chiếu_ tới bản thân object `person`! Chúng ta chỉ đơn giản là set giá trị của biến `city` bằng với giá trị của thuộc tính `city` trong object `person` mà thôi. + +Sau đó chúng ta set biến `city` bằng với chuỗi `"Amsterdam"`. Điều này không hề ảnh hưởng gì tới object person vì không có tham chiếu nào ở đây cả. + +Do đó khi ghi object `person` ra, Tất cả các thuộc tính vẫn như cũ không hề thay đổi gì cả. + +
++ +#### Đáp án: C + +Biến số được khai báo với các từ khóa như `const` hay `let` đều là _block-scoped_. Block chính là những khối được bao bọc bởi cặp ngoặc nhọn (`{ }`). Trong trường hợp này nó chính là cặp ngoặc bao quanh những câu lệnh `if/else`. Chúng ta không thể truy cập đến biến đó bên ngoài block, và kết quả là throw một ReferenceError. + +
++ +#### Đáp án: C + +The value of `res` in the second `.then` is equal to the returned value of the previous `.then`. You can keep chaining `.then`s like this, where the value is passed to the next handler. +Giá trị của `res` trong `.then` thứ hai chính là giá trị trả về từ `.then` trước đó. Chúng ta có thể thực hiện `.then` liên tiếp như vậy, các giá trị sẽ liên tiếp được truyền tới hàm xử lý tiếp theo. + +
++ +#### Đáp án: A + +Với `!!name`, chúng ta sẽ đánh giá giá trị của `name` là _truthy_ hay _falsy_. Nếu name là truthy, thì `!name` sẽ trả về `false`. `!false` (hay chính là `!!name` khi này) sẽ trả về `true`. + +Bằng cách set `hasName` bằng với `name`, chúng ta set `hasName` bằng với giá trị đối số đưa vào trong hàm `getName`, không thỏa mãn vì ta đã giới hạn là không đưa `true` vào. + +`new Boolean(true)` trả về một object wrapper, chứ không phải là một giá trị boolean. + +`name.length` trả về độ dài của đối số, chứ không phải `true`. + +
++ +#### Đáp án: B + +Trong trường hợp ta muốn lấy ra một ký tự trong một chuỗi, ta có thể sử dụng toán tử ngoặc vuông. Ký tự đầu tiên sẽ có thứ tự là 0, và cứ tiếp tục như vậy. Trong trường hợp này chúng ta lấy ra ký tự có thứ tự là 0, đó chính là ký tự `"I'`. + +Chú ý là phương thức này không hoạt động với IE7 trở xuống. Thay vì thế ta sử dụng `.charAt()` + +
++ +#### Đáp án: B + +Ta có thể set giá trị mặc định của một tham số là tham số khác trong hàm, miễn là tham số đó được khai báo _trước_ tham số mặc định. Chúng ta đưa `10` vào hàm `sum`. Nếu hàm `sum` chỉ nhận 1 đối số, nó có nghĩa là giá trị của `num2` không được đưa vào, nên nó sẽ lấy giá trị mặc định là giá trị của `num1` đã được đưa vào, hay chính là `10` trong trường hợp này. Khi này `num1 + num2` trả về `20`. + +Nếu chúng ta thử set một giá trị mặc định của tham số bằng với giá trị của tham số khai báo _sau_ (về bên phải), giá trị của tham số đó sẽ không được khởi tạo và dẫn đến throw ra lỗi. + +
++ +#### Đáp án: A + +Cú pháp `import * as data` sẽ import _tất cả những gì được export_ từ `module.js` vào trong `index.js` và lưu trữ dưới một object có tên là `data`. Trong file `module.js`, có hai thứ được export ra: default export và một named export. Default export là một hàm trả về chuỗi `"Hello World"`, và named export là một biến `name` nhận giá trị là chuỗi `"Lydia"`. + +Do đó `data` object có thuộc tính `default` cho default export, các thuộc tính khác sẽ có tên chính là tên của named exports và giá trị đi kèm. + +
++ +#### Đáp án: C + +Classes are syntactical sugar for function constructors. The equivalent of the `Person` class as a function constructor would be: +Classes chỉ đơn thuần là `syntactical sugar` (cú pháp đặc biệt) của function constructors mà thôi. Nó tương đương với việc ta viết một function thế này: + +```javascript +function Person() { + this.name = name +} +``` + +Gọi một constructor với từ khóa `new` sẽ tạo ra một instance của class `Person`, `typeof` sẽ trả về là `"object"` cho các instance. Do đó `typeof member` trả về `"object"`. + +
++ +#### Đáp án: D + +Hàm `.push` trả về _độ dài mới_ của mảng, chứ không phải bản thân mảng đó! Bằng cách set `newList` bằng với `[1, 2, 3].push(4)`, ta đã set cho `newList` giá trị là `4` - tức độ dài của mảng lúc này. + +Sau đó chúng ta tiến hành `.push` trên `newList`. Vì `newList` là một số thông thường, ta không thể dùng `.push` được, nên sẽ throw ra một TypeError. + +
++ +#### Đáp án: D + +Hàm thông thường giống như `giveLydiaPizza`, sẽ có thuộc tính `prototype` là một object (prototype object) với một thuộc tính là `constructor`. Còn `arrow functions` giống như `giveLydiaChocolate`thì không có thuộc tính `prototype` này. `undefined` trả về khi ta truy cập thuộc tính `prototype` bằng cách gọi `giveLydiaChocolate.prototype`. + +
++ +#### Đáp án: A + +`Object.entries(person)` sẽ trả về một mảng của mảng, bao gồm các key và các object: + +`[ [ 'name', 'Lydia' ], [ 'age', 21 ] ]` + +Khí sử dụng `for-of`, chúng ta sẽ duyệt qua từng thành phần của mảng, trong trường hợp này chính là những mảng con. Đồng thời tiến hành gán giá trị luôn trong vongf lặp for-of, bằng cách sử dụng `const [x, y]`. Khi này `x` sẽ là phần tử đầu tiên trong mảng con, `y` chính là phần tử thứ hai trong mảng con. + +Mảng con đầu tiên là `[ "name", "Lydia" ]`, nên `x` sẽ là `"name"`, và `y` sẽ là `"Lydia"`, và được ghi ra. +Mảng con thứ hai là `[ "age", 21 ]`, nên `x` sẽ là `"age"`, và `y` sẽ là `21`, và được ghi ra. + +
++ +#### Đáp án: D + +`...args` là cú pháp tham số cuối cùng. Giá trị của tham số cuối cùng chính là toàn bộ các đối số còn lại, **và nó là tham số cuối cùng duy nhất**! Trong trường hợp này, tham số cuối cùng lại là tham số thứ hai. Điều đó là không thể được, và sẽ throw ra một lỗi cú pháp. + +```javascript +function getItems(fruitList, favoriteFruit, ...args) { + return [...fruitList, ...args, favoriteFruit] +} + +getItems(["banana", "apple"], "pear", "orange") +``` + +Nếu ta code như thế này thì lại đúng. Giá trị trả về sẽ là `[ 'banana', 'apple', 'orange', 'pear' ]` +
++ +#### Đáp án: B + +Với JavaScript, ta _không bắt buộc_ phải viết dấu chấm phẩy (`;`), JavaScript engine sẽ tự động thêm vào sau mỗi câu lệnh. Nó gọi là **Automatic Semicolon Insertion**. Một câu lệnh có thể là khai báo biến, hoặc từ khóa như `throw`, `return`, `break`, vv. + +Ở đây ta sử dụng câu lệnh `return` ở một dòng và giá trị `a + b` ở một _dòng khác_. Tuy nhiên do khác dòng nên JS engine không thể biết đâu là giá trị ta thực sự muốn trả về. Thay vì thế, nó sẽ tự động thêm vào dấu chấm phẩy ngay sau `return` giống như này: + +```javascript + return; + a + b +``` + +Có nghĩa là `a + b` sẽ không bao giờ được thực hiện, vì hàm đã được `return` rồi. Do không giá trị nào được trả về, nên giá trị trả về của hàm sẽ là `undefined`. Lưu ý là sẽ không tự động thêm dấu chấm phẩy ngay sau `if/else` đâu nhé! + +
++ +#### Đáp án: B + +Chúng ta có thể set một class với giá trị là một classes/function constructor khác. Trong trường hợp này, ta set `Person` bằng với `AnotherPerson`. Trong constructor, `this.name` là `Sarah`, do đó giá trị của thuộc tính này trong instance `member` chính là `"Sarah"`. + +
++ +#### Đáp án: D + +Phương thức `Object.keys` sẽ trả về toàn bộ những key của các thuộc tính _enumerable_ trên một object. Nhưng Symbol không phải dạng _enumerable_. do đó nó sẽ trả về một mảng rỗng. Tuy nhiên khi ta log ra toàn bộ object, thì ta sẽ ghi ra toàn bộ các thuộc tính, cho dù đó có là thuộc tính _enumerable_ hay không. + +Đó chính là một đặc trưng của Symbol: Bên cạnh việc nó biểu diễn một giá trị duy nhất (tránh việc xảy ra xung đột tên gọi, ví dụ khi ta sử dụng 2 thư viện mà muốn thêm thuộc tính vào cho cùng một object chẳng hạn), nó còn giúp "ẩn" thuộc tính đó đi (dù không hoàn toàn, ta vẫn có thể truy cập được bằng cách sử dụng phương thức `Object.getOwnPropertySymbols()`). + +
++ +#### Đáp án: A + +Hàm `getList` nhận vào một mảng các đối số, và tiến hành xử lý mảng đó luôn khi đưa vào hàm: + + `[x, ...y] = [1, 2, 3, 4]` + + Với việc sử dụng cú pháp tham số cuối cùng `...y`, chúng ta đưa toàn bộ "những đối số còn lại" vào một mảng y. Trong trường hợp này đó là mảng gồm các phần tử `2`, `3` và `4`. Do đó giá trị của `y` lúc này chính là mảng `[2, 3, 4]`. Giá trị của `x` là `1`, nên khi ghi `[x, y]` ra, kết quả sẽ là `[1, [2, 3, 4]]`. + +Hàm `getUser` nhận vào một object. Với cú pháp arrow function, chúng ta sẽ không phải viết trong ngoặc nhọn `{}` nữa nếu ta chỉ muốn đơn thuần trả về giá trị. Tuy nhiên, nếu ta muốn trả về một _object_ t arrow function, ta sẽ phải viết chúng trong dấu ngoặc tròn `()`, nếu không thì sẽ không có giá trị nào được trả về! Ví dụ như sau: + +```const getUser = user => ({ name: user.name, age: user.age })``` + +Do không giá trị nào được trả về, kết quả sẽ là `undefined`. + +
++ +#### Đáp án: C + +Biến `name` có giá trị là một chuỗi, không phải hàm, vì thế không thể gọi được. + +TypeErrors sẽ được throw ra nếu một giá trị không được sử dụng đúng kiểu. JavaScript muốn `name` là một hàm khi ta tiến hành gọi nó. Nhưng nó là chuỗi, nên sẽ throw ra một TypeError. + +SyntaxErrors sẽ được throw khi ta viết code không đúng cú pháp của JavaScript, ví dụ thay vì `return` ta viết `retrun`. + +ReferenceErrors sẽ được throw ra khi Javascript không thể tìm được tham chiếu nào đến giá trị mà ta đang cố truy cập. + +
++ +#### Đáp án: B + +`[]` là một giá trị truthy. Với phép toán `&&` , giá trị bên phải sẽ được trả về nếu giá trị bên trái là truthy. Trong trường hợp này giá trị bên trái `[]` là truthy, nên `"Im'` sẽ được trả về. + +`""` là một giá trị falsy. Nếu giá trị bên trái là falsy, không có gì được trả về cả. Do đó `n't` sẽ không được trả về. + +
++ +#### Đáp án: C + +Với phép toán `||`, ta sẽ trả về giá trị truethy đầu tiên. Nếu tất cả đều là falsy, giá trị cuối cùng sẽ được trả về. + +`(false || {} || null)`: object rỗng `{}` là một giá trị truthy. Nó là giá trị truethy đầu tiên và duy nhất nên sẽ được trả về. Do đó `one` sẽ là `{}`. + +`(null || false || "")`: Tất cả toán hạng đều là falsy. Có nghĩa là toán hạng cuối cùng `""` sẽ được trả về. Do đó `two` sẽ là `""`. + +`([] || 0 || "")`: mảng rỗng `[]` là một giá trị truthy. Nó là giá trị truthy đầu tiên nên sẽ được trả về. Do đó `three` sẽ là `[]`. + +
+
-#### Answer: A
+#### 정답: A
_for-in_ 루프에서는, **열거 가능한** 속성들에 대해 반복 할 수 있어요. 배열에서, 열거 가능한 속성들은 배열 요소들의 "키"이고, 실제로는 그들의 인덱스죠. 배열을 다음과 같이 볼 수 있어요:
@@ -2523,7 +2523,7 @@ console.log(list);
-#### Answer: C
+#### 정답: C
배열 요소들은 모든 값을 포함 할 수 있어요. Numbers, strings, objects, 다른 arrays, null, boolean 값, undefined, 그리고 자료형, 함수, 연산자와 같은 표현식들
@@ -2552,7 +2552,7 @@ console.log(sayHi());
-#### Answer: B
+#### 정답: B
기본값으로, 함수에 값이 전달되지 않으면, 인수는 `undefined` 값을 가져요. 이 경우, `name` 인수를 위한 값을 전달하지 않았어요. `name`은 `undefined`로 출력돼요.
@@ -2595,7 +2595,7 @@ setTimeout(() => {
-#### Answer: B
+#### 정답: B
`this`키워드의 값은 사용하는 곳에 따라 달라요. **메소드**에서 `getStatus`메소드 처럼, `this`키워드는 _메소드가 속한 객체_ 를 참조해요. 이 메소드는 `data` 객체에 속해 있어, `this`는 `data`객체를 참조해요. `this.status`를 출력할 때, `data`객체의 `status` 속성 `"🥑"`이 출력돼요.
@@ -2628,7 +2628,7 @@ console.log(person);
-#### Answer: A
+#### 정답: A
`city` 변수를 `person` rorcpdml `city`라고 불리는 속성 값으로 설정 했어요. 이 객체에서는 `city`라고 불리는 속성이 없기 때문에, `city`는 `undefined`의 값을 가져요.
@@ -2667,7 +2667,7 @@ console.log(checkAge(21));
-#### Answer: C
+#### 정답: C
`const`와 `let` 키워드를 사용한 변수는 _블록-스코프_ 예요. 블록은 중괄호 (`{ }`) 사이에 있는 것이죠. 이 경우, if/else 표현식의 중괄호를 의미해요. 블록 안에 선언된 건 블록 밖의 변수들을 참조하지 못해, ReferenceError를 던져요.
@@ -2692,7 +2692,7 @@ fetch('https://www.website.com/api/user/1')
-#### Answer: C
+#### 정답: C
두번째 `.then`에서의 `res`의 값은 이전`.then`에서 리턴된 값이에요. 이것 처럼 `.then`을 계속해서 연결할 수 있고, 값은 계속해서 다음 핸들러로 전달 돼요.
@@ -2717,7 +2717,7 @@ function getName(name) {
-#### Answer: A
+#### 정답: A
`!!name`에서, 우리는 `name`의 값이 참 같은지 거짓 같은지 결정해요. 만약 테스트 하려는 name이 참 같다면, `!name`은 `false`를 리턴해요. `!false` (실제로는 `!!name`)는 `true`를 리턴해요.
@@ -2729,3 +2729,497 @@ function getName(name) {
+
+#### 정답: B
+
+문자열의 특정 인덱스의 문자를 얻으려면, 대괄호 표기법을 사용하면 돼요. 문자열의 첫 번째 문자는 인덱스 0과 기타등등을 가지고 있어요. 이 경우 문자 `"I'`인 인덱스 0이 출력되는 요소를 갖길 원해요.
+
+이 방법은 IE7 이하에서는 지원되지 않는다는 것을 유의하세요. 이 경우, `.charAt()`를 사용하세요.
+
+
+
+#### 정답: B
+
+기본 파라미터의 값은 기본 파라미터를 정의하기 _전_ 이라면, 함수의 다른 파라미터와 같게 설정 할 수 있어요. 우리는 `sum` 함수에 값 `10`을 전달 했어요. 만약 `sum` 함수에 인수의 값을 하나만 받았다면, `num2`를 위한 값은 전달되지 않고, `num1`은 전달된 값과 같다는 의미에요. `num1`의 기본값은 `num1`의 값인 `10`과 같아요. `num1 + num2`는 `20`을 리턴해요.
+
+만약 기본 파리미터가 정의된 _후_ (오른쪽에) 기본 파라미터의 값을 설정하려고 시도한다면, 파라미터의 값은 아직 초기화되지 않아, 오류를 던질 거에요.
+
+
+
+#### 정답: A
+
+`import * as name` 신택스를 사용해서, `module.js` 파일에 있는 _모든 exports_ 를 `index.js` 파일 안에 `data`라고 불리는 새로운 객체를 생성해요. `module.js` 파일에는, 2개의 export가 있어요: default export 와 named export. default export는 문자열 `"Hello World"`을 리턴하는 함수고, named export는 문자열 `"Lydia"`의 값을 가진 `name`이라고 불리는 변수예요.
+
+`data` 객체는 default export를 위한 `default` 속성을 가지고, 다른 속성들은 named exports의 이름들과 그에 해당하는 값들을 가져요.
+
+
+
+#### 정답: C
+
+Class는 함수 생성자를 위한 문법적 설탕이에요. 함수 생성자로서 `Person` 클래스와 동등한 것은 다음과 같아요:
+
+```javascript
+function Person() {
+ this.name = name;
+}
+```
+
+`new`와 함께 불려진 함수 생성자는 `Person`의 인스턴스를 생성하고, `typeof` 키워드는 인스턴스의 `"object"`를 리턴해요. `typeof member`는 `"object"`을 리턴해요.
+
+
+
+#### 정답: D
+
+`.push` 메소드는 배열 자체가 아니라, 배열의 _새로운 길이_ 를 리턴해요! `newList`를 `[1, 2, 3].push(4)`과 동일하게 설정함으로써, `newList`를 배열의 새로운 길이와 동일하게 설정했어요: `4`.
+
+그리고나서, `.push` 메소드를 `newList`에 사용하려고 했어요. `newList`는 숫자 값 `4` 이기 때문에, `.push` 메소드를 사용할 수 없어요: TypeError가 던져져요.
+
+
+
+#### 정답: D
+
+`giveLydiaPizza`와 같은 정규 함수는, `생성자` 속성을 가진 `프로토타입` 객체(프로토타입 객체)를 속성으로 가져요. 그러나 `giveLydiaChocolate` 함수와 같은 화살표 함수에서는, `prototype` 속성을 가지고 있지 않아요. `giveLydiaChocolate.prototype`을 사용해 `prototype` 속성에 접근하려고 할때, `undefined`이 리턴될 거에요.
+
+
+
+#### 정답: A
+
+`Object.entries(person)`은 키와 값을 세트로 가진 배열의 배열을 리턴해요:
+
+`[ [ 'name', 'Lydia' ], [ 'age', 21 ] ]`
+
+`for-of` 루프를 사용해서, 배열 안에 각 요소를 계속해서 반복할 수 있는데, 이 경우엔 하위 배열이에요. 하위 배열을 `const [x, y]`을 사용해, for-of 루프에서 즉시 분해할 수 있어요. `x`는 하위 배열의 첫 번째 요소와 같고, `y`는 하위 배열의 두 번째 요소와 같아요.
+
+첫번째 하위요소는 `[ "name", "Lydia" ]`로, `x`는 `"name"`, `y`는 `"Lydia"`을 출력해요.
+두번째 하위요소는 `[ "age", 21 ]`로, `x`는 `"age"`, `y`는 `21`을 출력해요.
+
+
+
+#### 정답: D
+
+`...args`은 나머지 파라미터예요. 나머지 파라미터의 값은 모든 나머지 인수들을 포함한 배열이며, **마지막 파라미터만 될 수 있어요**! 지금 예시에서는, 나머지 파라미터는 두번째 파라미터예요. 이것은 불가능하고, 신택스 에러를 던지게 될거에요.
+
+```javascript
+function getItems(fruitList, favoriteFruit, ...args) {
+ return [...fruitList, ...args, favoriteFruit]
+}
+
+getItems(["banana", "apple"], "pear", "orange")
+```
+
+The above example works. This returns the array `[ 'banana', 'apple', 'orange', 'pear' ]`
+
+
+#### 정답: B
+
+In JavaScript, we don't _have_ to write the semicolon (`;`) explicitly, however the JavaScript engine still adds them after statements. This is called **Automatic Semicolon Insertion**. A statement can for example be variables, or keywords like `throw`, `return`, `break`, etc.
+
+Here, we wrote a `return` statement, and another value `a + b` on a _new 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 after `return`. You could see this as:
+
+```javascript
+ return;
+ a + b
+```
+
+This means that `a + b` is never reached, since a function stops running after the `return` keyword. If no value gets returned, like here, the function returns `undefined`. Note that there is no automatic insertion after `if/else` statements!
+
+
+
+#### 정답: B
+
+We can set classes equal to other classes/function constructors. In this case, we set `Person` equal to `AnotherPerson`. The name on this constructor is `Sarah`, so the name property on the new `Person` instance `member` is `"Sarah"`.
+
+
+
+#### 정답: D
+
+A Symbol is not _enumerable_. The Object.keys method returns all _enumerable_ 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 the `Object.getOwnPropertySymbols()` method).
+
+
+
+#### 정답: A
+
+The `getList` function receives an array as its argument. Between the parentheses of the `getList` 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 are `2`, `3` and `4` in this case. The value of `y` is an array, containig all the rest parameters. The value of `x` is equal to `1` in this case, so when we log `[x, y]`, `[1, [2, 3, 4]]` gets logged.
+
+ The `getUser` function receives an object. With arrow functions, we don't _have_ to write curly brackets if we just return one value. However, if you want to return an _object_ from an arrow function, you have to write it between parentheses, otherwise no value gets returned! The following function would have returned an object:
+
+```const getUser = user => ({ name: user.name, age: user.age })```
+
+Since no value gets returned in this case, the function returns `undefined`.
+
+
+
+#### 정답: C
+
+The variable `name` holds the value of a string, which is not a function, thus cannot invoke.
+
+TypeErrors get thrown wehn a value is not of the expected type. JavaScript expected `name` 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 word `return` as `retrun`.
+ReferenceErrors get thrown when JavaScript isn't able to find a reference to a value that you're trying to access.
+
+
+
+#### 정답: 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.
+
+
+
+#### 정답: 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 past 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 `[]`.
+
+
#### 정답: D
-심볼은 _열거 가능_ 하지 않아요. Object.keys 메소드는 객체의 모든 _열거 가능_ 한 키 속성들을 리턴해요. 심볼은 보이지 않고, 빈 객체가 리턴돼요. 객체 전체를 출력할때, 모든 속성들은 보여요, 심지어 열거 불가능한 것이라해도.
+심볼은 _열거 불가능_ 해요. Object.keys 메소드는 객체의 모든 _열거 가능_ 한 키 속성들을 리턴해요. 심볼은 보이지 않고, 빈 객체가 리턴돼요. 객체 전체를 출력할때, 모든 속성들은 보여요, 심지어 열거 불가능한 것이라해도.
이것은 심볼의 많은 특성 중 하나에요: 완전히 고유한 값(예를들어 2개의 라이브러리를 같은 객체의 속성으로 추가하고 싶을때, 객체의 우연한 이름 충돌을 방지해요)을 나타내는 것 외에, 이 방법으로 객체의 속성을 "숨길" 수 있어요(비록 완전히는 아닐지라도. 여전히 `Object.getOwnPropertySymbols()` 메소드를 사용해 심볼에 접근 할 수 있어요).
@@ -3108,27 +3108,27 @@ console.log(getList(list))
console.log(getUser(user))
```
-- A: `[1, [2, 3, 4]]` and `undefined`
-- 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 }`
+- A: `[1, [2, 3, 4]]` 그리고 `undefined`
+- B: `[1, [2, 3, 4]]` 그리고 `{ name: "Lydia", age: 21 }`
+- C: `[1, 2, 3, 4]` 그리고 `{ name: "Lydia", age: 21 }`
+- D: `Error` 그리고 `{ name: "Lydia", age: 21 }`
#### 정답: A
-The `getList` function receives an array as its argument. Between the parentheses of the `getList` function, we destructure this array right away. You could see this as:
+`getList`함수는 배열을 인수로 받았어요. `getList` 함수의 괄호 사이에 있는 배열을 즉시 분해 했어요:
`[x, ...y] = [1, 2, 3, 4]`
- With the rest parameter `...y`, we put all "remaining" arguments in an array. The remaining arguments are `2`, `3` and `4` in this case. The value of `y` is an array, containig all the rest parameters. The value of `x` is equal to `1` in this case, so when we log `[x, y]`, `[1, [2, 3, 4]]` gets logged.
+나머지 파라미터를 사용해 `...y`에 모든 "남은" 인수들을 배열에 넣었어요. 이 경우에서 남아있는 인수는 `2`, `3` 그리고 `4`예요. `y`의 값은 배열이고, 모든 나머지 파라미터를 포함하고 있어요. 이 경우 `x`의 값은 `1`이기 때문에, `[x, y]`는 `[1, [2, 3, 4]]`로 출력돼요.
- The `getUser` function receives an object. With arrow functions, we don't _have_ to write curly brackets if we just return one value. However, if you want to return an _object_ from an arrow function, you have to write it between parentheses, otherwise no value gets returned! The following function would have returned an object:
+`getUser` 함수는 배열을 받았어요. 화살표 함수에서, 우리가 한개의 값을 리턴한다면 중괄호를 사용할 _필요_ 가 없어요. 그러나, 만약 화살표 함수에서 _객체_ 를 리턴하고 싶다면, 괄호 사이에 리턴할 값을 써야해요, 그렇지 않다면 아무 값도 리턴받을 수 없어요! 다음 함수에서는 객체가 리턴 될 거에요:
```const getUser = user => ({ name: user.name, age: user.age })```
-Since no value gets returned in this case, the function returns `undefined`.
+이 경우 값이 리턴되는 값이 없으므로, 함수는 `undefined`을 리턴할거에요.
정답
정답
정답
정답
정답
정답
정답
정답
+정답
+정답
+정답
+정답
+정답
+정답
+정답
+정답
+정답
+정답
+정답
+정답
+정답
+정답
+정답
@@ -3003,9 +3003,9 @@ console.log(nums(4, 2))
console.log(nums(1, 2))
```
-- A: `a is bigger`, `6` and `b is bigger`, `3`
-- B: `a is bigger`, `undefined` and `b is bigger`, `undefined`
-- C: `undefined` and `undefined`
+- A: `a is bigger`, `6` 그리고 `b is bigger`, `3`
+- B: `a is bigger`, `undefined` 그리고 `b is bigger`, `undefined`
+- C: `undefined` 그리고 `undefined`
- D: `SyntaxError`
정답
@@ -3013,7 +3013,7 @@ console.log(nums(1, 2))
#### 정답: B
-자바스크립트에서, 세미콜론을 (`;`)을 명시적으로 포함하여 쓰지 _않_ 더라도, 자바스크립트 엔진은 여전히 문 뒤에 그들을 추가해줘요. 이것은 **자동 세미콜론 삽입**이라고 불려요. 예를 들어 문은 변수, 또는 `throw`, `return`, `break` 등과 같은 키워드가 될 수도 있어요.
+JavaScript에서, 세미콜론을 (`;`)을 명시적으로 포함하여 쓰지 _않_ 더라도, JavaScript 엔진은 여전히 문 뒤에 그들을 추가해줘요. 이것은 **자동 세미콜론 삽입**이라고 불려요. 예를 들어 문은 변수, 또는 `throw`, `return`, `break` 등과 같은 키워드가 될 수도 있어요.
여기, `return`문을 썼고, 다른 값 `a + b`은 _새로운 줄_ 에 쓰였어요. 그러나, 새로운 줄이기 때문에, 엔진은 실제로 그 값이 리턴되길 바라는지 알 수 없어요. 대신에, 자동적으로 `return` 뒤에 세미콜론을 더해줘요. 이것을 볼 수 있을거에요:
@@ -3076,17 +3076,17 @@ 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 `[]`
+- A: `{Symbol('a'): 'b'}` 그리고 `["{Symbol('a')"]`
+- B: `{}` 그리고 `[]`
+- C: `{ a: "b" }` 그리고 `["a"]`
+- D: `{Symbol('a'): 'b'}` 그리고 `[]`
정답
정답
@@ -2166,7 +2166,7 @@ console.log(name.padStart(2))
#### Ответ: C
-С помощью метода `padStart` мы можем добавить отступ в начало строки. Значение, передаваемое этому методу, представляет собой _общую_ длину строки вместе с отступом. Строка `"Lydia Hallie"` имеет длину `12`. `name.padStart (13)` вставляет 1 пробел в начале строки, потому что 12 + 1 равно 13.
+С помощью метода `padStart` мы можем добавить отступ в начало строки. Значение, передаваемое этому методу, представляет собой _общую_ длину строки вместе с отступом. Строка `"Lydia Hallie"` имеет длину `12`. `name.padStart(13)` вставляет 1 пробел в начале строки, потому что 12 + 1 равно 13.
Если аргумент, переданный методу `padStart`, меньше длины строки, заполнение не будет добавлено.
@@ -2183,7 +2183,7 @@ console.log("🥑" + "💻");
- A: `"🥑💻"`
- B: `257548`
-- C: A string containing their code points
+- C: Строка, содержащая кодовые обозначения
- D: Error
#### Ответ: C
-Функция генератора "приостанавливает" выполнение, когда видит ключевое слово yield. Во-первых, мы должны позволить функции выдать строку "Do you love JavaScript?", Что можно сделать, вызвав `game.next (). Value`.
+Функция генератора "приостанавливает" выполнение, когда видит ключевое слово yield. Во-первых, мы должны позволить функции выдать строку "Do you love JavaScript?", что можно сделать, вызвав `game.next().value`.
Каждая строка выполняется до тех пор, пока не найдет первое ключевое слово `yield`. В первой строке функции есть ключевое слово `yield` на первом месте: выполнение останавливается с первым выходом! _Это означает, что переменная `answer` еще не определена!_
@@ -2405,8 +2405,8 @@ function sum(a, b) {
}
```
-- A: Yes
-- B: No
+- A: Да
+- B: Нет
@@ -2668,7 +2668,7 @@ console.log(checkAge(21))
#### Ответ: C
-Переменные с ключевыми словами `const` и `let` являются _block-scoped_. Блок - это что-то между фигурными скобками (`{}`). В этом случае в фигурных скобках операторов if/else. Вы не можете ссылаться на переменную за пределами блока, в котором она объявлена, вызывается ReferenceError.
+Переменные с ключевыми словами `const` и `let` имеют _блочную видимость_. Блок - это что-то между фигурными скобками (`{}`). В этом случае в фигурных скобках операторов if/else. Вы не можете ссылаться на переменную за пределами блока, в котором она объявлена, вызывается ReferenceError.
@@ -3116,7 +3116,6 @@ console.log(getUser(user))
#### Ответ: A
-The `getList` function receives an array as its argument. Between the parentheses of the `getList` function, we destructure this array right away. You could see this as:
Функция `getList` получает массив в качестве аргумента. Между скобками функции `getList` мы сразу же деструктурируем этот массив. Вы можете увидеть это как:
`[x, ...y] = [1, 2, 3, 4]`
From 4794cfb60fc26209c4105c46e6986160cd9d8e3e Mon Sep 17 00:00:00 2001
From: amullabaev
+
+#### Answer: D
+
+With a promise, we basically say _I 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 the `await` keyword in an `async` function. Although we can get a promise's value with both `.then` and `await`, they work a bit differently.
+
+In the `firstFunction`, we (sort of) put the myPromise function aside while it was running, but continued running the other code, which is `console.log('second')` in this case. Then, the function resolved with the string `I have resolved`, which then got logged after it saw that the callstack was empty.
+
+With the await keyword in `secondFunction`, we literally pause the execution of an async function until the value has been resolved befoer moving to the next line.
+
+This means that it waited for the `myPromise` to resolve with the value `I have resolved`, and only once that happened, we moved to the next line: `second` got logged.
+
+
+
+#### Answer: C
+
+The `+` operator is not only used for adding numerica lvalues, 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 is `1`, which is a numerical value. `1 + 2` returns the number 3.
+
+However, the second one is a string `"Lydia"`. `"Lydia"` is a string and `2` is a number: `2` gets coerced into a string. `"Lydia"` and `"2"` get concatenated, whic hresults 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"`.
+
+
+
+#### Answer: C
+
+We can pass any type of value we want to `Promise.resolve`, either a promise or a non-promise. The method itself returns a promise with the resolved value. 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 value `5`. It returns a resolved promise with the value `5`.
+
+
+
+#### Answer: B
+
+Objects are passed by reference. When we check objects for strict equality (`===`), we're comparing their references.
+
+We set the default value for `person2` equal to the `person` object, and passed the `person` object as the value for `person1`.
+
+This means that both values have a reference to the same spot in memory, thus they are equal.
+
+The code block in the `else` statement gets run, and `They are the same!` gets logged.
+
+
+
+#### 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 called `colors` on the `colorConfig` object. There is no proprety called `colorConfig`, so this returns `undefined`. Then, we try to access the value of the first element by using `[1]`. We cannot do this on a value that's `undefined`, so it throws a `TypeError`: `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 used `colorConfig[colors[1]]`, it would have returned the value of the `red` property on the `colorConfig` object.
+
+
+
+#### 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.
+
+
+
+#### Answer: D
+
+With `splice` 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` and `slice` return a new array, `find` returns an element, and `reduce` returns a reduced value.
+
+
+#### Answer: D
+
+With a promise, we basically say _I 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 the `await` keyword in an `async` function. Although we can get a promise's value with both `.then` and `await`, they work a bit differently.
+
+In the `firstFunction`, we (sort of) put the myPromise function aside while it was running, but continued running the other code, which is `console.log('second')` in this case. Then, the function resolved with the string `I have resolved`, which then got logged after it saw that the callstack was empty.
+
+With the await keyword in `secondFunction`, we literally pause the execution of an async function until the value has been resolved befoer moving to the next line.
+
+This means that it waited for the `myPromise` to resolve with the value `I have resolved`, and only once that happened, we moved to the next line: `second` got logged.
+
+
+
+#### Answer: C
+
+The `+` operator is not only used for adding numerica lvalues, 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 is `1`, which is a numerical value. `1 + 2` returns the number 3.
+
+However, the second one is a string `"Lydia"`. `"Lydia"` is a string and `2` is a number: `2` gets coerced into a string. `"Lydia"` and `"2"` get concatenated, whic hresults 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"`.
+
+
+
+#### Answer: C
+
+We can pass any type of value we want to `Promise.resolve`, either a promise or a non-promise. The method itself returns a promise with the resolved value. 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 value `5`. It returns a resolved promise with the value `5`.
+
+
+
+#### Answer: B
+
+Objects are passed by reference. When we check objects for strict equality (`===`), we're comparing their references.
+
+We set the default value for `person2` equal to the `person` object, and passed the `person` object as the value for `person1`.
+
+This means that both values have a reference to the same spot in memory, thus they are equal.
+
+The code block in the `else` statement gets run, and `They are the same!` gets logged.
+
+
+
+#### 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 called `colors` on the `colorConfig` object. There is no proprety called `colorConfig`, so this returns `undefined`. Then, we try to access the value of the first element by using `[1]`. We cannot do this on a value that's `undefined`, so it throws a `TypeError`: `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 used `colorConfig[colors[1]]`, it would have returned the value of the `red` property on the `colorConfig` object.
+
+
+
+#### 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.
+
+
+
+#### Answer: D
+
+With `splice` 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` and `slice` return a new array, `find` returns an element, and `reduce` returns a reduced value.
+
Ответ
@@ -2214,17 +2214,17 @@ console.log(/* 1 */); // Do you love JavaScript?
console.log(/* 2 */); // JavaScript loves you back ❤️
```
-- A: `game.next("Yes").value` and `game.next().value`
-- B: `game.next.value("Yes")` and `game.next.value()`
-- C: `game.next().value` and `game.next("Yes").value`
-- D: `game.next.value()` and `game.next.value("Yes")`
+- A: `game.next("Yes").value` и `game.next().value`
+- B: `game.next.value("Yes")` и `game.next.value()`
+- C: `game.next().value` и `game.next("Yes").value`
+- D: `game.next.value()` и `game.next.value("Yes")`
Ответ
Ответ
Ответ
Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+
+ +#### Antwort: D + +Mit einem Promise sagen wir _Ich möchte diese Funktion ausführen, aber ich lege sie erstmal beiseite, weil sie eine Weile braucht. Erst wenn ein bestimmter Wert ausgegeben (oder rejected) wird und der Call Stack leer ist möchte ich den Wert nutzen._ + +Wir können auf den Wert mit `.then()` oder `await` in einer `async` Funktion zugreifen, aber `.then()` und `await` unterscheiden sich in einem bestimmten Punkt. + +In `firstFunction` legen wir `myPromise` beiseite, während die Funktion durchläuft, aber wir arbeiten anderen Code ab, hier `console.log('second')`. +Dann wird die Funktion abgeschlossen und der String `I have resolved` wird ausgegeben, nachdem sich der Call Stack geleert hat. + +Mit dem `await` Keyword in `secondFunction` wird die Funktion gestoppt bis der Wert ausgegeben wurde, erst dann wird die nächste Zeile ausgeführt. + +Das bedeutet, dass auf `myPromise` gewartet und dann der Wert `I have resolved` ausgegeben wird und erst dann wird die nächste Zeile ausgeführt und `second` wird geloggt. + +
++ +#### Antwort: C + +Der `+` Operator wird nicht nur für numerische Werte verwendet, wir können mit ihm ebenso Strings zusammenfügen. Immer, wenn JavaScript merkt, dass mindestens ein Wert keine Nummer ist, wird ein String erstellt. + +Der erste Wert ist `1`, was ein numerischer Wert ist. `1 + 2` ergibt die Zahl `3`. + +Der zweite Wert hingegen ist der String `"Lydia"`. `"Lydia"` ist ein String und `2` ist eine Nummer: `2` wird in einem String umgewandelt. `"Lydia"` und `"2"` werden zusammengesetzt, was den String `"Lydia2"` ausgibt. + +`{ name: "Lydia" }` ist ein Objekt. Weder eine Nummer, noch ein Objekt sind ein String, aber beide werden zu Strings konvertiert und `"[Object object]"` wird ausgegeben. `"[Object object]"` zusammengesetzt mit `"2"` wird `"[Object object]2"`. + +
++ +#### Antwort: C + +Wir können jeden Wert an `Promise.resolve` übergeben, es muss nicht unbedingt ein Promise sein. Die Methode selbst gibt ein Promise zurück, was einen Wert ausgibt. Wenn man eine normale Funktion übergibt wird das Promise einen normalen Wert ausgeben. Wenn ein Promise übergeben wird so wird ein Promise gelöst und der Wert des gelösten Promises ausgegeben. + +In diesem Fall haben wir nur die Zahl `5` übergeben und diese wird genauso ausgegeben: `5`. + +
++ +#### Antwort: B + +Objekte werden durch eine Referenz übergeben. Wenn wir Objekte auf strikte Gleichheit (`===`) prüfen, vergleichen wir nur deren Referenz. + +Wir setzen den Standardwert für `person2` gleich dem `person` Objekt und übergeben dem `person` Objekt den Wert von `person1`. + +Das bedeutet, dass beide Werte eine Referenz zum gleichen Ort im Speicher aufweisen und daher gleich sind. + +Der Code im `else` Statement wird aufgerufen und `They are the same!` wird geloggt. + +
++ +#### Antwort: D + +In JavaScript gibt es zwei Wege auf Properties an Objekten zuzugreifen: Punkt-Notation oder Klammern-Notation. In diesem Beispiel nutzen wir Punkt-Notation (`colorConfig.colors`) anstelle von Klammern-Notation (`colorConfig["colors"]`). + +Mit Punkt-Notation versucht JavaScript die Property am Objekt mit diesem exakten Namen zu finden. In unserem Beispiel `colors` im `colorConfig` Objekt. Da es keine Property `colorConfig` gibt wird `undefined` ausgegeben. Dann versuchen wir den Wert des ersten Elements mit `[1]` aufzurufen, was an `undefined` nicht möglich ist, wodurch wir `TypeError: Cannot read property '1' of undefined` ausgegeben bekommen. + +JavaScript interpretiert Statements. Wenn wir Klammern-Notation verwenden wird die erste Klammer `[` gefunden und JavaScript sucht solange, bis eine schließende Klammer `]` gefunden wird. Erst dann wird das Statement interpretiert. Hätten wir `colorConfig[colors[1]]` verwendet, wäre der Wert `red` ausgegeben worden. + +
++ +#### Antwort: A + +Emojis sind im Endeffekt nur Unicodes. Der Unicode für das Herz Emoji ist `"U+2764 U+FE0F"`. Dieser ist immer gleich, für das selbe Emoji und daher wird `true` ausgegeben. + +
++ +#### Antwort: D + +Mit der `splice` Methode ändern wir das ursprüngliche Array durch löschen, ersetzen oder ergänzen von Elementen. In diesem Fall haben wir 2 Elemente vom Index 1 (`'🥑'` und `'😍'`) entfernt und ✨ stattdessen eingefügt. + +`map`, `filter` und `slice` geben ein neues Array aus, `find` gibt ein Element aus und `reduce` gibt einen neuen Wert aus. + +
+#### Ответ: A + Функция `getList` получает массив в качестве аргумента. Между скобками функции `getList` мы сразу же деструктурируем этот массив. Вы можете увидеть это как: `[x, ...y] = [1, 2, 3, 4]` @@ -3221,3 +3222,235 @@ console.log(one, two, three)
+ +--- + +###### 102. Какое значение будет на выходе? + +```javascript +const myPromise = () => Promise.resolve('I have resolved!') + +function firstFunction() { + myPromise().then(res => console.log(res)) + console.log('second') +} + +function secondFunction() { + console.log(await myPromise()) + console.log('second') +} +``` + +- A: `I have resolved!`, `second` and `I have resolved!`, `second` +- B: `second`, `I have resolved!` and `second`, `I have resolved!` +- C: `I have resolved!`, `second` and `second`, `I have resolved!` +- D: `second`, `I have resolved!` and `I have resolved!`, `second` + ++ +#### Ответ: D + +С обещанием мы в основном говорим: "Я хочу выполнить эту функцию и откладываю ее, пока она выполняется, поскольку это может занять некоторое время". Только когда определенное значение разрешено (или отклонено), и когда стек вызовов пуст, я хочу использовать это значение. + +Мы можем получить это значение с помощью ключевого слова `.then` и `await` в функции `async`. Хотя мы можем получить значение обещания с помощью `.then` и `await`, они работают немного по-разному. + +В `firstFunction` мы (вроде) отложили функцию `myPromise` во время ее работы, но продолжили выполнение другого кода, в данном случае `console.log ('second')`. Затем функция разрешается строкой `I have resolved`, которая затем логируется после того, как она увидела, что стек вызовов пуст. + +Используя ключевое слово `await` в `secondFunction`, мы буквально приостанавливаем выполнение асинхронной функции до тех пор, пока значение не будет разрешено до перехода на следующую строку. + +Это означает, что мы ожидали разрешения `myPromise` со значением `I have resolved`, и только когда это произошло, мы перешли к следующей строке: `second` была выведена в консоль последней. + +
++ +#### Ответ: C + +Оператор `+` используется не только для добавления числовых значений, но мы также можем использовать его для объединения строк. Всякий раз, когда движок JavaScript видит, что одно или несколько значений не являются числом, он приводит число к строке. + +Первым является `1`, который является числовым значением. `1 + 2` возвращает число `3`. + +Тем не менее, вторая строка `"Lydia"`. `"Lydia"` является строкой, а `2` является числом: `2` приводится к строке. `"Lydia"` и `"2"` объединяются, что приводит к результирующей строке `"Lydia2"`. + +`{name: "Lydia"}` является объектом. Ни число, ни объект не являются строкой, поэтому они приводятся к строке. Всякий раз, когда мы приводим обычный объект, он становится `"[Object object]"`. `"[Object object]"`, объединенный с `"2"`, становится `"[Object object]2"`. + +
++ +#### Ответ: C + +Мы можем передать любой тип значения, которое мы хотим, в `Promise.resolve`, либо обещание, либо не обещание. Сам метод возвращает обещание с разрешенным значением. Если вы передадите обычную функцию, это будет разрешенное обещание с обычным значением. Если вы передадите обещание, это будет разрешенное обещание с разрешенным значением этого пройденного обещания. + +В этом случае мы просто передали числовое значение `5`. Возвращается разрешенное обещание со значением `5`. + +
++ +#### Ответ: B + +Объекты передаются по ссылке. Когда мы проверяем объекты на строгое равенство (`===`), мы сравниваем их ссылки. + +Мы устанавливаем значение по умолчанию для `person2`, равное объекту `person`, и передаем объект `person` в качестве значения для `person1`. + +Это означает, что оба значения имеют ссылку на одно и то же место в памяти, поэтому они равны. + +Блок кода в операторе `else` запускается, и в лог выводится `They are the same!`. + +
++ +#### Ответ: D + +В JavaScript у нас есть два способа доступа к свойствам объекта: нотация в скобках или нотация в точках. В этом примере мы используем точечную нотацию (`colorConfig.colors`) вместо скобочной нотации (`colorConfig["colors"]`). + +В точечной нотации JavaScript пытается найти свойство объекта с таким точным именем. В этом примере JavaScript пытается найти свойство с именем `colors` в объекте `colorConfig`. Не существует свойства с именем `colorConfig`, поэтому возвращается `undefined`. Затем мы пытаемся получить доступ к значению первого элемента, используя `[1]`. Мы не можем сделать это для значения, которое `undefined`, поэтому оно выдает `TypeError`: `Cannot read свойство '1' of undefined`. + +JavaScript интерпретирует (или распаковывает) операторы. Когда мы используем скобочные обозначения, он видит первую открывающую скобку `[` и продолжает работать, пока не найдет закрывающую скобку `]`. Только тогда он оценит утверждение. Если бы мы использовали `colorConfig[colors [1]]`, он бы возвратил значение свойства `red` объекта `colorConfig`. + +
++ +#### Ответ: A + +Под капотом смайлики - это юникоды. Юникод для сердца смайликов `"U+2764 U+FE0F"`. Они всегда одинаковы для одного и того же смайлика, поэтому мы сравниваем две одинаковые строки друг с другом, что возвращает `true`. + +
++ +#### Ответ: D + +Используя метод `splice`, мы модифицируем исходный массив, удаляя, заменяя или добавляя элементы. В этом случае мы удалили 2 элемента из индекса 1 (мы удалили `'🥑'` и `'😍'`) и добавили `✨` emoji. + +`map`, `filter` и `slice` возвращают новый массив, `find` возвращает элемент, а `reduce` возвращает аккумулированное значение. + +
++ +#### 정답: D + +promise를 사용하면, 기본적으로 _이 함수를 실행하고 싶지만, 시간이 좀 걸릴 수 있으니 실행중에 잠시 미뤄둘거에요. 확실한 값이 resoloved(혹은 rejected)로 전달되었을 때와 콜 스택이 비었을 때 이 값을 사용하고 싶어요_ 라고 말해요. + +`async` 함수 안에서 `.then`과 `await` 두개의 키워드에서 값을 얻을 수 있어요. 비록 `.then`과 `await`에서 프라미스의 값을 얻을 수 있지만, 그들은 약간 다르게 작동해요. + +첫번째 `firstFunction`에서, (뭐랄까) myPromise 함수가 실행되는 것을 미뤘지만, 다른 코드를 계속해서 실행하는데, 이 경우 `console.log('second')`에요. 그리고나서, 함수는 콜스택이 비워져 있는 걸 본 다음 출력된 문자열 `I have resolved`를 resolved로 전달해요. + +`secondFunction`에서의 await 키워드를 사용하면, 말 그대로 다음 라인으로 옮기기 전 값이 resoloved함수로 전달될 때 까지 async 함수의 실행을 중단해요. + +이것은 `myPromise`이 값 `I have resolved`을 얻을 때 까지 기다린다는 의미이며, 단 한 번 발생하면, 다음라인으로 이동해요: `second`이 출력되죠. + +
++ +#### 정답: C + +`+` 연산자는 숫자로 나타난 값을 더하는데 사용될 뿐만 아니라, 문자열을 연결해주는데 사용 할 수 있어요. JavaScript 엔진은 하나 이상의 값들이 숫자가 아닌 것을 발견 했을 때, 숫자를 문자열로 강제로 변환해요. + +첫번째 `1`은, 숫자로된 값이에요. `1 + 2`는 숫자 3을 리턴해요. + +그러나, 두번째는 문자열 `"Lydia"`이에요. `"Lydia"`은 문자열이고, `2`는 숫자에요: `2`는 문자열로 강제 변환되어요. `"Lydia"`그리고 `"2"`이 연결되어, 문자열 `"Lydia2"`이 리턴되요. + +`{ name: "Lydia" }`은 객체에요. 객체가 아닌 숫자나 객체는 문자열이 아니므로, 둘다 문자화되어요. 정규 객체를 문자화 할때, `"[Object object]"`가 돼요. `"[Object object]"`는 `"2"`와 연결되어 `"[Object object]2"`가 돼요. + +
++ +#### 정답: C + +promise이나 non-promise이 아니더라도 값의 모든 타입은 `Promise.resolve`으로 전달 할 수 있어요. 메소드 그 자체는 resolved 값을 가진 promise를 리턴해요. 정규 함수를 전달한다면, 정규 값을 가진 resolved promise를 얻게 될거에요. 만약 promise를 전달한다면, 전달된 promise의 resolved 값과 resolved promise를 얻게 될거에요. + +이 경우, 숫자 값 `5`를 전달했어요. 이것은 값 `5`를 가진 resolved promise를 리턴해요. + +
++ +#### 정답: B + +객체는 참조에 의해 전달되었어요. 엄격한 같은 비교 (`===`)로 객체를 검사한다면, 그들의 참조를 비교할거에요. + +`person2`의 기본 값을 `person` 객체와 동일하게 설정 하고, `person` 객체를 `person1`의 값으로 전달 했어요. + +이것은 두개의 값은 메모리의 같은 장소의 참조를 가지고 있다는 걸 의미해요, 그렇기 때문에 그들은 같아요. + +`else`구문 안에 코드블럭이 실행되면, `They are the same!`을 출력해요. + +
++ +#### 정답: D + +JavaScript에서, 객체의 속성에 접근하는 2가지 방법을 가지고 있어요: 괄호 표기법, 또는 점 표기법. 이 예제에서는, 괄호표기법 (`colorConfig["colors"]`) 대신 점 표기법 (`colorConfig.colors`)을 사용 했어요. + +점 표기법에서, JavaScript는 정확한 이름을 가진 객체의 속성을 찾으려 해요. 이 예제에서 JavaScript는 `colorConfig` 객체의 `colors`라고 불리는 속성을 찾으려고 했어요. 그곳에는 `colors`라고 불리는 속성이 없어요, 그래서 `undefined`을 리턴해요. 그리고 나서, `[1]`을 사용해서 첫번째 요소의 값에 접근하려고 했어요. `undefined`의 값에는 이것을 할 수 없어요, 그래서 `TypeError`를 던져요: `Cannot read property '1' of undefined`. + +JavaScript 문장을 해석(또는 참조형 변수를 원시 데이터 타입으로 만들어 주도록) 해요. 괄호 표기법을 사용할때, 첫번째로 열린 괄호 `[`을 보고 닫힌 괄호 `]`를 찾을 때 까지 계속 진행되는 것으로 보여요. 그러고 나서야, 문장을 평가할거에요. 만약 `colorConfig[colors[1]]`을 사용했다면, `colorConfig` 객체의 속성 `red` 의 값이 리턴될 거에요. + +
++ +#### 정답: A + +엔진에서, 이모티콘은 유니코드에요. 하트 이모티콘의 유니코드는 `"U+2764 U+FE0F"`에요. 같은 이모티콘의 유니코드는 항상 같아요, 따라서 각각 다른 두개의 같은 문자열을 비교하는 것이므로 true를 리턴해요. + +
++ +#### 정답: D + +`splice` method를 사용하면, 요소를 삭제, 대체하거나 추가함으로써 원본 배열을 수정해요. 이 경우에서, 인덱스 1에서 부터 2개의 아이템을 제거했어요. (`'🥑'` 와 `'😍'`를 삭제했어요) 그리고 ✨ 이모티콘을 대신 추가했죠. + +`map`, `filter` 그리고 `slice` 는 새로운 배열을 리턴해하고, `find` 요소를 리턴하며, `reduce` 감소된 값을 리턴해요. + +
++ +#### คำตอบ: D + +Within the function, we first declare the `name` variable with the `var` keyword. This means that the variable gets hoisted (memory space is set up during the creation phase) with the default value of `undefined`, 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 the `name` variable, so it still holds the value of `undefined`. + +Variables with the `let` keyword (and `const`) are hoisted, but unlike `var`, don't get initialized. 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 a `ReferenceError`. + +
++ +#### คำตอบ: C + +Because of the event queue in JavaScript, the `setTimeout` callback function is called _after_ the loop has been executed. Since the variable `i` in the first loop was declared using the `var` keyword, this value was global. During the loop, we incremented the value of `i` by `1` each time, using the unary operator `++`. By the time the `setTimeout` callback function was invoked, `i` was equal to `3` in the first example. + +In the second loop, the variable `i` was declared using the `let` keyword: variables declared with the `let` (and `const`) 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. + +
++ +#### คำตอบ: B + +Note that the value of `diameter` is a regular function, whereas the value of `perimeter` is an arrow function. + +With arrow functions, the `this` keyword refers to its current surrounding scope, unlike regular functions! This means that when we call `perimeter`, it doesn't refer to the shape object, but to its surrounding scope (window for example). + +There is no value `radius` on that object, which returns `undefined`. + +
++ +#### คำตอบ: A + +The unary plus tries to convert an operand to a number. `true` is `1`, และ `false` is `0`. + +The string `'Lydia'` is a truthy value. What we're actually asking, is "is this truthy value falsy?". This returns `false`. + +
++ +#### คำตอบ: A + +In JavaScript, all object keys are strings (unless it's a Symbol). Even though we might not _type_ 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 evaluates `bird.size`, which is `"small"`. `mouse["small"]` returns `true` + +However, with dot notation, this doesn't happen. `mouse` does not have a key called `bird`, which means that `mouse.bird` is `undefined`. Then, we ask for the `size` using dot notation: `mouse.bird.size`. Since `mouse.bird` is `undefined`, we're actually asking `undefined.size`. This isn't valid, and will throw an error similar to `Cannot read property "size" of undefined`. + +
+
+
+#### คำตอบ: A
+
+In JavaScript, all objects interact by _reference_ when setting them equal to each other.
+
+First, variable `c` holds a value to an object. Later, we assign `d` with the same reference that `c` has to the object.
+
+
+
+When you change one object, you change all of them.
+
+
+ +#### คำตอบ: 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, it only checks whether it has the same _value_. They both have the value of `3`, so it returns `true`. + +However, when we use the `===` operator, both value _and_ type should be the same. It's not: `new Number()` is not a number, it's an **object**. Both return `false.` + +
++ +#### คำตอบ: D + +The `colorChange` 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. Since `freddie` is a child, the function is not passed down, and not available on the `freddie` instance: a `TypeError` is thrown. + +
++ +#### คำตอบ: A + +It logs the object, because we just created an empty object on the global object! When we mistyped `greeting` as `greetign`, the JS interpreter actually saw this as `global.greetign = {}` (or `window.greetign = {}` in a browser). + +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. + +
++ +#### คำตอบ: 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. + +
++ +#### คำตอบ: A + +You can't add properties to a constructor like you can with regular objects. If you want to add a feature to all objects at once, you have to use the prototype instead. So in this case, + +```js +Person.prototype.getFullName = function() { + return `${this.firstName} ${this.lastName}`; +}; +``` + +would have made `member.getFullName()` work. Why is this beneficial? Say that we added this method to the constructor itself. Maybe not every `Person` instance needed this method. This would waste a lot of memory space, since they would still have that property, which takes of memory space for each instance. Instead, if we only add it to the prototype, we just have it at one spot in memory, yet they all have access to it! + +
++ +#### คำตอบ: A + +For `sarah`, we didn't use the `new` keyword. When using `new`, it refers to the new empty object we create. However, if you don't add `new` it refers to the **global object**! + +We said that `this.firstName` equals `"Sarah"` และ `this.lastName` equals `"Smith"`. What we actually did, is defining `global.firstName = 'Sarah'` และ `global.lastName = 'Smith'`. `sarah` itself is left `undefined`, since we don't return a value from the `Person` function. + +
+
+
+#### คำตอบ: D
+
+During the **capturing** phase, the event goes through the ancestor elements down to the target element. It then reaches the **target** element, and **bubbling** begins.
+
+
+
+
+ +#### คำตอบ: B + +All objects have prototypes, except for the **base object**. The base object is the object created by the user, or an object that is created using the `new` 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. + +
++ +#### คำตอบ: C + +JavaScript is a **dynamically typed language**: we don't specify what types certain variables are. Values can automatically be converted into another type without you knowing, which is called _implicit type coercion_. **Coercion** is converting from one type into another. + +In this example, JavaScript converts the number `1` 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"`. + +
++ +#### คำตอบ: C + +The **postfix** unary operator `++`: + +1. Returns the value (this returns `0`) +2. Increments the value (number is now `1`) + +The **prefix** unary operator `++`: + +1. Increments the value (number is now `2`) +2. Returns the value (this returns `2`) + +This returns `0 2 2`. + +
++ +#### คำตอบ: 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! + +
++ +#### คำตอบ: C + +When testing equality, primitives are compared by their _value_, while objects are compared by their _reference_. 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 }` และ `{ age: 18 } == { age: 18 }` return `false`. + +
++ +#### คำตอบ: C + +The rest parameter (`...args`.) lets us "collect" all remaining arguments into an array. An array is an object, so `typeof args` returns `"object"` + +
++ +#### คำตอบ: C + +With `"use strict"`, you can make sure that you don't accidentally declare global variables. We never declared the variable `age`, 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 property `age` would have gotten added to the global object. + +
++ +#### คำตอบ: A + +`eval` evaluates codes that's passed as a string. If it's an expression, like in this case, it evaluates the expression. The expression is `10 * 10 + 5`. This returns the number `105`. + +
++ +#### คำตอบ: B + +The data stored in `sessionStorage` is removed after closing the _tab_. + +If you used `localStorage`, the data would've been there forever, unless for example `localStorage.clear()` is invoked. + +
++ +#### คำตอบ: B + +With the `var` keyword, you can declare multiple variables with the same name. The variable will then hold the latest value. + +You cannot do this with `let` or `const` since they're block-scoped. + +
++ +#### คำตอบ: C + +All object keys (excluding Symbols) are strings under the hood, even if you don't type it yourself as a string. This is why `obj.hasOwnProperty('1')` also returns true. + +It doesn't work that way for a set. There is no `'1'` in our set: `set.has('1')` returns `false`. It has the numeric type `1`, `set.has(1)` returns `true`. + +
++ +#### คำตอบ: 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. + +
++ +#### คำตอบ: A + +The base execution context is the global execution context: it's what's accessible everywhere in your code. + +
++ +#### คำตอบ: C + +The `continue` statement skips an iteration if a certain condition returns `true`. + +
++ +#### คำตอบ: A + +`String` is a built-in constructor, which 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! + +
++ +#### คำตอบ: B + +Object keys are automatically converted into strings. We are trying to set an object as a key to object `a`, with the value of `123`. + +However, when we stringify an object, it becomes `"[Object object]"`. So what we are saying here, is that `a["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 log `a[b]`, which is actually `a["Object object"]`. We just set that to `456`, so it returns `456`. + +
+
+
+#### คำตอบ: B
+
+We have a `setTimeout` 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 a `WebAPI`. The `WebAPI` gives us the `setTimeout` function to start with, and for example the DOM.
+
+After the _callback_ is pushed to the WebAPI, the `setTimeout` 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, and `baz` 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 the _queue_.
+
+
+
+This is where an event loop starts to work. An **event 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.
+
+
+ +#### คำตอบ: C + +The deepest nested element that caused the event is the target of the event. You can stop bubbling by `event.stopPropagation` + +
++ Click here! +
++ +#### คำตอบ: A + +If we click `p`, we see two logs: `p` และ `div`. During event propagation, there are 3 phases: capturing, target, and bubbling. By default, event handlers are executed in the bubbling phase (unless you set `useCapture` to `true`). It goes from the deepest nested element outwards. + +
++ +#### คำตอบ: D + +With both, we can pass the object to which we want the `this` keyword to refer to. However, `.call` is also _executed immediately_! + +`.bind.` returns a _copy_ of the function, but with a bound context! It is not executed immediately. + +
++ +#### คำตอบ: B + +The `sayHi` function returns the returned value of the immediately invoked function (IIFE). This function returned `0`, which is type `"number"`. + +FYI: there are only 7 built-in types: `null`, `undefined`, `boolean`, `number`, `string`, `object`, และ `symbol`. `"function"` is not a type, since functions are objects, it's of type `"object"`. +
++ +#### คำตอบ: A + +There are only six falsy values: + +- `undefined` +- `null` +- `NaN` +- `0` +- `''` (empty string) +- `false` + +Function constructors, like `new Number` และ `new Boolean` are truthy. + +
++ +#### คำตอบ: B + +`typeof 1` returns `"number"`. +`typeof "number"` returns `"string"` + +
++ +#### คำตอบ: 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 of `undefined`, but you will see something like: + +`[1, 2, 3, 7 x empty, 11]` + +depending on where you run it (it's different for every browser, node, etc.) + +
++ +#### คำตอบ: A + +The `catch` block receives the argument `x`. This is not the same `x` as the variable when we pass arguments. This variable `x` is block-scoped. + +Later, we set this block-scoped variable equal to `1`, and set the value of the variable `y`. Now, we log the block-scoped variable `x`, which is equal to `1`. + +Outside of the `catch` block, `x` is still `undefined`, และ `y` is `2`. When we want to `console.log(x)` outside of the `catch` block, it returns `undefined`, และ `y` returns `2`. + +
++ +#### คำตอบ: A + +JavaScript only has primitive types and objects. + +Primitive types are `boolean`, `null`, `undefined`, `bigint`, `number`, `string`, และ `symbol`. + +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 a `TypeError`. This is because when you try to access a property or method on a primitive like a string, JavaScript will implicitly wrap the object using one of the wrapper classes, i.e. `String`, and then immediately discard the wrapper after the expression evaluates. All primitives except for `null`และd `undefined` exhibit this behaviour. + +
++ +#### คำตอบ: C + +`[1, 2]` is our initial value. This is the value we start with, and the value of the very first `acc`. During the first round, `acc` is `[1,2]`, และ `cur` is `[0, 1]`. We concatenate them, which results in `[1, 2, 0, 1]`. + +Then, `[1, 2, 0, 1]` is `acc` และ `[2, 3]` is `cur`. We concatenate them, and get `[1, 2, 0, 1, 2, 3]` + +
++ +#### คำตอบ: B + +`null` is falsy. `!null` returns `true`. `!true` returns `false`. + +`""` is falsy. `!""` returns `true`. `!true` returns `false`. + +`1` is truthy. `!1` returns `false`. `!false` returns `true`. + +
++ +#### คำตอบ: A + +It returns a unique id. This id can be used to clear that interval with the `clearInterval()` function. + +
++ +#### คำตอบ: A + +A string is an iterable. The spread operator maps every character of an iterable to one element. + +
++ +#### คำตอบ: 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 a `yield` keyword, the function yields the value specified after it. Note that the generator function in that case doesn’t _return_ the value, it _yields_ the value. + +First, we initialize the generator function with `i` equal to `10`. We invoke the generator function using the `next()` method. The first time we invoke the generator function, `i` is equal to `10`. It encounters the first `yield` keyword: it yields the value of `i`. The generator is now "paused", and `10` gets logged. + +Then, we invoke the function again with the `next()` method. It starts to continue where it stopped previously, still with `i` equal to `10`. Now, it encounters the next `yield` keyword, and yields `i * 2`. `i` is equal to `10`, so it returns `10 * 2`, which is `20`. This results in `10, 20`. + +
++ +#### คำตอบ: B + +When we pass multiple promises to the `Promise.race` method, it resolves/rejects the _first_ promise that resolves/rejects. To the `setTimeout` method, we pass a timer: 500ms for the first promise (`firstPromise`), and 100ms for the second promise (`secondPromise`). This means that the `secondPromise` resolves first with the value of `'two'`. `res` now holds the value of `'two'`, which gets logged. + +
+
+
+#### คำตอบ: D
+
+First, we declare a variable `person` with the value of an object that has a `name` property.
+
+
+
+Then, we declare a variable called `members`. We set the first element of that array equal to the value of the `person` variable. Objects interact by _reference_ when setting them equal to each other. When you assign a reference from one variable to another, you make a _copy_ of that reference. (note that they don't have the _same_ reference!)
+
+
+
+Then, we set the variable `person` equal to `null`.
+
+
+
+We are only modifying the value of the `person` variable, and not the first element in the array, since that element has a different (copied) reference to the object. The first element in `members` still holds its reference to the original object. When we log the `members` array, the first element still holds the value of the object, which gets logged.
+
+
+ +#### คำตอบ: B + +With a `for-in` loop, we can iterate through object keys, in this case `name` และ `age`. Under the hood, object keys are strings (if they're not a Symbol). On every loop, we set the value of `item` equal to the current key it’s iterating over. First, `item` is equal to `name`, and gets logged. Then, `item` is equal to `age`, which gets logged. + +
++ +#### คำตอบ: 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 the _same_ 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 number `7`. + +`7 + '5'` results in `"75"` because of coercion. JavaScript converts the number `7` into a string, see question 15. We can concatenate two strings using the `+`operator. `"7" + "5"` results in `"75"`. + +
++ +#### คำตอบ: C + +Only the first numbers in the string is returned. Based on the _radix_ (the second argument in order to specify what type of number we want to parse it to: base 10, hexadecimal, octal, binary, etc.), the `parseInt` 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 decimal `7`. `num` now holds the value of `7`. + +
++ +#### คำตอบ: C + +When mapping over the array, the value of `num` is equal to the element it’s currently looping over. In this case, the elements are numbers, so the condition of the if statement `typeof num === "number"` returns `true`. 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 returns `undefined`. For every element in the array, the function block gets called, so for each element we return `undefined`. + +
++ +#### คำตอบ: A + +Arguments are passed by _value_, unless their value is an object, then they're passed by _reference_. `birthYear` is passed by value, since it's a string, not an object. When we pass arguments by value, a _copy_ of that value is created (see question 46). + +The variable `birthYear` has a reference to the value `"1997"`. The argument `year` also has a reference to the value `"1997"`, but it's not the same value as `birthYear` has a reference to. When we update the value of `year` by setting `year` equal to `"1998"`, we are only updating the value of `year`. `birthYear` is still equal to `"1997"`. + +The value of `person` is an object. The argument `member` has a (copied) reference to the _same_ object. When we modify a property of the object `member` has a reference to, the value of `person` will also be modified, since they both have a reference to the same object. `person`'s `name` property is now equal to the value `"Lydia"` + +
++ +#### คำตอบ: D + +With the `throw` statement, we can create custom errors. With this statement, you can throw exceptions. An exception can be a string, a number, a boolean or an object. In this case, our exception is the string `'Hello world'`. + +With the `catch` statement, we can specify what to do if an exception is thrown in the `try` 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'`. + +
++ +#### คำตอบ: B + +When you return a property, the value of the property is equal to the _returned_ value, not the value set in the constructor function. We return the string `"Maserati"`, so `myCar.make` is equal to `"Maserati"`. + +
++ +#### คำตอบ: A + +`let x = y = 10;` is actually shorthand for: + +```javascript +y = 10; +let x = y; +``` + +When we set `y` equal to `10`, we actually add a property `y` to the global object (`window` in browser, `global` in Node). In a browser, `window.y` is now equal to `10`. + +Then, we declare a variable `x` with the value of `y`, which is `10`. Variables declared with the `let` keyword are _block scoped_, they are only defined within the block they're declared in; the immediately-invoked function (IIFE) in this case. When we use the `typeof` operator, the operand `x` is not defined: we are trying to access `x` outside of the block it's declared in. This means that `x` 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 variable `y` when setting `y` equal to `10`. This value is accessible anywhere in our code. `y` is defined, and holds a value of type `"number"`. `console.log(typeof y)` returns `"number"`. + +
++ +#### คำตอบ: A + +We can delete properties from objects using the `delete` keyword, also on the prototype. By deleting a property on the prototype, it is not available anymore in the prototype chain. In this case, the `bark` function is not available anymore on the prototype after `delete Dog.prototype.bark`, yet we still try to access it. + +When we try to invoke something that is not a function, a `TypeError` is thrown. In this case `TypeError: pet.bark is not a function`, since `pet.bark` is `undefined`. + +
++ +#### คำตอบ: D + +The `Set` object is a collection of _unique_ values: a value can only occur once in a set. + +We passed the iterable `[1, 1, 2, 3, 4]` with a duplicate value `1`. Since we cannot have two of the same values in a set, one of them is removed. This results in `{1, 2, 3, 4}`. + +
++ +#### คำตอบ: C + +An imported module is _read-only_: you cannot modify the imported module. Only the module that exports them can change its value. + +When we try to increment the value of `myCounter`, it throws an error: `myCounter` is read-only and cannot be modified. + +
++ +#### คำตอบ: A + +The `delete` operator returns a boolean value: `true` on a successful deletion, else it'll return `false`. However, variables declared with the `var`, `const` or `let` keyword cannot be deleted using the `delete` operator. + +The `name` variable was declared with a `const` keyword, so its deletion is not successful: `false` is returned. When we set `age` equal to `21`, we actually added a property called `age` to the global object. You can successfully delete properties from objects this way, also the global object, so `delete age` returns `true`. + +
+
+
+#### คำตอบ: C
+
+We can unpack values from arrays or properties from objects through destructuring. For example:
+
+```javascript
+[a, b] = [1, 2];
+```
+
+
+
+The value of `a` is now `1`, and the value of `b` is now `2`. What we actually did in the question, is:
+
+```javascript
+[y] = [1, 2, 3, 4, 5];
+```
+
+
+
+This means that the value of `y` is equal to the first value in the array, which is the number `1`. When we log `y`, `1` is returned.
+
+
+ +#### คำตอบ: 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 the `user` object, and add them to the `admin` object. The `admin` object now contains the copied key/value pairs, which results in `{ admin: true, name: "Lydia", age: 21 }`. + +
++ +#### คำตอบ: B + +With the `defineProperty` method, we can add new properties to an object, or modify existing ones. When we add a property to an object using the `defineProperty` method, they are by default _not enumerable_. The `Object.keys` method returns all _enumerable_ property names from an object, in this case only `"name"`. + +Properties added using the `defineProperty` method are immutable by default. You can override this behavior using the `writable`, `configurable` และ `enumerable` properties. This way, the `defineProperty` method gives you a lot more control over the properties you're adding to an object. + +
++ +#### คำตอบ: A + +The second argument of `JSON.stringify` is the _replacer_. 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 an _array_, 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"`และd `"health"` are included, `"username"` is excluded. `data` is now equal to `"{"level":19, "health":90}"`. + +If the replacer is a _function_, 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 is `undefined`, this property is excluded from the JSON string. + +
++ +#### คำตอบ: A + +The unary operator `++` _first returns_ the value of the operand, _then increments_ the value of the operand. The value of `num1` is `10`, since the `increaseNumber` function first returns the value of `num`, which is `10`, and only increments the value of `num` afterwards. + +`num2` is `10`, since we passed `num1` to the `increasePassedNumber`. `number` is equal to `10`(the value of `num1`. Again, the unary operator `++` _first returns_ the value of the operand, _then increments_ the value of the operand. The value of `number` is `10`, so `num2` is equal to `10`. + +
++ +#### คำตอบ: 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 the `value` object into a new object, so `x` has the default value of `{ number: 10 }`. + +The default argument is evaluated at _call time_! Every time we call the function, a _new_ object is created. We invoke the `multiply` 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 is `20`. + +The third time we invoke multiply, we do pass an argument: the object called `value`. The `*=` operator is actually shorthand for `x.number = x.number * 2`: we modify the value of `x.number`, and log the multiplied value `20`. + +The fourth time, we pass the `value` object again. `x.number` was previously modified to `20`, so `x.number *= 2` logs `40`. + +
++ +#### คำตอบ: D + +The first argument that the `reduce` method receives is the _accumulator_, `x` in this case. The second argument is the _current 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 optional `initialValue` argument to the `reduce` method, the accumulator is equal to the first element on the first call. + +On the first call, the accumulator (`x`) is `1`, and the current value (`y`) is `2`. We don't return from the callback function, we log the accumulator and current value: `1` และ `2` get logged. + +If you don't return a value from a function, it returns `undefined`. On the next call, the accumulator is `undefined`, and the current value is `3`. `undefined` และ `3` get logged. + +On the fourth call, we again don't return from the callback function. The accumulator is again `undefined`, and the current value is `4`. `undefined` และ `4` get logged. +
++ +#### คำตอบ: B + +In a derived class, you cannot access the `this` keyword before calling `super`. If you try to do that, it will throw a ReferenceError: 1 and 4 would throw a reference error. + +With the `super` keyword, we call that parent class's constructor with the given arguments. The parent's constructor receives the `name` argument, so we need to pass `name` to `super`. + +The `Labrador` class receives two arguments, `name` since it extends `Dog`, และ `size` as an extra property on the `Labrador` class. They both need to be passed to the constructor function on `Labrador`, which is done correctly using constructor 2. +
++ +#### คำตอบ: B + +With the `import` keyword, all imported modules are _pre-parsed_. This means that the imported modules get run _first_, the code in the file which imports the module gets executed _after_. + +This is a difference between `require()` in CommonJS and `import`! With `require()`, you can load dependencies on demand while the code is being run. If we would have used `require` instead of `import`, `running index.js`, `running sum.js`, `3` would have been logged to the console. + +
++ +#### คำตอบ: 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 first `Symbol('foo')`, and the second `Symbol('foo')`. These two values are unique and not equal to each other, `Symbol('foo') === Symbol('foo')` returns `false`. + +
++ +#### คำตอบ: C + +With the `padStart` method, we can add padding to the beginning of a string. The value passed to this method is the _total_ length of the string together with the padding. The string `"Lydia Hallie"` has a length of `12`. `name.padStart(13)` inserts 1 space at the start of the string, because 12 + 1 is 13. + +If the argument passed to the `padStart` method is smaller than the length of the array, no padding will be added. + +
++ +#### คำตอบ: A + +With the `+` operator, you can concatenate strings. In this case, we are concatenating the string `"🥑"` with the string `"💻"`, resulting in `"🥑💻"`. + +
++ +#### คำตอบ: C + +A generator function "pauses" its execution when it sees the `yield` keyword. First, we have to let the function yield the string "Do you love JavaScript?", which can be done by calling `game.next().value`. + +Every line is executed, until it finds the first `yield` keyword. There is a `yield` keyword on the first line within the function: the execution stops with the first yield! _This means that the variable `answer` is not defined yet!_ + +When we call `game.next("Yes").value`, the previous `yield` is replaced with the value of the parameters passed to the `next()` function, `"Yes"` in this case. The value of the variable `answer` is now equal to `"Yes"`. The condition of the if-statement returns `false`, และ `JavaScript loves you back ❤️` gets logged. + +
++ +#### คำตอบ: 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"` + +With `String.raw`, it would simply ignore the escape and print: + +`C:\Documents\Projects\table.html` + +In this case, the string is `Hello\nworld`, which gets logged. + +
++ +#### คำตอบ: C + +An async function always returns a promise. The `await` still has to wait for the promise to resolve: a pending promise gets returned when we call `getData()` in order to set `data` equal to it. + +If we wanted to get access to the resolved value `"I made it"`, we could have used the `.then()` method on `data`: + +`data.then(res => console.log(res))` + +This would've logged `"I made it!"` + +
++ +#### คำตอบ: B + +The `.push()` method returns the _length_ of the new array! Previously, the array contained one element (the string `"banana"`) and had a length of `1`. After adding the string `"apple"` to the array, the array contains two elements, and has a length of `2`. This gets returned from the `addToList` function. + +The `push` method modifies the original array. If you wanted to return the _array_ from the function rather than the _length of the array_, you should have returned `list` after pushing `item` to it. + +
++ +#### คำตอบ: 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 variable `shape` and set it equal to the frozen object `box`, `shape` also refers to a frozen object. You can check whether an object is frozen by using `Object.isFrozen`. In this case, `Object.isFrozen(shape)` returns true, since the variable `shape` has a reference to a frozen object. + +Since `shape` is frozen, and since the value of `x` is not an object, we cannot modify the property `x`. `x` is still equal to `10`, และ `{ x: 10, y: 20 }` gets logged. + +
++ +#### คำตอบ: D + +When we unpack the property `name` from the object on the right-hand side, we assign its value `"Lydia"` to a variable with the name `myName`. + +With `{ name: myName }`, we tell JavaScript that we want to create a new variable called `myName` with the value of the `name` property on the right-hand side. + +Since we try to log `name`, a variable that is not defined, a ReferenceError gets thrown. + +
++ +#### คำตอบ: A + +A pure function is a function that _always_ returns the same result, if the same arguments are passed. + +The `sum` function always returns the same result. If we pass `1` และ `2`, it will _always_ return `3` without side effects. If we pass `5` และ `10`, it will _always_ return `15`, and so on. This is the definition of a pure function. + +
++ +#### คำตอบ: C + +The `add` function is a _memoized_ function. With memoization, we can cache the results of a function in order to speed up its execution. In this case, we create a `cache` object that stores the previously returned values. + +If we call the `addFunction` 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 caches value will be returned, which saves on execution time. Else, if it's not cached, it will calculate the value and store it afterwards. + +We call the `addFunction` function three times with the same value: on the first invocation, the value of the function when `num` is equal to `10` isn't cached yet. The condition of the if-statement `num in cache` returns `false`, 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, the `cache` object contains the value that gets returned for `10`. The condition of the if-statement `num in cache` returns `true`, และ `'From cache! 20'` gets logged. + +The third time, we pass `5 * 2` to the function which gets evaluated to `10`. The `cache` object contains the value that gets returned for `10`. The condition of the if-statement `num in cache` returns `true`, และ `'From cache! 20'` gets logged. + +
++ +#### คำตอบ: A + +With a _for-in_ loop, we can iterate over **enumerable** 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. `0` `1` `2` `3` get logged. + +With a _for-of_ loop, we can iterate over **iterables**. 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. + +
++ +#### คำตอบ: 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` returns `3`, `1 * 2` returns `2`, และ `1 / 2` returns `0.5`. + +
++ +#### คำตอบ: B + +By default, arguments have the value of `undefined`, unless a value has been passed to the function. In this case, we didn't pass a value for the `name` argument. `name` is equal to `undefined` which gets logged. + +In ES6, we can overwrite this default `undefined` value with default parameters. For example: + +`function sayHi(name = "Lydia") { ... }` + +In this case, if we didn't pass a value or if we passed `undefined`, `name` would always be equal to the string `Lydia` + +
++ +#### คำตอบ: B + +The value of the `this` keyword is dependent on where you use it. In a **method**, like the `getStatus` method, the `this` keyword refers to _the object that the method belongs to_. The method belongs to the `data` object, so `this` refers to the `data` object. When we log `this.status`, the `status` property on the `data` object gets logged, which is `"🥑"`. + +With the `call` method, we can change the object to which the `this` keyword refers. In **functions**, the `this` keyword refers to the _the object that the function belongs to_. We declared the `setTimeout` function on the _global object_, so within the `setTimeout` function, the `this` keyword refers to the _global object_. On the global object, there is a variable called _status_ with the value of `"😎"`. When logging `this.status`, `"😎"` gets logged. + + +
++ +#### คำตอบ: A + +We set the variable `city` equal to the value of the property called `city` on the `person` object. There is no property on this object called `city`, so the variable `city` has the value of `undefined`. + +Note that we are _not_ referencing the `person` object itself! We simply set the variable `city` equal to the current value of the `city` property on the `person` object. + +Then, we set `city` equal to the string `"Amsterdam"`. This doesn't change the person object: there is no reference to that object. + +When logging the `person` object, the unmodified object gets returned. + +
++ +#### คำตอบ: C + +Variables with the `const` และ `let` keyword are _block-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. + +
++ +#### คำตอบ: C + +The value of `res` in the second `.then` is equal to the returned value of the previous `.then`. You can keep chaining `.then`s like this, where the value is passed to the next handler. + +
++ +#### คำตอบ: A + +With `!!name`, we determine whether the value of `name` is truthy or falsy. If name is truthy, which we want to test for, `!name` returns `false`. `!false` (which is what `!!name` practically is) returns `true`. + +By setting `hasName` equal to `name`, you set `hasName` equal to whatever value you passed to the `getName` function, not the boolean value `true`. + +`new Boolean(true)` returns an object wrapper, not the boolean value itself. + +`name.length` returns the length of the passed argument, not whether it's `true`. + +
++ +#### คำตอบ: B + +In order to get an character on a specific index in 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 which index is 0, the character `"I'`, which gets logged. + +Note that this method is not supported in IE7 and below. In that case, use `.charAt()` + +
++ +#### คำตอบ: B + +You can set a default parameter's value equal to another parameter of the function, as long as they've been defined _before_ the default parameter. We pass the value `10` to the `sum` function. If the `sum` function only receives 1 argument, it means that the value for `num2` is not passed, and the value of `num1` is equal to the passed value `10` in this case. The default value of `num2` is the value of `num1`, which is `10`. `num1 + num2` returns `20`. + +If you're trying to set a default parameter's value equal to a parameter which is defined _after_ (to the right), the parameter's value hasn't been initialized yet, which will throw an error. + +
++ +#### คำตอบ: A + +With the `import * as name` syntax, we import _all exports_ from the `module.js` file into the `index.js` file as a new object called `data` is created. In the `module.js` file, there are two exports: the default export, and a named export. The default export is a function which returns the string `"Hello World"`, and the named export is a variable called `name` which has the value of the string `"Lydia"`. + +The `data` object has a `default` property for the default export, other properties have the names of the named exports and their corresponding values. + +
++ +#### คำตอบ: C + +Classes are syntactical sugar for function constructors. The equivalent of the `Person` class as a function constructor would be: + +```javascript +function Person() { + this.name = name +} +``` + +Calling a function constructor with `new` results in the creation of an instance of `Person`, `typeof` keyword returns `"object"` for an instance. `typeof member` returns `"object"`. + +
++ +#### คำตอบ: D + +The `.push` method returns the _new length_ of the array, not the array itself! By setting `newList` equal to `[1, 2, 3].push(4)`, we set `newList` equal to the new length of the array: `4`. + +Then, we try to use the `.push` method on `newList`. Since `newList` is the numerical value `4`, we cannot use the `.push` method: a TypeError is thrown. + +
++ +#### คำตอบ: D + +Regular functions, such as the `giveLydiaPizza` function, have a `prototype` property, which is an object (prototype object) with a `constructor` property. Arrow functions however, such as the `giveLydiaChocolate` function, do not have this `prototype` property. `undefined` gets returned when trying to access the `prototype` property using `giveLydiaChocolate.prototype`. + +
++ +#### คำตอบ: A + +`Object.entries(person)` returns an array of nested arrays, containing the keys and objects: + +`[ [ 'name', 'Lydia' ], [ 'age', 21 ] ]` + +Using the `for-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, using `const [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" ]`, with `x` equal to `"name"`, และ `y` equal to `"Lydia"`, which get logged. +The second subarray is `[ "age", 21 ]`, with `x` equal to `"age"`, และ `y` equal to `21`, which get logged. + +
++ +#### คำตอบ: 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. + +```javascript +function getItems(fruitList, favoriteFruit, ...args) { + return [...fruitList, ...args, favoriteFruit] +} + +getItems(["banana", "apple"], "pear", "orange") +``` + +The above example works. This returns the array `[ 'banana', 'apple', 'orange', 'pear' ]` +
++ +#### คำตอบ: B + +In JavaScript, we don't _have_ to write the semicolon (`;`) explicitly, however the JavaScript engine still adds them after statements. This is called **Automatic Semicolon Insertion**. A statement can for example be variables, or keywords like `throw`, `return`, `break`, etc. + +Here, we wrote a `return` statement, and another value `a + b` on a _new 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 after `return`. You could see this as: + +```javascript + return; + a + b +``` + +This means that `a + b` is never reached, since a function stops running after the `return` keyword. If no value gets returned, like here, the function returns `undefined`. Note that there is no automatic insertion after `if/else` statements! + +
++ +#### คำตอบ: B + +We can set classes equal to other classes/function constructors. In this case, we set `Person` equal to `AnotherPerson`. The name on this constructor is `Sarah`, so the name property on the new `Person` instance `member` is `"Sarah"`. + +
++ +#### คำตอบ: D + +A Symbol is not _enumerable_. The Object.keys method returns all _enumerable_ 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 the `Object.getOwnPropertySymbols()` method). + +
++ +#### คำตอบ: A + +The `getList` function receives an array as its argument. Between the parentheses of the `getList` 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 are `2`, `3` และ `4` in this case. The value of `y` is an array, containing all the rest parameters. The value of `x` is equal to `1` in this case, so when we log `[x, y]`, `[1, [2, 3, 4]]` gets logged. + + The `getUser` function receives an object. With arrow functions, we don't _have_ to write curly brackets if we just return one value. However, if you want to return an _object_ from an arrow function, you have to write it between parentheses, otherwise no value gets returned! The following function would have returned an object: + +```const getUser = user => ({ name: user.name, age: user.age })``` + +Since no value gets returned in this case, the function returns `undefined`. + +
++ +#### คำตอบ: C + +The variable `name` holds the value of a string, which is not a function, thus cannot invoke. + +TypeErrors get thrown when a value is not of the expected type. JavaScript expected `name` 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 word `return` as `retrun`. +ReferenceErrors get thrown when JavaScript isn't able to find a reference to a value that you're trying to access. + +
++ +#### คำตอบ: 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. + +
++ +#### คำตอบ: 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 past 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 `[]`. + +
++ +#### คำตอบ: D + +With a promise, we basically say _I 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 the `await` keyword in an `async` function. Although we can get a promise's value with both `.then` และ `await`, they work a bit differently. + +In the `firstFunction`, we (sort of) put the myPromise function aside while it was running, but continued running the other code, which is `console.log('second')` in this case. Then, the function resolved with the string `I have resolved`, which then got logged after it saw that the callstack was empty. + +With the await keyword in `secondFunction`, we literally pause the execution of an async function until the value has been resolved befoer moving to the next line. + +This means that it waited for the `myPromise` to resolve with the value `I have resolved`, and only once that happened, we moved to the next line: `second` got logged. + +
++ +#### คำตอบ: C + +The `+` operator is not only used for adding numerica lvalues, 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 is `1`, which is a numerical value. `1 + 2` returns the number 3. + +However, the second one is a string `"Lydia"`. `"Lydia"` is a string and `2` is a number: `2` gets coerced into a string. `"Lydia"` และ `"2"` get concatenated, whic hresults 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"`. + +
++ +#### คำตอบ: C + +We can pass any type of value we want to `Promise.resolve`, either a promise or a non-promise. The method itself returns a promise with the resolved value. 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 value `5`. It returns a resolved promise with the value `5`. + +
++ +#### คำตอบ: B + +Objects are passed by reference. When we check objects for strict equality (`===`), we're comparing their references. + +We set the default value for `person2` equal to the `person` object, and passed the `person` object as the value for `person1`. + +This means that both values have a reference to the same spot in memory, thus they are equal. + +The code block in the `else` statement gets run, and `They are the same!` gets logged. + +
++ +#### คำตอบ: 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 called `colors` on the `colorConfig` object. There is no proprety called `colorConfig`, so this returns `undefined`. Then, we try to access the value of the first element by using `[1]`. We cannot do this on a value that's `undefined`, so it throws a `TypeError`: `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 used `colorConfig[colors[1]]`, it would have returned the value of the `red` property on the `colorConfig` object. + +
++ +#### คำตอบ: 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. + +
++ +#### คำตอบ: D + +With `splice` 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 added the ✨ emoji instead. + +`map`, `filter` และ `slice` return a new array, `find` returns an element, and `reduce` returns a reduced value. + +
++ +#### Answer: A + +We set the value of the `favoriteFood` property on the `info` object equal to the string with the pizza emoji, `'🍕'`. A string is a primitive data type. In JavaScript, primitive data types act by reference + +In JavaScript, primitive data types (everything that's not an object) interact by _value_. In this case, we set the value of the `favoriteFood` property on the `info` object equal to the value of the first element in the `food` array, the string with the pizza emoji in this case (`'🍕'`). A string is a primitive data type, and interact by value (see my [blogpost](https://www.theavocoder.com/complete-javascript/2018/12/21/by-value-vs-by-reference) if you're interested in learning more) + +Then, we change the value of the `favoriteFood` property on the `info` object. The `food` array hasn't changed, since the value of `favoriteFood` was merely a _copy_ 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 on `food[0]`. When we log food, it's still the original array, `['🍕', '🍫', '🥑', '🍔']`. + +
++ +#### Answer: A + +With the `JSON.parse()` method, we can parse JSON string to a JavaScript value. + +```javascript +// Stringifying a number into valid JSON, then parsing the JSON string to a JavaScript value: +const jsonNumber = JSON.stringify(4) // '4' +JSON.parse(jsonNumber) // 4 + +// Stringifying an array value into valid JSON, then parsing the JSON string to a JavaScript value: +const jsonArray = 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: +const jsonArray = JSON.stringify({ name: "Lydia" }) // '{"name":"Lydia"}' +JSON.parse(jsonArray) // { name: 'Lydia' } +``` + +
++ +#### Answer: D + +Each function has its own _execution context_ (or _scope_). The `getName` function first looks within its own context (scope) to see if it contains the variable `name` we're trying to access. In this case, the `getName` function contains its own `name` variable: we declare the variable `name` with the `let` keyword, and with the value of `'Sarah'`. + +Variables with the `let` keyword (and `const`) are hoisted, but unlike `var`, don't get initialized. 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 a `ReferenceError`. + +If we wouldn't have declared the `name` variable within the `getName` function, the javascript engine would've looked down the _scope chain_. The outer scope has a variable called `name` with the value of `Lydia`. In that case, it would've logged `Lydia`. + +```javascript +let name = 'Lydia' + +function getName() { + console.log(name) +} + +getName() // Lydia +``` + +
++ +#### Answer: C + +With the `yield` keyword, we `yield` values in a generator function. With the `yield*` keyword, we can yield values from another generator function, or iterable object (for example an array). + +In `generatorOne`, we yield the entire array `['a', 'b', 'c']` using the `yield` keyword. The value of `value` property on the object returned by the `next` method on `one` (`one.next().value`) is equal to the entire array `['a', 'b', 'c']`. + +```javascript +console.log(one.next().value) // ['a', 'b', 'c'] +console.log(one.next().value) // undefined +``` + +In `generatorTwo`, we use the `yield*` keyword. This means that the first yielded value of `two`, is equal to the first yielded value in the iterator. The iterator is the array `['a', 'b', 'c']`. The first yielded value is `a`, so the first time we call `two.next().value`, `a` is returned. + +```javascript +console.log(two.next().value) // 'a' +console.log(two.next().value) // 'b' +console.log(two.next().value) // 'c' +console.log(two.next().value) // undefined +``` + +
++ +#### 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 the `x => x` arrow function. `x` is equal to `'I love'`, which gets returned. This results in `I love to program`. + +
++ +#### Answer: C + +Normally when we set objects equal to `null`, those objects get _garbage collected_ as there is no reference anymore to that object. However, since the callback function within `setInterval` is an arrow function (thus bound to the `config` object), the callback function still holds a reference to the `config` object. As long as there is a reference, the object won't get garbage collected. Since it's not garbage collected, the `setInterval` callback function will still get invoked every 1000ms (1s). + +
++ +#### Answer: B + +When adding a key/value pair using the `set` method, the key will be the value of the first argument passed to the `set` function, and the value will be the second argument passed to the `set` function. The key is the _function_ `() => '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 the `get` method. Object interact by _reference_. 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. + +
++ +#### Answer: C + +Both the `changeAge` and `changeAgeAndName` functions have a default parameter, namely a _newly_ created object `{ ...person }`. This object has copies of all the key/values in the `person` object. + +First, we invoke the `changeAge` function and pass the `person` object as its argument. This function increases the value of the `age` property by 1. `person` is now `{ name: "Lydia", age: 22 }`. + +Then, we invoke the `changeAgeAndName` function, however we don't pass a parameter. Instead, the value of `x` is equal to a _new_ object: `{ ...person }`. Since it's a new object, it doesn't affect the values of the properties on the `person` object. `person` is still equal to `{ name: "Lydia", age: 22 }`. + +
++ +#### Answer: A + +We set the value of the `favoriteFood` property on the `info` object equal to the string with the pizza emoji, `'🍕'`. A string is a primitive data type. In JavaScript, primitive data types act by reference + +In JavaScript, primitive data types (everything that's not an object) interact by _value_. In this case, we set the value of the `favoriteFood` property on the `info` object equal to the value of the first element in the `food` array, the string with the pizza emoji in this case (`'🍕'`). A string is a primitive data type, and interact by value (see my [blogpost](https://www.theavocoder.com/complete-javascript/2018/12/21/by-value-vs-by-reference) if you're interested in learning more) + +Then, we change the value of the `favoriteFood` property on the `info` object. The `food` array hasn't changed, since the value of `favoriteFood` was merely a _copy_ 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 on `food[0]`. When we log food, it's still the original array, `['🍕', '🍫', '🥑', '🍔']`. + +
++ +#### Answer: A + +With the `JSON.parse()` method, we can parse JSON string to a JavaScript value. + +```javascript +// Stringifying a number into valid JSON, then parsing the JSON string to a JavaScript value: +const jsonNumber = JSON.stringify(4) // '4' +JSON.parse(jsonNumber) // 4 + +// Stringifying an array value into valid JSON, then parsing the JSON string to a JavaScript value: +const jsonArray = 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: +const jsonArray = JSON.stringify({ name: "Lydia" }) // '{"name":"Lydia"}' +JSON.parse(jsonArray) // { name: 'Lydia' } +``` + +
++ +#### Answer: D + +Each function has its own _execution context_ (or _scope_). The `getName` function first looks within its own context (scope) to see if it contains the variable `name` we're trying to access. In this case, the `getName` function contains its own `name` variable: we declare the variable `name` with the `let` keyword, and with the value of `'Sarah'`. + +Variables with the `let` keyword (and `const`) are hoisted, but unlike `var`, don't get initialized. 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 a `ReferenceError`. + +If we wouldn't have declared the `name` variable within the `getName` function, the javascript engine would've looked down the _scope chain_. The outer scope has a variable called `name` with the value of `Lydia`. In that case, it would've logged `Lydia`. + +```javascript +let name = 'Lydia' + +function getName() { + console.log(name) +} + +getName() // Lydia +``` + +
++ +#### Answer: C + +With the `yield` keyword, we `yield` values in a generator function. With the `yield*` keyword, we can yield values from another generator function, or iterable object (for example an array). + +In `generatorOne`, we yield the entire array `['a', 'b', 'c']` using the `yield` keyword. The value of `value` property on the object returned by the `next` method on `one` (`one.next().value`) is equal to the entire array `['a', 'b', 'c']`. + +```javascript +console.log(one.next().value) // ['a', 'b', 'c'] +console.log(one.next().value) // undefined +``` + +In `generatorTwo`, we use the `yield*` keyword. This means that the first yielded value of `two`, is equal to the first yielded value in the iterator. The iterator is the array `['a', 'b', 'c']`. The first yielded value is `a`, so the first time we call `two.next().value`, `a` is returned. + +```javascript +console.log(two.next().value) // 'a' +console.log(two.next().value) // 'b' +console.log(two.next().value) // 'c' +console.log(two.next().value) // undefined +``` + +
++ +#### 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 the `x => x` arrow function. `x` is equal to `'I love'`, which gets returned. This results in `I love to program`. + +
++ +#### Answer: C + +Normally when we set objects equal to `null`, those objects get _garbage collected_ as there is no reference anymore to that object. However, since the callback function within `setInterval` is an arrow function (thus bound to the `config` object), the callback function still holds a reference to the `config` object. As long as there is a reference, the object won't get garbage collected. Since it's not garbage collected, the `setInterval` callback function will still get invoked every 1000ms (1s). + +
++ +#### Answer: B + +When adding a key/value pair using the `set` method, the key will be the value of the first argument passed to the `set` function, and the value will be the second argument passed to the `set` function. The key is the _function_ `() => '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 the `get` method. Object interact by _reference_. 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. + +
++ +#### Answer: C + +Both the `changeAge` and `changeAgeAndName` functions have a default parameter, namely a _newly_ created object `{ ...person }`. This object has copies of all the key/values in the `person` object. + +First, we invoke the `changeAge` function and pass the `person` object as its argument. This function increases the value of the `age` property by 1. `person` is now `{ name: "Lydia", age: 22 }`. + +Then, we invoke the `changeAgeAndName` function, however we don't pass a parameter. Instead, the value of `x` is equal to a _new_ object: `{ ...person }`. Since it's a new object, it doesn't affect the values of the properties on the `person` object. `person` is still equal to `{ name: "Lydia", age: 22 }`. + +
++ +#### Ответ: A + +Мы устанавливаем значение свойства `favourFood` для объекта `info` равным строке со смайликами для пиццы, `'🍕'`. Строка является примитивным типом данных. В JavaScript примитивные типы данных передаются по ссылке ... + +В JavaScript примитивные типы данных (все, что не является объектом) передаются как _значение_. В этом случае мы устанавливаем значение свойства `favourFood` объекта `info` равным значению первого элемента в массиве `food`, в данном случае это строка с emoji пиццы (`'🍕'`). Строка является примитивным типом данных и взаимодействует по значению (см. мой [пост в блоге](https://www.theavocoder.com/complete-javascript/2018/12/21/by-value-vs-by-reference), если вы заинтересованы в получении дополнительной информации). + +Затем мы меняем значение свойства `favourFood` объекта `info`. Массив `food` не изменился, поскольку значение `favourFood` было просто _скопировано_ из значения первого элемента в массиве и не имеет ссылки на то же место в памяти, что и элемент на `food[0]`. Когда мы выводим в лог `food`, это все равно исходный массив, `['🍕', '🍫', '🥑', '🍔']`. + +
++ +#### Ответ: A + +С помощью метода `JSON.parse ()` мы можем разобрать строку JSON в значение JavaScript. + +```javascript +// Преобразование числа в допустимый JSON, затем преобразование строки JSON в значение JavaScript: +const jsonNumber = JSON.stringify(4) // '4' +JSON.parse(jsonNumber) // 4 + +// Преобразование значения массива в допустимый JSON, затем разбор строки JSON в значение JavaScript: +const jsonArray = JSON.stringify([1, 2, 3]) // '[1, 2, 3]' +JSON.parse(jsonArray) // [1, 2, 3] + +// Преобразование объекта в допустимый JSON, затем преобразование строки JSON в значение JavaScript: +const jsonArray = JSON.stringify({ name: "Lydia" }) // '{"name":"Lydia"}' +JSON.parse(jsonArray) // { name: 'Lydia' } +``` + +
++ +#### Ответ: D + +Каждая функция имеет свой собственный _контекст исполнения_ (или _область действия_). Функция `getName` сначала ищет в своем собственном контексте (области действия), чтобы увидеть, содержит ли она переменную `name`, к которой мы пытаемся получить доступ. В этом случае функция `getName` содержит собственную переменную `name`: мы объявляем переменную `name` с ключевым словом `let` и значением `'Sarah'`. + +Переменные с ключевым словом `let` (и `const`) поднимаются в начало функции, в отличие от `var`, которые не инициализируется. Они недоступны до того, как мы объявим (инициализируем) их строку. Это называется "временной мертвой зоной". Когда мы пытаемся получить доступ к переменным до их объявления, JavaScript выдает `ReferenceError`. + +Если бы мы не объявили переменную `name` в функции `getName`, движок javascript посмотрел бы вниз по _цепочки области действия_. Внешняя область имеет переменную с именем `name` со значением `Lydia`. В этом случае он бы записал "Лидию". + +```javascript +let name = 'Lydia' + +function getName() { + console.log(name) +} + +getName() // Lydia +``` + +
++ +#### Ответ: C + +Используя ключевое слово `yield`, мы получаем значения в функции генератора. С помощью ключевого слова `yield*` мы можем получить значения из другой функции-генератора или итерируемого объекта (например, массива). + +В `generatorOne` мы получаем весь массив `[' a ',' b ',' c ']`, используя ключевое слово `yield`. Значение свойства `value` для объекта, возвращаемого методом `next` для `one` (`one.next().value`), равно всему массиву `['a', 'b', 'c']`. + +```javascript +console.log(one.next().value) // ['a', 'b', 'c'] +console.log(one.next().value) // undefined +``` + +В файле `generatorTwo` мы используем ключевое слово `yield*`. Это означает, что первое полученное значение `two` равно первому полученному значению в итераторе. Итератор - это массив `['a', 'b', 'c']`. Первым полученным значением является `a`, поэтому в первый раз, когда мы вызываем `two.next().value`, возвращается `a`. + +```javascript +console.log(two.next().value) // 'a' +console.log(two.next().value) // 'b' +console.log(two.next().value) // 'c' +console.log(two.next().value) // undefined +``` + +
++ +#### Ответ: A + +Выражения внутри литералов шаблона расчитываются первыми. Это означает, что строка будет содержать возвращаемое значение выражения, в данном случае немедленно исполняемую функцию `(x => x)('I love')`. Мы передаем значение `'I love'` в качестве аргумента стрелочной функции `x => x`. `x` равно `'I love'`, которое и возвращается. Это приводит к `I love to program`. + +
++ +#### Ответ: C + +Обычно, когда мы устанавливаем объекты равными `null`, эти объекты получают метку _собрано в мусор_, так как больше нет ссылок на этот объект. Однако, поскольку функция обратного вызова в `setInterval` является стрелочной функцией стрелки (таким образом, привязанной к объекту `config`), функция обратного вызова все еще содержит ссылку на объект `config`. Пока есть ссылка, объект не будет собран в мусор. Поскольку сборщик мусора не отрабатывает, функция обратного вызова `setInterval` будет по-прежнему вызываться каждые 1000 мс (1с). + +
++ +#### Ответ: B + +При добавлении пары ключ/значение с использованием метода `set` имя ключа будет равно значению первого аргумента, переданного в функцию `set`, а значением будет второй аргумент, переданный в функцию `set`. В данном случае ключом является _функция_ `() => 'greeting'` и значение `'Hello world'`. `myMap` теперь это `{ () => 'greeting' => 'Hello world!' }`. + +1 неверно, поскольку ключ не `'greeting'`, а `() => 'greeting'`. +3 неверно, так как мы создаем новую функцию, передавая ее в качестве параметра методу `get`. Объект взаимодействует со _ссылкой_. Функции - это объекты, поэтому две функции никогда не бывают строго равными, даже если они идентичны: они имеют ссылки на разные места в памяти. + +
++ +#### Ответ: C + +Функции `changeAge` и `changeAgeAndName` имеют параметр по умолчанию, а именно _вновь_ созданный объект `{ ...person }`. Этот объект имеет копии всех ключей/значений объекта `person`. + +Сначала мы вызываем функцию `changeAge` и передаем объект `person` в качестве аргумента. Эта функция увеличивает значение свойства `age` на 1. `person` теперь `{name: "Lydia", age: 22}`. + +Затем мы вызываем функцию `changeAgeAndName`, однако мы не передаем параметр. Вместо этого значение `x` равно новому объекту: `{ ... person }`. Поскольку это новый объект, он не влияет на значения свойств объекта `person`. `person` по-прежнему равен `{name: "Lydia", age: 22}`. + +
++ +#### Antwort: A + +In JavaScript interagieren primitive Datentypen (alles außer Objekte) anhand des _Wertes_. In diesem Beispiel setzen wir den Wert von `favoriteFood` am `info` Objekt gleich dem Wert des ersten Elements im `food` Array, in dem Fall ein String mit dem Pizza Emoji (`'🍕'`). Ein String ist ein primitiver Datentyp und agiert daher in JavaScript nach Referenz. (Siehe mein [Blogpost](https://www.theavocoder.com/complete-javascript/2018/12/21/by-value-vs-by-reference) für mehr Informationen) + +Dann ändern wir den Wert von `favoriteFood` am `info` Objekt. Das `food` Array hat sich nicht verändert, da der Wert von `favoriteFood` nur eine _Kopie_ des Wertes des ersten Elements im Array war und keine Referenz zum Element `food[0]` im Speicher finden kann. Wenn wir also das Essen loggen ist es immernoch das ursprüngliche Array `['🍕', '🍫', '🥑', '🍔']`. + +
++ +#### Antwort: A + +Mit der `JSON.parse()` Methode können wir einen JSON String zu einem JavaScript Wert umwandeln. + +```javascript +// Stringifying a number into valid JSON, then parsing the JSON string to a JavaScript value: +const jsonNumber = JSON.stringify(4) // '4' +JSON.parse(jsonNumber) // 4 + +// Stringifying an array value into valid JSON, then parsing the JSON string to a JavaScript value: +const jsonArray = 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: +const jsonArray = JSON.stringify({ name: "Lydia" }) // '{"name":"Lydia"}' +JSON.parse(jsonArray) // { name: 'Lydia' } +``` + +
++ +#### Antwort: D + +Jede Funktion hat ihren eigenen _Ausführungskontext_ (oder _scope_). Die `getName` Funktion sucht zuerst in ihrem eigenen Kontext (scope) um zu sehen, ob sie den Wert `name` finden kann. In diesem Fall beinhaltet die `getName` Funktion ihre eigene Variable `name`: wir setzen die Variable `name` mit dem `let` Keyword und dem Wert `'Sarah'`. + +Variablen mit dem `let` und `const` Keyword werden gehoisted, aber entgegen `var` werden diese nicht _initialisiert_. Sie sind nicht aufrufbar, bevor wir sie deklarieren (initialisieren). Das ist eine "vorübergehende tote Zone" (temporal dead zone). Wir bekommen einen `ReferenceError` ausgegeben. + +Hätten wir die `name` Variable nicht innerhalb `getName` deklariert, so hätte JavaScript außerhalb der Funktion in der _Scope-Kette_ weitergesucht. Der äußere Scope beinhaltet ebenfalls eine Variable `name` mit dem Wert `'Lydia'`. In diesem Fall wäre `Lydia` geloggt worden. + +```javascript +let name = 'Lydia' + +function getName() { + console.log(name) +} + +getName() // Lydia +``` + +
++ +#### Antwort: C + +Mit dem `yield` Keyword, halten wir Werte in einer Generator-Funktion. Mit dem `yield*` Keyword können wir Werte einer anderen Generator-Funktion oder Objekte und Arrays halten. + +In `generatorOne` halten wir das gesamte Array `['a', 'b', 'c']` mit dem `yield` Keyword. Der Wert von `value` am Objekt gibt die `next` Methode an `one` (`one.next().value`) aus, was dem gesamten Array entspricht: `['a', 'b', 'c']`. + +```javascript +console.log(one.next().value) // ['a', 'b', 'c'] +console.log(one.next().value) // undefined +``` + +In `generatorTwo` verwenden wir das `yield*` Keyword. Das bedeutet, dass der erste gehaltene Wert von `two` gleich dem ersten gehaltenen Wert ist. Das ist das Array `['a', 'b', 'c']`. Der erste gehaltene Wert ist `a`, was ausgegeben wird. + +```javascript +console.log(two.next().value) // 'a' +console.log(two.next().value) // 'b' +console.log(two.next().value) // 'c' +console.log(two.next().value) // undefined +``` + +
++ +#### Antwort: A + +Expressions innerhalb von Template Literals werden zuerst berechnet. Das bedeutet, dass der String den ausgegebenen Wert der Expression beinhaltet, hier die IIFE (immediately invoked Function) `(x => x)('I love')`. Wir geben den Wert `'I love'` als Argument an die `x => x` Arrow Funktion. `x` ist gleich `'I love'` und wird ausgegeben. Das Ergebnis ist `I love to program`. + +
++ +#### Antwort: C + +Wenn wir normalerweise Objekte gleich `null` setzen, werden diese _verworfen_, weil keine Referenz mehr zu ihnen existiert. Da die Callback Funktion in `setInterval` eine Arrow Funktion (und daher an `config` gebunden) ist, hält die Callback Funktion immernoch eine Referenz zum `config` Objekt. Solange eine Referenz besteht, wird das Objekt nicht verworfen und die `setInterval` Funktion wird weiterhin alle 1000ms (1 Sekunde) aufgerufen. + +
++ +#### Antwort: B + +Beim Setzen eines Key/Wert Paars mit der `set` Methode wird der Key als erstes Argument an die `set` Funktion übergeben und der Wert wird als zweites Argument eingegeben. Der Key ist die _Funktion_ `() => 'greeting'` und der Wert ist `'Hello world'`. `myMap` ist jetzt `{ () => 'greeting' => 'Hello world!' }`. + +1 ist falsch, weil der Key nicht `'greeting'`, sondern `() => 'greeting'` ist. +3 ist falsch, weil wir eine neue Funktion erstellen, indem wir sie als Argument übergeben. Objekte interagieren anhand von _Referenzen_. Funktionen sind Objekte, weshalb zwei Funktionen streng gesehen nie gleich sind, selbst wenn sie sich nicht unterscheiden. + +
++ +#### Antwort: C + +Beide Funktionen, `changeAge` und `changeAgeAndName`, haben Standard Parameter, nämlich ein neu erstelltes Objekt `{ ...person }`. Dieses Objekt hat Kopien aller Key/Werte Paare im `person` Objekt. + +Zuerst führen wir die `changeAge` Funktion aus und übergeben ihr das `person` Objekt als Argument. Daher wird `age` um 1 erhöht. `person` ist jetzt `{ name: "Lydia", age: 22 }`. + +Dann führen wir `changeAgeAndName` aus, allerdings ohne Parameter. Stattdessen ist der Wert von `x` gleich dem neuen Objekt `{ ...person }`. Da dies ein neues Objekt ist hat es keinen Einfluss auf die Werte des `person` Objekts. `person` ist immernoch gleich `{ name: "Lydia", age: 22 }`. + +
++ +#### 答案: D + +对于promise,我们基本上说 _我想要执行此函数,但是由于执行此函数可能需要一段时间,因此,先暂时将其搁置一旁。仅当某个值被resolved(或rejected)并且调用栈为空时,我才想使用这个值。_ + +我们可以在异步函数中同时使用`.then`和`await`关键字来获取promise的返回值。尽管我们可以同时使用`.then`和`await`来获得promise的返回值,但它们的运行方式有所不同。 + +在`firstFunction`函数中,当这个函数运行的时候,代码执行到myPromise函数时,系统会将其放在一边,继续执行下一行代码,在本例中为`console.log('second')`,执行完成之后,myPromise函数返回一个resolved后的字符串'I have resolved!' 在看到调用堆栈为空之后将其记录下来。 + +由于在`secondFunction`函数中使用了`await`关键字,从字面上暂停了异步函数的执行,程序将会等到myPromise函数返回结果之后,才会执行下一行代码, + +This means that it waited for the `myPromise` to resolve with the value `I have resolved`, and only once that happened, we moved to the next line: `second` got logged. + +这意味着,程序在等待`myPromise`的resolved的值`I have resolved!`,只有发生这种情况后,程序才会执行下一行代码:`console.log('second')` + +
++ +#### 答案: C + +“+”运算符不仅用于添加数值,还可以使用它来连接字符串。 每当JavaScript引擎发现一个或多个值不是数字时,就会将数字强制为字符串。 + +第一个是数字1。 1 + 2返回数字3。 + +但是,第二个是字符串“Lydia”。 “Lydia”是一个字符串,2是一个数字:2被强制转换为字符串。 “Lydia”和“2”被连接起来,产生字符串“Lydia2”。 + +`{name:“ Lydia”}`是一个对象。 数字和对象都不是字符串,因此将二者都字符串化。 每当我们对常规对象进行字符串化时,它就会变成“[Object object]”`。 与“2”串联的“ [Object object]”成为“[Object object]2”。 + +
++ +#### 答案: C + +我们可以将我们想要的任何类型的值传递给Promise.resolve,无论是Promise还是非Promise。 该方法本身返回带有resolved值的Promise。 +如果您传递常规函数,它将是具有常规值的resolved的Promise。 如果您传入一个promise,它将是resolved的promise,其中包含已传入promise的resolved值。 + +在这种情况下,我们只传递了数值 5 。 它返回值为 5 的resolved的promise。 + +
++ +#### 答案: B + +对象通过引用传递。 当我们检查对象的严格相等性(===)时,我们正在比较它们的引用。 + +我们将“person2”的默认值设置为“person”对象,并将“person”对象作为“person1”的值传递。 + +这意味着两个值都引用内存中的同一位置,因此它们是相等的。 + +运行“ else”语句中的代码块,并记录`They are the same!` 。 + +
++ +#### 答案: D + +在JavaScript中,我们有两种访问对象属性的方法:括号表示法或点表示法。 在此示例中,我们使用点表示法(`colorConfig.colors`)代替括号表示法(`colorConfig [“ colors”]`)。 + +使用点表示法,JavaScript会尝试使用该确切名称在对象上查找属性。 在此示例中,JavaScript尝试在colorconfig对象上找到名为colors的属性。 没有名为“colors”的属性,因此返回“undefined”。 +然后,我们尝试使用`[1]`访问第一个元素的值。 我们无法对未定义的值执行此操作,因此会抛出`Cannot read property '1' of undefined`。 + +JavaScript解释(或取消装箱)语句。 当我们使用方括号表示法时,它会看到第一个左方括号`[`并一直进行下去,直到找到右方括号`]`。 只有这样,它才会评估该语句。 如果我们使用了colorConfig [colors [1]],它将返回colorConfig对象上red属性的值。 + +
++ +#### 答案: A + +在内部,表情符号是unicode。 heat表情符号的unicode是`“ U + 2764 U + FE0F”`。 对于相同的表情符号,它们总是相同的,因此我们将两个相等的字符串相互比较,这将返回true。 + +
++ +#### 答案: D + +使用`splice`方法,我们通过删除,替换或添加元素来修改原始数组。 在这种情况下,我们从索引1中删除了2个项目(我们删除了`'🥑'`和`'😍'`),而是添加了✨emoji表情。 + +“map”,“filter”和“slice”返回一个新数组,“find”返回一个元素,而“reduce”返回一个减小的值。 + +
+@@ -3300,7 +3300,7 @@ The first one is `1`, which is a numerical value. `1 + 2` returns the number 3. However, the second one is a string `"Lydia"`. `"Lydia"` is a string and `2` 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"`. +`{ 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"`.
@@ -3301,7 +3301,7 @@ Der erste Wert ist `1`, was ein numerischer Wert ist. `1 + 2` ergibt die Zahl `3 Der zweite Wert hingegen ist der String `"Lydia"`. `"Lydia"` ist ein String und `2` ist eine Nummer: `2` wird in einem String umgewandelt. `"Lydia"` und `"2"` werden zusammengesetzt, was den String `"Lydia2"` ausgibt. -`{ name: "Lydia" }` ist ein Objekt. Weder eine Nummer, noch ein Objekt sind ein String, aber beide werden zu Strings konvertiert und `"[Object object]"` wird ausgegeben. `"[Object object]"` zusammengesetzt mit `"2"` wird `"[Object object]2"`. +`{ name: "Lydia" }` ist ein Objekt. Weder eine Nummer, noch ein Objekt sind ein String, aber beide werden zu Strings konvertiert und `"[object Object]"` wird ausgegeben. `"[object Object]"` zusammengesetzt mit `"2"` wird `"[object Object]2"`.
@@ -3300,7 +3300,7 @@ The first one is `1`, which is a numerical value. `1 + 2` returns the number 3. However, the second one is a string `"Lydia"`. `"Lydia"` is a string and `2` is a number: `2` gets coerced into a string. `"Lydia"` and `"2"` get concatenated, whic hresults 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"`. +`{ 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"`.
@@ -3302,7 +3302,7 @@ for (let item of set) { 그러나, 두번째는 문자열 `"Lydia"`이에요. `"Lydia"`은 문자열이고, `2`는 숫자에요: `2`는 문자열로 강제 변환되어요. `"Lydia"`그리고 `"2"`이 연결되어, 문자열 `"Lydia2"`이 리턴되요. -`{ name: "Lydia" }`은 객체에요. 객체가 아닌 숫자나 객체는 문자열이 아니므로, 둘다 문자화되어요. 정규 객체를 문자화 할때, `"[Object object]"`가 돼요. `"[Object object]"`는 `"2"`와 연결되어 `"[Object object]2"`가 돼요. +`{ name: "Lydia" }`은 객체에요. 객체가 아닌 숫자나 객체는 문자열이 아니므로, 둘다 문자화되어요. 정규 객체를 문자화 할때, `"[object Object]"`가 돼요. `"[object Object]"`는 `"2"`와 연결되어 `"[object Object]2"`가 돼요.
@@ -3300,7 +3300,7 @@ for (let item of set) { Тем не менее, вторая строка `"Lydia"`. `"Lydia"` является строкой, а `2` является числом: `2` приводится к строке. `"Lydia"` и `"2"` объединяются, что приводит к результирующей строке `"Lydia2"`. -`{name: "Lydia"}` является объектом. Ни число, ни объект не являются строкой, поэтому они приводятся к строке. Всякий раз, когда мы приводим обычный объект, он становится `"[Object object]"`. `"[Object object]"`, объединенный с `"2"`, становится `"[Object object]2"`. +`{name: "Lydia"}` является объектом. Ни число, ни объект не являются строкой, поэтому они приводятся к строке. Всякий раз, когда мы приводим обычный объект, он становится `"[object Object]"`. `"[object Object]"`, объединенный с `"2"`, становится `"[object Object]2"`.
@@ -3299,7 +3299,7 @@ The first one is `1`, which is a numerical value. `1 + 2` returns the number 3. However, the second one is a string `"Lydia"`. `"Lydia"` is a string and `2` is a number: `2` gets coerced into a string. `"Lydia"` และ `"2"` get concatenated, whic hresults 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"`. +`{ 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"`.
+ +#### Answer: B + +En JavaScript, no _tenemos_ que escribir el punto y coma (`;`) de forma explicita, sin embargo el motor de JavaScript todavía las añade al final de cada sentencia. Esto se denomina **Insercción automática de punto y coma**. Una sentencia puede ser, por ejemplo, variables, o palabras clave como `throw`, `return`, `break`, etc. + +Aqui, escribimos una sentencia `return`, y otra sentencia de valor `a + b` en una _nueva línea_. Sin embargo, como es una línea nueva, el motor no sabe que en realidad es el valor que queríamos devolver. En cambio, añadió automáticamente un punto y coma después de `return`. Puedes ver esto como: + +```javascript + return; + a + b +``` + +Esto significa que nunca se alcanza `a + b`, ya que una función deja de ejecutarse después de la palabra clave` return`. Si no se devuelve ningún valor, como aquí, la función devuelve `undefined`. ¡Ten en cuenta que no hay inserción automática después de las sentencias `if/else`! + +
++ +#### Answer: B + +Podemos establecer clases iguales a otros constructures de clases/funciones. En este caso, establecemos `Person` igual a `AnotherPerson`. El nombre en este constructor es `Sarah`, por lo que la propiedad nombre en la nueva instancia de `Person` de `member` es `"Sarah"`. + +
++ +#### Answer: D + +Un símbolo no es _enumerable_. El método Object.keys devuelve todas las propiedades _enumerables_ de un objeto. El símbolo no será visible, y un array vacío será devuelto. Cuando se imprime el objeto completo, se mostrarán todas las propiedades, incluidas las no-enumerables. + +Esta es una de las muchas cualidades de un símbolo: además de representar un valor completamente único (que evita la colisión accidental de nombres en los objetos, por ejemplo, cuando se utilizan 2 bibliotecas que desean agregar propiedades al mismo objeto), también puedes "ocultar" propiedades en los objetos de esta manera (aunque no del todo. Todavía puedes acceder a los símbolos utilizando el método `Object.getOwnPropertySymbols()`). + +
++ +#### Answer: A + +La función `getList` recibe un array argumento. Entre los paréntesis de la función `getList`, desestructuramos este array de inmediato. Podrías ver esto como: + + `[x, ...y] = [1, 2, 3, 4]` + +Con el parámetro rest `...y`, ponemos todos los argumentos "restantes" en un array. Los argumentos restantes son `2`, `3` and `4` en este caso. El valor de `y` es un array, conteniendo todos los parámetros restantes. El valor de `x` es igual a `1` en este caso, por la tanto cuando registramos `[x, y]`, se imprime `[1, [2, 3, 4]]`. + + La función `getUser` recibe un objeto. Con las funciones flecha, no _tenemos_ que escribir llaves cuando simplemente devolvemos un valor. Sin embargo, si quieres devolver un _objeto_ desde una función llave, tienes que escribir el objeto entre paréntesis, ¡de otra manera no se devuelve ningún valor! La siguiente función habría devuelto un objeto: + +```const getUser = user => ({ name: user.name, age: user.age })``` + +Como no se devuelve ningún valor en este caso, la función devuelve `undefined`. + +
++ +#### Answer: C + +La variable `name` contiene el valor de una cadena, que no es una función, por lo tanto no puede invocar. + +Se genera una excepción de tipo TypeError cuando un valor no es del tipo esperado. JavaScript esperaba que `name` fuera una función ya que estamos intentando invocarla. Era una cadena sin embargo, por lo tanto se lanza una excepción del tipo TypeError: name is not a function! + +Se lanzan errores del tipo SyntaxError cuando has escrito algo que no es válido JavaScript, pro ejemplo cuando has escrito `return` como `retrun`. +Se lanzan errores del tipo ReferenceError cuando JavaScript no puede encontrar una referencia a un valor al que estás intentando acceder. + +
++ +#### Answer: B + +`[]` es un valor verdadero (se convierte a un valor verdadero en un contexto booleano). Con el operador `&&`, se devolverá el valor de la derecha si el valor de la izquierda es un valor verdadero. En este caso, el valor de la izquierda `[]` es un valor verdadero, por lo tanto se devuelve `"Im'`. + +`""` es un valor falso (se convierte a un valor falso en un contexto booleano). Si el valor de la izquierda es falso, no se devuelve nada. `n't` no se devuelve. + +
++ +#### Answer: C + +Con el operador `||`, podemos devolver el primer operando verdadero. Si todos los valores son falsos, se devuelve el último operando. + +`(false || {} || null)`: el objecto vacío `{}` es un valor verdadero. Este es el primero (y único) valor verdadero, que se devuelve. `one` es igual a `{}`. + +`(null || false || "")`: todos los operandos son valores falsos. Esto significa que el último operando, `""` es devuelto. `two` es igual a `""`. + +`([] || 0 || "")`: el array vacío `[]` es un valor verdadero. Este es el primer valor verdadero, que se devuelve. `three` es igual a `[]`. + +
++ +#### Answer: D + +Con una promesa, básicamente decimos _Quiero ejecutar esta función, pero la dejaré a un lado por ahora mientras se está ejecutando, ya que esto puede llevar un tiempo. Solo cuando se resuelve (o se rechaza) un cierto valor, y cuando la pila de llamadas está vacía, quiero usar este valor._ + +Podemos obtener este valor con las palabras clave `.then` y `await` en una función `async`. Aunque podemos obtener el valor de una promesa tanto con `.then` como con` wait ', funcionan de manera un poco diferente. + +En la función `firstFunction`, dejamos (de algún modo) a un lado la función myPromise mientras se estaba ejecutando, y seguimos ejecutando el otro código, que es `console.log('second')` en este caso. Luego, la función se resolvió con la cadena `I have resolved`, que luego se imprimió una vez que pila de llamadas quedó vacía. + +Con la palabra clave await en `secondFunction`, literalmente hacemos una pausa en la ejecución de una función asíncrona hasta que el valor se haya resuelto antes de pasar a la siguiente línea de código. + +Esto significa que se esperó a que `myPromise` resolviera con el valor `I have resolved`, y solo una vez que eso sucedió, pasamos a la siguiente línea: `second` que se imprime. + +
++ +#### Answer: C + +El operador `+` no solo se usa para sumar valores numéricos, sino que también podemos usarlo para concatenar cadenas. Cada vez que el motor de JavaScript ve que uno o más valores no son un número, coerce el número en una cadena. + +El primero es `1`, que es un valor numérico. `1 + 2` devuelve el número 3. + +Sin embargo, el segundo es la cadena `"Lydia"`. `"Lydia"` es una cadena y `2` es un número: `2` coerce a una cadena. `"Lydia"` y `"2"` son concatenados, cuyo resultado es la cadena `"Lydia2"`. + +`{ name: "Lydia" }` es un objeto. Ni un número ni un objeto son una cadena, así que se convierten a cadena ambos. Cada vez que convertimos un objeto estandar, se convierte en `"[Object object]"`. `"[Object object]"` concatenado con `"2"` resulta en `"[Object object]2"`. + +
++ +#### Answer: C + +Podemos pasar cualquier tipo de valor que queramos a `Promise.resolve`, ya sea una promesa o no promesa. El método en sí mismo devuelve una promesa con el valor resuelto. Si pasas una función estandar, será una promesa resuelta con un valor normal. Si pasas una promesa, será una promesa resuelta con el valor resuelto de esa promesa pasada. + +En este caso, acabamos de pasar el valor numérico `5`. Devuelve una promesa resuelta con el valor `5`. + +
++ +#### Answer: B + +Los objetos se pasan por referencia. Cuando verificamos la igualdad estricta de los objetos (`===`), estamos comparando sus referencias. + +Establecemos el valor por defecto para `person2` igual al objeto `person`, y pasamos el objeto `person` como el valor de `person1`. + +Esto significa que ambos valores tienen una referencia al mismo punto en la memoria, por lo tanto, son iguales. + +El bloque de código en la instrucción `else` se ejecuta, y se imprime `They are the same!`. + +
++ +#### 答案: D + +有了promise,我们通常会说:当我想要调用某个方法,但是由于它可能需要一段时间,因此暂时将它放在一边。只有当某个值被resolved/rejected,并且执行栈为空时才使用这个值。 + +我们可以在`async`函数中通过`.then`和`await`关键字获得该值。 尽管我们可以通过`.then`和`await`获得promise的价值,但是它们的工作方式有所不同。 + +在 `firstFunction`中,当运行到`myPromise`方法时我们将其放在一边,即promise进入微任务队列,其他后面的代码(`console.log('second')`)照常运行,因此`second`被打印出,`firstFunction`方法到此执行完毕,执行栈中宏任务队列被清空,此时开始执行微任务队列中的任务,`I have resolved`被打印出。 + +在`secondFunction`方法中,我们通过`await`关键字,暂停了后面代码的执行,直到异步函数的值被解析才开始后面代码的执行。这意味着,它会等着直到 `myPromise` 以值`I have resolved`被解决之后,下一行`second`才开始执行。 + +
++ +#### 答案: C + +`“+”`运算符不仅用于数值相加,还可以使用它来连接字符串。 每当JavaScript引擎发现一个或多个值不是数字时,就会将数字强制转化为字符串。 + +第一个是数字`1`, 1 + 2返回数字3。 + +但是,第二个是字符串`Lydia`。 `Lydia`是字符串,`2`是数字:`2`被强制转换为字符串。 `Lydia`和`2`被连接起来,产生字符`Lydia2`。 + +`{name:“Lydia”}`是一个对象。 数字和对象都不是字符串,因此将二者都字符串化。 每当我们对常规对象进行字符串化时,它就会变成`“[Object object]”`。 + +
++ +#### 答案: C + +我们可以将我们想要的任何类型的值传递`Promise.resolve`,无论是否`promise`。 该方法本身返回带有已解析值的`Promise`。 如果您传递常规函数,它将是具有常规值的已解决`promise`。 如果你通过了promise,它将是一个已经resolved的且带有传的值的promise。 + +上述情况,我们传了数字5,因此返回一个resolved状态的promise,resolve值为`5` + +
++ +#### 答案: B + +对象通过引用传递。 当我们检查对象的严格相等性(===)时,我们正在比较它们的引用。 + +我们将`person2`的默认值设置为等于`person`对象,并将`person`对象作为`person1`的值传递。 + +这意味着两个值都引用内存中的同一位置,因此它们是相等的。 + +
++ +#### 答案: D + +在JavaScript中,我们有两种访问对象属性的方法:括号表示法或点表示法。在此示例中,我们使用点表示法(`colorConfig.colors`)代替括号表示法(`colorConfig ['colors']`)。 + +使用点表示法,JavaScript会尝试使用该确切名称在对象上查找属性。在此示例中,JavaScript尝试在`colorconfig`对象上找到名为`'colors'`的属性。没有`'colors'`的属性,因此返回`undefined`。然后,我们尝试使用`[1]`访问第一个元素的值。我们无法对`undefined`执行此操作,因此会抛出`TypeError`: `Cannot read property '1' of undefined` + +当我们使用方括号表示法时,JavaScript会看到第一个左方括号`[`,并且一直走到找到右方括号`]`。只有这样,它才会解析该语句。如果我们使用了`colorConfig[colors[1]]`,它将返回`colorConfig`对象上`red`属性的值。 + +
++ +#### 答案: A + +在内部,表情符号是unicode。 心表情符号的unicode是`U+2764 U+FE0F`。 对于相同的表情符号,它们总是相同的,因此我们正在将两个相等的字符串相互比较,这将返回true。 + +
++ +#### 答案: D + +使用`splice`方法,我们通过删除,替换或添加元素来修改原始数组。 上述情况,我们从索引1中删除了2个元素(删除了'🥑'和'😍'),并添加了✨emoji表情。 + +`map`,`filter`和`slice`返回一个新数组,`find`返回一个元素,而`reduce`返回一个减小的值。 + +
++ +#### 答案: A + +我们将`info`对象上的`favoriteFood`属性的值设置为披萨表情符号“🍕”的字符串。字符串是原始数据类型。在JavaScript中,原始数据类型通过值起作用 + +在这种情况下,我们将`info`对象上的`favoriteFood`属性的值设置为等于`food`数组中的第一个元素的值,字符串为披萨表情符号(`'🍕'` )。字符串是原始数据类型,并且通过值进行交互,我们更改`info`对象上`favoriteFood`属性的值。 food数组没有改变,因为favoriteFood的值只是该数组中第一个元素的值的复制,并且与该元素上的元素没有相同的内存引用食物`[0]`。当我们记录食物时,它仍然是原始数组'['🍕','🍫','🥑','🍔']`。 + +
++ +#### 答案: A + +使用`JSON.parse()`方法,我们可以将JSON字符串解析为JavaScript值。 + +```javascript +// 将数字字符串化为有效的JSON,然后将JSON字符串解析为JavaScript值: +const jsonNumber = JSON.stringify(4) // '4' +JSON.parse(jsonNumber) // 4 + +// 将数组值字符串化为有效的JSON,然后将JSON字符串解析为JavaScript值: +const jsonArray = JSON.stringify([1, 2, 3]) // '[1, 2, 3]' +JSON.parse(jsonArray) // [1, 2, 3] + +// 将对象字符串化为有效的JSON,然后将JSON字符串解析为JavaScript值: +const jsonArray = JSON.stringify({ name: "Lydia" }) // '{"name":"Lydia"}' +JSON.parse(jsonArray) // { name: 'Lydia' } +``` + +
++ +#### 答案: D + +每个函数都有其自己的执行上下文。 `getName`函数首先在其自身的上下文(范围)内查找,以查看其是否包含我们尝试访问的变量`name`。 上述情况,`getName`函数包含其自己的`name`变量:我们用`let`关键字和`Sarah`的值声明变量`name`。 + +带有`let`关键字(和`const`)的变量被提升,但是与`var`不同,它不会被***初始化***。 在我们声明(初始化)它们之前,无法访问它们。 这称为“暂时性死区”。 当我们尝试在声明变量之前访问变量时,JavaScript会抛出`ReferenceError: Cannot access 'name' before initialization`。 + +如果我们不在`getName`函数中声明`name`变量,则javascript引擎会查看原型练。会找到其外部作用域有一个名为`name`的变量,其值为`Lydia`。 在这种情况下,它将打印`Lydia`: + +```javascript +let name = 'Lydia' + +function getName() { + console.log(name) +} + +getName() // Lydia +``` + +
++ +#### Answer: D + +En JavaScript, tenemos dos formas de acceder a las propiedades de un objeto: notación por corchetes o notación por punto. En este ejemplo, usamos la notación por punto (`colorConfig.colors`) en lugar de la notación por corchetes (`colorConfig["colors"]`). + +Con la notación por punto, JavaScript intenta encontrar la propiedad en el objeto con ese nombre exacto. En este ejemplo, JavaScript intenta encontrar una propiedad llamada `colors` en el objeto `colorConfig`. No hay propiedad llamada `colors`, por lo que devuelve `undefined`. Luego, intentamos acceder al valor del primer elemento usando `[1]`. No podemos hacer esto en un valor que sea `undefined`, por lo que lanza una expeción `TypeError`: `Cannot read property '1' of undefined`. + +JavaScript interpreta (o descompone) las sentencias. Cuando usamos la notación por corchetes, ve el primer corchete de apertura `[` y continúa hasta que encuentra el corchete de cierre `]`. Solo entonces, evaluará la declaración. Si hubiéramos utilizado `colorConfig[colors[1]]`, habría devuelto el valor de la propiedad `red` del objeto `colorConfig`. + +
++ +#### Answer: A + +Bajo el capó, los emojis son caracteres unicode. Los valores unicode para el emoji del corazón son `"U+2764 U+FE0F"`. Estos son siempre los mismos para los mismos emojis, por lo que estamos comparando dos cadenas iguales entre sí, lo que devuelve verdadero. + +
++ +#### Answer: D + +Con el método `splice`, modificamos el array original eliminando, reemplazando o agregando elementos. En este caso, eliminamos 2 elementos desde el índice 1 (eliminamos `'🥑'` y `'😍'`) y agregamos el emoji ✨ en su lugar. + +`map`, `filter` y `slice` devuelven un nuevo array, `find` devuelve un elemento, y `reduce` devuelve un valor reducido. + +
++ +#### Answer: A + +Establecemos el valor de la propiedad `favoriteFood` en el objeto` info` igual a la cadena con el emoji de la pizza, `'🍕'`. Una cadena es un tipo de dato primitivo. En JavaScript, los tipos de datos primitivos actúan por referencia + +En JavaScript, los tipos de datos primitivos (todo aquello que no es un objeto) interactúan por _valor_. En este caso, establecemos el valor de la propiedad `favoriteFood` en el objeto` info` igual al valor del primer elemento en el array `food`, la cadena del emoji de la pizza en este caso (`'🍕'`). Una cadena es un tipo de datos primitivo e interactúa por valor (consulte mi [artículo](https://www.theavocoder.com/complete-javascript/2018/12/21/by-value-vs-by-reference) si estás interesado en aprender más) + +Luego, cambiamos el valor de la propiedad `favoriteFood` en el objeto` info`. El array `food` no cambia, ya que el valor de `favoriteFood` era simplemente una _copia_ del valor del primer elemento del array, y no tiene una referencia al mismo punto en la memoria que el elemento en `food[0]`. Cuando imprimimos food, éste sigue siendo el array original, `['🍕', '🍫', '🥑', '🍔']`. + +
++ +#### Answer: A + +Con el método `JSON.parse()`, podemos convertir la cadena de texto en formato JSON a un valor en JavaScript. + +```javascript +// Stringifying a number into valid JSON, then parsing the JSON string to a JavaScript value: +const jsonNumber = JSON.stringify(4) // '4' +JSON.parse(jsonNumber) // 4 + +// Stringifying an array value into valid JSON, then parsing the JSON string to a JavaScript value: +const jsonArray = 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: +const jsonArray = JSON.stringify({ name: "Lydia" }) // '{"name":"Lydia"}' +JSON.parse(jsonArray) // { name: 'Lydia' } +``` + +
++ +#### Answer: D + +Cada función tiene su propio _contexto de ejecución_ (o _ámbito_). La función `getName` primero mira dentro de su propio contexto (ámbito) para ver si contiene la variable `name` a la que estamos intentando acceder. En este caso, la función `getName` contiene su propia variable `name`: declaramos la variable `name` con la palabra clave` let`, y con el valor de `'Sarah'`. + +Las variables con la palabra clave `let` (y `const`) se mueven al comienzo (hoisting), pero a diferencia de `var`, no se inicializan. No son accesibles antes de la línea en la que las declaramos (inicializamos). Esto se llama la "zona muerta temporal". Cuando intentamos acceder a las variables antes de que se declaren, JavaScript genera una excepción del tipo `ReferenceError`. + +Si no hubiéramos declarado la variable `name` dentro de la función `getName`, el motor de JavaScript habría mirado hacia abajo _ámbito encadenado_. El alcance externo tiene una variable llamada `name` con el valor de `Lydia`. En ese caso, habría imprimido `Lydia`. + +```javascript +let name = 'Lydia' + +function getName() { + console.log(name) +} + +getName() // Lydia +``` + +
++ +#### Answer: C + +Con la palabra clave `yield`, cedemos valores en una función generadora. Con la palabra clave `yield*`, podemos obtener valores de otra función generadora u objeto iterable (por ejemplo, un array). + +En la función `generatorOne`, cedemos todo el array `['a', 'b', 'c']` usando la palabra clave `yield`. El valor de la propiedad `value` en el objeto devuelto por el método `next` en `one` (`one.next().value`) es igual a todo el array `['a', 'b', 'c']`. + +```javascript +console.log(one.next().value) // ['a', 'b', 'c'] +console.log(one.next().value) // undefined +``` + +En la función `generatorTwo`, usamos la palabra clave `yield*`. Esto significa que el primer valor cedido de `two` es igual al primer valor cedido en el iterador. El iterador es el array `['a', 'b', 'c']`. El primer valor producido es `a`, por lo que la primera vez que llamamos a `two.next().value`, se devuelve `a`. + +```javascript +console.log(two.next().value) // 'a' +console.log(two.next().value) // 'b' +console.log(two.next().value) // 'c' +console.log(two.next().value) // undefined +``` + +
++ +#### Answer: A + +Las expresiones dentro de las plantillas de cadena de texto se evalúan primero. Esto significa que la cadena contendrá el valor devuelto de la expresión, la función invocada inmediatamente `(x => x)('I love')` en este caso. Pasamos el valor `'I love'` como argumento para la función de flecha `x => x`. `x` es igual a `'I love'`, que se devuelve tal cual. Esto da como resultado `I love to program`. + +
++ +#### Answer: C + +Normalmente, cuando establecemos objetos iguales a `null`, esos objetos se recogen por el _recolector de basura_ ya que ya no hay ninguna referencia a ese objeto. Sin embargo, dado que la función de devolución de llamada dentro de `setInterval` es una función flecha (por lo tanto vinculada al objeto` config`), la función de devolución de llamada todavía tiene una referencia al objeto `config`. Mientras haya una referencia, el objeto no será recolectado. Como no es recolectado, la función de devolución de llamada `setInterval` aún se invocará cada 1000ms (1s). + +
++ +#### Answer: B + +Al agregar un par clave/valor utilizando el método `set`, la clave será el valor del primer argumento pasado a la función `set`, y el valor será el segundo argumento pasado a la función `set`. La clave es la _función_ `() => 'greeting'` en este caso, y el valor `'Hello world'`. `myMap` ahora es `{ () => 'greeting' => 'Hello world!' }`. + +1 es incorrecto, ya que la clave no es `'greeting'` sino `() => 'greeting'`. +3 es incorrecto, ya que estamos creando una nueva función pasándola como parámetro al método `get`. El objeto interactúa por _referencia_. Las funciones son objetos, por eso dos funciones nunca son estrictamente iguales, aunque sean idénticas: tienen una referencia a un punto diferente en la memoria. + +
++ +#### Answer: C + +Tanto las funciones `changeAge` como `changeAgeAndName` tienen un parámetro por defecto, a saber, un objeto _nuevo_ creado `{ ...person }`. Este objeto tiene copias de todos los pares clave/valor en el objeto `person`. + +Primero, invocamos la función `changeAge` y le pasamos el objeto `person` como argumento. Esta función aumenta el valor de la propiedad `age` en 1. `person` ahora es `{name: "Lydia", age: 22}`. + +Luego, invocamos la función `changeAgeAndName`, sin embargo, no pasamos un parámetro. En cambio, el valor de `x` es igual a un _nuevo_ objeto: `{ ...person }`. Dado que es un objeto nuevo, no afecta los valores de las propiedades en el objeto `person`. `person` sigue siendo igual a `{ name: "Lydia",age: 22 }`. + +
++ +#### 정답: A + +`info` 객체의 `favoriteFood` 속성 값을 피자 이모티콘 `'🍕'`와 같게 설정했어요. 문자는 원시 데이터 형이에요. JavaScript에서, 원시 데이터 형은 (객체가 아닌 모든 것) _값_ 에 의해 상호 작용해요. 이 경우, `info` 객체의 `favoriteFood` 속성 값을 `food` 배열 안의 첫 번째 요소와 같게 설정했어요. 문자열은 원시 데이터 형이므로 값에의해 상호 작용해요. (좀 더 알고싶다면 내 [블로그 포스트](https://www.theavocoder.com/complete-javascript/2018/12/21/by-value-vs-by-reference)를 참고하세요.) + +그리고나서, `info` 객체의 `favoriteFood` 속성 값을 바꿨어요. `favoriteFood`의 값은 단지 배열의 첫 번째 요소의 값을 _복사_ 했기 때문에 `food` 배열은 바뀌지 않고, `food[0]` 요소의 메모리 공간과 같은 참조를 갖지 않아요. food를 출력할 때, 여전히 원본 배열 ['🍕', '🍫', '🥑', '🍔']` 이에요. + +
++ +#### 정답: A + +`JSON.parse()`메소드를 사용하면, JSON 문자열의 구문을 분석하여 JavaScript 값으로 생성해요. +With the `JSON.parse()` method, we can parse JSON string to a JavaScript value. + +```javascript +// 숫자를 유효한 JSON 문자열로 변환해요, 그리고 나서 JSON 문자열의 구문을 분석해 JavaScript 값으로 생성해요. +const jsonNumber = JSON.stringify(4) // '4' +JSON.parse(jsonNumber) // 4 + +// 배열 값을 유효한 JSON 문자열로 변환해요, 그리고 나서 JSON 문자열의 구문을 분석해 JavaScript 값으로 생성해요. +const jsonArray = JSON.stringify([1, 2, 3]) // '[1, 2, 3]' +JSON.parse(jsonArray) // [1, 2, 3] + +// 객체를 유효한 JSON 문자열로 변환해요, 그리고 나서 JSON 문자열의 구문을 분석해 JavaScript 값으로 생성해요. +const jsonArray = JSON.stringify({ name: "Lydia" }) // '{"name":"Lydia"}' +JSON.parse(jsonArray) // { name: 'Lydia' } +``` + +
++ +#### 정답: D + +각 기능에는 자체 _실행 컨텍스트_ (또는 _범위_)가 있어요. `getName` 함수는 먼저 자체 컨텍스트(범위) 내에서 접근하려고 하는 변수 `name`이 포함되어 있는지 살펴봐요: `let` 키워드와 함께 선언 했기 때문에 `'Sarah'`의 값을 가져요. + +`let` 키워드 (그리고 `const`)를 사용한 변수는 끌어올려지지만, `var`와 다르게 초기화 되지는 않아요. 그들을 선언 (초기화) 하는 줄 전에 접근 할 수 없어요. "일시적 사각지대"라고 불려요. 그들을 선언하기 전에 접근하려고 한다면, JavaScript는 `ReferenceError`를 던져요. + +`getName` 함수 안에 `name` 변수를 선언하지 않았다면, javaScript 엔진은 _스코프 체인_ 을 내려다 보지 않았을 거예요. 외부 범위에 `Lydia`의 값을 가진 `name` 변수가 있어요. 이 경우엔 `Lydia`를 출력할거예요. + +```javascript +let name = 'Lydia' + +function getName() { + console.log(name) +} + +getName() // Lydia +``` + +
++ +#### 정답: C + +`yield` 키워드를 사용하면, 제너레이터 함수 안의 값을 `중단` 했어요. `yield`키워드를 사용하면, 다른 제너레이터 함수 또는 반복 가능한 객체(예를들면 배열)의 값을 중단 시킬 수 있어요. + +`generatorOne`에서, 전체 배열 `['a', 'b', 'c']`을 `yield` 키워드를 사용해서 중단 했어요. `one` (`one.next().value`)의 `next` 메소드가 리턴 한 객체의 `value`속성 값은 전체 배열 `['a', 'b', 'c']`과 같아요. + +```javascript +console.log(one.next().value) // ['a', 'b', 'c'] +console.log(one.next().value) // undefined +``` + +`generatorTwo`에서, `yield*` 키워드를 사용했어요. `two`의 첫번째 값이 중단 되었다는 의미이고, 반복자의 첫번째로 중단된 값과 같아요.반복자는 배열 `['a', 'b', 'c']` 이에요. +처음으로 중단된 값은 `a`이고, 따라서 첫번째 순서에서 `two.next().value`를 부르면 `a`를 리턴해요. + +```javascript +console.log(two.next().value) // 'a' +console.log(two.next().value) // 'b' +console.log(two.next().value) // 'c' +console.log(two.next().value) // undefined +``` + +
++ +#### 정답: A + +템플릿 리터러를 사용한 표현식은 첫번째로 평가돼요. 문자열은 표현식의 리턴된 값을 포함하게 된다는 것을 의미하고, 이 경우 함수 `(x => x)('I love')`는 즉시 호출 돼요. 화살표 함수 `x => x`의 인수 값으로 `I love`를 전달 했어요. `x`는 `'I love'`이고 리턴 될 거에요. 이 결과는 `I love to program` 이에요. + +
++ +#### 정답: C + +일반적으로 객체를 `null`로 설정했을때, 객체는 더 이상의 객체 참조가 없어 _쓰레기 수집_ 되어요. 그러나, `setInterval`을 가진 콜백 함수는 화살표 함수 (`config` 객체로 감싸진) 이기 때문에, 콜백 함수는 여전히 `config` 객체의 참조를 갖고 있고, 객체는 쓰레기 수집 되지 않아요. 쓰레기 수집 되지 않았기 때문에, `setInterval` 콜백 함수는 여전히 매 1000ms (1s) 마다 호출 돼요, + +
++ +#### 정답: B + +`set` 메소드를 사용해서 키/값을 쌍으로 추가할 때, 키는 `set`함수로 전달 된 첫 번째 인수의 값이 되고, 값은 `set`함수로 전달된 두 번째 인수의 값이 될거에요. 이 경우에선 키는 _함수_ `() => 'greeting'`이고, 값은 `'Hello world'` 에요. `myMap`은 이제 `{ () => 'greeting' => 'Hello world!' }` 예요. + +1은 틀렸어요, 키는 `'greeting'`가 아니라 `() => 'greeting'`이기 때문이에요. +3은 틀렸어요, `get`메소드에 새로 생성한 함수를 전달 했기 때문이에요. 객체는 _참조_에 의해 상호작용해요. 함수는 객체이고, 그들이 같다고 하더라도 두 함수가 절대로 같지 않은 이유예요: 메모리 안 다른 장소의 참조를 가지고 있어요. + +
++ +#### 정답: C + +`changeAge`와 `changeAgeAndName`함수 둘다 기본 파라미터를 가지고 있는데 즉, _새롭게_ 만들어진 객체 `{ ...person }`를 가지고 있어요. 이 객체는 `person` 객체의 모든 키/값의 복사본을 가지고 있어요. + +첫번째로, `changeAge`함수를 호출 했고, 그것의 인수로 `person` 객체를 전달 했어요. 이 함수는 `age`속성의 값을 1 증가 시켜요. `person`은 이제 `{ name: "Lydia", age: 22 }`이에요. + +그리고나서, `changeAgeAndName` 함수를 호출 했지만, 파라미터를 전달하지 않았어요. 대신에, `x`의 값은 _새로운_ 객체와 같아요: `{ ...person }`. 새로운 객체이기 때문에, `person`객체의 속성들의 값에 영향을 주지 않아요. `person`은 여전히 `{ name: "Lydia", age: 22 }`와 같아요. + +
++ +#### Answer: C + +With the spread operator `...`, we can _spread_ iterables to individual elements. The `sumValues` function receives three arguments: `x`, `y` and `z`. `...[1, 2, 3]` will result in `1, 2, 3`, which we pass to the `sumValues` function. + +
++ +#### Answer: B + +With the `+=` operand, we're incrementing the value of `num` by `1`. `num` had the initial value `1`, so `1 + 1` is `2`. The item on the second index in the `list` array is 🥰, `console.log(list[2])` prints 🥰. + +
++ +#### 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 an `undefined` or `null` value (_nullish_), the expression short-circuits and returns `undefined`. + +`person.pet?.name`: `person` has a property named `pet`: `person.pet` is not nullish. It has a property called `name`, and returns `Mara`. +`person.pet?.family?.name`: `person` has a property named `pet`: `person.pet` is not nullish. `pet` does _not_ have a property called `family`, `person.pet.family` is nullish. The expression returns `undefined`. +`person.getFullName?.()`: `person` has a property named `getFullName`: `person.getFullName()` is not nullish and can get invoked, which returns `Lydia Hallie`. +`member.getLastName?.()`: `member` is not defined: `member.getLastName()` is nullish. The expression returns `undefined`. + +
++ +#### Answer: B + +We passed the condition `groceries.indexOf("banana")` to the if-statement. `groceries.indexOf("banana")` returns `0`, which is a falsy value. Since the condition in the if-statement is falsy, the code in the `else` block runs, and `We don't have to buy bananas!` gets logged. + +
++ +#### Answer: D + +The `language` method is a `setter`. Setters don't hold an actual value, their purpose is to _modify_ properties. When calling a `setter` method, `undefined` gets returned. + +
++ +#### Answer: C + +`typeof name` returns `"string"`. The string `"string"` is a truthy value, so `!typeof name` returns the boolean value `false`. `false === "object"` and `false === "string"` both return`false`. + +(If we wanted to check whether the type was (un)equal to a certain type, we should've written `!==` instead of `!typeof`) + +
++ +#### Answer: A + +The `add` function returns an arrow function, which returns an arrow function, which returns an arrow function (still with me?). The first function receives an argument `x` with the value of `4`. We invoke the second function, which receives an argument `y` with the value `5`. Then we invoke the third function, which receives an argument `z` with the value `6`. When we're trying to access the value `x`, `y` and `z` within the last arrow function, the JS engine goes up the scope chain in order to find the values for `x` and `y` accordingly. This returns `4` `5` `6`. + +
++ +#### Answer: C + +The generator function `range` returns an async object with promises for each item in the range we pass: `Promise{1}`, `Promise{2}`, `Promise{3}`. We set the variable `gen` equal to the async object, after which we loop over it using a `for await ... of` loop. We set the variable `item` equal to the returned Promise values: first `Promise{1}`, then `Promise{2}`, then `Promise{3}`. Since we're _awaiting_ the value of `item`, the resolved promsie, the resolved _values_ of the promises get returned: `1`, `2`, then `3`. + +
++ +#### Answer: D + +`myFunc` expects an object with properties `x`, `y` and `z` as its argument. Since we're only passing three separate numeric values (1, 2, 3) instead of one object with properties `x`, `y` and `z` ({x: 1, y: 2, z: 3}), `x`, `y` and `z` have their default value of `undefined`. + +
++ +#### Answer: B + +With the `Intl.NumberFormat` method, we can format numeric values to any locale. We format the numeric value `130` to the `en-US` locale as a `unit` in `mile-per-hour`, which results in `130 mph`. The numeric value `300` to the `en-US` locale as a `currentcy` in `USD` results in `$300.00`. + +
++ +#### 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 "💀" to `spookyItems[3]`. This means that we're modifying the `spookyItems` array, we're adding the "💀" to it. When logging `spookyItems`, `["👻", "🎃", "🕸", "💀"]` gets logged. + +
++ +#### Answer: C + +With the `Number.isNaN` method, you can check if the value you pass is a _numeric value_ and equal to `NaN`. `name` is not a numeric value, so `Number.isNaN(name)` returns `false`. `age` is a numeric value, but is not equal to `NaN`, so `Number.isNaN(age)` returns `false`. + +With the `isNaN` method, you can check if the value you pass is not a number. `name` is not a number, so `isNaN(name)` returns true. `age` is a number, so `isNaN(age)` returns `false`. + +
++ +#### Answer: D + +Variables declared with the `const` keyword are not referencable before their initialization: this is called the _temporal dead zone_. In the `getInfo` function, the variable `randomValue` is scoped in the functional scope of `getInfo`. On the line where we want to log the value of `typeof randomValue`, the variable `randomValue` isn't initialized yet: a `ReferenceError` gets thrown! The engine didn't go down the scope chain since we declared the variable `randomValue` in the `getInfo` function. + +
++ +#### Answer: C + +In the `try` block, we're logging the awaited value of the `myPromise` variable: `"Woah some cool data"`. Since no errors were thrown in the `try` block, the code in the `catch` block doesn't run. The code in the `finally` block _always_ runs, `"Oh finally!"` gets logged. + +
++ +#### Answer: B + +With the `flat` 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 value `1` (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 `['🥑', '✨', '✨', ['🍕', '🍕']]`. + +
++ +#### Answer: C + +With the spread operator `...`, we can _spread_ iterables to individual elements. The `sumValues` function receives three arguments: `x`, `y` and `z`. `...[1, 2, 3]` will result in `1, 2, 3`, which we pass to the `sumValues` function. + +
++ +#### Answer: B + +With the `+=` operand, we're incrementing the value of `num` by `1`. `num` had the initial value `1`, so `1 + 1` is `2`. The item on the second index in the `list` array is 🥰, `console.log(list[2])` prints 🥰. + +
++ +#### 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 an `undefined` or `null` value (_nullish_), the expression short-circuits and returns `undefined`. + +`person.pet?.name`: `person` has a property named `pet`: `person.pet` is not nullish. It has a property called `name`, and returns `Mara`. +`person.pet?.family?.name`: `person` has a property named `pet`: `person.pet` is not nullish. `pet` does _not_ have a property called `family`, `person.pet.family` is nullish. The expression returns `undefined`. +`person.getFullName?.()`: `person` has a property named `getFullName`: `person.getFullName()` is not nullish and can get invoked, which returns `Lydia Hallie`. +`member.getLastName?.()`: `member` is not defined: `member.getLastName()` is nullish. The expression returns `undefined`. + +
++ +#### Answer: B + +We passed the condition `groceries.indexOf("banana")` to the if-statement. `groceries.indexOf("banana")` returns `0`, which is a falsy value. Since the condition in the if-statement is falsy, the code in the `else` block runs, and `We don't have to buy bananas!` gets logged. + +
++ +#### Answer: D + +The `language` method is a `setter`. Setters don't hold an actual value, their purpose is to _modify_ properties. When calling a `setter` method, `undefined` gets returned. + +
++ +#### Answer: C + +`typeof name` returns `"string"`. The string `"string"` is a truthy value, so `!typeof name` returns the boolean value `false`. `false === "object"` and `false === "string"` both return`false`. + +(If we wanted to check whether the type was (un)equal to a certain type, we should've written `!==` instead of `!typeof`) + +
++ +#### Answer: A + +The `add` function returns an arrow function, which returns an arrow function, which returns an arrow function (still with me?). The first function receives an argument `x` with the value of `4`. We invoke the second function, which receives an argument `y` with the value `5`. Then we invoke the third function, which receives an argument `z` with the value `6`. When we're trying to access the value `x`, `y` and `z` within the last arrow function, the JS engine goes up the scope chain in order to find the values for `x` and `y` accordingly. This returns `4` `5` `6`. + +
++ +#### Answer: C + +The generator function `range` returns an async object with promises for each item in the range we pass: `Promise{1}`, `Promise{2}`, `Promise{3}`. We set the variable `gen` equal to the async object, after which we loop over it using a `for await ... of` loop. We set the variable `item` equal to the returned Promise values: first `Promise{1}`, then `Promise{2}`, then `Promise{3}`. Since we're _awaiting_ the value of `item`, the resolved promsie, the resolved _values_ of the promises get returned: `1`, `2`, then `3`. + +
++ +#### Answer: D + +`myFunc` expects an object with properties `x`, `y` and `z` as its argument. Since we're only passing three separate numeric values (1, 2, 3) instead of one object with properties `x`, `y` and `z` ({x: 1, y: 2, z: 3}), `x`, `y` and `z` have their default value of `undefined`. + +
++ +#### Answer: B + +With the `Intl.NumberFormat` method, we can format numeric values to any locale. We format the numeric value `130` to the `en-US` locale as a `unit` in `mile-per-hour`, which results in `130 mph`. The numeric value `300` to the `en-US` locale as a `currentcy` in `USD` results in `$300.00`. + +
++ +#### 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 "💀" to `spookyItems[3]`. This means that we're modifying the `spookyItems` array, we're adding the "💀" to it. When logging `spookyItems`, `["👻", "🎃", "🕸", "💀"]` gets logged. + +
++ +#### Answer: C + +With the `Number.isNaN` method, you can check if the value you pass is a _numeric value_ and equal to `NaN`. `name` is not a numeric value, so `Number.isNaN(name)` returns `false`. `age` is a numeric value, but is not equal to `NaN`, so `Number.isNaN(age)` returns `false`. + +With the `isNaN` method, you can check if the value you pass is not a number. `name` is not a number, so `isNaN(name)` returns true. `age` is a number, so `isNaN(age)` returns `false`. + +
++ +#### Answer: D + +Variables declared with the `const` keyword are not referencable before their initialization: this is called the _temporal dead zone_. In the `getInfo` function, the variable `randomValue` is scoped in the functional scope of `getInfo`. On the line where we want to log the value of `typeof randomValue`, the variable `randomValue` isn't initialized yet: a `ReferenceError` gets thrown! The engine didn't go down the scope chain since we declared the variable `randomValue` in the `getInfo` function. + +
++ +#### Answer: C + +In the `try` block, we're logging the awaited value of the `myPromise` variable: `"Woah some cool data"`. Since no errors were thrown in the `try` block, the code in the `catch` block doesn't run. The code in the `finally` block _always_ runs, `"Oh finally!"` gets logged. + +
++ +#### Answer: B + +With the `flat` 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 value `1` (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 `['🥑', '✨', '✨', ['🍕', '🍕']]`. +
@@ -4063,6 +4085,8 @@ By destructuring objects, we can unpack values from the right-hand object, and a
@@ -4063,6 +4085,8 @@ By destructuring objects, we can unpack values from the right-hand object, and a
@@ -1352,7 +1352,6 @@ Promise.race([firstPromise, secondPromise]).then(res => console.log(res));
+ +#### Ответ: C + +С помощью оператора распространения (spread) `...` мы можем _распределить_ итерации в отдельньные элементы. `sumValues` принимает три аргумента:`x`, `y` и `z`. `...[1, 2, 3]` приведет к перечню `1, 2, 3`, который мы передаем функции `sumValues`. + +
++ +#### Ответ: B + +С операндом `+=` мы увеличиваем значение `num` на `1`. `num` имеет начальное значение `1`, поэтому `1 + 1` равно `2`. Элементом второго индекса в массиве `list` и является вывод `console.log (list [2])`🥰. + +
++ +#### Ответ: B + +С необязательным оператором связывания `?.` нам больше не нужно явно проверять, действительны ли более глубокие вложенные значения или нет. Если мы пытаемся получить доступ к свойству со (_нулевым_) значением `undefined` или `null`, выражение замыкается и возвращает `undefined`. + +`person.pet?.name`: `person` имеет свойство с именем `pet`: `person.pet` не нулевое. Оно имеет свойство с именем `name`, и возвращает `Mara`. +`person.pet?.family?.name`: `person` имеет свойство с именем `pet`: `person.pet` не нулевое. `pet` _не_ имеет свойство с именем `family`, `person.pet.family` нулевое. Выражение возвращает `undefined`. +`person.getFullName?.()`: `person` имеет свойство с именем `getFullName`: `person.getFullName()` не нулевое, и может быть вызвано, возвращает `Lydia Hallie`. +`member.getLastName?.()`: `member` не определено: `member.getLastName()` нулевое. Выражение возвращает `undefined`. + +
++ +#### Ответ: B + +Мы передали условие `groceries.indexOf("banana")` в оператор `if`. `groceries.indexOf("banana")` возвращает `0`, что является ложным значением. Поскольку условие в операторе `if` ложно, выполняется код в блоке `else`, и в лог выводится ``We don't have to buy bananas!``. + +
++ +#### Ответ: D + +Метод `language` является `сеттером`. Сеттеры не содержат действительного значения, их целью является изменение свойств. При вызове метода `setter` возвращается `undefined`. + +
++ +#### Ответ: C + +`typeof name` возвращает `"строку"`. Строка `"string"` является истинным значением, поэтому `!typeof name` возвращает логическое значение `false`. `false === "object"` и `false === "string"` оба возвращают `false`. + +(Если бы мы хотели проверить, был ли тип (не)равен определенному типу, мы должны были написать `!==` вместо `!typeof`) + +
++ +#### Ответ: A + +Функция `add` возвращает стрелочную функцию, которая возвращает стрелочную функцию, которая возвращает стрелочную функцию (все еще у тут?). Первая функция получает аргумент `x` со значением `4`. Мы вызываем вторую функцию, которая получает аргумент `y` со значением `5`. Затем мы вызываем третью функцию, которая получает аргумент `z` со значением `6`. Когда мы пытаемся получить доступ к значениям `x`, `y` и `z` в функции последней стрелки, движок JS поднимается вверх по цепочке областей видимости, чтобы найти значения для `x` и `y` соответственно. Это возвращает `4` `5` `6`. + +
++ +#### Ответ: C + +Функция генератора `range` возвращает асинхронный объект с обещаниями для каждого элемента в диапазоне, который мы передаем: `Promise {1}`, `Promise {2}`, `Promise {3}`. Мы устанавливаем переменную `gen` равной асинхронному объекту, после чего зацикливаем ее, используя цикл `for await ... of`. Мы устанавливаем переменную `item` равной возвращаемым значениям `Promise`: сначала `Promise {1}`, затем `Promise {2}`, затем `Promise {3}`. Так как мы _ожидаем_ значение `item`, разрешается обещание, возвращаются разрешенные _значения_ обещания: `1`, `2`, затем `3`. + +
++ +#### Ответ: D + +`myFunc` ожидает объект со свойствами `x`, `y` и `z` в качестве аргумента. Поскольку мы передаем только три отдельных числовых значения (1, 2, 3) вместо одного объекта со свойствами `x`, `y` и `z` ({x: 1, y: 2, z: 3}), то `x`, `y` и `z` имеют значение по умолчанию` undefined`. + +
++ +#### Ответ: B + +С помощью метода `Intl.NumberFormat` мы можем форматировать числовые значения в любой локали. Мы форматируем числовое значение `130` для локали `en-US` как `unit` в `mile-per-hour`, что приводит к `130 mph`. Числовое значение `300` для локали `en-US` в качестве `currentcy` в `USD` приводит к `$300.00`. + +
++ +#### Ответ: B + +Деструктурируя объекты, мы можем распаковать значения из правого объекта и присвоить распакованному значению значение того же по имени свойства в левом объекте. В этом случае мы присваиваем значение "💀" `spookyItems[3]`. Это означает, что мы модифицируем массив `spookyItems`, добавляем к нему «💀». При логировании `spookyItems` выводится ` ["👻", "🎃", "🕸", "💀"]`. + +
++ +#### Ответ: C + +С помощью метода `Number.isNaN` вы можете проверить, является ли передаваемое вами значение _числовым значением_ и равно ли оно `NaN`. `name` не является числовым значением, поэтому `Number.isNaN(name)` возвращает `false`. `age` является числовым значением, но не равно `NaN`, поэтому `Number.isNaN(age)` возвращает `false`. + +С помощью метода `isNaN` вы можете проверить, не является ли передаваемое вами значение числом. `name` не является числом, поэтому `isNaN(name)` возвращает true. `age` - это число, поэтому `isNaN(age)` возвращает `false`. + +
++ +#### Ответ: D + +Переменные, объявленные с ключевым словом `const`, не имеют ссылки до их инициализации: это называется _временная мертвая зона_. В функции `getInfo` переменная `randomValue` находится в области видимости `getInfo`. В строке, где мы хотим записать значение `typeof randomValue`, переменная `randomValue` еще не инициализирована: выдается `ReferenceError`! Движок не пошел по цепочке областей видимости, так как мы объявили переменную `randomValue` в функции `getInfo`. + +
++ +#### Ответ: C + +В блоке `try` мы выводим в лог ожидаемое значение переменной `myPromise`: `"Woah some cool data"`. Поскольку в блоке `try` не было выдано никаких ошибок, код в блоке `catch` не запускается. Код в блоке `finally` _всегда_ выполняется, `"Oh finally!"` также выводится в лог. + +
++ +#### Ответ: B + +С помощью метода `flat` мы можем создать новый плоский массив. Глубина уплощенного массива зависит от значения, которое мы передаем. В этом случае мы передали значение `1` (которое нам не нужно, это значение по умолчанию), что означает, что будут объединены только массивы на первой глубине. `['🥑']` и `['✨', '✨', ['🍕', '🍕']]` в этом случае. Конкатенация этих двух массивов приводит к `['🥑', '✨', '✨', ['🍕', '🍕']]`. + +
++ +#### Antwort: C + +Mit dem Spread-Operator `...` können wir Werte _spreaden_ ("verstreichen"). Die `sumValues` Funktion erhält drei Argumente: `x`, `y` und `z`. `...[1, 2, 3]` ergibt `1, 2, 3`, was wir an `sumValues` übergeben. + +
++ +#### Antwort: B + +Mit dem`+=` Operanden erhöhen wir den Wert von `num` um `1`. `num` hatte den ursprünglichen Wert `1` und `1 + 1` ergibt `2`. Der Wert an zweiter Stelle im `list` Array ist 🥰. `console.log(list[2])` gibt 🥰 aus. + +
++ +#### Antwort: B + +Mit den optionalen Kettenoperator `?.` müssen wir nicht mehr prüfen, ob die tiefer genesteten Werte gültig sind oder nicht. Wenn wir die Property von `undefined` oder `null` aufrufen (_nullish_) gibt die Expression direkt `undefined` aus. + +`person.pet?.name`: `person` hat eine Property `pet`: `person.pet` ist nicht nullish. Diese hat eine Property `name` und gibt `Mara` aus. +`person.pet?.family?.name`: `person` hat eine Property `pet`: `person.pet` ist nicht nullish. `pet` hat _keine_ Property `family`, `person.pet.family` ist nullish. Die Expression gibt `undefined` aus. +`person.getFullName?.()`: `person` hat eine Property `getFullName`: `person.getFullName()` ist nicht nullish und wird ausgeführt: `Lydia Hallie` wird ausgegeben. +`member.getLastName?.()`: `member` ist undefined: `member.getLastName()` ist nullish. Die Expression gibt `undefined` aus. + +
++ +#### Antwort: B + +Wir haben die Kondition `groceries.indexOf("banana")` an das if-Statement übergeben. `groceries.indexOf("banana")` gibt `0` aus, was ein _falsy_ Wert ist. Da die Kondition nicht erfüllt ist wird der `else` Block ausgeführt und `We don't have to buy bananas!` wird geloggt. + +
++ +#### Antwort: D + +Die Methode `language` ist ein `setter`. Setter halten keinen Wert, sondern ändern Properties. Wenn eine `setter` Methode aufgerufen wird, wird `undefined` zurückgegeben. + +
++ +#### Antwort: C + +`typeof name` gibt `"string"` aus. Der String `"string"` ist _truthy_, sodass `!typeof name` den Boolean-Wert `false` ergibt. `false === "object"` und `false === "string"` geben beide `false` aus. + +(Würden wir prüfen wollen, oob der Typ (un)gleich zu einem bestimmten anderen Typen ist hätten wir `!==` anstelle von `!typeof` schreiben müssen) + +
++ +#### Antwort: A + +Die `add` Funktion gibt eine Arrow Funktion zurück, welche eine Arrow Funktion zurückgibt, welche eine Arrow Funktion zurückgibt. Die erste Funktion erhält ein Argument `x` mit dem Wert `4`. Wir führen die zweite Funktion aus, welche ein Argument `y` mit dem Wert `5` erhält. Dann führen wir die dritte Funktion aus, die ein Argument `z` mit dem Wert `6` erhält. Wenn wir versuchen die Werte von `x`, `y` und `z` der jeweils letzten Arrow Funktion aufzurufen geht die JavaScript Engine in der Scope-Kette nach oben um die jeweiligen Werte zu finden. Das gibt `4` `5` `6` aus. + +
++ +#### Antwort: C + +Die Generator-Funktion `range` gibt ein asynchrones Objekt mit Promisen für jeden Wert zurück: `Promise{1}`, `Promise{2}`, `Promise{3}`. Wir setzen die Variable `gen` gleich dem asynchronen Objekt. Danach loopen wir mit einer `for await ... of` Schleife darüber. Wir setzen die Variable `item` gleich dem ausgegebenen Promise: zuerst `Promise{1}`, dann `Promise{2}`, und dann `Promise{3}`. Da wir das Ergebnis von `item` _await_-en (erwarten), werden die gelösten Ergebnisse der Promises ausgegeben: `1`, `2` und `3`. + +
++ +#### Antwort: D + +`myFunc` erwartet ein Objekt mit den Properties `x`, `y` und `z` als Argumente. Da wir nur drei separate Werte anstelle eines Objektes mit den Properties `x`, `y` und `z` ({x: 1, y: 2, z: 3}) eingeben, bekommen `x`, `y` und `z` den Standardwert `undefined` zugewiesen. + +
+-List of available languages: * [English](./en-EN/README.md) * [العربية](./ar-AR/README_AR.md) * [اللغة العامية - Egyptian Arabic](./ar-EG/README_ar-EG.md) @@ -28,8 +33,10 @@ List of available languages: * [Türkçe](./tr-TR/README-tr_TR.md) * [ไทย](./th-TH/README-th_TH.md) +
+
+
+#### Answer: D
+
+`counterOne` is an instance of the `Counter` class. The counter class contains a `count` property on its constructor, and an `increment` method. First, we invoked the `increment` method twice by calling `counterOne.increment()`. Currently, `counterOne.count` is `2`.
+
+
+
+Then, we create a new variable `counterTwo`, and set it equal to `counterOne`. Since objects interact by reference, we're just creating a new reference to the same spot in memory that `counterOne` points to. Since it has the same spot in memory, any changes made to the object that `counterTwo` has a reference to, also apply to `counterOne`. Currently, `counterTwo.count` is `2`.
+
+We invoke the `counterTwo.increment()`, which sets the `count` to `3`. Then, we log the count on `counterOne`, which logs `3`.
+
+
+
+
+ +#### Answer: D + +First, we invoke `funcOne`. On the first line of `funcOne`, we call the `myPromise` promise, which is an _asynchronous_ operation. While the engine is busy completing the promise, it keeps on running the function `funcOne`. The next line is the _asynchronous_ `setTimeout` function, from which the callback is sent to the Web API. (see my article on the event loop here.) + +Both the promise and the timeout are asynchronous operations, the function keeps on running while it's busy completing the promise and handling the `setTimeout` callback. This means that `Last line!` gets logged first, since this is not an asynchonous operation. This is the last line of `funcOne`, the promise resolved, and `Promise!` gets logged. However, since we're invoking `funcTwo()`, the call stack isn't empty, and the callback of the `setTimeout` function cannot get added to the callstack yet. + +In `funcTwo` we're, first _awaiting_ the myPromise promise. With the `await` keyword, we pause the execution of the function until the promise has resolved (or rejected). Then, we log the awaited value of `res` (since the promise itself returns a promise). This logs `Promise!`. + +The next line is the _asynchronous_ `setTimeout` function, from which the callback is sent to the Web API. + +We get to the last line of `funcTwo`, which logs `Last line!` to the console. Now, since `funcTwo` popped off the call stack, the call stack is empty. The callbacks waiting in the queue (`() => console.log("Timeout!")` from `funcOne`, and `() => console.log("Timeout!")` from `funcTwo`) get added to the call stack one by one. The first callback logs `Timeout!`, and gets popped off the stack. Then, the second callback logs `Timeout!`, and gets popped off the stack. This logs `Last line! Promise! Promise! Last line! Timeout! Timeout!` + +
++ +#### Answer: C + +With the asterisk `*`, we import all exported values from that file, both default and named. If we had the following file: + +```javascript +// info.js +export const name = "Lydia"; +export const age = 21; +export default "I love JavaScript"; + +// index.js +import * as info from "./info"; +console.log(info); +``` + +The following would get logged: + +```javascript +{ + default: "I love JavaScript", + name: "Lydia", + age: 21 +} +``` + +For the `sum` example, it means that the imported value `sum` looks like this: + +```javascript +{ default: function sum(x) { return x + x } } +``` + +We can invoke this function, by calling `sum.default` + +
++ +#### Answer: C + +With a Proxy object, we can add custom behavior to an object that we pass to it as the second argument. In tis case, we pass the `handler` object which contained to properties: `set` and `get`. `set` gets invoked whenever we _set_ property values, `get` gets invoked whenever we _get_ (access) property values. + +The first argument is an empty object `{}`, which is the value of `person`. To this object, the custom behavior specified in the `handler` object gets added. If we add a property to the `person` object, `set` will get invoked. If we access a property on the `person` object, `get` gets invoked. + +First, we added a new property `name` 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, the `get` property on the handler object got invoked. `"Accessed a property!"` gets logged. + +
++ +#### Answer: A + +With `Object.seal` we can prevent new properies from being _added_, or existing properties to be _removed_. + +However, you can still modify the value of existing properties. + +
++ +#### Answer: C + +The `Object.freeze` method _freezes_ an object. No properties can be added, modified, or removed. + +However, it only _shallowly_ freezes the object, meaning that only _direct_ properties on the object are frozen. If the property is another object, like `address` in this case, the properties on that object aren't frozen, and can be modified. + +
++ +#### Answer: C + +The `Object.freeze` method _freezes_ an object. No properties can be added, modified, or removed. + +However, it only _shallowly_ freezes the object, meaning that only _direct_ properties on the object are frozen. If the property is another object, like `address` in this case, the properties on that object aren't frozen, and can be modified. + +
++ +#### Answer: A + +First, we invoked `myFunc()` without passing any arguments. Since we didn't pass arguments, `num` and `value` got their default values: num is `2`, and `value` the returned value of the function `add`. To the `add` function, we pass `num` as an argument, which had the value of `2`. `add` returns `4`, which is the value of `value`. + +Then, we invoked `myFunc(3)` and passed the value `3` as the value for the argument `num`. We didn't pass an argument for `value`. Since we didn't pass a value for the `value` argument, it got the default value: the returned value of the `add` function. To `add`, we pass `num`, which has the value of `3`. `add` returns `6`, which is the value of `value`. + +
++ +#### 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 log `counter.#number`, a SyntaxError gets thrown: we cannot acccess it outside the `Counter` class! + +
++ +#### Answer: B + +In order to iterate over the `members` in each element in the `teams` array, we need to pass `teams[i].members` to the `getMembers` generator function. The generator function returns a generator object. In order to iterate over each element in this generator object, we need to use `yield*`. + +If we would've written `yield`, `return yield`, or `return`, the entire generator function would've gotten returned the first time we called the `next` method. + +
++ +#### Answer: C + +The `addHobby` function receives two arguments, `hobby` and `hobbies` with the default value of the `hobbies` array on the `person` object. + +First, we invoke the `addHobby` function, and pass `"running"` as the value for `hobby` and an empty array as the value for `hobbies`. Since we pass an empty array as the value for `y`, `"running"` gets added to this empty array. + +Then, we invoke the `addHobby` function, and pass `"dancing"` as the value for `hobby`. We didn't pass a value for `hobbies`, so it gets the default value, the `hobbies` property on the `person` object. We push the hobby `dancing` to the `person.hobbies` array. + +Last, we invoke the `addHobby` function, and pass `"bdaking"` as the value for `hobby`, and the `person.hobbies` array as the value for `hobbies`. We push the hobby `baking` to the `person.hobbies` array. + +After pushing `dancing` and `baking`, the value of `person.hobbies` is `["coding", "dancing", "baking"]` + +
++ +#### Answer: B + +We create the variable `pet` which is an instance of the `Flamingo` class. When we instantiate this instance, the `constructor` on `Flamingo` gets called. First, `"I'm pink. 🌸"` gets logged, after which we call `super()`. `super()` calls the constructor of the parent class, `Bird`. THe constructor in `Bird` gets called, and logs `"I'm a bird. 🦢"`. + +
++ +#### Answer: D + +The `const` keyword simply means we cannot _redeclare_ the value of that variable, it's _read-only_. However, the value itself isn't immutable. The propeties on the `emojis` array can be modified, for example by pushing new values, splicing them, or setting the length of the array to 0. + +
++ +#### 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 the `Object.values` of the `person` object if we want it to return the array `["Lydia Hallie", 21]`: `yield* Object.values(this)`. + +
+-List of available languages: * [English](../en-EN/README.md) * [العربية](../ar-AR/README_AR.md) * [اللغة العامية - Egyptian Arabic](../ar-EG/README_ar-EG.md) @@ -28,8 +33,10 @@ List of available languages: * [Türkçe](../tr-TR/README-tr_TR.md) * [ไทย](../th-TH/README-th_TH.md) +
+
+
+#### Answer: D
+
+`counterOne` is an instance of the `Counter` class. The counter class contains a `count` property on its constructor, and an `increment` method. First, we invoked the `increment` method twice by calling `counterOne.increment()`. Currently, `counterOne.count` is `2`.
+
+
+
+Then, we create a new variable `counterTwo`, and set it equal to `counterOne`. Since objects interact by reference, we're just creating a new reference to the same spot in memory that `counterOne` points to. Since it has the same spot in memory, any changes made to the object that `counterTwo` has a reference to, also apply to `counterOne`. Currently, `counterTwo.count` is `2`.
+
+We invoke the `counterTwo.increment()`, which sets the `count` to `3`. Then, we log the count on `counterOne`, which logs `3`.
+
+
+
+
+ +#### Answer: D + +First, we invoke `funcOne`. On the first line of `funcOne`, we call the `myPromise` promise, which is an _asynchronous_ operation. While the engine is busy completing the promise, it keeps on running the function `funcOne`. The next line is the _asynchronous_ `setTimeout` function, from which the callback is sent to the Web API. (see my article on the event loop here.) + +Both the promise and the timeout are asynchronous operations, the function keeps on running while it's busy completing the promise and handling the `setTimeout` callback. This means that `Last line!` gets logged first, since this is not an asynchonous operation. This is the last line of `funcOne`, the promise resolved, and `Promise!` gets logged. However, since we're invoking `funcTwo()`, the call stack isn't empty, and the callback of the `setTimeout` function cannot get added to the callstack yet. + +In `funcTwo` we're, first _awaiting_ the myPromise promise. With the `await` keyword, we pause the execution of the function until the promise has resolved (or rejected). Then, we log the awaited value of `res` (since the promise itself returns a promise). This logs `Promise!`. + +The next line is the _asynchronous_ `setTimeout` function, from which the callback is sent to the Web API. + +We get to the last line of `funcTwo`, which logs `Last line!` to the console. Now, since `funcTwo` popped off the call stack, the call stack is empty. The callbacks waiting in the queue (`() => console.log("Timeout!")` from `funcOne`, and `() => console.log("Timeout!")` from `funcTwo`) get added to the call stack one by one. The first callback logs `Timeout!`, and gets popped off the stack. Then, the second callback logs `Timeout!`, and gets popped off the stack. This logs `Last line! Promise! Promise! Last line! Timeout! Timeout!` + +
++ +#### Answer: C + +With the asterisk `*`, we import all exported values from that file, both default and named. If we had the following file: + +```javascript +// info.js +export const name = "Lydia"; +export const age = 21; +export default "I love JavaScript"; + +// index.js +import * as info from "./info"; +console.log(info); +``` + +The following would get logged: + +```javascript +{ + default: "I love JavaScript", + name: "Lydia", + age: 21 +} +``` + +For the `sum` example, it means that the imported value `sum` looks like this: + +```javascript +{ default: function sum(x) { return x + x } } +``` + +We can invoke this function, by calling `sum.default` + +
++ +#### Answer: C + +With a Proxy object, we can add custom behavior to an object that we pass to it as the second argument. In tis case, we pass the `handler` object which contained to properties: `set` and `get`. `set` gets invoked whenever we _set_ property values, `get` gets invoked whenever we _get_ (access) property values. + +The first argument is an empty object `{}`, which is the value of `person`. To this object, the custom behavior specified in the `handler` object gets added. If we add a property to the `person` object, `set` will get invoked. If we access a property on the `person` object, `get` gets invoked. + +First, we added a new property `name` 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, the `get` property on the handler object got invoked. `"Accessed a property!"` gets logged. + +
++ +#### Answer: A + +With `Object.seal` we can prevent new properies from being _added_, or existing properties to be _removed_. + +However, you can still modify the value of existing properties. + +
++ +#### Answer: C + +The `Object.freeze` method _freezes_ an object. No properties can be added, modified, or removed. + +However, it only _shallowly_ freezes the object, meaning that only _direct_ properties on the object are frozen. If the property is another object, like `address` in this case, the properties on that object aren't frozen, and can be modified. + +
++ +#### Answer: C + +The `Object.freeze` method _freezes_ an object. No properties can be added, modified, or removed. + +However, it only _shallowly_ freezes the object, meaning that only _direct_ properties on the object are frozen. If the property is another object, like `address` in this case, the properties on that object aren't frozen, and can be modified. + +
++ +#### Answer: A + +First, we invoked `myFunc()` without passing any arguments. Since we didn't pass arguments, `num` and `value` got their default values: num is `2`, and `value` the returned value of the function `add`. To the `add` function, we pass `num` as an argument, which had the value of `2`. `add` returns `4`, which is the value of `value`. + +Then, we invoked `myFunc(3)` and passed the value `3` as the value for the argument `num`. We didn't pass an argument for `value`. Since we didn't pass a value for the `value` argument, it got the default value: the returned value of the `add` function. To `add`, we pass `num`, which has the value of `3`. `add` returns `6`, which is the value of `value`. + +
++ +#### 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 log `counter.#number`, a SyntaxError gets thrown: we cannot acccess it outside the `Counter` class! + +
++ +#### Answer: B + +In order to iterate over the `members` in each element in the `teams` array, we need to pass `teams[i].members` to the `getMembers` generator function. The generator function returns a generator object. In order to iterate over each element in this generator object, we need to use `yield*`. + +If we would've written `yield`, `return yield`, or `return`, the entire generator function would've gotten returned the first time we called the `next` method. + +
++ +#### Answer: C + +The `addHobby` function receives two arguments, `hobby` and `hobbies` with the default value of the `hobbies` array on the `person` object. + +First, we invoke the `addHobby` function, and pass `"running"` as the value for `hobby` and an empty array as the value for `hobbies`. Since we pass an empty array as the value for `y`, `"running"` gets added to this empty array. + +Then, we invoke the `addHobby` function, and pass `"dancing"` as the value for `hobby`. We didn't pass a value for `hobbies`, so it gets the default value, the `hobbies` property on the `person` object. We push the hobby `dancing` to the `person.hobbies` array. + +Last, we invoke the `addHobby` function, and pass `"bdaking"` as the value for `hobby`, and the `person.hobbies` array as the value for `hobbies`. We push the hobby `baking` to the `person.hobbies` array. + +After pushing `dancing` and `baking`, the value of `person.hobbies` is `["coding", "dancing", "baking"]` + +
++ +#### Answer: B + +We create the variable `pet` which is an instance of the `Flamingo` class. When we instantiate this instance, the `constructor` on `Flamingo` gets called. First, `"I'm pink. 🌸"` gets logged, after which we call `super()`. `super()` calls the constructor of the parent class, `Bird`. THe constructor in `Bird` gets called, and logs `"I'm a bird. 🦢"`. + +
++ +#### Answer: D + +The `const` keyword simply means we cannot _redeclare_ the value of that variable, it's _read-only_. However, the value itself isn't immutable. The propeties on the `emojis` array can be modified, for example by pushing new values, splicing them, or setting the length of the array to 0. + +
++ +#### 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 the `Object.values` of the `person` object if we want it to return the array `["Lydia Hallie", 21]`: `yield* Object.values(this)`. + +
+-#### Answer: C +#### Resposta: 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 of `undefined`, but you will see something like: @@ -1309,3 +1309,220 @@ Strings são iteráveis. O operador do spread `...` mapeia todo caractére de um
+ +#### Resposta: C + +Funções regulares não podem ser interrompidas durante execução após sua invocação. Entretanto, uma função generator pode ser interrompida, e depois continuar de onde parou. Uma função generator sempre possue a palavra chave `yield`, a função gera o valor específicado logo após. Note que a função generator, neste caso não retorna o valor, ele utiliza _yields_ no valor. + +Primeiro, nós inicializamos a função generator com `i` igual a `10`. Nós chamamos a função generator utilizando o `next()` para próxima função. A primeira vez que executamos a função generator o `i` é igual a `10`. que possue a palavra chave `yield`: que atribue o yields ao valor de `i`. O generator é pausado e `10` é logado. + +Então, chamamos a próxima função novamente com o `next()`. Que continua de onde foi interrompido anteirormente, ainda com `i` igual a `10`. Agora, ele encontra o próximo `yield`, e yields `i * 2`. `i` é igual a `10`, que então retorna `10 * 2`, que é `20`. Seu resultado é `10, 20`. + +
++ +#### Resposta: B + +Quando passamos múltiplas "promises" para a função `Promise.race`, ele resolve ou rejeita a primeira "promise". Para a função de `setTimeout`, nós passamos um tempo de 500ms para a primeira promise (`firstPromise`), e 100ms para a segunda promise (`secondPromise`). Isso significa que o `secondPromise` resolve primeiro com o valor de `'two'`. `res` que agora possui o valor `'two'`, que foi logado. + +
+
+
+#### Resposta: D
+
+Primeiro, declaramos a variável `person` com o valor de um objeto que possui o propriedade `name`.
+
+
+
+Então, declaramos a variável chamada `members`. Setamos o valor do primeiro elemento do array igual ao valor da variável `person`. Objetos interados por _referência_ quando ao defini-los iguais entre si. Quando você atribui uma referência de uma variável para outra, você faz uma _cópia_ de sua referência. (note que eles não possuem a _mesma_ referência!)
+
+
+
+Então, setamos a variável `person` igual a `null`.
+
+
+
+Estamos apenas modificando o valor da variável `person`, e não o primeiro elemento do array, desde que o elemento tem uma diferente referência (copiada) de um objeto. O primeiro elemento de `members` ainda mantém sua referência com o objeto original. Quando logamos o array de `members`, o primeiro elemento ainda mantém o valor do objeto, que é logado.
+
+
+ +#### Resposta: B + +Utilizando o loop `for-in`, podemos interar através das chaves do objeto, neste caso o `name` e `age`. Por baixo dos panos, chaves de objetos são strings (eles não são um símbolo). Em cada loop, setamos ao valor do `item` igual ao da chave atual, que se intera. Primeiro, `item` é igual ao `name`, e é logado. Então, `item` é igual a idade `age`, que é logado. + +
++ +#### Resposta: B + +Associatividade do operador é a ordem na qual o compilador avalia as expressões, ou esquerda-para-direita ou direita-para-esquerda. Isso apenas acontece se todos os operatores possuem a _mesma_ precedência. Apenas temos um tipo de operador: `+`. Para adição, a associatividade é esquerda-para-direita. + +`3 + 4` é avaliado primeiro. Seu resultado é o número `7`. + +`7 + '5'` resulta em `"75"` por causa da coerção. JavaScript converte o número `7` em string, veja a questão 15. Podemos concatenar duas strings com o operador de `+`. `"7" + "5"` resulta em `"75"`. + +
++ +#### Resposta: C + +Apenas os primeiros números da string é retornado. Baseado no _radix_ (o segundo parametro na ordem especifica qual o tipo de número queremos atribuir o parse: base 10, hexadecimal, octal, binary, etc.), o `parseInt` checa se os caracteres na string são válidos. Depois de encontrar um caracter que não é um número válido no radix, ele interrompe o parse e ignora os seguintes caracteres. + +`*` não é um número válido. Ele apenas usa o parse no `"7"` em decimal `7`. `num` possui o valor `7`. + +
++ +#### Resposta: C + +Quando mapeamos um array (map), o valor de `num` é igual ao elemento que está percorrendo. Neste caso, os elementos são números, então a condição do se (if) `typeof num === "number"` retorna `true`. A função map cria um novo array e insere os valores retornados da função. + +Entretanto, não se retorna o valor. Quando não se retorna um valor para a função, a função retorna `undefined`. Para cada elemento do array, o bloco de função é chamado, então para cada elemento é retornado `undefined`. + +
+
@@ -760,9 +760,9 @@ console.log(obj)
###### 26. JavaScript 全局执行上下文为你做了两件事:全局对象和 this 关键字。
-- A: true
-- B: false
-- C: it depends
+- A: 对
+- B: 错
+- C: 看情况
From c5ab2fafd28a62565dfee3a476982385ff17305b Mon Sep 17 00:00:00 2001
From: Nusendra Hanggarawan
+
+- [English](../en-EN/README.md)
+- [العربية](../ar-AR/README_AR.md)
+- [اللغة العامية - Egyptian Arabic](../ar-EG/README_ar-EG.md)
+- [Bosanski](../bs-BS/README-bs_BS.md)
+- [Deutsch](../de-DE/README.md)
+- [Español](../es-ES/README-ES.md)
+- [Français](../fr-FR/README_fr-FR.md)
+- [日本語](../ja-JA/README-ja_JA.md)
+- [한국어](../ko-KR/README-ko_KR.md)
+- [Português Brasil](../pt-BR/README_pt_BR.md)
+- [Русский](../ru-RU/README.md)
+- [Українська мова](../ua-UA/README-ua_UA.md)
+- [Tiếng Việt](../vi-VI/README-vi.md)
+- [中文版本](../zh-CN/README-zh_CN.md)
+- [Türkçe](../tr-TR/README-tr_TR.md)
+- [ไทย](../th-TH/README-th_TH.md)
+- [Indonesia](../id-ID/README.md)
+
+
+
+#### Jawaban: D
+
+Within the function, we first declare the `name` variable with the `var` keyword. This means that the variable gets hoisted (memory space is set up during the creation phase) with the default value of `undefined`, 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 the `name` variable, so it still holds the value of `undefined`.
+
+Variables with the `let` keyword (and `const`) are hoisted, but unlike `var`, don't get initialized. 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 a `ReferenceError`.
+
+
+
+#### Jawaban: C
+
+Because of the event queue in JavaScript, the `setTimeout` callback function is called _after_ the loop has been executed. Since the variable `i` in the first loop was declared using the `var` keyword, this value was global. During the loop, we incremented the value of `i` by `1` each time, using the unary operator `++`. By the time the `setTimeout` callback function was invoked, `i` was equal to `3` in the first example.
+
+In the second loop, the variable `i` was declared using the `let` keyword: variables declared with the `let` (and `const`) 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.
+
+
+
+#### Jawaban: B
+
+Note that the value of `diameter` is a regular function, whereas the value of `perimeter` is an arrow function.
+
+With arrow functions, the `this` keyword refers to its current surrounding scope, unlike regular functions! This means that when we call `perimeter`, it doesn't refer to the shape object, but to its surrounding scope (window for example).
+
+There is no value `radius` on that object, which returns `undefined`.
+
+
+
+#### Jawaban: A
+
+The unary plus tries to convert an operand to a number. `true` is `1`, and `false` is `0`.
+
+The string `'Lydia'` is a truthy value. What we're actually asking, is "is this truthy value falsy?". This returns `false`.
+
+
+
+#### Jawaban: A
+
+In JavaScript, all object keys are strings (unless it's a Symbol). Even though we might not _type_ 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 evaluates `bird.size`, which is `"small"`. `mouse["small"]` returns `true`
+
+However, with dot notation, this doesn't happen. `mouse` does not have a key called `bird`, which means that `mouse.bird` is `undefined`. Then, we ask for the `size` using dot notation: `mouse.bird.size`. Since `mouse.bird` is `undefined`, we're actually asking `undefined.size`. This isn't valid, and will throw an error similar to `Cannot read property "size" of undefined`.
+
+
+
+#### Jawaban: A
+
+In JavaScript, all objects interact by _reference_ when setting them equal to each other.
+
+First, variable `c` holds a value to an object. Later, we assign `d` with the same reference that `c` has to the object.
+
+
+
+#### Jawaban: 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, it only checks whether it has the same _value_. They both have the value of `3`, so it returns `true`.
+
+However, when we use the `===` operator, both value _and_ type should be the same. It's not: `new Number()` is not a number, it's an **object**. Both return `false.`
+
+
+
+#### Jawaban: D
+
+The `colorChange` 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. Since `freddie` is a child, the function is not passed down, and not available on the `freddie` instance: a `TypeError` is thrown.
+
+
+
+#### Jawaban: A
+
+It logs the object, because we just created an empty object on the global object! When we mistyped `greeting` as `greetign`, the JS interpreter actually saw this as `global.greetign = {}` (or `window.greetign = {}` in a browser).
+
+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.
+
+
+
+#### Jawaban: 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.
+
+
+
+#### Jawaban: A
+
+You can't add properties to a constructor like you can with regular objects. If you want to add a feature to all objects at once, you have to use the prototype instead. So in this case,
+
+```js
+Person.prototype.getFullName = function() {
+ return `${this.firstName} ${this.lastName}`;
+};
+```
+
+would have made `member.getFullName()` work. Why is this beneficial? Say that we added this method to the constructor itself. Maybe not every `Person` instance needed this method. This would waste a lot of memory space, since they would still have that property, which takes of memory space for each instance. Instead, if we only add it to the prototype, we just have it at one spot in memory, yet they all have access to it!
+
+
+
+#### Jawaban: A
+
+For `sarah`, we didn't use the `new` keyword. When using `new`, it refers to the new empty object we create. However, if you don't add `new` it refers to the **global object**!
+
+We said that `this.firstName` equals `"Sarah"` and `this.lastName` equals `"Smith"`. What we actually did, is defining `global.firstName = 'Sarah'` and `global.lastName = 'Smith'`. `sarah` itself is left `undefined`, since we don't return a value from the `Person` function.
+
+
+
+#### Jawaban: D
+
+During the **capturing** phase, the event goes through the ancestor elements down to the target element. It then reaches the **target** element, and **bubbling** begins.
+
+
+
+#### Jawaban: B
+
+All objects have prototypes, except for the **base object**. The base object is the object created by the user, or an object that is created using the `new` 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.
+
+
+
+#### Jawaban: C
+
+JavaScript is a **dynamically typed language**: we don't specify what types certain variables are. Values can automatically be converted into another type without you knowing, which is called _implicit type coercion_. **Coercion** is converting from one type into another.
+
+In this example, JavaScript converts the number `1` 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"`.
+
+
+
+#### Jawaban: C
+
+The **postfix** unary operator `++`:
+
+1. Returns the value (this returns `0`)
+2. Increments the value (number is now `1`)
+
+The **prefix** unary operator `++`:
+
+1. Increments the value (number is now `2`)
+2. Returns the value (this returns `2`)
+
+This returns `0 2 2`.
+
+
+
+#### Jawaban: 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!
+
+
+
+#### Jawaban: C
+
+When testing equality, primitives are compared by their _value_, while objects are compared by their _reference_. 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 }` return `false`.
+
+
+
+#### Jawaban: C
+
+The rest parameter (`...args`.) lets us "collect" all remaining arguments into an array. An array is an object, so `typeof args` returns `"object"`
+
+
+
+#### Jawaban: C
+
+With `"use strict"`, you can make sure that you don't accidentally declare global variables. We never declared the variable `age`, 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 property `age` would have gotten added to the global object.
+
+
+
+#### Jawaban: A
+
+`eval` evaluates codes that's passed as a string. If it's an expression, like in this case, it evaluates the expression. The expression is `10 * 10 + 5`. This returns the number `105`.
+
+
+
+#### Jawaban: B
+
+The data stored in `sessionStorage` is removed after closing the _tab_.
+
+If you used `localStorage`, the data would've been there forever, unless for example `localStorage.clear()` is invoked.
+
+
+
+#### Jawaban: B
+
+With the `var` keyword, you can declare multiple variables with the same name. The variable will then hold the latest value.
+
+You cannot do this with `let` or `const` since they're block-scoped.
+
+
+
+#### Jawaban: C
+
+All object keys (excluding Symbols) are strings under the hood, even if you don't type it yourself as a string. This is why `obj.hasOwnProperty('1')` also returns true.
+
+It doesn't work that way for a set. There is no `'1'` in our set: `set.has('1')` returns `false`. It has the numeric type `1`, `set.has(1)` returns `true`.
+
+
+
+#### Jawaban: 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.
+
+
+
+#### Jawaban: A
+
+The base execution context is the global execution context: it's what's accessible everywhere in your code.
+
+
+
+#### Jawaban: C
+
+The `continue` statement skips an iteration if a certain condition returns `true`.
+
+
+
+#### Jawaban: A
+
+`String` is a built-in constructor, which 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!
+
+
+
+#### Jawaban: B
+
+Object keys are automatically converted into strings. We are trying to set an object as a key to object `a`, with the value of `123`.
+
+However, when we stringify an object, it becomes `"[object Object]"`. So what we are saying here, is that `a["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 log `a[b]`, which is actually `a["object Object"]`. We just set that to `456`, so it returns `456`.
+
+
+
+#### Jawaban: B
+
+We have a `setTimeout` 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 a `WebAPI`. The `WebAPI` gives us the `setTimeout` function to start with, and for example the DOM.
+
+After the _callback_ is pushed to the WebAPI, the `setTimeout` function itself (but not the callback!) is popped off the stack.
+
+
+
+#### Jawaban: C
+
+The deepest nested element that caused the event is the target of the event. You can stop bubbling by `event.stopPropagation`
+
+
+ Click here!
+
+
+#### Jawaban: A
+
+If we click `p`, we see two logs: `p` and `div`. During event propagation, there are 3 phases: capturing, target, and bubbling. By default, event handlers are executed in the bubbling phase (unless you set `useCapture` to `true`). It goes from the deepest nested element outwards.
+
+
+
+#### Jawaban: D
+
+With both, we can pass the object to which we want the `this` keyword to refer to. However, `.call` is also _executed immediately_!
+
+`.bind.` returns a _copy_ of the function, but with a bound context! It is not executed immediately.
+
+
+
+#### Jawaban: B
+
+The `sayHi` function returns the returned value of the immediately invoked function (IIFE). This function returned `0`, which is type `"number"`.
+
+FYI: there are only 7 built-in types: `null`, `undefined`, `boolean`, `number`, `string`, `object`, and `symbol`. `"function"` is not a type, since functions are objects, it's of type `"object"`.
+
+
+
+#### Jawaban: A
+
+There are only six falsy values:
+
+- `undefined`
+- `null`
+- `NaN`
+- `0`
+- `''` (empty string)
+- `false`
+
+Function constructors, like `new Number` and `new Boolean` are truthy.
+
+
+
+#### Jawaban: B
+
+`typeof 1` returns `"number"`.
+`typeof "number"` returns `"string"`
+
+
+
+#### Jawaban: 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 of `undefined`, but you will see something like:
+
+`[1, 2, 3, 7 x empty, 11]`
+
+depending on where you run it (it's different for every browser, node, etc.)
+
+
+
+#### Jawaban: A
+
+The `catch` block receives the argument `x`. This is not the same `x` as the variable when we pass arguments. This variable `x` is block-scoped.
+
+Later, we set this block-scoped variable equal to `1`, and set the value of the variable `y`. Now, we log the block-scoped variable `x`, which is equal to `1`.
+
+Outside of the `catch` block, `x` is still `undefined`, and `y` is `2`. When we want to `console.log(x)` outside of the `catch` block, it returns `undefined`, and `y` returns `2`.
+
+
+
+#### Jawaban: A
+
+JavaScript only has primitive types and objects.
+
+Primitive types are `boolean`, `null`, `undefined`, `bigint`, `number`, `string`, and `symbol`.
+
+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 a `TypeError`. This is because when you try to access a property or method on a primitive like a string, JavaScript will implicitly wrap the object using one of the wrapper classes, i.e. `String`, and then immediately discard the wrapper after the expression evaluates. All primitives except for `null` and `undefined` exhibit this behaviour.
+
+
+
+#### Jawaban: C
+
+`[1, 2]` is our initial value. This is the value we start with, and the value of the very first `acc`. During the first round, `acc` is `[1,2]`, and `cur` is `[0, 1]`. We concatenate them, which results in `[1, 2, 0, 1]`.
+
+Then, `[1, 2, 0, 1]` is `acc` and `[2, 3]` is `cur`. We concatenate them, and get `[1, 2, 0, 1, 2, 3]`
+
+
+
+#### Jawaban: B
+
+`null` is falsy. `!null` returns `true`. `!true` returns `false`.
+
+`""` is falsy. `!""` returns `true`. `!true` returns `false`.
+
+`1` is truthy. `!1` returns `false`. `!false` returns `true`.
+
+
+
+#### Jawaban: A
+
+It returns a unique id. This id can be used to clear that interval with the `clearInterval()` function.
+
+
+
+#### Jawaban: A
+
+A string is an iterable. The spread operator maps every character of an iterable to one element.
+
+
+
+#### Jawaban: 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 a `yield` keyword, the function yields the value specified after it. Note that the generator function in that case doesn’t _return_ the value, it _yields_ the value.
+
+First, we initialize the generator function with `i` equal to `10`. We invoke the generator function using the `next()` method. The first time we invoke the generator function, `i` is equal to `10`. It encounters the first `yield` keyword: it yields the value of `i`. The generator is now "paused", and `10` gets logged.
+
+Then, we invoke the function again with the `next()` method. It starts to continue where it stopped previously, still with `i` equal to `10`. Now, it encounters the next `yield` keyword, and yields `i * 2`. `i` is equal to `10`, so it returns `10 * 2`, which is `20`. This results in `10, 20`.
+
+
+
+#### Jawaban: B
+
+When we pass multiple promises to the `Promise.race` method, it resolves/rejects the _first_ promise that resolves/rejects. To the `setTimeout` method, we pass a timer: 500ms for the first promise (`firstPromise`), and 100ms for the second promise (`secondPromise`). This means that the `secondPromise` resolves first with the value of `'two'`. `res` now holds the value of `'two'`, which gets logged.
+
+
+
+#### Jawaban: D
+
+First, we declare a variable `person` with the value of an object that has a `name` property.
+
+
+
+#### Jawaban: B
+
+With a `for-in` loop, we can iterate through object keys, in this case `name` and `age`. Under the hood, object keys are strings (if they're not a Symbol). On every loop, we set the value of `item` equal to the current key it’s iterating over. First, `item` is equal to `name`, and gets logged. Then, `item` is equal to `age`, which gets logged.
+
+
+
+#### Jawaban: 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 the _same_ 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 number `7`.
+
+`7 + '5'` results in `"75"` because of coercion. JavaScript converts the number `7` into a string, see question 15. We can concatenate two strings using the `+`operator. `"7" + "5"` results in `"75"`.
+
+
+
+#### Jawaban: C
+
+Only the first numbers in the string is returned. Based on the _radix_ (the second argument in order to specify what type of number we want to parse it to: base 10, hexadecimal, octal, binary, etc.), the `parseInt` 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 decimal `7`. `num` now holds the value of `7`.
+
+
+
+#### Jawaban: C
+
+When mapping over the array, the value of `num` is equal to the element it’s currently looping over. In this case, the elements are numbers, so the condition of the if statement `typeof num === "number"` returns `true`. 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 returns `undefined`. For every element in the array, the function block gets called, so for each element we return `undefined`.
+
+
+
+#### Jawaban: A
+
+Arguments are passed by _value_, unless their value is an object, then they're passed by _reference_. `birthYear` is passed by value, since it's a string, not an object. When we pass arguments by value, a _copy_ of that value is created (see question 46).
+
+The variable `birthYear` has a reference to the value `"1997"`. The argument `year` also has a reference to the value `"1997"`, but it's not the same value as `birthYear` has a reference to. When we update the value of `year` by setting `year` equal to `"1998"`, we are only updating the value of `year`. `birthYear` is still equal to `"1997"`.
+
+The value of `person` is an object. The argument `member` has a (copied) reference to the _same_ object. When we modify a property of the object `member` has a reference to, the value of `person` will also be modified, since they both have a reference to the same object. `person`'s `name` property is now equal to the value `"Lydia"`
+
+
+
+#### Jawaban: D
+
+With the `throw` statement, we can create custom errors. With this statement, you can throw exceptions. An exception can be a string, a number, a boolean or an object. In this case, our exception is the string `'Hello world'`.
+
+With the `catch` statement, we can specify what to do if an exception is thrown in the `try` 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'`.
+
+
+
+#### Jawaban: B
+
+When you return a property, the value of the property is equal to the _returned_ value, not the value set in the constructor function. We return the string `"Maserati"`, so `myCar.make` is equal to `"Maserati"`.
+
+
+
+#### Jawaban: A
+
+`let x = y = 10;` is actually shorthand for:
+
+```javascript
+y = 10;
+let x = y;
+```
+
+When we set `y` equal to `10`, we actually add a property `y` to the global object (`window` in browser, `global` in Node). In a browser, `window.y` is now equal to `10`.
+
+Then, we declare a variable `x` with the value of `y`, which is `10`. Variables declared with the `let` keyword are _block scoped_, they are only defined within the block they're declared in; the immediately-invoked function (IIFE) in this case. When we use the `typeof` operator, the operand `x` is not defined: we are trying to access `x` outside of the block it's declared in. This means that `x` 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 variable `y` when setting `y` equal to `10`. This value is accessible anywhere in our code. `y` is defined, and holds a value of type `"number"`. `console.log(typeof y)` returns `"number"`.
+
+
+
+#### Jawaban: A
+
+We can delete properties from objects using the `delete` keyword, also on the prototype. By deleting a property on the prototype, it is not available anymore in the prototype chain. In this case, the `bark` function is not available anymore on the prototype after `delete Dog.prototype.bark`, yet we still try to access it.
+
+When we try to invoke something that is not a function, a `TypeError` is thrown. In this case `TypeError: pet.bark is not a function`, since `pet.bark` is `undefined`.
+
+
+
+#### Jawaban: D
+
+The `Set` object is a collection of _unique_ values: a value can only occur once in a set.
+
+We passed the iterable `[1, 1, 2, 3, 4]` with a duplicate value `1`. Since we cannot have two of the same values in a set, one of them is removed. This results in `{1, 2, 3, 4}`.
+
+
+
+#### Jawaban: C
+
+An imported module is _read-only_: you cannot modify the imported module. Only the module that exports them can change its value.
+
+When we try to increment the value of `myCounter`, it throws an error: `myCounter` is read-only and cannot be modified.
+
+
+
+#### Jawaban: A
+
+The `delete` operator returns a boolean value: `true` on a successful deletion, else it'll return `false`. However, variables declared with the `var`, `const` or `let` keyword cannot be deleted using the `delete` operator.
+
+The `name` variable was declared with a `const` keyword, so its deletion is not successful: `false` is returned. When we set `age` equal to `21`, we actually added a property called `age` to the global object. You can successfully delete properties from objects this way, also the global object, so `delete age` returns `true`.
+
+
+
+#### Jawaban: C
+
+We can unpack values from arrays or properties from objects through destructuring. For example:
+
+```javascript
+[a, b] = [1, 2];
+```
+
+
+
+#### Jawaban: 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 the `user` object, and add them to the `admin` object. The `admin` object now contains the copied key/value pairs, which results in `{ admin: true, name: "Lydia", age: 21 }`.
+
+
+
+#### Jawaban: B
+
+With the `defineProperty` method, we can add new properties to an object, or modify existing ones. When we add a property to an object using the `defineProperty` method, they are by default _not enumerable_. The `Object.keys` method returns all _enumerable_ property names from an object, in this case only `"name"`.
+
+Properties added using the `defineProperty` method are immutable by default. You can override this behavior using the `writable`, `configurable` and `enumerable` properties. This way, the `defineProperty` method gives you a lot more control over the properties you're adding to an object.
+
+
+
+#### Jawaban: A
+
+The second argument of `JSON.stringify` is the _replacer_. 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 an _array_, 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 a _function_, 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 is `undefined`, this property is excluded from the JSON string.
+
+
+
+#### Jawaban: A
+
+The unary operator `++` _first returns_ the value of the operand, _then increments_ the value of the operand. The value of `num1` is `10`, since the `increaseNumber` function first returns the value of `num`, which is `10`, and only increments the value of `num` afterwards.
+
+`num2` is `10`, since we passed `num1` to the `increasePassedNumber`. `number` is equal to `10`(the value of `num1`. Again, the unary operator `++` _first returns_ the value of the operand, _then increments_ the value of the operand. The value of `number` is `10`, so `num2` is equal to `10`.
+
+
+
+#### Jawaban: 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 the `value` object into a new object, so `x` has the default value of `{ number: 10 }`.
+
+The default argument is evaluated at _call time_! Every time we call the function, a _new_ object is created. We invoke the `multiply` 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 is `20`.
+
+The third time we invoke multiply, we do pass an argument: the object called `value`. The `*=` operator is actually shorthand for `x.number = x.number * 2`: we modify the value of `x.number`, and log the multiplied value `20`.
+
+The fourth time, we pass the `value` object again. `x.number` was previously modified to `20`, so `x.number *= 2` logs `40`.
+
+
+
+#### Jawaban: D
+
+The first argument that the `reduce` method receives is the _accumulator_, `x` in this case. The second argument is the _current 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 optional `initialValue` argument to the `reduce` method, the accumulator is equal to the first element on the first call.
+
+On the first call, the accumulator (`x`) is `1`, and the current value (`y`) is `2`. We don't return from the callback function, we log the accumulator and current value: `1` and `2` get logged.
+
+If you don't return a value from a function, it returns `undefined`. On the next call, the accumulator is `undefined`, and the current value is `3`. `undefined` and `3` get logged.
+
+On the fourth call, we again don't return from the callback function. The accumulator is again `undefined`, and the current value is `4`. `undefined` and `4` get logged.
+
+
+
+#### Jawaban: B
+
+In a derived class, you cannot access the `this` keyword before calling `super`. If you try to do that, it will throw a ReferenceError: 1 and 4 would throw a reference error.
+
+With the `super` keyword, we call that parent class's constructor with the given arguments. The parent's constructor receives the `name` argument, so we need to pass `name` to `super`.
+
+The `Labrador` class receives two arguments, `name` since it extends `Dog`, and `size` as an extra property on the `Labrador` class. They both need to be passed to the constructor function on `Labrador`, which is done correctly using constructor 2.
+
+
+
+#### Jawaban: B
+
+With the `import` keyword, all imported modules are _pre-parsed_. This means that the imported modules get run _first_, the code in the file which imports the module gets executed _after_.
+
+This is a difference between `require()` in CommonJS and `import`! With `require()`, you can load dependencies on demand while the code is being run. If we would have used `require` instead of `import`, `running index.js`, `running sum.js`, `3` would have been logged to the console.
+
+
+
+#### Jawaban: 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 first `Symbol('foo')`, and the second `Symbol('foo')`. These two values are unique and not equal to each other, `Symbol('foo') === Symbol('foo')` returns `false`.
+
+
+
+#### Jawaban: C
+
+With the `padStart` method, we can add padding to the beginning of a string. The value passed to this method is the _total_ length of the string together with the padding. The string `"Lydia Hallie"` has a length of `12`. `name.padStart(13)` inserts 1 space at the start of the string, because 12 + 1 is 13.
+
+If the argument passed to the `padStart` method is smaller than the length of the array, no padding will be added.
+
+
+
+#### Jawaban: A
+
+With the `+` operator, you can concatenate strings. In this case, we are concatenating the string `"🥑"` with the string `"💻"`, resulting in `"🥑💻"`.
+
+
+
+#### Jawaban: C
+
+A generator function "pauses" its execution when it sees the `yield` keyword. First, we have to let the function yield the string "Do you love JavaScript?", which can be done by calling `game.next().value`.
+
+Every line is executed, until it finds the first `yield` keyword. There is a `yield` keyword on the first line within the function: the execution stops with the first yield! _This means that the variable `answer` is not defined yet!_
+
+When we call `game.next("Yes").value`, the previous `yield` is replaced with the value of the parameters passed to the `next()` function, `"Yes"` in this case. The value of the variable `answer` is now equal to `"Yes"`. The condition of the if-statement returns `false`, and `JavaScript loves you back ❤️` gets logged.
+
+
+
+#### Jawaban: 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"`
+
+With `String.raw`, it would simply ignore the escape and print:
+
+`C:\Documents\Projects\table.html`
+
+In this case, the string is `Hello\nworld`, which gets logged.
+
+
+
+#### Jawaban: C
+
+An async function always returns a promise. The `await` still has to wait for the promise to resolve: a pending promise gets returned when we call `getData()` in order to set `data` equal to it.
+
+If we wanted to get access to the resolved value `"I made it"`, we could have used the `.then()` method on `data`:
+
+`data.then(res => console.log(res))`
+
+This would've logged `"I made it!"`
+
+
+
+#### Jawaban: B
+
+The `.push()` method returns the _length_ of the new array! Previously, the array contained one element (the string `"banana"`) and had a length of `1`. After adding the string `"apple"` to the array, the array contains two elements, and has a length of `2`. This gets returned from the `addToList` function.
+
+The `push` method modifies the original array. If you wanted to return the _array_ from the function rather than the _length of the array_, you should have returned `list` after pushing `item` to it.
+
+
+
+#### Jawaban: 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 variable `shape` and set it equal to the frozen object `box`, `shape` also refers to a frozen object. You can check whether an object is frozen by using `Object.isFrozen`. In this case, `Object.isFrozen(shape)` returns true, since the variable `shape` has a reference to a frozen object.
+
+Since `shape` is frozen, and since the value of `x` is not an object, we cannot modify the property `x`. `x` is still equal to `10`, and `{ x: 10, y: 20 }` gets logged.
+
+
+
+#### Jawaban: D
+
+When we unpack the property `name` from the object on the right-hand side, we assign its value `"Lydia"` to a variable with the name `myName`.
+
+With `{ name: myName }`, we tell JavaScript that we want to create a new variable called `myName` with the value of the `name` property on the right-hand side.
+
+Since we try to log `name`, a variable that is not defined, a ReferenceError gets thrown.
+
+
+
+#### Jawaban: A
+
+A pure function is a function that _always_ returns the same result, if the same arguments are passed.
+
+The `sum` function always returns the same result. If we pass `1` and `2`, it will _always_ return `3` without side effects. If we pass `5` and `10`, it will _always_ return `15`, and so on. This is the definition of a pure function.
+
+
+
+#### Jawaban: C
+
+The `add` function is a _memoized_ function. With memoization, we can cache the results of a function in order to speed up its execution. In this case, we create a `cache` object that stores the previously returned values.
+
+If we call the `addFunction` 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 caches value will be returned, which saves on execution time. Else, if it's not cached, it will calculate the value and store it afterwards.
+
+We call the `addFunction` function three times with the same value: on the first invocation, the value of the function when `num` is equal to `10` isn't cached yet. The condition of the if-statement `num in cache` returns `false`, 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, the `cache` object contains the value that gets returned for `10`. The condition of the if-statement `num in cache` returns `true`, and `'From cache! 20'` gets logged.
+
+The third time, we pass `5 * 2` to the function which gets evaluated to `10`. The `cache` object contains the value that gets returned for `10`. The condition of the if-statement `num in cache` returns `true`, and `'From cache! 20'` gets logged.
+
+
+
+#### Jawaban: A
+
+With a _for-in_ loop, we can iterate over **enumerable** 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. `0` `1` `2` `3` get logged.
+
+With a _for-of_ loop, we can iterate over **iterables**. 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.
+
+
+
+#### Jawaban: 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` returns `3`, `1 * 2` returns `2`, and `1 / 2` returns `0.5`.
+
+
+
+#### Jawaban: B
+
+By default, arguments have the value of `undefined`, unless a value has been passed to the function. In this case, we didn't pass a value for the `name` argument. `name` is equal to `undefined` which gets logged.
+
+In ES6, we can overwrite this default `undefined` value with default parameters. For example:
+
+`function sayHi(name = "Lydia") { ... }`
+
+In this case, if we didn't pass a value or if we passed `undefined`, `name` would always be equal to the string `Lydia`
+
+
+
+#### Jawaban: B
+
+The value of the `this` keyword is dependent on where you use it. In a **method**, like the `getStatus` method, the `this` keyword refers to _the object that the method belongs to_. The method belongs to the `data` object, so `this` refers to the `data` object. When we log `this.status`, the `status` property on the `data` object gets logged, which is `"🥑"`.
+
+With the `call` method, we can change the object to which the `this` keyword refers. In **functions**, the `this` keyword refers to the _the object that the function belongs to_. We declared the `setTimeout` function on the _global object_, so within the `setTimeout` function, the `this` keyword refers to the _global object_. On the global object, there is a variable called _status_ with the value of `"😎"`. When logging `this.status`, `"😎"` gets logged.
+
+
+
+#### Jawaban: A
+
+We set the variable `city` equal to the value of the property called `city` on the `person` object. There is no property on this object called `city`, so the variable `city` has the value of `undefined`.
+
+Note that we are _not_ referencing the `person` object itself! We simply set the variable `city` equal to the current value of the `city` property on the `person` object.
+
+Then, we set `city` equal to the string `"Amsterdam"`. This doesn't change the person object: there is no reference to that object.
+
+When logging the `person` object, the unmodified object gets returned.
+
+
+
+#### Jawaban: C
+
+Variables with the `const` and `let` keyword are _block-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.
+
+
+
+#### Jawaban: C
+
+The value of `res` in the second `.then` is equal to the returned value of the previous `.then`. You can keep chaining `.then`s like this, where the value is passed to the next handler.
+
+
+
+#### Jawaban: A
+
+With `!!name`, we determine whether the value of `name` is truthy or falsy. If name is truthy, which we want to test for, `!name` returns `false`. `!false` (which is what `!!name` practically is) returns `true`.
+
+By setting `hasName` equal to `name`, you set `hasName` equal to whatever value you passed to the `getName` function, not the boolean value `true`.
+
+`new Boolean(true)` returns an object wrapper, not the boolean value itself.
+
+`name.length` returns the length of the passed argument, not whether it's `true`.
+
+
+
+#### Jawaban: B
+
+In order to get an character on a specific index in 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 which index is 0, the character `"I'`, which gets logged.
+
+Note that this method is not supported in IE7 and below. In that case, use `.charAt()`
+
+
+
+#### Jawaban: B
+
+You can set a default parameter's value equal to another parameter of the function, as long as they've been defined _before_ the default parameter. We pass the value `10` to the `sum` function. If the `sum` function only receives 1 argument, it means that the value for `num2` is not passed, and the value of `num1` is equal to the passed value `10` in this case. The default value of `num2` is the value of `num1`, which is `10`. `num1 + num2` returns `20`.
+
+If you're trying to set a default parameter's value equal to a parameter which is defined _after_ (to the right), the parameter's value hasn't been initialized yet, which will throw an error.
+
+
+
+#### Jawaban: A
+
+With the `import * as name` syntax, we import _all exports_ from the `module.js` file into the `index.js` file as a new object called `data` is created. In the `module.js` file, there are two exports: the default export, and a named export. The default export is a function which returns the string `"Hello World"`, and the named export is a variable called `name` which has the value of the string `"Lydia"`.
+
+The `data` object has a `default` property for the default export, other properties have the names of the named exports and their corresponding values.
+
+
+
+#### Jawaban: C
+
+Classes are syntactical sugar for function constructors. The equivalent of the `Person` class as a function constructor would be:
+
+```javascript
+function Person() {
+ this.name = name;
+}
+```
+
+Calling a function constructor with `new` results in the creation of an instance of `Person`, `typeof` keyword returns `"object"` for an instance. `typeof member` returns `"object"`.
+
+
+
+#### Jawaban: D
+
+The `.push` method returns the _new length_ of the array, not the array itself! By setting `newList` equal to `[1, 2, 3].push(4)`, we set `newList` equal to the new length of the array: `4`.
+
+Then, we try to use the `.push` method on `newList`. Since `newList` is the numerical value `4`, we cannot use the `.push` method: a TypeError is thrown.
+
+
+
+#### Jawaban: D
+
+Regular functions, such as the `giveLydiaPizza` function, have a `prototype` property, which is an object (prototype object) with a `constructor` property. Arrow functions however, such as the `giveLydiaChocolate` function, do not have this `prototype` property. `undefined` gets returned when trying to access the `prototype` property using `giveLydiaChocolate.prototype`.
+
+
+
+#### Jawaban: A
+
+`Object.entries(person)` returns an array of nested arrays, containing the keys and objects:
+
+`[ [ 'name', 'Lydia' ], [ 'age', 21 ] ]`
+
+Using the `for-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, using `const [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" ]`, with `x` equal to `"name"`, and `y` equal to `"Lydia"`, which get logged.
+The second subarray is `[ "age", 21 ]`, with `x` equal to `"age"`, and `y` equal to `21`, which get logged.
+
+
+
+#### Jawaban: 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.
+
+```javascript
+function getItems(fruitList, favoriteFruit, ...args) {
+ return [...fruitList, ...args, favoriteFruit];
+}
+
+getItems(['banana', 'apple'], 'pear', 'orange');
+```
+
+The above example works. This returns the array `[ 'banana', 'apple', 'orange', 'pear' ]`
+
+
+
+#### Jawaban: B
+
+In JavaScript, we don't _have_ to write the semicolon (`;`) explicitly, however the JavaScript engine still adds them after statements. This is called **Automatic Semicolon Insertion**. A statement can for example be variables, or keywords like `throw`, `return`, `break`, etc.
+
+Here, we wrote a `return` statement, and another value `a + b` on a _new 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 after `return`. You could see this as:
+
+```javascript
+return;
+a + b;
+```
+
+This means that `a + b` is never reached, since a function stops running after the `return` keyword. If no value gets returned, like here, the function returns `undefined`. Note that there is no automatic insertion after `if/else` statements!
+
+
+
+#### Jawaban: B
+
+We can set classes equal to other classes/function constructors. In this case, we set `Person` equal to `AnotherPerson`. The name on this constructor is `Sarah`, so the name property on the new `Person` instance `member` is `"Sarah"`.
+
+
+
+#### Jawaban: D
+
+A Symbol is not _enumerable_. The Object.keys method returns all _enumerable_ 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 the `Object.getOwnPropertySymbols()` method).
+
+
+
+#### Jawaban: A
+
+The `getList` function receives an array as its argument. Between the parentheses of the `getList` 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 are `2`, `3` and `4` in this case. The value of `y` is an array, containing all the rest parameters. The value of `x` is equal to `1` in this case, so when we log `[x, y]`, `[1, [2, 3, 4]]` gets logged.
+
+The `getUser` function receives an object. With arrow functions, we don't _have_ to write curly brackets if we just return one value. However, if you want to return an _object_ from an arrow function, you have to write it between parentheses, otherwise no value gets returned! The following function would have returned an object:
+
+`const getUser = user => ({ name: user.name, age: user.age })`
+
+Since no value gets returned in this case, the function returns `undefined`.
+
+
+
+#### Jawaban: C
+
+The variable `name` holds the value of a string, which is not a function, thus cannot invoke.
+
+TypeErrors get thrown when a value is not of the expected type. JavaScript expected `name` 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 word `return` as `retrun`.
+ReferenceErrors get thrown when JavaScript isn't able to find a reference to a value that you're trying to access.
+
+
+
+#### Jawaban: 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.
+
+
+
+#### Jawaban: 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 past 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 `[]`.
+
+
+
+#### Jawaban: D
+
+With a promise, we basically say _I 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 the `await` keyword in an `async` function. Although we can get a promise's value with both `.then` and `await`, they work a bit differently.
+
+In the `firstFunction`, we (sort of) put the myPromise function aside while it was running, but continued running the other code, which is `console.log('second')` in this case. Then, the function resolved with the string `I have resolved`, which then got logged after it saw that the callstack was empty.
+
+With the await keyword in `secondFunction`, we literally pause the execution of an async function until the value has been resolved befoer moving to the next line.
+
+This means that it waited for the `myPromise` to resolve with the value `I have resolved`, and only once that happened, we moved to the next line: `second` got logged.
+
+
+
+#### Jawaban: 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 is `1`, which is a numerical value. `1 + 2` returns the number 3.
+
+However, the second one is a string `"Lydia"`. `"Lydia"` is a string and `2` 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"`.
+
+
+
+#### Jawaban: C
+
+We can pass any type of value we want to `Promise.resolve`, either a promise or a non-promise. The method itself returns a promise with the resolved value. 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 value `5`. It returns a resolved promise with the value `5`.
+
+
+
+#### Jawaban: B
+
+Objects are passed by reference. When we check objects for strict equality (`===`), we're comparing their references.
+
+We set the default value for `person2` equal to the `person` object, and passed the `person` object as the value for `person1`.
+
+This means that both values have a reference to the same spot in memory, thus they are equal.
+
+The code block in the `else` statement gets run, and `They are the same!` gets logged.
+
+
+
+#### Jawaban: 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 called `colors` on the `colorConfig` object. There is no proprety called `colors`, so this returns `undefined`. Then, we try to access the value of the first element by using `[1]`. We cannot do this on a value that's `undefined`, so it throws a `TypeError`: `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 used `colorConfig[colors[1]]`, it would have returned the value of the `red` property on the `colorConfig` object.
+
+
+
+#### Jawaban: 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.
+
+
+
+#### Jawaban: D
+
+With `splice` 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` and `slice` return a new array, `find` returns an element, and `reduce` returns a reduced value.
+
+
+
+#### Jawaban: A
+
+We set the value of the `favoriteFood` property on the `info` object equal to the string with the pizza emoji, `'🍕'`. A string is a primitive data type. In JavaScript, primitive data types act by reference
+
+In JavaScript, primitive data types (everything that's not an object) interact by _value_. In this case, we set the value of the `favoriteFood` property on the `info` object equal to the value of the first element in the `food` array, the string with the pizza emoji in this case (`'🍕'`). A string is a primitive data type, and interact by value (see my [blogpost](https://www.theavocoder.com/complete-javascript/2018/12/21/by-value-vs-by-reference) if you're interested in learning more)
+
+Then, we change the value of the `favoriteFood` property on the `info` object. The `food` array hasn't changed, since the value of `favoriteFood` was merely a _copy_ 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 on `food[0]`. When we log food, it's still the original array, `['🍕', '🍫', '🥑', '🍔']`.
+
+
+
+#### Jawaban: A
+
+With the `JSON.parse()` method, we can parse JSON string to a JavaScript value.
+
+```javascript
+// Stringifying a number into valid JSON, then parsing the JSON string to a JavaScript value:
+const jsonNumber = JSON.stringify(4); // '4'
+JSON.parse(jsonNumber); // 4
+
+// Stringifying an array value into valid JSON, then parsing the JSON string to a JavaScript value:
+const jsonArray = 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:
+const jsonArray = JSON.stringify({ name: 'Lydia' }); // '{"name":"Lydia"}'
+JSON.parse(jsonArray); // { name: 'Lydia' }
+```
+
+
+
+#### Jawaban: D
+
+Each function has its own _execution context_ (or _scope_). The `getName` function first looks within its own context (scope) to see if it contains the variable `name` we're trying to access. In this case, the `getName` function contains its own `name` variable: we declare the variable `name` with the `let` keyword, and with the value of `'Sarah'`.
+
+Variables with the `let` keyword (and `const`) are hoisted, but unlike `var`, don't get initialized. 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 a `ReferenceError`.
+
+If we wouldn't have declared the `name` variable within the `getName` function, the javascript engine would've looked down the _scope chain_. The outer scope has a variable called `name` with the value of `Lydia`. In that case, it would've logged `Lydia`.
+
+```javascript
+let name = 'Lydia';
+
+function getName() {
+ console.log(name);
+}
+
+getName(); // Lydia
+```
+
+
+
+#### Jawaban: C
+
+With the `yield` keyword, we `yield` values in a generator function. With the `yield*` keyword, we can yield values from another generator function, or iterable object (for example an array).
+
+In `generatorOne`, we yield the entire array `['a', 'b', 'c']` using the `yield` keyword. The value of `value` property on the object returned by the `next` method on `one` (`one.next().value`) is equal to the entire array `['a', 'b', 'c']`.
+
+```javascript
+console.log(one.next().value); // ['a', 'b', 'c']
+console.log(one.next().value); // undefined
+```
+
+In `generatorTwo`, we use the `yield*` keyword. This means that the first yielded value of `two`, is equal to the first yielded value in the iterator. The iterator is the array `['a', 'b', 'c']`. The first yielded value is `a`, so the first time we call `two.next().value`, `a` is returned.
+
+```javascript
+console.log(two.next().value); // 'a'
+console.log(two.next().value); // 'b'
+console.log(two.next().value); // 'c'
+console.log(two.next().value); // undefined
+```
+
+
+
+#### Jawaban: 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 the `x => x` arrow function. `x` is equal to `'I love'`, which gets returned. This results in `I love to program`.
+
+
+
+#### Jawaban: C
+
+Normally when we set objects equal to `null`, those objects get _garbage collected_ as there is no reference anymore to that object. However, since the callback function within `setInterval` is an arrow function (thus bound to the `config` object), the callback function still holds a reference to the `config` object. As long as there is a reference, the object won't get garbage collected. Since it's not garbage collected, the `setInterval` callback function will still get invoked every 1000ms (1s).
+
+
+
+#### Jawaban: B
+
+When adding a key/value pair using the `set` method, the key will be the value of the first argument passed to the `set` function, and the value will be the second argument passed to the `set` function. The key is the _function_ `() => '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 the `get` method. Object interact by _reference_. 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.
+
+
+
+#### Jawaban: C
+
+Both the `changeAge` and `changeAgeAndName` functions have a default parameter, namely a _newly_ created object `{ ...person }`. This object has copies of all the key/values in the `person` object.
+
+First, we invoke the `changeAge` function and pass the `person` object as its argument. This function increases the value of the `age` property by 1. `person` is now `{ name: "Lydia", age: 22 }`.
+
+Then, we invoke the `changeAgeAndName` function, however we don't pass a parameter. Instead, the value of `x` is equal to a _new_ object: `{ ...person }`. Since it's a new object, it doesn't affect the values of the properties on the `person` object. `person` is still equal to `{ name: "Lydia", age: 22 }`.
+
+
+
+#### Jawaban: C
+
+With the spread operator `...`, we can _spread_ iterables to individual elements. The `sumValues` function receives three arguments: `x`, `y` and `z`. `...[1, 2, 3]` will result in `1, 2, 3`, which we pass to the `sumValues` function.
+
+
+
+#### Jawaban: B
+
+With the `+=` operand, we're incrementing the value of `num` by `1`. `num` had the initial value `1`, so `1 + 1` is `2`. The item on the second index in the `list` array is 🥰, `console.log(list[2])` prints 🥰.
+
+
+
+#### Jawaban: 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 an `undefined` or `null` value (_nullish_), the expression short-circuits and returns `undefined`.
+
+`person.pet?.name`: `person` has a property named `pet`: `person.pet` is not nullish. It has a property called `name`, and returns `Mara`.
+`person.pet?.family?.name`: `person` has a property named `pet`: `person.pet` is not nullish. `pet` does _not_ have a property called `family`, `person.pet.family` is nullish. The expression returns `undefined`.
+`person.getFullName?.()`: `person` has a property named `getFullName`: `person.getFullName()` is not nullish and can get invoked, which returns `Lydia Hallie`.
+`member.getLastName?.()`: `member` is not defined: `member.getLastName()` is nullish. The expression returns `undefined`.
+
+
+
+#### Jawaban: B
+
+We passed the condition `groceries.indexOf("banana")` to the if-statement. `groceries.indexOf("banana")` returns `0`, which is a falsy value. Since the condition in the if-statement is falsy, the code in the `else` block runs, and `We don't have to buy bananas!` gets logged.
+
+
+
+#### Jawaban: D
+
+The `language` method is a `setter`. Setters don't hold an actual value, their purpose is to _modify_ properties. When calling a `setter` method, `undefined` gets returned.
+
+
+
+#### Jawaban: C
+
+`typeof name` returns `"string"`. The string `"string"` is a truthy value, so `!typeof name` returns the boolean value `false`. `false === "object"` and `false === "string"` both return`false`.
+
+(If we wanted to check whether the type was (un)equal to a certain type, we should've written `!==` instead of `!typeof`)
+
+
+
+#### Jawaban: A
+
+The `add` function returns an arrow function, which returns an arrow function, which returns an arrow function (still with me?). The first function receives an argument `x` with the value of `4`. We invoke the second function, which receives an argument `y` with the value `5`. Then we invoke the third function, which receives an argument `z` with the value `6`. When we're trying to access the value `x`, `y` and `z` within the last arrow function, the JS engine goes up the scope chain in order to find the values for `x` and `y` accordingly. This returns `4` `5` `6`.
+
+
+
+#### Jawaban: C
+
+The generator function `range` returns an async object with promises for each item in the range we pass: `Promise{1}`, `Promise{2}`, `Promise{3}`. We set the variable `gen` equal to the async object, after which we loop over it using a `for await ... of` loop. We set the variable `item` equal to the returned Promise values: first `Promise{1}`, then `Promise{2}`, then `Promise{3}`. Since we're _awaiting_ the value of `item`, the resolved promsie, the resolved _values_ of the promises get returned: `1`, `2`, then `3`.
+
+
+
+#### Jawaban: D
+
+`myFunc` expects an object with properties `x`, `y` and `z` as its argument. Since we're only passing three separate numeric values (1, 2, 3) instead of one object with properties `x`, `y` and `z` ({x: 1, y: 2, z: 3}), `x`, `y` and `z` have their default value of `undefined`.
+
+
+
+#### Jawaban: B
+
+With the `Intl.NumberFormat` method, we can format numeric values to any locale. We format the numeric value `130` to the `en-US` locale as a `unit` in `mile-per-hour`, which results in `130 mph`. The numeric value `300` to the `en-US` locale as a `currentcy` in `USD` results in `$300.00`.
+
+
+
+#### Jawaban: 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 "💀" to `spookyItems[3]`. This means that we're modifying the `spookyItems` array, we're adding the "💀" to it. When logging `spookyItems`, `["👻", "🎃", "🕸", "💀"]` gets logged.
+
+
+
+#### Jawaban: C
+
+With the `Number.isNaN` method, you can check if the value you pass is a _numeric value_ and equal to `NaN`. `name` is not a numeric value, so `Number.isNaN(name)` returns `false`. `age` is a numeric value, but is not equal to `NaN`, so `Number.isNaN(age)` returns `false`.
+
+With the `isNaN` method, you can check if the value you pass is not a number. `name` is not a number, so `isNaN(name)` returns true. `age` is a number, so `isNaN(age)` returns `false`.
+
+
+
+#### Jawaban: D
+
+Variables declared with the `const` keyword are not referencable before their initialization: this is called the _temporal dead zone_. In the `getInfo` function, the variable `randomValue` is scoped in the functional scope of `getInfo`. On the line where we want to log the value of `typeof randomValue`, the variable `randomValue` isn't initialized yet: a `ReferenceError` gets thrown! The engine didn't go down the scope chain since we declared the variable `randomValue` in the `getInfo` function.
+
+
+
+#### Jawaban: C
+
+In the `try` block, we're logging the awaited value of the `myPromise` variable: `"Woah some cool data"`. Since no errors were thrown in the `try` block, the code in the `catch` block doesn't run. The code in the `finally` block _always_ runs, `"Oh finally!"` gets logged.
+
+
+
+#### Jawaban: B
+
+With the `flat` 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 value `1` (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 `['🥑', '✨', '✨', ['🍕', '🍕']]`.
+
+
+
+#### Jawaban: D
+
+`counterOne` is an instance of the `Counter` class. The counter class contains a `count` property on its constructor, and an `increment` method. First, we invoked the `increment` method twice by calling `counterOne.increment()`. Currently, `counterOne.count` is `2`.
+
+
+
+#### Jawaban: D
+
+First, we invoke `funcOne`. On the first line of `funcOne`, we call the `myPromise` promise, which is an _asynchronous_ operation. While the engine is busy completing the promise, it keeps on running the function `funcOne`. The next line is the _asynchronous_ `setTimeout` function, from which the callback is sent to the Web API. (see my article on the event loop here.)
+
+Both the promise and the timeout are asynchronous operations, the function keeps on running while it's busy completing the promise and handling the `setTimeout` callback. This means that `Last line!` gets logged first, since this is not an asynchonous operation. This is the last line of `funcOne`, the promise resolved, and `Promise!` gets logged. However, since we're invoking `funcTwo()`, the call stack isn't empty, and the callback of the `setTimeout` function cannot get added to the callstack yet.
+
+In `funcTwo` we're, first _awaiting_ the myPromise promise. With the `await` keyword, we pause the execution of the function until the promise has resolved (or rejected). Then, we log the awaited value of `res` (since the promise itself returns a promise). This logs `Promise!`.
+
+The next line is the _asynchronous_ `setTimeout` function, from which the callback is sent to the Web API.
+
+We get to the last line of `funcTwo`, which logs `Last line!` to the console. Now, since `funcTwo` popped off the call stack, the call stack is empty. The callbacks waiting in the queue (`() => console.log("Timeout!")` from `funcOne`, and `() => console.log("Timeout!")` from `funcTwo`) get added to the call stack one by one. The first callback logs `Timeout!`, and gets popped off the stack. Then, the second callback logs `Timeout!`, and gets popped off the stack. This logs `Last line! Promise! Promise! Last line! Timeout! Timeout!`
+
+
+
+#### Jawaban: C
+
+With the asterisk `*`, we import all exported values from that file, both default and named. If we had the following file:
+
+```javascript
+// info.js
+export const name = 'Lydia';
+export const age = 21;
+export default 'I love JavaScript';
+
+// index.js
+import * as info from './info';
+console.log(info);
+```
+
+The following would get logged:
+
+```javascript
+{
+ default: "I love JavaScript",
+ name: "Lydia",
+ age: 21
+}
+```
+
+For the `sum` example, it means that the imported value `sum` looks like this:
+
+```javascript
+{ default: function sum(x) { return x + x } }
+```
+
+We can invoke this function, by calling `sum.default`
+
+
+
+#### Jawaban: C
+
+With a Proxy object, we can add custom behavior to an object that we pass to it as the second argument. In tis case, we pass the `handler` object which contained to properties: `set` and `get`. `set` gets invoked whenever we _set_ property values, `get` gets invoked whenever we _get_ (access) property values.
+
+The first argument is an empty object `{}`, which is the value of `person`. To this object, the custom behavior specified in the `handler` object gets added. If we add a property to the `person` object, `set` will get invoked. If we access a property on the `person` object, `get` gets invoked.
+
+First, we added a new property `name` 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, the `get` property on the handler object got invoked. `"Accessed a property!"` gets logged.
+
+
+
+#### Jawaban: A
+
+With `Object.seal` we can prevent new properies from being _added_, or existing properties to be _removed_.
+
+However, you can still modify the value of existing properties.
+
+
+
+#### Jawaban: C
+
+The `Object.freeze` method _freezes_ an object. No properties can be added, modified, or removed.
+
+However, it only _shallowly_ freezes the object, meaning that only _direct_ properties on the object are frozen. If the property is another object, like `address` in this case, the properties on that object aren't frozen, and can be modified.
+
+
+
+#### Jawaban: C
+
+The `Object.freeze` method _freezes_ an object. No properties can be added, modified, or removed.
+
+However, it only _shallowly_ freezes the object, meaning that only _direct_ properties on the object are frozen. If the property is another object, like `address` in this case, the properties on that object aren't frozen, and can be modified.
+
+
+
+#### Jawaban: A
+
+First, we invoked `myFunc()` without passing any arguments. Since we didn't pass arguments, `num` and `value` got their default values: num is `2`, and `value` the returned value of the function `add`. To the `add` function, we pass `num` as an argument, which had the value of `2`. `add` returns `4`, which is the value of `value`.
+
+Then, we invoked `myFunc(3)` and passed the value `3` as the value for the argument `num`. We didn't pass an argument for `value`. Since we didn't pass a value for the `value` argument, it got the default value: the returned value of the `add` function. To `add`, we pass `num`, which has the value of `3`. `add` returns `6`, which is the value of `value`.
+
+
+
+#### Jawaban: 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 log `counter.#number`, a SyntaxError gets thrown: we cannot acccess it outside the `Counter` class!
+
+
+
+#### Jawaban: B
+
+In order to iterate over the `members` in each element in the `teams` array, we need to pass `teams[i].members` to the `getMembers` generator function. The generator function returns a generator object. In order to iterate over each element in this generator object, we need to use `yield*`.
+
+If we would've written `yield`, `return yield`, or `return`, the entire generator function would've gotten returned the first time we called the `next` method.
+
+
+
+#### Jawaban: C
+
+The `addHobby` function receives two arguments, `hobby` and `hobbies` with the default value of the `hobbies` array on the `person` object.
+
+First, we invoke the `addHobby` function, and pass `"running"` as the value for `hobby` and an empty array as the value for `hobbies`. Since we pass an empty array as the value for `y`, `"running"` gets added to this empty array.
+
+Then, we invoke the `addHobby` function, and pass `"dancing"` as the value for `hobby`. We didn't pass a value for `hobbies`, so it gets the default value, the `hobbies` property on the `person` object. We push the hobby `dancing` to the `person.hobbies` array.
+
+Last, we invoke the `addHobby` function, and pass `"bdaking"` as the value for `hobby`, and the `person.hobbies` array as the value for `hobbies`. We push the hobby `baking` to the `person.hobbies` array.
+
+After pushing `dancing` and `baking`, the value of `person.hobbies` is `["coding", "dancing", "baking"]`
+
+
+
+#### Jawaban: B
+
+We create the variable `pet` which is an instance of the `Flamingo` class. When we instantiate this instance, the `constructor` on `Flamingo` gets called. First, `"I'm pink. 🌸"` gets logged, after which we call `super()`. `super()` calls the constructor of the parent class, `Bird`. THe constructor in `Bird` gets called, and logs `"I'm a bird. 🦢"`.
+
+
+
+#### Jawaban: D
+
+The `const` keyword simply means we cannot _redeclare_ the value of that variable, it's _read-only_. However, the value itself isn't immutable. The propeties on the `emojis` array can be modified, for example by pushing new values, splicing them, or setting the length of the array to 0.
+
+
+
+#### Jawaban: 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 the `Object.values` of the `person` object if we want it to return the array `["Lydia Hallie", 21]`: `yield* Object.values(this)`.
+
+
+
+#### 答案: C
+
+通过 `yield` 关键字, 我们在 `Generator` 函数里执行`yield`表达式. 通过 `yield*` 关键字, 我们可以在一个`Generator` 函数里面执行(`yield`表达式)另一个 `Generator` 函数, 或可遍历的对象 (如数组).
+
+在函数 `generatorOne` 中, 我们通过 `yield` 关键字 yield 了一个完整的数组 `['a', 'b', 'c']`。函数`one`通过`next`方法返回的对象的`value` 属性的值 (`one.next().value`) 等价于数组 `['a', 'b', 'c']`.
+
+```javascript
+console.log(one.next().value) // ['a', 'b', 'c']
+console.log(one.next().value) // undefined
+```
+
+在函数 `generatorTwo` 中, 我们使用 `yield*` 关键字。就相当于函数`two`第一个`yield`的值, 等价于在迭代器中第一个 `yield` 的值。数组`['a', 'b', 'c']`就是这个迭代器. 第一个 `yield` 的值就是 `a`, 所以我们第一次调用 `two.next().value`时, 就返回`a`。
+
+```javascript
+console.log(two.next().value) // 'a'
+console.log(two.next().value) // 'b'
+console.log(two.next().value) // 'c'
+console.log(two.next().value) // undefined
+```
+
+
+
+#### 答案: A
+
+带有模板字面量的表达式首先被执行。相当于字符串会包含表达式,这个立即执行函数 `(x => x)('I love')` 返回的值. 我们向箭头函数 `x => x` 传递 `'I love'` 作为参数。`x` 等价于返回的 `'I love'`。这就是结果 `I love to program`。
+
+
+
+#### 答案: C
+
+一般情况下当我们将对象赋值为 `null`, 那些对象会被进行 _垃圾回收(garbage collected)_ 因为已经没有对这些对象的引用了。然而,`setInterval`的参数是一个箭头函数(所以上下文绑定到对象 `config` 了),回调函数仍然保留着对 `config`的引用。只要存在引用,对象就不会被垃圾回收。因为没有被垃圾回收,`setInterval` 的回调每1000ms (1s)会被调用一次。
+
+
+
+#### 答案: B
+
+当通过 `set` 方法添加一个键值对,一个传递给 `set`方法的参数将会是键名,第二个参数将会是值。在这个case里,键名为 _函数_ `() => 'greeting'`,值为`'Hello world'`。 `myMap` 现在就是 `{ () => 'greeting' => 'Hello world!' }`。
+
+1 是错的,因为键名不是 `'greeting'` 而是 `() => 'greeting'`。
+3 是错的,因为我们给`get` 方法传递了一个新的函数。对象受 _引用_ 影响。函数也是对象,因此两个函数严格上并不等价,尽管他们相同:他们有两个不同的内存引用地址。
+
+
+
+#### 答案: C
+
+函数 `changeAge` 和函数 `changeAgeAndName` 有着不同的参数,定义一个 _新_ 生成的对象 `{ ...person }`。这个对象有着所有 `person` 对象 中 k/v 值的副本。
+
+首项, 我们调用 `changeAge` 函数并传递 `person` 对象作为它的参数。这个函数对 `age` 属性进行加一操作。`person` 现在是 `{ name: "Lydia", age: 22 }`。
+
+然后,我们调用函数 `changeAgeAndName` ,然而我们没有传递参数。取而代之,`x` 的值等价 _new_ 生成的对象: `{ ...person }`。因为它是一个新生成的对象,它并不会对对象 `person` 造成任何副作用。`person` 仍然等价于 `{ name: "Lydia", age: 22 }`。
+
+
+
+#### 答案: C
+
+通过展开操作符 `...`,我们可以 _暂开_ 单个可迭代的元素。函数 `sumValues` function 接收三个参数: `x`, `y` 和 `z`。`...[1, 2, 3]` 的执行结果为 `1, 2, 3`,将会传递给函数 `sumValues`。
+
+
+
+#### 答案: B
+
+通过 `+=` 操作符,我们对值 `num` 进行加 `1` 操作。 `num` 有初始值 `1`,因此 `1 + 1` 的执行结果为 `2`。数组 `list` 的第二项为 🥰,`console.log(list[2])` 输出 🥰.
+
+
+
+#### 答案: B
+
+通过 ES10 或 TS3.7+[可选链操作符 `?.`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/%E5%8F%AF%E9%80%89%E9%93%BE),我们不再需要显式检测更深层的嵌套值是否有效。如果我们尝试获取 `undefined` 或 `null` 的值 (_nullish_),表达将会短路并返回 `undefined`.
+
+`person.pet?.name`: `person` 有一个名为 `pet` 的属性: `person.pet` 不是 nullish。它有个名为 `name` 的属性,并返回字符串 `Mara`。
+`person.pet?.family?.name`: `person` 有一个名为 `pet` 的属性: `person.pet` 不是 nullish. `pet` _并没有_ 一个名为 `family` 的属性, `person.pet.family` 是 nullish。表达式返回 `undefined`。
+`person.getFullName?.()`: `person` 有一个名为 `getFullName` 的属性: `person.getFullName()` 不是 nullish 并可以被调用,返回字符串 `Lydia Hallie`。
+`member.getLastName?.()`: `member` is not defined: `member.getLastName()` is nullish. The expression returns `undefined`.
+
+
+
+#### 答案: B
+
+我们传递了一个状态 `groceries.indexOf("banana")` 给if条件语句。`groceries.indexOf("banana")` 返回 `0`, 一个 falsy 的值。因为if条件语句的状态为 falsy,`else` 块区内的代码执行,并且 `We don't have to buy bananas!` 被输出.
+
+
+
+#### 答案: D
+
+方法 `language` 是一个 `setter`。Setters 并不保存一个实际值,它们的使命在于 _修改_ 属性。当调用方法 `setter`, 返回 `undefined`。
+
+
+
+#### 答案: C
+
+`typeof name` 返回 `"string"`。字符串 `"string"` 是一个 truthy 的值,因此 `!typeof name` 返回一个布尔值 `false`。 `false === "object"` 和 `false === "string"` 都返回 `false`。
+
+(如果我们想检测一个值的类型,我们不应该用 `!==` 而不是 `!typeof`)
+
+
+
+#### 答案: A
+
+函数 `add` 是一个返回 返回箭头函数的箭头函数 的箭头函数(still with me?)。第一个函数接收一个值为 `4` 的参数 `x`。我们调用第二个函数,它接收一个值为 `5` 的参数 `y`。然后我们调用第三个函数,它接收一个值为 `6` 的参数 `z`。当我们尝试在最后一个箭头函数中获取 `x`, `y` 和 `z` 的值,JS 引擎根据作用域链去找 `x` 和 `y` 的值。得到 `4` `5` `6`.
+
+
+
+#### 答案: C
+
+我们给 函数range 传递: `Promise{1}`, `Promise{2}`, `Promise{3}`,Generator 函数 `range` 返回一个全是 async object promise 数组。我们将 async object 赋值给变量 `gen`,之后我们使用`for await ... of` 进行循环遍历。我们将返回的 Promise 实例赋值给 `item`: 第一个返回 `Promise{1}`, 第二个返回 `Promise{2}`,之后是 `Promise{3}`。因为我们正 _awaiting_ `item` 的值,resolved 状态的 promsie,promise数组的resolved _值_ 以此为: `1`,`2`,`3`.
+
+
+
+#### 答案: D
+
+`myFunc` 期望接收一个包含 `x`, `y` 和 `z` 属性的对象作为它的参数。因为我们仅仅传递三个单独的数字值 (1, 2, 3) 而不是一个含有 `x`, `y` 和 `z` 属性的对象 ({x: 1, y: 2, z: 3}), `x`, `y` 和 `z` 有着各自的默认值 `undefined`.
+
+
+
+#### 答案: B
+
+通过方法 `Intl.NumberFormat`,我们可以格式化任意区域的数字值。我们对数字值 `130` 进行 `mile-per-hour` 作为 `unit` 的 `en-US` 区域 格式化,结果为 `130 mph`。对数字值 `300` 进行 `USD` 作为 `currentcy` 的 `en-US` 区域格式化,结果为 `$300.00`.
+
+
+
+#### 答案: B
+
+通过解构对象们,我们可以从右手边的对象中拆出值,并且将拆出的值分配给左手边对象同名的属性。在这种情况下,我们将值 "💀" 分配给 `spookyItems[3]`。相当于我们正在篡改数组 `spookyItems`,我们给它添加了值 "💀"。当输出 `spookyItems` 时,结果为 `["👻", "🎃", "🕸", "💀"]`。
+
+
+
+#### 答案: C
+
+通过方法 `Number.isNaN`,你可以检测你传递的值是否为 _数字值_ 并且是否等价于 `NaN`。`name` 不是一个数字值,因此 `Number.isNaN(name)` 返回 `false`。`age` 是一个数字值,但它不等价于 `NaN`,因此 `Number.isNaN(age)` 返回 `false`.
+
+通过方法 `isNaN`, 你可以检测你传递的值是否一个 number。`name` 不是一个 `number`,因此 `isNaN(name)` 返回 `true`. `age` 是一个 `number` 因此 `isNaN(age)` 返回 `false`.
+
+
+
+#### 答案: D
+
+通过 `const` 关键字声明的变量在被初始化之前不可被引用:这被称之为 _暂时性死去_。在函数 `getInfo` 中, 变量 `randomValue` 声明在`getInfo` 的作用域的此法环境中。在想要对 `typeof randomValue` 进行log之前,变量 `randomValue` 仍未被初始化: 错误`ReferenceError` 被抛出! JS引擎并不会根据作用域链网上寻找该变量,因为我们已经在 `getInfo` 函数中声明了 `randomValue` 变量。
+
+
+
+#### 答案: C
+
+在 `try` 块区,我们打印 `myPromise` 变量的 awaited 值: `"Woah some cool data"`。因为`try` 块区没有错误抛出,`catch` 块区的代码并不执行。`finally` 块区的代码 _总是_ 执行,`"Oh finally!"` 被输出。
+
+
+
+#### Answer: B
+
+With the `flat` 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 value `1` (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 `['🥑', '✨', '✨', ['🍕', '🍕']]`.
+
+
+
+#### Answer: D
+
+`counterOne` is an instance of the `Counter` class. The counter class contains a `count` property on its constructor, and an `increment` method. First, we invoked the `increment` method twice by calling `counterOne.increment()`. Currently, `counterOne.count` is `2`.
+
+
+
+#### Answer: D
+
+First, we invoke `funcOne`. On the first line of `funcOne`, we call the `myPromise` promise, which is an _asynchronous_ operation. While the engine is busy completing the promise, it keeps on running the function `funcOne`. The next line is the _asynchronous_ `setTimeout` function, from which the callback is sent to the Web API. (see my article on the event loop here.)
+
+Both the promise and the timeout are asynchronous operations, the function keeps on running while it's busy completing the promise and handling the `setTimeout` callback. This means that `Last line!` gets logged first, since this is not an asynchonous operation. This is the last line of `funcOne`, the promise resolved, and `Promise!` gets logged. However, since we're invoking `funcTwo()`, the call stack isn't empty, and the callback of the `setTimeout` function cannot get added to the callstack yet.
+
+In `funcTwo` we're, first _awaiting_ the myPromise promise. With the `await` keyword, we pause the execution of the function until the promise has resolved (or rejected). Then, we log the awaited value of `res` (since the promise itself returns a promise). This logs `Promise!`.
+
+The next line is the _asynchronous_ `setTimeout` function, from which the callback is sent to the Web API.
+
+We get to the last line of `funcTwo`, which logs `Last line!` to the console. Now, since `funcTwo` popped off the call stack, the call stack is empty. The callbacks waiting in the queue (`() => console.log("Timeout!")` from `funcOne`, and `() => console.log("Timeout!")` from `funcTwo`) get added to the call stack one by one. The first callback logs `Timeout!`, and gets popped off the stack. Then, the second callback logs `Timeout!`, and gets popped off the stack. This logs `Last line! Promise! Promise! Last line! Timeout! Timeout!`
+
+
+
+#### Answer: C
+
+With the asterisk `*`, we import all exported values from that file, both default and named. If we had the following file:
+
+```javascript
+// info.js
+export const name = "Lydia";
+export const age = 21;
+export default "I love JavaScript";
+
+// index.js
+import * as info from "./info";
+console.log(info);
+```
+
+The following would get logged:
+
+```javascript
+{
+ default: "I love JavaScript",
+ name: "Lydia",
+ age: 21
+}
+```
+
+For the `sum` example, it means that the imported value `sum` looks like this:
+
+```javascript
+{ default: function sum(x) { return x + x } }
+```
+
+We can invoke this function, by calling `sum.default`
+
+
+
+#### Answer: C
+
+With a Proxy object, we can add custom behavior to an object that we pass to it as the second argument. In tis case, we pass the `handler` object which contained to properties: `set` and `get`. `set` gets invoked whenever we _set_ property values, `get` gets invoked whenever we _get_ (access) property values.
+
+The first argument is an empty object `{}`, which is the value of `person`. To this object, the custom behavior specified in the `handler` object gets added. If we add a property to the `person` object, `set` will get invoked. If we access a property on the `person` object, `get` gets invoked.
+
+First, we added a new property `name` 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, the `get` property on the handler object got invoked. `"Accessed a property!"` gets logged.
+
+
+
+#### Answer: A
+
+With `Object.seal` we can prevent new properies from being _added_, or existing properties to be _removed_.
+
+However, you can still modify the value of existing properties.
+
+
+
+#### Answer: C
+
+The `Object.freeze` method _freezes_ an object. No properties can be added, modified, or removed.
+
+However, it only _shallowly_ freezes the object, meaning that only _direct_ properties on the object are frozen. If the property is another object, like `address` in this case, the properties on that object aren't frozen, and can be modified.
+
+
+
+#### Answer: C
+
+The `Object.freeze` method _freezes_ an object. No properties can be added, modified, or removed.
+
+However, it only _shallowly_ freezes the object, meaning that only _direct_ properties on the object are frozen. If the property is another object, like `address` in this case, the properties on that object aren't frozen, and can be modified.
+
+
+
+#### Answer: A
+
+First, we invoked `myFunc()` without passing any arguments. Since we didn't pass arguments, `num` and `value` got their default values: num is `2`, and `value` the returned value of the function `add`. To the `add` function, we pass `num` as an argument, which had the value of `2`. `add` returns `4`, which is the value of `value`.
+
+Then, we invoked `myFunc(3)` and passed the value `3` as the value for the argument `num`. We didn't pass an argument for `value`. Since we didn't pass a value for the `value` argument, it got the default value: the returned value of the `add` function. To `add`, we pass `num`, which has the value of `3`. `add` returns `6`, which is the value of `value`.
+
+
+
+#### 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 log `counter.#number`, a SyntaxError gets thrown: we cannot acccess it outside the `Counter` class!
+
+
+
+#### Answer: B
+
+In order to iterate over the `members` in each element in the `teams` array, we need to pass `teams[i].members` to the `getMembers` generator function. The generator function returns a generator object. In order to iterate over each element in this generator object, we need to use `yield*`.
+
+If we would've written `yield`, `return yield`, or `return`, the entire generator function would've gotten returned the first time we called the `next` method.
+
+
+
+#### Answer: C
+
+The `addHobby` function receives two arguments, `hobby` and `hobbies` with the default value of the `hobbies` array on the `person` object.
+
+First, we invoke the `addHobby` function, and pass `"running"` as the value for `hobby` and an empty array as the value for `hobbies`. Since we pass an empty array as the value for `y`, `"running"` gets added to this empty array.
+
+Then, we invoke the `addHobby` function, and pass `"dancing"` as the value for `hobby`. We didn't pass a value for `hobbies`, so it gets the default value, the `hobbies` property on the `person` object. We push the hobby `dancing` to the `person.hobbies` array.
+
+Last, we invoke the `addHobby` function, and pass `"bdaking"` as the value for `hobby`, and the `person.hobbies` array as the value for `hobbies`. We push the hobby `baking` to the `person.hobbies` array.
+
+After pushing `dancing` and `baking`, the value of `person.hobbies` is `["coding", "dancing", "baking"]`
+
+
+
+#### Answer: B
+
+We create the variable `pet` which is an instance of the `Flamingo` class. When we instantiate this instance, the `constructor` on `Flamingo` gets called. First, `"I'm pink. 🌸"` gets logged, after which we call `super()`. `super()` calls the constructor of the parent class, `Bird`. THe constructor in `Bird` gets called, and logs `"I'm a bird. 🦢"`.
+
+
+
+#### Answer: D
+
+The `const` keyword simply means we cannot _redeclare_ the value of that variable, it's _read-only_. However, the value itself isn't immutable. The propeties on the `emojis` array can be modified, for example by pushing new values, splicing them, or setting the length of the array to 0.
+
+
+
+#### 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 the `Object.values` of the `person` object if we want it to return the array `["Lydia Hallie", 21]`: `yield* Object.values(this)`.
+
+答案
+
Pertanyaan JavaScript
+
+---
+
+Saya menerbitkan beberapa pilihan pertanyaan Javascript di akun Instagram Story [Instagram](https://www.instagram.com/theavocoder), yang mana diterbitkan disini juga! Terakhir diperbaharui: 24 Desember
+
+From basic to advanced: test how well you know JavaScript, refresh your knowledge a bit, or prepare for your coding interview! :muscle: :rocket: 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! :heart:
+Dari tingkat dasar sampai tingkat lanjut: Menguji seberapa jago Anda di JavaScript, asah pengetahuan Anda, atau untuk persiapan interview tentang pemrograman! :muscle: :rocket: Saya akan memperbaharui jawaban di bagian yang tertutup di bawah pertanyaan, sederhananya tinggal di klik saja yang nantinya jawaban akan muncul disana. Ini hanya untuk bersenang - senang saja, semoga berhasil! :heart:
+
+Feel free to reach out to me! 😊
+Jangan sungkan untuk terhubung dengan saya! 😊
+Instagram || Twitter || LinkedIn || Blog
+
+ Lihat 17 Terjemahan yang tersedia 🇪🇸🇮🇹🇩🇪 🇫🇷🇷🇺🇨🇳🇵🇹
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+
+
+When you change one object, you change all of them.
+
+
Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+
+
+
Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+
+
+Now, `foo` gets invoked, and `"First"` is being logged.
+
+
+
+`foo` is popped off the stack, and `baz` 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 the _queue_.
+
+
+
+This is where an event loop starts to work. An **event 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.
+
+
Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+
+
+Then, we declare a variable called `members`. We set the first element of that array equal to the value of the `person` variable. Objects interact by _reference_ when setting them equal to each other. When you assign a reference from one variable to another, you make a _copy_ of that reference. (note that they don't have the _same_ reference!)
+
+
+
+Then, we set the variable `person` equal to `null`.
+
+
+
+We are only modifying the value of the `person` variable, and not the first element in the array, since that element has a different (copied) reference to the object. The first element in `members` still holds its reference to the original object. When we log the `members` array, the first element still holds the value of the object, which gets logged.
+
+
Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+
+
+The value of `a` is now `1`, and the value of `b` is now `2`. What we actually did in the question, is:
+
+```javascript
+[y] = [1, 2, 3, 4, 5];
+```
+
+
+
+This means that the value of `y` is equal to the first value in the array, which is the number `1`. When we log `y`, `1` is returned.
+
+
Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+
`world`
+- C: `Hello\nworld`
+- D: `Hello\n`
`world`
+
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+
+
+Then, we create a new variable `counterTwo`, and set it equal to `counterOne`. Since objects interact by reference, we're just creating a new reference to the same spot in memory that `counterOne` points to. Since it has the same spot in memory, any changes made to the object that `counterTwo` has a reference to, also apply to `counterOne`. Currently, `counterTwo.count` is `2`.
+
+We invoke the `counterTwo.increment()`, which sets the `count` to `3`. Then, we log the count on `counterOne`, which logs `3`.
+
+
+
+
Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+Jawaban
+答案
+答案
+答案
+答案
+答案
+答案
+答案
+答案
+答案
+答案
+答案
+答案
+答案
+答案
+答案
+答案
+答案
+答案
+答案
+Answer
+Answer
+
+
+Then, we create a new variable `counterTwo`, and set it equal to `counterOne`. Since objects interact by reference, we're just creating a new reference to the same spot in memory that `counterOne` points to. Since it has the same spot in memory, any changes made to the object that `counterTwo` has a reference to, also apply to `counterOne`. Currently, `counterTwo.count` is `2`.
+
+We invoke the `counterTwo.increment()`, which sets the `count` to `3`. Then, we log the count on `counterOne`, which logs `3`.
+
+
+
+
Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+Jawaban
@@ -4716,7 +4716,7 @@ const emojis = ['🎄', '🎅🏼', '🎁', '⭐'];
#### Jawaban: D
-The `const` keyword simply means we cannot _redeclare_ the value of that variable, it's _read-only_. However, the value itself isn't immutable. The propeties on the `emojis` array can be modified, for example by pushing new values, splicing them, or setting the length of the array to 0.
+Deklarasi `const` pada dasarnya berarti tidak dapat _mengubah_ nilai dari variable tersebut, karena bersifat _read-only (tidak dapat diubah)_. Bagaimanapun, nilainya tidak mutlak. Seperti array pada variable `emojis` dimana nilainya bisa diubah, contohnya untuk menambah nilai array baru, menghilangkan, atau mengubah properti `length` dari array menjadi 0.
-#### Answer: B +#### 答案: B -With the `flat` 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 value `1` (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 `['🥑', '✨', '✨', ['🍕', '🍕']]`. +通过方法 `flat`, 我们可以创建一个新的, 已被扁平化的数组。被扁平化的深度取决于我们传递的值。在这个case里,我们传递了值 `1` (并不必要,这是默认值),相当于只有第一层的数组才会被连接。即这个 case 里的 `['🥑']` and `['✨', '✨', ['🍕', '🍕']]`。连接这两个数组得到结果 `['🥑', '✨', '✨', ['🍕', '🍕']]`.
-#### Answer: D
+#### 答案: D
-`counterOne` is an instance of the `Counter` class. The counter class contains a `count` property on its constructor, and an `increment` method. First, we invoked the `increment` method twice by calling `counterOne.increment()`. Currently, `counterOne.count` is `2`.
+`counterOne` 是类 `Counter` 的一个实例。类 Counter 包含一个`count` 属性在它的构造函数里, 和一个 `increment` 方法。首先,我们通过 `counterOne.increment()` 调用方法 `increment` 两次。现在, `counterOne.count` 为 `2`.
-#### Answer: D
+#### 答案: D
-First, we invoke `funcOne`. On the first line of `funcOne`, we call the `myPromise` promise, which is an _asynchronous_ operation. While the engine is busy completing the promise, it keeps on running the function `funcOne`. The next line is the _asynchronous_ `setTimeout` function, from which the callback is sent to the Web API. (see my article on the event loop here.)
+首先,我们调用 `funcOne`。在函数 `funcOne` 的第一行,我们调用`myPromise` promise _异步操作_。当JS引擎在忙于执行 promise,它继续执行函数 `funcOne`。下一行 _异步操作_ `setTimeout`,其回调函数被 Web API 调用。 (详情请参考我关于event loop的文章.)
-Both the promise and the timeout are asynchronous operations, the function keeps on running while it's busy completing the promise and handling the `setTimeout` callback. This means that `Last line!` gets logged first, since this is not an asynchonous operation. This is the last line of `funcOne`, the promise resolved, and `Promise!` gets logged. However, since we're invoking `funcTwo()`, the call stack isn't empty, and the callback of the `setTimeout` function cannot get added to the callstack yet.
+promise 和 timeout 都是异步操作,函数继续执行当JS引擎忙于执行promise 和 处理 `setTimeout` 的回调。相当于 `Last line!` 首先被输出, 因为它不是异步操作。执行完 `funcOne` 的最后一行,promise 状态转变为 resolved,`Promise!` 被打印。然而,因为我们调用了 `funcTwo()`, 调用栈不为空,`setTimeout` 的回调仍不能入栈。
-In `funcTwo` we're, first _awaiting_ the myPromise promise. With the `await` keyword, we pause the execution of the function until the promise has resolved (or rejected). Then, we log the awaited value of `res` (since the promise itself returns a promise). This logs `Promise!`.
+我们现在处于 `funcTwo`,先 _awaiting_ myPromise。通过 `await` 关键字, 我们暂停了函数的执行直到 promise 状态变为 resolved (或 rejected)。然后,我们输出 `res` 的 awaited 值(因为 promise 本身返回一个 promise)。 接着输出 `Promise!`。
-The next line is the _asynchronous_ `setTimeout` function, from which the callback is sent to the Web API.
+下一行就是 _异步操作_ `setTimeout`,其回调函数被 Web API 调用。
-We get to the last line of `funcTwo`, which logs `Last line!` to the console. Now, since `funcTwo` popped off the call stack, the call stack is empty. The callbacks waiting in the queue (`() => console.log("Timeout!")` from `funcOne`, and `() => console.log("Timeout!")` from `funcTwo`) get added to the call stack one by one. The first callback logs `Timeout!`, and gets popped off the stack. Then, the second callback logs `Timeout!`, and gets popped off the stack. This logs `Last line! Promise! Promise! Last line! Timeout! Timeout!`
+我们执行到函数 `funcTwo` 的最后一行,输出 `Last line!`。现在,因为 `funcTwo` 出栈,调用栈为空。在事件队列中等待的回调函数(`() => console.log("Timeout!")` from `funcOne`, and `() => console.log("Timeout!")` from `funcTwo`)以此入栈。第一个回调输出 `Timeout!`,并出栈。然后,第二个回调输出 `Timeout!`,并出栈。得到结果 `Last line! Promise! Promise! Last line! Timeout! Timeout!`
-#### Answer: C
+#### 答案: C
-With the asterisk `*`, we import all exported values from that file, both default and named. If we had the following file:
+使用符号 `*`,我们引入文件中的所有值,包括默认和具名。如果我们有以下文件:
```javascript
// info.js
@@ -4339,7 +4339,7 @@ import * as info from "./info";
console.log(info);
```
-The following would get logged:
+将会输出以下内容:
```javascript
{
@@ -4349,20 +4349,20 @@ The following would get logged:
}
```
-For the `sum` example, it means that the imported value `sum` looks like this:
+以 `sum` 为例,相当于以下形式引入值 `sum`:
```javascript
{ default: function sum(x) { return x + x } }
```
-We can invoke this function, by calling `sum.default`
+我们可以通过调用 `sum.default` 来调用该函数
-#### Answer: C
+#### 答案: C
-With a Proxy object, we can add custom behavior to an object that we pass to it as the second argument. In tis case, we pass the `handler` object which contained to properties: `set` and `get`. `set` gets invoked whenever we _set_ property values, `get` gets invoked whenever we _get_ (access) property values.
+使用 Proxy 对象,我们可以给一个对象添加自定义行为。在这个 case,我们传递一个包含以下属性的对象 `handler` : `set` and `get`。每当我门 _设置_ 属性值时 `set` 被调用,每当我们 _获取_ 时 `get` 被调用。
-The first argument is an empty object `{}`, which is the value of `person`. To this object, the custom behavior specified in the `handler` object gets added. If we add a property to the `person` object, `set` will get invoked. If we access a property on the `person` object, `get` gets invoked.
+第一个参数是一个空对象 `{}`,作为 `person` 的值。对于这个对象,自定义行为被定义在对象 `handler`。如果我们向对象 `person` 添加属性,`set` 将被调用。如果我们获取 `person` 的属性, `get` 将被调用。
-First, we added a new property `name` to the proxy object (`person.name = "Lydia"`). `set` gets invoked, and logs `"Added a new property!"`.
+首先,我们向 proxy 对象(`person.name = "Lydia"`)添加一个属性 `name`。`set` 被调用并输出 `"Added a new property!"`。
-Then, we access a property value on the proxy object, the `get` property on the handler object got invoked. `"Accessed a property!"` gets logged.
+然后,我们获取 proxy 对象的一个属性,对象 handler 的属性 `get` 被调用。输出 `"Accessed a property!"`。
-#### Answer: A
+#### 答案: A
-With `Object.seal` we can prevent new properies from being _added_, or existing properties to be _removed_.
+使用 `Object.seal` 我们可以防止新属性 _被添加_,或者存在属性 _被移除_.
-However, you can still modify the value of existing properties.
+然而,你仍然可以对存在属性进行更改。
-#### Answer: C
+#### 答案: C
-The `Object.freeze` method _freezes_ an object. No properties can be added, modified, or removed.
+使用方法 `Object.freeze` 对一个对象进行 _冻结_。不能对属性进行添加,修改,删除。
-However, it only _shallowly_ freezes the object, meaning that only _direct_ properties on the object are frozen. If the property is another object, like `address` in this case, the properties on that object aren't frozen, and can be modified.
+然而,它仅 对对象进行 _浅_ 冻结,意味着只有 对象中的 _直接_ 属性被冻结。如果属性是另一个 object,像案例中的 `address`,`address` 中的属性没有被冻结,仍然可以被修改。
-#### Answer: C
+#### 答案: C
-The `Object.freeze` method _freezes_ an object. No properties can be added, modified, or removed.
+使用方法 `Object.freeze` 对一个对象进行 _冻结_。不能对属性进行添加,修改,删除。
-However, it only _shallowly_ freezes the object, meaning that only _direct_ properties on the object are frozen. If the property is another object, like `address` in this case, the properties on that object aren't frozen, and can be modified.
+然而,它仅 对对象进行 _浅_ 冻结,意味着只有 对象中的 _直接_ 属性被冻结。如果属性是另一个 object,像案例中的 `address`,`address` 中的属性没有被冻结,仍然可以被修改。
-#### Answer: A
+#### 答案: A
-First, we invoked `myFunc()` without passing any arguments. Since we didn't pass arguments, `num` and `value` got their default values: num is `2`, and `value` the returned value of the function `add`. To the `add` function, we pass `num` as an argument, which had the value of `2`. `add` returns `4`, which is the value of `value`.
+首先我们不传递任何参数调用 `myFunc()`。因为我们没有传递参数,`num` 和 `value` 获取它们各自的默认值:num 为 `2`, 而 `value` 为函数 `add` 的返回值。对于函数 `add`,我们传递值为2的 `num` 作为参数。函数 `add` 返回 `4` 作为 `value` 的值。
-Then, we invoked `myFunc(3)` and passed the value `3` as the value for the argument `num`. We didn't pass an argument for `value`. Since we didn't pass a value for the `value` argument, it got the default value: the returned value of the `add` function. To `add`, we pass `num`, which has the value of `3`. `add` returns `6`, which is the value of `value`.
+然后,我们调用 `myFunc(3)` 并传递值 `3` 参数 `num` 的值。我们没有给 `value` 传递值。因为我们没有给参数 `value` 传递值,它获取默认值:函数 `add` 的返回值。对于函数 `add`,我们传递值为3的 `num`给它。函数 `add` 返回 `6` 作为 `value` 的值。
-#### Answer: D
+#### 答案: 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 log `counter.#number`, a SyntaxError gets thrown: we cannot acccess it outside the `Counter` class!
+在 ES2020 中,通过 `#` 我们可以给 class 添加私有变量。在 class 的外部我们无法获取该值。当我们尝试输出 `counter.#number`,语法错误被抛出:我们无法在 class `Counter` 外部获取它!
-#### Answer: B
+#### 答案: B
-In order to iterate over the `members` in each element in the `teams` array, we need to pass `teams[i].members` to the `getMembers` generator function. The generator function returns a generator object. In order to iterate over each element in this generator object, we need to use `yield*`.
+为了遍历 `teams` 数组中对象的属性 `members` 中的每一项,我们需要将 `teams[i].members` 传递给 Generator 函数 `getMembers`。Generator 函数返回一个 generator 对象。为了遍历这个 generator 对象中的每一项,我们需要使用 `yield*`.
-If we would've written `yield`, `return yield`, or `return`, the entire generator function would've gotten returned the first time we called the `next` method.
+如果我们没有写 `yield`,`return yield` 或者 `return`,整个 Generator 函数不会第一时间 return 当我们调用 `next` 方法.
-#### Answer: C
+#### 答案: C
-The `addHobby` function receives two arguments, `hobby` and `hobbies` with the default value of the `hobbies` array on the `person` object.
+函数 `addHobby` 接受两个参数,`hobby` 和有着对象 `person` 中数组 `hobbies` 默认值的 `hobbies`。
-First, we invoke the `addHobby` function, and pass `"running"` as the value for `hobby` and an empty array as the value for `hobbies`. Since we pass an empty array as the value for `y`, `"running"` gets added to this empty array.
+首相,我们调用函数 `addHobby`,并给 `hobby` 传递 `"running"` 以及给 `hobbies` 传递一个空数组。因为我们给 `hobbies` 传递了空数组,`"running"` 被添加到这个空数组。
-Then, we invoke the `addHobby` function, and pass `"dancing"` as the value for `hobby`. We didn't pass a value for `hobbies`, so it gets the default value, the `hobbies` property on the `person` object. We push the hobby `dancing` to the `person.hobbies` array.
+然后,我们调用函数 `addHobby`,并给 `hobby` 传递 `"dancing"`。我们不向 `hobbies` 传递值,因此它获取其默认值 —— 对象 `person` 的 属性 `hobbies`。我们向数组 `person.hobbies` push `dancing`。
-Last, we invoke the `addHobby` function, and pass `"bdaking"` as the value for `hobby`, and the `person.hobbies` array as the value for `hobbies`. We push the hobby `baking` to the `person.hobbies` array.
+最后,我们调用函数 `addHobby`,并向 `hobby` 传递 值 `"bdaking"`,并且向 `hobbies` 传递 `person.hobbies`。我们向数组 `person.hobbies` push `dancing`。
-After pushing `dancing` and `baking`, the value of `person.hobbies` is `["coding", "dancing", "baking"]`
+pushing `dancing` 和 `baking` 之后,`person.hobbies` 的值为 `["coding", "dancing", "baking"]`
-#### Answer: B
+#### 答案: B
-We create the variable `pet` which is an instance of the `Flamingo` class. When we instantiate this instance, the `constructor` on `Flamingo` gets called. First, `"I'm pink. 🌸"` gets logged, after which we call `super()`. `super()` calls the constructor of the parent class, `Bird`. THe constructor in `Bird` gets called, and logs `"I'm a bird. 🦢"`.
+我们创建了类 `Flamingo` 的实例 `pet`。当我们实例化这个实例,`Flamingo` 中的 `constructor` 被调用。首相,输出 `"I'm pink. 🌸"`, 之后我们调用`super()`。`super()` 调用父类的构造函数,`Bird`。`Bird` 的构造函数被调用,并输出 `"I'm a bird. 🦢"`。
-#### Answer: D
+#### 答案: D
-The `const` keyword simply means we cannot _redeclare_ the value of that variable, it's _read-only_. However, the value itself isn't immutable. The propeties on the `emojis` array can be modified, for example by pushing new values, splicing them, or setting the length of the array to 0.
+`const` 关键字意味着我们不能 _重定义_ 变量中的值,它 _仅可读_。而然,值本身不可修改。数组 `emojis` 中的值可被修改,如 push 新的值, 拼接,又或者将数组的长度设置为0。
-#### Answer: C
+#### 答案: 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 the `Object.values` of the `person` object if we want it to return the array `["Lydia Hallie", 21]`: `yield* Object.values(this)`.
+对象默认并不是可迭代的。如果迭代规则被定义,则一个对象是可迭代的(An iterable is an iterable if the iterator protocol is present)。我们可以通过添加迭代器symbol `[Symbol.iterator]` 来定义迭代规则,其返回一个 generator 对象,比如说构建一个 generator 函数 `*[Symbol.iterator]() {}`。如果我们想要返回数组 `["Lydia Hallie", 21]`: `yield* Object.values(this)`,这个 generator 函数一定要 yield 对象 `person` 的`Object.values`。
-Then, we create a new variable `counterTwo`, and set it equal to `counterOne`. Since objects interact by reference, we're just creating a new reference to the same spot in memory that `counterOne` points to. Since it has the same spot in memory, any changes made to the object that `counterTwo` has a reference to, also apply to `counterOne`. Currently, `counterTwo.count` is `2`.
+然后,我们创建一个新的变量 `counterTwo` 并将 `counterOne` 的引用地址赋值给它。因为对象受引用地址的影响,我们刚刚创建了一个新的对象,其引用地址和 `counterOne` 的等价。因此它们指向同一块内存地址,任何对其的副作用都会影响 `counterTwo`。现在 `counterTwo.count` 为 `2`。
-We invoke the `counterTwo.increment()`, which sets the `count` to `3`. Then, we log the count on `counterOne`, which logs `3`.
+我们调用 `counterTwo.increment()` 将 `count` 的值设为 `3`。然后,我们打印 `counterOne` 里的count,结果为 `3`。
@@ -4257,7 +4257,7 @@ We invoke the `counterTwo.increment()`, which sets the `count` to `3`. Then, we
---
-###### 133. What's the output?
+###### 133. 输出什么?
```javascript
const myPromise = Promise.resolve(Promise.resolve("Promise!"));
@@ -4284,27 +4284,27 @@ funcTwo();
- C: `Promise! Last line! Last line! Promise! Timeout! Timeout!`
- D: `Last line! Promise! Promise! Last line! Timeout! Timeout!`
-
Answer
+答案
Answer
+答案
Answer
+答案
Answer
+答案
Answer
+答案
Answer
+答案
Answer
+答案
Answer
+答案
Answer
+答案
Answer
+答案
Answer
+答案
Answer
+答案
Answer
+答案
From b02a4b33c4f9ee5f6168a84081fc3557058afff6 Mon Sep 17 00:00:00 2001
From: nobody <411298027@qq.com>
Date: Wed, 8 Jan 2020 19:21:44 +0800
Subject: [PATCH 105/618] fix: zh_CN question 52 typo problem
---
zh-CN/README-zh_CN.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/zh-CN/README-zh_CN.md b/zh-CN/README-zh_CN.md
index 443f5cd9..d2ecef8e 100644
--- a/zh-CN/README-zh_CN.md
+++ b/zh-CN/README-zh_CN.md
@@ -1553,7 +1553,7 @@ function sayHi() {
const data = greeting();
console.log("It worked!", data);
} catch (e) {
- console.log("Oh no an error!", e);
+ console.log("Oh no an error:", e);
}
}
From c8e8ec197a1a4fad45301d197e50d582f8e65f1f Mon Sep 17 00:00:00 2001
From: Askie Lin
+
+#### 答案: D
+
+在函式內部,我們首先透過 `var` 關鍵字宣告了 `name` 變數。這表示變數被提升了(記憶體位置在創建時期就被設置好了),直到程式執行到定義變數的那行之前,預設值都是 `undefined`。因為當我們印出 `name` 變數時,還沒有執行到定義變數的那一行程式碼,因此變數的值保持為 `undefined`。
+
+透過 `let` 和 `const` 關鍵字宣告的變數也會提升,但是和 `var` 不同,它們不會被初始化,在我們初始化之前是不能訪問它們的,這個行為被稱之為暫時性死區。當我們嘗試在初始化之前訪問它們時,JavaScript 將會抛出一個 `ReferenceError` 錯誤。
+
+
+
+#### 答案: C
+
+由於 JavaScript 的事件佇列(Event Queue),`setTimeout` 的 `callback` 會在*遍歷結束後*才執行。因為在第一個迴圈中,遍歷 `i` 是透過 `var` 關鍵字宣告的,`var` 屬於 Function scope(需要用 `function() {}` 才能將值鎖在作用域裡面)
+,所以 `for` 迴圈會造成變數外流,變成全域變數。在遍歷過程中,我們透過一元運算子 `++` 來遞增 `i` 的值。當 `setTimeout` 的 `callback` 執行的時候,`i` 的值等於 3。
+
+在第二個迴圈中,遍歷 `i` 是透過 `let` 關鍵字宣告的:透過 `let` 和 `const` 關鍵字的變數擁有塊級作用域(指的是任何在 `{}` 中的内容)。在每次的遍歷過程中,`i` 都有一個新值,每次遍歷時 `i` 值的作用域都在迴圈内。
+
+
+
+#### 答案: B
+
+注意 `diameter` 的值是一個一般的函式,但是 `perimeter` 的值是一個箭頭函式。
+
+對於箭頭函式,`this` 關鍵字指向的是它當前周圍作用域,這個行為和一般函式不同。這表示當我們呼叫 `perimeter` 時,`this` 不是指向 `shape` 物件,而是它的周圍作用域(在範例中是 `window`)。
+
+在 `window` 中沒有 `radius` 這個屬性,因此回傳 `undefined`。
+
+
+
+#### 答案: A
+
+一元運算子加號 `+`,嘗試將 boolean 布林值型別轉為 number 數字型別。`true` 轉為 number 數字型別的話為 `1`,`false` 爲 `0`。
+
+字串型別 `'Lydia'` 是一個真值,我們實際上問的題目是:「這個真值的相反會是什麼?」,真值的相反,將得到 `false`。
+
+
+
+#### 答案: A
+
+在 JavaScript 中,所有物件的 keys 都是字串型別(除非是 Symbol 物件)。儘管我們或許不會定義它們為字串,但它們在底層總會被轉換爲字串。
+
+當我們使用中括號時([]),JavaScript 會解譯語句。它首先看到中括號的第一個開始處 `[` 並繼續往下直到找到結束的中括號 `]`。只有這樣,它才能計算語句的值。
+
+`mouse[bird.size]`:首先計算 `bird.size`,這會得到 `small`。`mouse["small"]` 得到 `true`。
+
+使用點的語法的時候,上面這一切都不會發生。`mouse` 沒有 `bird` 這個 key,這就表示 `mouse.bird` 是 `undefined`。然後當我們使用點語法 `mouse.bird.size` 時,因為 `mouse.bird` 是 `undefined`,這也就變成了我們實際的語句是 `undefined.size`,而此行為是無效的,並會抛出一個錯誤 `Cannot read property "size" of undefined`。
+
+
+
+#### 答案: A
+
+在 JavaScript 中,當設定兩個物件彼此相等時,它們會經由*引用(reference)*進行互動。
+
+首先,變數 `c` 的值是一個物件。接下来,我們將 `d` 分配了一個和 `c` 物件相同的引用。
+
+
+
+#### 答案: C
+
+`new Number()` 是一個内建的函式建構子。它雖然看起來像是個 number,但它實際上並非真正的 number:它有一堆額外的功能,而且它是一個物件。
+
+當我們使用 `==` 運算子的時候,它只會檢查兩者是否擁有有相同的*值*。因為它們的值都是 `3`,因此回傳 `true`。
+
+然後,當我們使用 `===` 運算子時,兩者的值以及*型別*都必須是相同的。`new Number()` 是一個物件型別而不是 number(一般型別),因此回傳 `false`。
+
+
+
+#### 答案: D
+
+`colorChange` 是一個靜態方法。靜態方法被設計爲只能被創造它們的建構子使用(也就是 `Chameleon` 中的 `constructor` ),並且不能傳遞給實例。因為 `freddie` 是一個實例,而靜態方法不能被實例使用,因此會抛出 `TypeError` 錯誤。
+
+
+
+#### 答案: A
+
+程式碼印出了一個物件,這是因為我們在全域物件上創建了一個空物件!當我們將 `greeting` 寫錯成 `greetign` 時,JS 解譯器實際上將它視爲 `global.greetign = {}` (或者在瀏覽器中視為 `window.greetign = {}`)。
+
+為了避免這個狀況,我們可以使用 `"use strict"`,來確保當你宣告變數時,必須賦值。
+
+
+
+#### 答案: A
+
+這在 JavaScript 中是可以的,因爲函式是物件!(除了基本型別之外其他都是物件)
+
+函式是一個特殊的物件,函式是一個擁有屬性的物件,屬性也可被使用、呼叫的。
+
+
+
+#### 答案: A
+
+你可以為一般物件新增屬性,但建構函式(constructor)無法透過上面的方式來新增屬性。若你想一次性在所有實例上都新增某個屬性,要使用原型的方式。因此本例中,使用以下的方式:
+
+```js
+Person.prototype.getFullName = function () {
+ return `${this.firstName} ${this.lastName}`;
+}
+```
+
+這樣一來, `member.getFullName()` 就能有效。這樣做有什麼好處?假設我們真的能如題將這個方法新增到建構函式本身,並不是每個 `Person` 實例都需要這個方法,但每個實例卻仍然擁有該属性,代表著這將佔據每個實例的記憶體,造成大量的記憶體空間因此浪費掉了。相反,如果我們只將它新增在原型中,那麼它只存在記憶體中的一個位置,而所有實例都可以使用它!
+
+
+
+#### 答案: A
+
+對 `sarah` 而言,我們沒有使用 `new` 關鍵字。當使用 `new` 時,`this` 引用我們建立的空物件。沒有使用 `new` 的時候,`this` 引用的是**全域物件**(global object)。
+
+我們會說 `this.firstName` 等於 `"Sarah"`,而 `this.lastName` 等於 `"Smith"`。實際上我們做的是,定義了 `global.firstName = 'Sarah'` 和 `global.lastName = 'Smith'`。而 `sarah` 本身是 `undefined`,因為 `Person` 這個函式本身並沒有回傳值。
+
+
+
+#### 答案: D
+
+先捕獲,再冒泡!在**捕獲**(capturing)階段中,事件從祖先元素向下傳播到目標元素。當事件到達**目標**(target)元素後,**冒泡**(bubbling)才開始。
+
+
+
+#### 答案: B
+
+除了**基本物件**(base object,使用 `new` 關鍵字建立的物件)以外,所有物件都有原型。基本物件可以使用一些方法和属性,比如 `.toString`,這就是為什麼你可以使用內建的 JavaScript 方法!所有這類在原型上的方法都是可被使用的。雖然 JavaScript 不能直接在物件上找到這些方法,但 JavaScript 會沿著原型鍊找到它們,以便使用。
+
+
+
+#### 答案: C
+
+JavaScript 是一個**動態型別語言**:我們不指定變數的型別。值可以在你不知道的情况下自動轉換成另一種型別,稱為**隱含式轉型**(implicit type coercion)。**Coercion** 是指將一種型別轉換成另一種型別。
+
+在此範例中,JavaScript 將數字型別 `1` 轉換為字串型別,以便函式能回傳一個有意義的值。數字型別(`1`)和字串型別(`'2'`)相加的時候,該數字會被視為字串。我們也能連接不同的字串,比如 `"Hello" + "World"`,而此例是 `"1" + "2"`,它將回傳 `"12"`。
+
+
+
JavaScript 進階題目列表
+
+ ---
+
+ 我會在我的 [Instagram](https://www.instagram.com/theavocoder) 上發布關於 JavaScript 的複選題,同時也會更新到這個 Repo 當中。更新日期: 2019 年 12 月 24 日
+
+ 從基礎到進階程度,測試你有多了解 JavaScript,不僅更新你的知識,更能幫助你的 coding 面試!
+:muscle: :rocket: 我每週都會在這個 Repo 中更新新的題目。
+
+答案在題目下方的摺疊區塊,點擊即可展開答案。祝你好運 :heart:
+
+ 歡迎和我聯繫!😊
+ Instagram || Twitter || LinkedIn || Blog
+ 答案
+答案
+答案
+答案
+答案
+答案
+
+
+因此當我們改變其中一個物件時,其實是改變了所有的物件的同一個引用的內容。
+
+
答案
+答案
+答案
+答案
+答案
+答案
+答案
+
+
+
答案
+答案
+
+ +#### Đáp án: D + +Có thể tưởng tượng đơn giản cách promise thực thi như sau: _bây giờ tôi sẽ để tạm nó sang một bên vì nó tính toán mất thời gian. Chỉ khi nào nó được hoàn thành (resolved) hay bị hủy bỏ (rejected) hay khi call stack trở nên rỗng thì tôi sẽ lấy giá trị trả về ra._ + +Dù chúng ta có thể sử dụng giá trị thu được bằng cú pháp `.then`, hoặc sử dụng cặp cú pháp `await/async`, nhưng, cách chúng hoạt động là khác nhau. + +Trong `firstFunction`, chúng ta đưa promise qua một bên chờ cho nó tính toán xong, và vẫn tiếp tục chạy những code tiếp sau đó, theo đó `console.log('second')` sẽ được chạy. Sau đó promise được hoàn thành trả về giá trị `I have resolved`, giá trị này sẽ được log ra khi call stack trở nên rỗng. + +Với từ khóa `await` trong `secondFunction`, ta đã tạm dừng một hàm bất đồng bộ cho tới khi chúng trả về giá trị, sau đó ta mới đi tiếp đến các câu lệnh tiếp theo. + +Do đó nó sẽ chờ cho tới khi `myPromise` được hoàn thành và trả về giá trị `I have resolved`, sau đó chúng ta sẽ chạy tiếp câu lệnh tiếp theo in ra `second`. + +
++ +#### Đáp án: C + +Phép toán `+` không chỉ dùng để cộng các số, mà nó còn dùng để nối chuỗi nữa. Mỗi khi Javascript engine gặp một giá trị trong phép toán không phải dạng số, nó sẽ chuyển các số trong phép toán đó sang dạng chuỗi. + +Phép toán đầu tiên item là một số `1`, nên `1 + 2` trả về 3. + +Ở phép toán thứ hai, item là một chuỗi `"Lydia"`. trong khi đó `2` là một số, nên `2` sẽ bị chuyển sang dạng chuỗi, sau khi nối vào ta có chuỗi `"Lydia2"`. + +Ở phép toán thứ ba, `{ name: "Lydia" }` là một object. Tuy nhiên dù có là object hay gì đi nữa thì nó cũng sẽ bị chuyển sang dạng chuỗi. Đối với object thì khi chuyển sang dạng chuỗi nó sẽ trở thành `"[object Object]"`. `"[object Object]"` nối với `"2"` trở thành `"[object Object]2"`. + +
++ +#### Đáp án: C + +Ta có thể truyền vào giá trị bất kì cho `Promise.resolve`, dù có là promise hay không promise. Bản thân nó sẽ là một hàm trả về một promise với giá trị đã được resolved. + +Trong trường hợp này ta đưa vào giá trị `5`. Nó sẽ trả về một resolved promise với giá trị `5`. + +
++ +#### Đáp án: B + +Object sẽ được truyền vào hàm theo reference. Khi chúng ta nói so sánh strict equal (`===`), nghĩa là ta đang so sánh các reference của chúng. + +We set the default value for `person2` equal to the `person` object, and passed the `person` object as the value for `person1`. +Ta set giá trị mặc định của `person2` là object `person`, và đưa object `person` vào làm giá trị cho đối số `person1`. + +Điều đó có nghĩa là chúng cùng trỏ đến một object trong bộ nhớ, do đó chúng bằng nhau, và `They are the same!` được in ra. + +
++ +#### Đáp án: D + +Trong Javascript ta có hai cách để truy cập thuộc tính của một object: sử dụng ngoặc vuông `[]`, hoặc sử dụng chấm `.`. Trong trương hợp này chúng ta sử dụng chấm (`colorConfig.colors`) thay cho ngoặc vuông (`colorConfig["colors"]`). + +Với cách sử dụng chấm, Javascript sẽ tìm kiếm một thuộc tính có tên chính xác như tên ta đưa vào. Trong trường hợp này nó là thuộc tính `colors` trong object `colorConfig` Tuy nhiên trong object này không có thuộc tính nào tên là `colors`, nên nó sẽ trả về `undefined`. Sau đó chúng ta cố truy cậ vào thuộc tính 1 của nó bằng cách gọi `[1]`. Chúng ta không thể làm như vậy trên giá trị `undefined`, nên nó sẽ trả về `TypeError`: `Cannot read property '1' of undefined`. + +Javascript thông dịch theo câu lệnh. Khi ta sử dụng ngoặc vuông, Nnó sẽ tìm mở ngoặc đầu tiên `[` và tiếp tục cho tới khi gặp đóng ngoặc tương ứng `]`. Chỉ khi đó nó mới đánh giá câu lệnh. Nếu chúng ta sử dụng cú pháp `colorConfig[colors[1]]`, nó sẽ trả về giá trị của thuộc tính `red` trong object `colorConfig`. + +
++ +#### Đáp án: A + +Về cơ bản, emoji vẫn là các ký tự unicode mà thôi. Mã unicode cho hình trái tim là `"U+2764 U+FE0F"`. Chúng luôn luôn là một, nên phép toán đơn giản trả về `true`. + +
++ +#### Đáp án: D + +Với `splice`, ta thay đổi mảng gốc bằng cách thêm sửa xóa các phần tử. Trong trường hợp này ta xóa 2 phần tử kể từ index 1 (ta xóa `'🥑'` và `'😍'`) và thêm vào ✨ emoji. + +`map`, `filter` và `slice` trả về một mảng mới, `find` trả về một phần tử, và `reduce` trả về giá trị tích lũy. + +
++ +#### Đáp án: A + +Trong Javascript tất cả các kiểu cơ bản (mọi thứ không phải object) đều tương tác bằng _giá trị_. Chúng ta set giá trị của thuộc tính `favoriteFood` trong object `info` bằng ký tự bánh pizza, `'🍕'`. Chuỗi trong javascript là một kiểu cơ bản, nên nó cũng sẽ tương tác bằng giá trị. + +Bản thân mảng `food` không hề thay đổi, do giá trị của `favoriteFood` chỉ là một bản _copy_ của giá trị đầu tiên trong mảng mà thôi, và không hề trỏ tới reference của `food[0]`. Do đó khi ghi ra, giá trị của mảng vẫn là giá trị ban đầu, `['🍕', '🍫', '🥑', '🍔']`. + +
++ +#### Đáp án: A + +Với phương thức `JSON.parse()`, ta sẽ parse một chuỗi JSON thành một giá trị JavaScript. + +Ví dụ: + +```javascript +// Chuyển một số thành một chuỗi JSON, sau đó parse chuỗi JSON đó để trả về một giá trị JavaScript: +const jsonNumber = JSON.stringify(4) // '4' +JSON.parse(jsonNumber) // 4 + +// Chuyển một mảng thành một chuỗi JSON, sau đó parse chuỗi JSON để trả về một giá trị JavaScript: +const jsonArray = JSON.stringify([1, 2, 3]) // '[1, 2, 3]' +JSON.parse(jsonArray) // [1, 2, 3] + +// Chuyển một object thành một chuỗi JSON, sau đó parse chuỗi JSON để trả về một giá trị JavaScript: +const jsonArray = JSON.stringify({ name: "Lydia" }) // '{"name":"Lydia"}' +JSON.parse(jsonArray) // { name: 'Lydia' } +``` + +
++ +#### Đáp án: D + +Mỗi hàm sẽ có một _context thực thi_ (hay _scope_) của riêng nó. Hàm `getName` đầu tiên sẽ tìm trong context của nó (scope) để tìm xem có biến nào tên là `name` hay không. Trong trường hợp này, hàm `getName` có biến `name` được khai báo với từ khóa `let`, giá trị là `'Sarah'`. + +Một biến được khai báo với từ khóa `let` (hoặc `const`) sẽ được `hoisted`, nhưng không giống như `var`, nó sẽ không được khởi tạo. Nó sẽ không thể truy cập được trước dòng ta khai báo (initialize). Nó được gọi là "temporal dead zone". Khi ta cố truy cập một biến trước khi nó được khai báo, JavaScript sẽ throw ra `ReferenceError`. + +Nếu ta không khai báo biến `name` bên trong hàm `getName`, thì Javascript engine sẽ tiếp tục tìm kiếm trong _scope chain_. Nó sẽ tìm thấy ở scope phía ngoài một biến `name` với giá trị là `Lydia`. Trong trường hợp này nó sẽ log ra `Lydia`. + +```javascript +let name = 'Lydia' + +function getName() { + console.log(name) +} + +getName() // Lydia +``` + +
++ +#### Đáp án: C + +With the `yield` keyword, we `yield` values in a generator function. With the `yield*` keyword, we can yield values from another generator function, or iterable object (for example an array). + +In `generatorOne`, we yield the entire array `['a', 'b', 'c']` using the `yield` keyword. The value of `value` property on the object returned by the `next` method on `one` (`one.next().value`) is equal to the entire array `['a', 'b', 'c']`. + +```javascript +console.log(one.next().value) // ['a', 'b', 'c'] +console.log(one.next().value) // undefined +``` + +In `generatorTwo`, we use the `yield*` keyword. This means that the first yielded value of `two`, is equal to the first yielded value in the iterator. The iterator is the array `['a', 'b', 'c']`. The first yielded value is `a`, so the first time we call `two.next().value`, `a` is returned. + +```javascript +console.log(two.next().value) // 'a' +console.log(two.next().value) // 'b' +console.log(two.next().value) // 'c' +console.log(two.next().value) // undefined +``` + +
++ +#### Đáp án: 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 the `x => x` arrow function. `x` is equal to `'I love'`, which gets returned. This results in `I love to program`. + +
++ +#### Đáp án: C + +Normally when we set objects equal to `null`, those objects get _garbage collected_ as there is no reference anymore to that object. However, since the callback function within `setInterval` is an arrow function (thus bound to the `config` object), the callback function still holds a reference to the `config` object. As long as there is a reference, the object won't get garbage collected. Since it's not garbage collected, the `setInterval` callback function will still get invoked every 1000ms (1s). + +
++ +#### Đáp án: B + +When adding a key/value pair using the `set` method, the key will be the value of the first argument passed to the `set` function, and the value will be the second argument passed to the `set` function. The key is the _function_ `() => '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 the `get` method. Object interact by _reference_. 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. + +
++ +#### Đáp án: C + +Both the `changeAge` and `changeAgeAndName` functions have a default parameter, namely a _newly_ created object `{ ...person }`. This object has copies of all the key/values in the `person` object. + +First, we invoke the `changeAge` function and pass the `person` object as its argument. This function increases the value of the `age` property by 1. `person` is now `{ name: "Lydia", age: 22 }`. + +Then, we invoke the `changeAgeAndName` function, however we don't pass a parameter. Instead, the value of `x` is equal to a _new_ object: `{ ...person }`. Since it's a new object, it doesn't affect the values of the properties on the `person` object. `person` is still equal to `{ name: "Lydia", age: 22 }`. + +
++ +#### Đáp án: C + +With the spread operator `...`, we can _spread_ iterables to individual elements. The `sumValues` function receives three arguments: `x`, `y` and `z`. `...[1, 2, 3]` will result in `1, 2, 3`, which we pass to the `sumValues` function. + +
++ +#### Đáp án: B + +With the `+=` operand, we're incrementing the value of `num` by `1`. `num` had the initial value `1`, so `1 + 1` is `2`. The item on the second index in the `list` array is 🥰, `console.log(list[2])` prints 🥰. + +
++ +#### Đáp án: 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 an `undefined` or `null` value (_nullish_), the expression short-circuits and returns `undefined`. + +`person.pet?.name`: `person` has a property named `pet`: `person.pet` is not nullish. It has a property called `name`, and returns `Mara`. +`person.pet?.family?.name`: `person` has a property named `pet`: `person.pet` is not nullish. `pet` does _not_ have a property called `family`, `person.pet.family` is nullish. The expression returns `undefined`. +`person.getFullName?.()`: `person` has a property named `getFullName`: `person.getFullName()` is not nullish and can get invoked, which returns `Lydia Hallie`. +`member.getLastName?.()`: `member` is not defined: `member.getLastName()` is nullish. The expression returns `undefined`. + +
++ +#### Đáp án: B + +We passed the condition `groceries.indexOf("banana")` to the if-statement. `groceries.indexOf("banana")` returns `0`, which is a falsy value. Since the condition in the if-statement is falsy, the code in the `else` block runs, and `We don't have to buy bananas!` gets logged. + +
++ +#### Đáp án: D + +The `language` method is a `setter`. Setters don't hold an actual value, their purpose is to _modify_ properties. When calling a `setter` method, `undefined` gets returned. + +
++ +#### Đáp án: C + +`typeof name` returns `"string"`. The string `"string"` is a truthy value, so `!typeof name` returns the boolean value `false`. `false === "object"` and `false === "string"` both return`false`. + +(If we wanted to check whether the type was (un)equal to a certain type, we should've written `!==` instead of `!typeof`) + +
++ +#### Đáp án: A + +The `add` function returns an arrow function, which returns an arrow function, which returns an arrow function (still with me?). The first function receives an argument `x` with the value of `4`. We invoke the second function, which receives an argument `y` with the value `5`. Then we invoke the third function, which receives an argument `z` with the value `6`. When we're trying to access the value `x`, `y` and `z` within the last arrow function, the JS engine goes up the scope chain in order to find the values for `x` and `y` accordingly. This returns `4` `5` `6`. + +
++ +#### Đáp án: C + +The generator function `range` returns an async object with promises for each item in the range we pass: `Promise{1}`, `Promise{2}`, `Promise{3}`. We set the variable `gen` equal to the async object, after which we loop over it using a `for await ... of` loop. We set the variable `item` equal to the returned Promise values: first `Promise{1}`, then `Promise{2}`, then `Promise{3}`. Since we're _awaiting_ the value of `item`, the resolved promsie, the resolved _values_ of the promises get returned: `1`, `2`, then `3`. + +
++ +#### Đáp án: D + +`myFunc` expects an object with properties `x`, `y` and `z` as its argument. Since we're only passing three separate numeric values (1, 2, 3) instead of one object with properties `x`, `y` and `z` ({x: 1, y: 2, z: 3}), `x`, `y` and `z` have their default value of `undefined`. + +
++ +#### Đáp án: B + +With the `Intl.NumberFormat` method, we can format numeric values to any locale. We format the numeric value `130` to the `en-US` locale as a `unit` in `mile-per-hour`, which results in `130 mph`. The numeric value `300` to the `en-US` locale as a `currentcy` in `USD` results in `$300.00`. + +
++ +#### Đáp án: 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 "💀" to `spookyItems[3]`. This means that we're modifying the `spookyItems` array, we're adding the "💀" to it. When logging `spookyItems`, `["👻", "🎃", "🕸", "💀"]` gets logged. + +
++ +#### Đáp án: C + +With the `Number.isNaN` method, you can check if the value you pass is a _numeric value_ and equal to `NaN`. `name` is not a numeric value, so `Number.isNaN(name)` returns `false`. `age` is a numeric value, but is not equal to `NaN`, so `Number.isNaN(age)` returns `false`. + +With the `isNaN` method, you can check if the value you pass is not a number. `name` is not a number, so `isNaN(name)` returns true. `age` is a number, so `isNaN(age)` returns `false`. + +
++ +#### Đáp án: D + +Variables declared with the `const` keyword are not referencable before their initialization: this is called the _temporal dead zone_. In the `getInfo` function, the variable `randomValue` is scoped in the functional scope of `getInfo`. On the line where we want to log the value of `typeof randomValue`, the variable `randomValue` isn't initialized yet: a `ReferenceError` gets thrown! The engine didn't go down the scope chain since we declared the variable `randomValue` in the `getInfo` function. + +
++ +#### Đáp án: C + +In the `try` block, we're logging the awaited value of the `myPromise` variable: `"Woah some cool data"`. Since no errors were thrown in the `try` block, the code in the `catch` block doesn't run. The code in the `finally` block _always_ runs, `"Oh finally!"` gets logged. + +
++ +#### Đáp án: B + +With the `flat` 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 value `1` (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 `['🥑', '✨', '✨', ['🍕', '🍕']]`. + +
+
+
+#### Đáp án: D
+
+`counterOne` is an instance of the `Counter` class. The counter class contains a `count` property on its constructor, and an `increment` method. First, we invoked the `increment` method twice by calling `counterOne.increment()`. Currently, `counterOne.count` is `2`.
+
+
+
+Then, we create a new variable `counterTwo`, and set it equal to `counterOne`. Since objects interact by reference, we're just creating a new reference to the same spot in memory that `counterOne` points to. Since it has the same spot in memory, any changes made to the object that `counterTwo` has a reference to, also apply to `counterOne`. Currently, `counterTwo.count` is `2`.
+
+We invoke the `counterTwo.increment()`, which sets the `count` to `3`. Then, we log the count on `counterOne`, which logs `3`.
+
+
+
+
+ +#### Đáp án: D + +First, we invoke `funcOne`. On the first line of `funcOne`, we call the `myPromise` promise, which is an _asynchronous_ operation. While the engine is busy completing the promise, it keeps on running the function `funcOne`. The next line is the _asynchronous_ `setTimeout` function, from which the callback is sent to the Web API. (see my article on the event loop here.) + +Both the promise and the timeout are asynchronous operations, the function keeps on running while it's busy completing the promise and handling the `setTimeout` callback. This means that `Last line!` gets logged first, since this is not an asynchonous operation. This is the last line of `funcOne`, the promise resolved, and `Promise!` gets logged. However, since we're invoking `funcTwo()`, the call stack isn't empty, and the callback of the `setTimeout` function cannot get added to the callstack yet. + +In `funcTwo` we're, first _awaiting_ the myPromise promise. With the `await` keyword, we pause the execution of the function until the promise has resolved (or rejected). Then, we log the awaited value of `res` (since the promise itself returns a promise). This logs `Promise!`. + +The next line is the _asynchronous_ `setTimeout` function, from which the callback is sent to the Web API. + +We get to the last line of `funcTwo`, which logs `Last line!` to the console. Now, since `funcTwo` popped off the call stack, the call stack is empty. The callbacks waiting in the queue (`() => console.log("Timeout!")` from `funcOne`, and `() => console.log("Timeout!")` from `funcTwo`) get added to the call stack one by one. The first callback logs `Timeout!`, and gets popped off the stack. Then, the second callback logs `Timeout!`, and gets popped off the stack. This logs `Last line! Promise! Promise! Last line! Timeout! Timeout!` + +
++ +#### Đáp án: C + +With the asterisk `*`, we import all exported values from that file, both default and named. If we had the following file: + +```javascript +// info.js +export const name = "Lydia"; +export const age = 21; +export default "I love JavaScript"; + +// index.js +import * as info from "./info"; +console.log(info); +``` + +The following would get logged: + +```javascript +{ + default: "I love JavaScript", + name: "Lydia", + age: 21 +} +``` + +For the `sum` example, it means that the imported value `sum` looks like this: + +```javascript +{ default: function sum(x) { return x + x } } +``` + +We can invoke this function, by calling `sum.default` + +
++ +#### Đáp án: C + +With a Proxy object, we can add custom behavior to an object that we pass to it as the second argument. In tis case, we pass the `handler` object which contained to properties: `set` and `get`. `set` gets invoked whenever we _set_ property values, `get` gets invoked whenever we _get_ (access) property values. + +The first argument is an empty object `{}`, which is the value of `person`. To this object, the custom behavior specified in the `handler` object gets added. If we add a property to the `person` object, `set` will get invoked. If we access a property on the `person` object, `get` gets invoked. + +First, we added a new property `name` 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, the `get` property on the handler object got invoked. `"Accessed a property!"` gets logged. + +
++ +#### Đáp án: A + +With `Object.seal` we can prevent new properies from being _added_, or existing properties to be _removed_. + +However, you can still modify the value of existing properties. + +
++ +#### Đáp án: C + +The `Object.freeze` method _freezes_ an object. No properties can be added, modified, or removed. + +However, it only _shallowly_ freezes the object, meaning that only _direct_ properties on the object are frozen. If the property is another object, like `address` in this case, the properties on that object aren't frozen, and can be modified. + +
++ +#### Đáp án: C + +The `Object.freeze` method _freezes_ an object. No properties can be added, modified, or removed. + +However, it only _shallowly_ freezes the object, meaning that only _direct_ properties on the object are frozen. If the property is another object, like `address` in this case, the properties on that object aren't frozen, and can be modified. + +
++ +#### Đáp án: A + +First, we invoked `myFunc()` without passing any arguments. Since we didn't pass arguments, `num` and `value` got their default values: num is `2`, and `value` the returned value of the function `add`. To the `add` function, we pass `num` as an argument, which had the value of `2`. `add` returns `4`, which is the value of `value`. + +Then, we invoked `myFunc(3)` and passed the value `3` as the value for the argument `num`. We didn't pass an argument for `value`. Since we didn't pass a value for the `value` argument, it got the default value: the returned value of the `add` function. To `add`, we pass `num`, which has the value of `3`. `add` returns `6`, which is the value of `value`. + +
++ +#### Đáp án: 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 log `counter.#number`, a SyntaxError gets thrown: we cannot acccess it outside the `Counter` class! + +
++ +#### Đáp án: B + +In order to iterate over the `members` in each element in the `teams` array, we need to pass `teams[i].members` to the `getMembers` generator function. The generator function returns a generator object. In order to iterate over each element in this generator object, we need to use `yield*`. + +If we would've written `yield`, `return yield`, or `return`, the entire generator function would've gotten returned the first time we called the `next` method. + +
++ +#### Đáp án: C + +The `addHobby` function receives two arguments, `hobby` and `hobbies` with the default value of the `hobbies` array on the `person` object. + +First, we invoke the `addHobby` function, and pass `"running"` as the value for `hobby` and an empty array as the value for `hobbies`. Since we pass an empty array as the value for `y`, `"running"` gets added to this empty array. + +Then, we invoke the `addHobby` function, and pass `"dancing"` as the value for `hobby`. We didn't pass a value for `hobbies`, so it gets the default value, the `hobbies` property on the `person` object. We push the hobby `dancing` to the `person.hobbies` array. + +Last, we invoke the `addHobby` function, and pass `"bdaking"` as the value for `hobby`, and the `person.hobbies` array as the value for `hobbies`. We push the hobby `baking` to the `person.hobbies` array. + +After pushing `dancing` and `baking`, the value of `person.hobbies` is `["coding", "dancing", "baking"]` + +
++ +#### Đáp án: B + +We create the variable `pet` which is an instance of the `Flamingo` class. When we instantiate this instance, the `constructor` on `Flamingo` gets called. First, `"I'm pink. 🌸"` gets logged, after which we call `super()`. `super()` calls the constructor of the parent class, `Bird`. THe constructor in `Bird` gets called, and logs `"I'm a bird. 🦢"`. + +
++ +#### Đáp án: D + +The `const` keyword simply means we cannot _redeclare_ the value of that variable, it's _read-only_. However, the value itself isn't immutable. The propeties on the `emojis` array can be modified, for example by pushing new values, splicing them, or setting the length of the array to 0. + +
++ +#### Đáp án: 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 the `Object.values` of the `person` object if we want it to return the array `["Lydia Hallie", 21]`: `yield* Object.values(this)`. + +
+#### Đáp án: C -Normally when we set objects equal to `null`, those objects get _garbage collected_ as there is no reference anymore to that object. However, since the callback function within `setInterval` is an arrow function (thus bound to the `config` object), the callback function still holds a reference to the `config` object. As long as there is a reference, the object won't get garbage collected. Since it's not garbage collected, the `setInterval` callback function will still get invoked every 1000ms (1s). +Thông thường khi ta set một object bằng `null`, thì object này sẽ được bộ dọn rác dọn đi do không còn gì reference đến nó nữa (_garbage collected_). Tuy nhiên, do callback trong `setInterval` là một arrow function (do đó nó sẽ gắn với object `config`), nên callback này vẫn sẽ giữ reference đến object `config`. Vì vẫn còn giữ reference, nên object sẽ không bị dọn đi. Do đó nó vẫn sẽ được gọi sau mỗi 1000ms (tức 1 giây).
#### Đáp án: B -When adding a key/value pair using the `set` method, the key will be the value of the first argument passed to the `set` function, and the value will be the second argument passed to the `set` function. The key is the _function_ `() => 'greeting'` in this case, and the value `'Hello world'`. `myMap` is now `{ () => 'greeting' => 'Hello world!' }`. +Khi ta thêm vào một cặp key/value với từ khóa `set`, key sẽ là đối số đầu tiên đưa vào trong hàm `set` function, và value sẽ là đối số thứ hai.Trong trường hơp này key chính là _hàm_ `() => 'greeting'`, value là `'Hello world'`. `myMap` trở thành `{ () => '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 the `get` method. Object interact by _reference_. 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. +1 sai, vì key là `() => 'greeting'` chứ không phải là `'greeting'`. +3 sai, vì khi chúng ta đưa một hàm vào làm đối số trong phương thức `get`, nó sẽ được đưa vào dưới dạng _reference_. Function vốn là object, do đó 2 hàm sẽ không bao giờ là `strictly equal`, mặc dù chúng có trông giống nhau đi chăng nữa thì chúng vẫn trỏ đến các vùng nhớ khác nhau.
+ +* [English](../en-EN/README.md) +* [العربية](../ar-AR/README_AR.md) +* [اللغة العامية - Egyptian Arabic](../ar-EG/README_ar-EG.md) +* [Bosanski](../bs-BS/README-bs_BS.md) +* [Deutsch](../de-DE/README.md) +* [Español](../es-ES/README-ES.md) +* [Français](../fr-FR/README_fr-FR.md) +* [日本語](../ja-JA/README-ja_JA.md) +* [한국어](../ko-KR/README-ko_KR.md) +* [Nederlands](./nl-NL/README.md) +* [Português Brasil](../pt-BR/README_pt_BR.md) +* [Русский](../ru-RU/README.md) +* [Українська мова](../ua-UA/README-ua_UA.md) +* [Tiếng Việt](../vi-VI/README-vi.md) +* [中文版本](../zh-CN/README-zh_CN.md) +* [Türkçe](../tr-TR/README-tr_TR.md) +* [ไทย](../th-TH/README-th_TH.md) + +
++ +#### Answer: D + +Within the function, we first declare the `name` variable with the `var` keyword. This means that the variable gets hoisted (memory space is set up during the creation phase) with the default value of `undefined`, 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 the `name` variable, so it still holds the value of `undefined`. + +Variables with the `let` keyword (and `const`) are hoisted, but unlike `var`, don't get initialized. 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 a `ReferenceError`. + +
++ +#### Answer: C + +Because of the event queue in JavaScript, the `setTimeout` callback function is called _after_ the loop has been executed. Since the variable `i` in the first loop was declared using the `var` keyword, this value was global. During the loop, we incremented the value of `i` by `1` each time, using the unary operator `++`. By the time the `setTimeout` callback function was invoked, `i` was equal to `3` in the first example. + +In the second loop, the variable `i` was declared using the `let` keyword: variables declared with the `let` (and `const`) 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. + +
++ +#### Answer: B + +Note that the value of `diameter` is a regular function, whereas the value of `perimeter` is an arrow function. + +With arrow functions, the `this` keyword refers to its current surrounding scope, unlike regular functions! This means that when we call `perimeter`, it doesn't refer to the shape object, but to its surrounding scope (window for example). + +There is no value `radius` on that object, which returns `undefined`. + +
++ +#### Answer: A + +The unary plus tries to convert an operand to a number. `true` is `1`, and `false` is `0`. + +The string `'Lydia'` is a truthy value. What we're actually asking, is "is this truthy value falsy?". This returns `false`. + +
++ +#### Answer: A + +In JavaScript, all object keys are strings (unless it's a Symbol). Even though we might not _type_ 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 evaluates `bird.size`, which is `"small"`. `mouse["small"]` returns `true` + +However, with dot notation, this doesn't happen. `mouse` does not have a key called `bird`, which means that `mouse.bird` is `undefined`. Then, we ask for the `size` using dot notation: `mouse.bird.size`. Since `mouse.bird` is `undefined`, we're actually asking `undefined.size`. This isn't valid, and will throw an error similar to `Cannot read property "size" of undefined`. + +
+
+
+#### Answer: A
+
+In JavaScript, all objects interact by _reference_ when setting them equal to each other.
+
+First, variable `c` holds a value to an object. Later, we assign `d` with the same reference that `c` has to the object.
+
+
+
+When you change one object, you change all of them.
+
+
+ +#### 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, it only checks whether it has the same _value_. They both have the value of `3`, so it returns `true`. + +However, when we use the `===` operator, both value _and_ type should be the same. It's not: `new Number()` is not a number, it's an **object**. Both return `false.` + +
++ +#### Answer: D + +The `colorChange` 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. Since `freddie` is a child, the function is not passed down, and not available on the `freddie` instance: a `TypeError` is thrown. + +
++ +#### Answer: A + +It logs the object, because we just created an empty object on the global object! When we mistyped `greeting` as `greetign`, the JS interpreter actually saw this as `global.greetign = {}` (or `window.greetign = {}` in a browser). + +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. + +
++ +#### 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. + +
++ +#### Answer: A + +You can't add properties to a constructor like you can with regular objects. If you want to add a feature to all objects at once, you have to use the prototype instead. So in this case, + +```js +Person.prototype.getFullName = function() { + return `${this.firstName} ${this.lastName}`; +}; +``` + +would have made `member.getFullName()` work. Why is this beneficial? Say that we added this method to the constructor itself. Maybe not every `Person` instance needed this method. This would waste a lot of memory space, since they would still have that property, which takes of memory space for each instance. Instead, if we only add it to the prototype, we just have it at one spot in memory, yet they all have access to it! + +
++ +#### Answer: A + +For `sarah`, we didn't use the `new` keyword. When using `new`, it refers to the new empty object we create. However, if you don't add `new` it refers to the **global object**! + +We said that `this.firstName` equals `"Sarah"` and `this.lastName` equals `"Smith"`. What we actually did, is defining `global.firstName = 'Sarah'` and `global.lastName = 'Smith'`. `sarah` itself is left `undefined`, since we don't return a value from the `Person` function. + +
+
+
+#### Answer: D
+
+During the **capturing** phase, the event goes through the ancestor elements down to the target element. It then reaches the **target** element, and **bubbling** begins.
+
+
+
+
+ +#### Answer: B + +All objects have prototypes, except for the **base object**. The base object is the object created by the user, or an object that is created using the `new` 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. + +
++ +#### Answer: C + +JavaScript is a **dynamically typed language**: we don't specify what types certain variables are. Values can automatically be converted into another type without you knowing, which is called _implicit type coercion_. **Coercion** is converting from one type into another. + +In this example, JavaScript converts the number `1` 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"`. + +
++ +#### Answer: C + +The **postfix** unary operator `++`: + +1. Returns the value (this returns `0`) +2. Increments the value (number is now `1`) + +The **prefix** unary operator `++`: + +1. Increments the value (number is now `2`) +2. Returns the value (this returns `2`) + +This returns `0 2 2`. + +
++ +#### 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! + +
++ +#### Answer: C + +When testing equality, primitives are compared by their _value_, while objects are compared by their _reference_. 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 }` return `false`. + +
++ +#### Answer: C + +The rest parameter (`...args`.) lets us "collect" all remaining arguments into an array. An array is an object, so `typeof args` returns `"object"` + +
++ +#### Answer: C + +With `"use strict"`, you can make sure that you don't accidentally declare global variables. We never declared the variable `age`, 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 property `age` would have gotten added to the global object. + +
++ +#### Answer: A + +`eval` evaluates codes that's passed as a string. If it's an expression, like in this case, it evaluates the expression. The expression is `10 * 10 + 5`. This returns the number `105`. + +
++ +#### Answer: B + +The data stored in `sessionStorage` is removed after closing the _tab_. + +If you used `localStorage`, the data would've been there forever, unless for example `localStorage.clear()` is invoked. + +
++ +#### Answer: B + +With the `var` keyword, you can declare multiple variables with the same name. The variable will then hold the latest value. + +You cannot do this with `let` or `const` since they're block-scoped. + +
++ +#### 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 why `obj.hasOwnProperty('1')` also returns true. + +It doesn't work that way for a set. There is no `'1'` in our set: `set.has('1')` returns `false`. It has the numeric type `1`, `set.has(1)` returns `true`. + +
++ +#### 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. + +
++ +#### Answer: A + +The base execution context is the global execution context: it's what's accessible everywhere in your code. + +
++ +#### Answer: C + +The `continue` statement skips an iteration if a certain condition returns `true`. + +
++ +#### Answer: A + +`String` is a built-in constructor, which 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! + +
++ +#### Answer: B + +Object keys are automatically converted into strings. We are trying to set an object as a key to object `a`, with the value of `123`. + +However, when we stringify an object, it becomes `"[object Object]"`. So what we are saying here, is that `a["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 log `a[b]`, which is actually `a["object Object"]`. We just set that to `456`, so it returns `456`. + +
+
+
+#### Answer: B
+
+We have a `setTimeout` 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 a `WebAPI`. The `WebAPI` gives us the `setTimeout` function to start with, and for example the DOM.
+
+After the _callback_ is pushed to the WebAPI, the `setTimeout` 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, and `baz` 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 the _queue_.
+
+
+
+This is where an event loop starts to work. An **event 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.
+
+
+ +#### Answer: C + +The deepest nested element that caused the event is the target of the event. You can stop bubbling by `event.stopPropagation` + +
++ Click here! +
++ +#### Answer: A + +If we click `p`, we see two logs: `p` and `div`. During event propagation, there are 3 phases: capturing, target, and bubbling. By default, event handlers are executed in the bubbling phase (unless you set `useCapture` to `true`). It goes from the deepest nested element outwards. + +
++ +#### Answer: D + +With both, we can pass the object to which we want the `this` keyword to refer to. However, `.call` is also _executed immediately_! + +`.bind.` returns a _copy_ of the function, but with a bound context! It is not executed immediately. + +
++ +#### Answer: B + +The `sayHi` function returns the returned value of the immediately invoked function (IIFE). This function returned `0`, which is type `"number"`. + +FYI: there are only 7 built-in types: `null`, `undefined`, `boolean`, `number`, `string`, `object`, and `symbol`. `"function"` is not a type, since functions are objects, it's of type `"object"`. +
++ +#### Answer: A + +There are only six falsy values: + +- `undefined` +- `null` +- `NaN` +- `0` +- `''` (empty string) +- `false` + +Function constructors, like `new Number` and `new Boolean` are truthy. + +
++ +#### Answer: B + +`typeof 1` returns `"number"`. +`typeof "number"` returns `"string"` + +
++ +#### 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 of `undefined`, but you will see something like: + +`[1, 2, 3, 7 x empty, 11]` + +depending on where you run it (it's different for every browser, node, etc.) + +
++ +#### Answer: A + +The `catch` block receives the argument `x`. This is not the same `x` as the variable when we pass arguments. This variable `x` is block-scoped. + +Later, we set this block-scoped variable equal to `1`, and set the value of the variable `y`. Now, we log the block-scoped variable `x`, which is equal to `1`. + +Outside of the `catch` block, `x` is still `undefined`, and `y` is `2`. When we want to `console.log(x)` outside of the `catch` block, it returns `undefined`, and `y` returns `2`. + +
++ +#### Answer: A + +JavaScript only has primitive types and objects. + +Primitive types are `boolean`, `null`, `undefined`, `bigint`, `number`, `string`, and `symbol`. + +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 a `TypeError`. This is because when you try to access a property or method on a primitive like a string, JavaScript will implicitly wrap the object using one of the wrapper classes, i.e. `String`, and then immediately discard the wrapper after the expression evaluates. All primitives except for `null` and `undefined` exhibit this behaviour. + +
++ +#### Answer: C + +`[1, 2]` is our initial value. This is the value we start with, and the value of the very first `acc`. During the first round, `acc` is `[1,2]`, and `cur` is `[0, 1]`. We concatenate them, which results in `[1, 2, 0, 1]`. + +Then, `[1, 2, 0, 1]` is `acc` and `[2, 3]` is `cur`. We concatenate them, and get `[1, 2, 0, 1, 2, 3]` + +
++ +#### Answer: B + +`null` is falsy. `!null` returns `true`. `!true` returns `false`. + +`""` is falsy. `!""` returns `true`. `!true` returns `false`. + +`1` is truthy. `!1` returns `false`. `!false` returns `true`. + +
++ +#### Answer: A + +It returns a unique id. This id can be used to clear that interval with the `clearInterval()` function. + +
++ +#### Answer: A + +A string is an iterable. The spread operator maps every character of an iterable to one element. + +
++ +#### 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 a `yield` keyword, the function yields the value specified after it. Note that the generator function in that case doesn’t _return_ the value, it _yields_ the value. + +First, we initialize the generator function with `i` equal to `10`. We invoke the generator function using the `next()` method. The first time we invoke the generator function, `i` is equal to `10`. It encounters the first `yield` keyword: it yields the value of `i`. The generator is now "paused", and `10` gets logged. + +Then, we invoke the function again with the `next()` method. It starts to continue where it stopped previously, still with `i` equal to `10`. Now, it encounters the next `yield` keyword, and yields `i * 2`. `i` is equal to `10`, so it returns `10 * 2`, which is `20`. This results in `10, 20`. + +
++ +#### Answer: B + +When we pass multiple promises to the `Promise.race` method, it resolves/rejects the _first_ promise that resolves/rejects. To the `setTimeout` method, we pass a timer: 500ms for the first promise (`firstPromise`), and 100ms for the second promise (`secondPromise`). This means that the `secondPromise` resolves first with the value of `'two'`. `res` now holds the value of `'two'`, which gets logged. + +
+
+
+#### Answer: D
+
+First, we declare a variable `person` with the value of an object that has a `name` property.
+
+
+
+Then, we declare a variable called `members`. We set the first element of that array equal to the value of the `person` variable. Objects interact by _reference_ when setting them equal to each other. When you assign a reference from one variable to another, you make a _copy_ of that reference. (note that they don't have the _same_ reference!)
+
+
+
+Then, we set the variable `person` equal to `null`.
+
+
+
+We are only modifying the value of the `person` variable, and not the first element in the array, since that element has a different (copied) reference to the object. The first element in `members` still holds its reference to the original object. When we log the `members` array, the first element still holds the value of the object, which gets logged.
+
+
+ +#### Answer: B + +With a `for-in` loop, we can iterate through object keys, in this case `name` and `age`. Under the hood, object keys are strings (if they're not a Symbol). On every loop, we set the value of `item` equal to the current key it’s iterating over. First, `item` is equal to `name`, and gets logged. Then, `item` is equal to `age`, which gets logged. + +
++ +#### 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 the _same_ 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 number `7`. + +`7 + '5'` results in `"75"` because of coercion. JavaScript converts the number `7` into a string, see question 15. We can concatenate two strings using the `+`operator. `"7" + "5"` results in `"75"`. + +
++ +#### Answer: C + +Only the first numbers in the string is returned. Based on the _radix_ (the second argument in order to specify what type of number we want to parse it to: base 10, hexadecimal, octal, binary, etc.), the `parseInt` 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 decimal `7`. `num` now holds the value of `7`. + +
++ +#### Answer: C + +When mapping over the array, the value of `num` is equal to the element it’s currently looping over. In this case, the elements are numbers, so the condition of the if statement `typeof num === "number"` returns `true`. 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 returns `undefined`. For every element in the array, the function block gets called, so for each element we return `undefined`. + +
++ +#### Answer: A + +Arguments are passed by _value_, unless their value is an object, then they're passed by _reference_. `birthYear` is passed by value, since it's a string, not an object. When we pass arguments by value, a _copy_ of that value is created (see question 46). + +The variable `birthYear` has a reference to the value `"1997"`. The argument `year` also has a reference to the value `"1997"`, but it's not the same value as `birthYear` has a reference to. When we update the value of `year` by setting `year` equal to `"1998"`, we are only updating the value of `year`. `birthYear` is still equal to `"1997"`. + +The value of `person` is an object. The argument `member` has a (copied) reference to the _same_ object. When we modify a property of the object `member` has a reference to, the value of `person` will also be modified, since they both have a reference to the same object. `person`'s `name` property is now equal to the value `"Lydia"` + +
++ +#### Answer: D + +With the `throw` statement, we can create custom errors. With this statement, you can throw exceptions. An exception can be a string, a number, a boolean or an object. In this case, our exception is the string `'Hello world'`. + +With the `catch` statement, we can specify what to do if an exception is thrown in the `try` 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'`. + +
++ +#### Answer: B + +When you return a property, the value of the property is equal to the _returned_ value, not the value set in the constructor function. We return the string `"Maserati"`, so `myCar.make` is equal to `"Maserati"`. + +
++ +#### Answer: A + +`let x = y = 10;` is actually shorthand for: + +```javascript +y = 10; +let x = y; +``` + +When we set `y` equal to `10`, we actually add a property `y` to the global object (`window` in browser, `global` in Node). In a browser, `window.y` is now equal to `10`. + +Then, we declare a variable `x` with the value of `y`, which is `10`. Variables declared with the `let` keyword are _block scoped_, they are only defined within the block they're declared in; the immediately-invoked function (IIFE) in this case. When we use the `typeof` operator, the operand `x` is not defined: we are trying to access `x` outside of the block it's declared in. This means that `x` 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 variable `y` when setting `y` equal to `10`. This value is accessible anywhere in our code. `y` is defined, and holds a value of type `"number"`. `console.log(typeof y)` returns `"number"`. + +
++ +#### Answer: A + +We can delete properties from objects using the `delete` keyword, also on the prototype. By deleting a property on the prototype, it is not available anymore in the prototype chain. In this case, the `bark` function is not available anymore on the prototype after `delete Dog.prototype.bark`, yet we still try to access it. + +When we try to invoke something that is not a function, a `TypeError` is thrown. In this case `TypeError: pet.bark is not a function`, since `pet.bark` is `undefined`. + +
++ +#### Answer: D + +The `Set` object is a collection of _unique_ values: a value can only occur once in a set. + +We passed the iterable `[1, 1, 2, 3, 4]` with a duplicate value `1`. Since we cannot have two of the same values in a set, one of them is removed. This results in `{1, 2, 3, 4}`. + +
++ +#### Answer: C + +An imported module is _read-only_: you cannot modify the imported module. Only the module that exports them can change its value. + +When we try to increment the value of `myCounter`, it throws an error: `myCounter` is read-only and cannot be modified. + +
++ +#### Answer: A + +The `delete` operator returns a boolean value: `true` on a successful deletion, else it'll return `false`. However, variables declared with the `var`, `const` or `let` keyword cannot be deleted using the `delete` operator. + +The `name` variable was declared with a `const` keyword, so its deletion is not successful: `false` is returned. When we set `age` equal to `21`, we actually added a property called `age` to the global object. You can successfully delete properties from objects this way, also the global object, so `delete age` returns `true`. + +
+
+
+#### Answer: C
+
+We can unpack values from arrays or properties from objects through destructuring. For example:
+
+```javascript
+[a, b] = [1, 2];
+```
+
+
+
+The value of `a` is now `1`, and the value of `b` is now `2`. What we actually did in the question, is:
+
+```javascript
+[y] = [1, 2, 3, 4, 5];
+```
+
+
+
+This means that the value of `y` is equal to the first value in the array, which is the number `1`. When we log `y`, `1` is returned.
+
+
+ +#### 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 the `user` object, and add them to the `admin` object. The `admin` object now contains the copied key/value pairs, which results in `{ admin: true, name: "Lydia", age: 21 }`. + +
++ +#### Answer: B + +With the `defineProperty` method, we can add new properties to an object, or modify existing ones. When we add a property to an object using the `defineProperty` method, they are by default _not enumerable_. The `Object.keys` method returns all _enumerable_ property names from an object, in this case only `"name"`. + +Properties added using the `defineProperty` method are immutable by default. You can override this behavior using the `writable`, `configurable` and `enumerable` properties. This way, the `defineProperty` method gives you a lot more control over the properties you're adding to an object. + +
++ +#### Answer: A + +The second argument of `JSON.stringify` is the _replacer_. 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 an _array_, 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 a _function_, 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 is `undefined`, this property is excluded from the JSON string. + +
++ +#### Answer: A + +The unary operator `++` _first returns_ the value of the operand, _then increments_ the value of the operand. The value of `num1` is `10`, since the `increaseNumber` function first returns the value of `num`, which is `10`, and only increments the value of `num` afterwards. + +`num2` is `10`, since we passed `num1` to the `increasePassedNumber`. `number` is equal to `10`(the value of `num1`. Again, the unary operator `++` _first returns_ the value of the operand, _then increments_ the value of the operand. The value of `number` is `10`, so `num2` is equal to `10`. + +
++ +#### 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 the `value` object into a new object, so `x` has the default value of `{ number: 10 }`. + +The default argument is evaluated at _call time_! Every time we call the function, a _new_ object is created. We invoke the `multiply` 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 is `20`. + +The third time we invoke multiply, we do pass an argument: the object called `value`. The `*=` operator is actually shorthand for `x.number = x.number * 2`: we modify the value of `x.number`, and log the multiplied value `20`. + +The fourth time, we pass the `value` object again. `x.number` was previously modified to `20`, so `x.number *= 2` logs `40`. + +
++ +#### Answer: D + +The first argument that the `reduce` method receives is the _accumulator_, `x` in this case. The second argument is the _current 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 optional `initialValue` argument to the `reduce` method, the accumulator is equal to the first element on the first call. + +On the first call, the accumulator (`x`) is `1`, and the current value (`y`) is `2`. We don't return from the callback function, we log the accumulator and current value: `1` and `2` get logged. + +If you don't return a value from a function, it returns `undefined`. On the next call, the accumulator is `undefined`, and the current value is `3`. `undefined` and `3` get logged. + +On the fourth call, we again don't return from the callback function. The accumulator is again `undefined`, and the current value is `4`. `undefined` and `4` get logged. +
++ +#### Answer: B + +In a derived class, you cannot access the `this` keyword before calling `super`. If you try to do that, it will throw a ReferenceError: 1 and 4 would throw a reference error. + +With the `super` keyword, we call that parent class's constructor with the given arguments. The parent's constructor receives the `name` argument, so we need to pass `name` to `super`. + +The `Labrador` class receives two arguments, `name` since it extends `Dog`, and `size` as an extra property on the `Labrador` class. They both need to be passed to the constructor function on `Labrador`, which is done correctly using constructor 2. +
++ +#### Answer: B + +With the `import` keyword, all imported modules are _pre-parsed_. This means that the imported modules get run _first_, the code in the file which imports the module gets executed _after_. + +This is a difference between `require()` in CommonJS and `import`! With `require()`, you can load dependencies on demand while the code is being run. If we would have used `require` instead of `import`, `running index.js`, `running sum.js`, `3` would have been logged to the console. + +
++ +#### 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 first `Symbol('foo')`, and the second `Symbol('foo')`. These two values are unique and not equal to each other, `Symbol('foo') === Symbol('foo')` returns `false`. + +
++ +#### Answer: C + +With the `padStart` method, we can add padding to the beginning of a string. The value passed to this method is the _total_ length of the string together with the padding. The string `"Lydia Hallie"` has a length of `12`. `name.padStart(13)` inserts 1 space at the start of the string, because 12 + 1 is 13. + +If the argument passed to the `padStart` method is smaller than the length of the array, no padding will be added. + +
++ +#### Answer: A + +With the `+` operator, you can concatenate strings. In this case, we are concatenating the string `"🥑"` with the string `"💻"`, resulting in `"🥑💻"`. + +
++ +#### Answer: C + +A generator function "pauses" its execution when it sees the `yield` keyword. First, we have to let the function yield the string "Do you love JavaScript?", which can be done by calling `game.next().value`. + +Every line is executed, until it finds the first `yield` keyword. There is a `yield` keyword on the first line within the function: the execution stops with the first yield! _This means that the variable `answer` is not defined yet!_ + +When we call `game.next("Yes").value`, the previous `yield` is replaced with the value of the parameters passed to the `next()` function, `"Yes"` in this case. The value of the variable `answer` is now equal to `"Yes"`. The condition of the if-statement returns `false`, and `JavaScript loves you back ❤️` gets logged. + +
++ +#### 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"` + +With `String.raw`, it would simply ignore the escape and print: + +`C:\Documents\Projects\table.html` + +In this case, the string is `Hello\nworld`, which gets logged. + +
++ +#### Answer: C + +An async function always returns a promise. The `await` still has to wait for the promise to resolve: a pending promise gets returned when we call `getData()` in order to set `data` equal to it. + +If we wanted to get access to the resolved value `"I made it"`, we could have used the `.then()` method on `data`: + +`data.then(res => console.log(res))` + +This would've logged `"I made it!"` + +
++ +#### Answer: B + +The `.push()` method returns the _length_ of the new array! Previously, the array contained one element (the string `"banana"`) and had a length of `1`. After adding the string `"apple"` to the array, the array contains two elements, and has a length of `2`. This gets returned from the `addToList` function. + +The `push` method modifies the original array. If you wanted to return the _array_ from the function rather than the _length of the array_, you should have returned `list` after pushing `item` to it. + +
++ +#### 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 variable `shape` and set it equal to the frozen object `box`, `shape` also refers to a frozen object. You can check whether an object is frozen by using `Object.isFrozen`. In this case, `Object.isFrozen(shape)` returns true, since the variable `shape` has a reference to a frozen object. + +Since `shape` is frozen, and since the value of `x` is not an object, we cannot modify the property `x`. `x` is still equal to `10`, and `{ x: 10, y: 20 }` gets logged. + +
++ +#### Answer: D + +When we unpack the property `name` from the object on the right-hand side, we assign its value `"Lydia"` to a variable with the name `myName`. + +With `{ name: myName }`, we tell JavaScript that we want to create a new variable called `myName` with the value of the `name` property on the right-hand side. + +Since we try to log `name`, a variable that is not defined, a ReferenceError gets thrown. + +
++ +#### Answer: A + +A pure function is a function that _always_ returns the same result, if the same arguments are passed. + +The `sum` function always returns the same result. If we pass `1` and `2`, it will _always_ return `3` without side effects. If we pass `5` and `10`, it will _always_ return `15`, and so on. This is the definition of a pure function. + +
++ +#### Answer: C + +The `add` function is a _memoized_ function. With memoization, we can cache the results of a function in order to speed up its execution. In this case, we create a `cache` object that stores the previously returned values. + +If we call the `addFunction` 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 caches value will be returned, which saves on execution time. Else, if it's not cached, it will calculate the value and store it afterwards. + +We call the `addFunction` function three times with the same value: on the first invocation, the value of the function when `num` is equal to `10` isn't cached yet. The condition of the if-statement `num in cache` returns `false`, 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, the `cache` object contains the value that gets returned for `10`. The condition of the if-statement `num in cache` returns `true`, and `'From cache! 20'` gets logged. + +The third time, we pass `5 * 2` to the function which gets evaluated to `10`. The `cache` object contains the value that gets returned for `10`. The condition of the if-statement `num in cache` returns `true`, and `'From cache! 20'` gets logged. + +
++ +#### Answer: A + +With a _for-in_ loop, we can iterate over **enumerable** 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. `0` `1` `2` `3` get logged. + +With a _for-of_ loop, we can iterate over **iterables**. 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. + +
++ +#### 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` returns `3`, `1 * 2` returns `2`, and `1 / 2` returns `0.5`. + +
++ +#### Answer: B + +By default, arguments have the value of `undefined`, unless a value has been passed to the function. In this case, we didn't pass a value for the `name` argument. `name` is equal to `undefined` which gets logged. + +In ES6, we can overwrite this default `undefined` value with default parameters. For example: + +`function sayHi(name = "Lydia") { ... }` + +In this case, if we didn't pass a value or if we passed `undefined`, `name` would always be equal to the string `Lydia` + +
++ +#### Answer: B + +The value of the `this` keyword is dependent on where you use it. In a **method**, like the `getStatus` method, the `this` keyword refers to _the object that the method belongs to_. The method belongs to the `data` object, so `this` refers to the `data` object. When we log `this.status`, the `status` property on the `data` object gets logged, which is `"🥑"`. + +With the `call` method, we can change the object to which the `this` keyword refers. In **functions**, the `this` keyword refers to the _the object that the function belongs to_. We declared the `setTimeout` function on the _global object_, so within the `setTimeout` function, the `this` keyword refers to the _global object_. On the global object, there is a variable called _status_ with the value of `"😎"`. When logging `this.status`, `"😎"` gets logged. + + +
++ +#### Answer: A + +We set the variable `city` equal to the value of the property called `city` on the `person` object. There is no property on this object called `city`, so the variable `city` has the value of `undefined`. + +Note that we are _not_ referencing the `person` object itself! We simply set the variable `city` equal to the current value of the `city` property on the `person` object. + +Then, we set `city` equal to the string `"Amsterdam"`. This doesn't change the person object: there is no reference to that object. + +When logging the `person` object, the unmodified object gets returned. + +
++ +#### Answer: C + +Variables with the `const` and `let` keyword are _block-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. + +
++ +#### Answer: C + +The value of `res` in the second `.then` is equal to the returned value of the previous `.then`. You can keep chaining `.then`s like this, where the value is passed to the next handler. + +
++ +#### Answer: A + +With `!!name`, we determine whether the value of `name` is truthy or falsy. If name is truthy, which we want to test for, `!name` returns `false`. `!false` (which is what `!!name` practically is) returns `true`. + +By setting `hasName` equal to `name`, you set `hasName` equal to whatever value you passed to the `getName` function, not the boolean value `true`. + +`new Boolean(true)` returns an object wrapper, not the boolean value itself. + +`name.length` returns the length of the passed argument, not whether it's `true`. + +
++ +#### Answer: B + +In order to get an character on a specific index in 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 which index is 0, the character `"I'`, which gets logged. + +Note that this method is not supported in IE7 and below. In that case, use `.charAt()` + +
++ +#### Answer: B + +You can set a default parameter's value equal to another parameter of the function, as long as they've been defined _before_ the default parameter. We pass the value `10` to the `sum` function. If the `sum` function only receives 1 argument, it means that the value for `num2` is not passed, and the value of `num1` is equal to the passed value `10` in this case. The default value of `num2` is the value of `num1`, which is `10`. `num1 + num2` returns `20`. + +If you're trying to set a default parameter's value equal to a parameter which is defined _after_ (to the right), the parameter's value hasn't been initialized yet, which will throw an error. + +
++ +#### Answer: A + +With the `import * as name` syntax, we import _all exports_ from the `module.js` file into the `index.js` file as a new object called `data` is created. In the `module.js` file, there are two exports: the default export, and a named export. The default export is a function which returns the string `"Hello World"`, and the named export is a variable called `name` which has the value of the string `"Lydia"`. + +The `data` object has a `default` property for the default export, other properties have the names of the named exports and their corresponding values. + +
++ +#### Answer: C + +Classes are syntactical sugar for function constructors. The equivalent of the `Person` class as a function constructor would be: + +```javascript +function Person() { + this.name = name +} +``` + +Calling a function constructor with `new` results in the creation of an instance of `Person`, `typeof` keyword returns `"object"` for an instance. `typeof member` returns `"object"`. + +
++ +#### Answer: D + +The `.push` method returns the _new length_ of the array, not the array itself! By setting `newList` equal to `[1, 2, 3].push(4)`, we set `newList` equal to the new length of the array: `4`. + +Then, we try to use the `.push` method on `newList`. Since `newList` is the numerical value `4`, we cannot use the `.push` method: a TypeError is thrown. + +
++ +#### Answer: D + +Regular functions, such as the `giveLydiaPizza` function, have a `prototype` property, which is an object (prototype object) with a `constructor` property. Arrow functions however, such as the `giveLydiaChocolate` function, do not have this `prototype` property. `undefined` gets returned when trying to access the `prototype` property using `giveLydiaChocolate.prototype`. + +
++ +#### Answer: A + +`Object.entries(person)` returns an array of nested arrays, containing the keys and objects: + +`[ [ 'name', 'Lydia' ], [ 'age', 21 ] ]` + +Using the `for-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, using `const [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" ]`, with `x` equal to `"name"`, and `y` equal to `"Lydia"`, which get logged. +The second subarray is `[ "age", 21 ]`, with `x` equal to `"age"`, and `y` equal to `21`, which get logged. + +
++ +#### 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. + +```javascript +function getItems(fruitList, favoriteFruit, ...args) { + return [...fruitList, ...args, favoriteFruit] +} + +getItems(["banana", "apple"], "pear", "orange") +``` + +The above example works. This returns the array `[ 'banana', 'apple', 'orange', 'pear' ]` +
++ +#### Answer: B + +In JavaScript, we don't _have_ to write the semicolon (`;`) explicitly, however the JavaScript engine still adds them after statements. This is called **Automatic Semicolon Insertion**. A statement can for example be variables, or keywords like `throw`, `return`, `break`, etc. + +Here, we wrote a `return` statement, and another value `a + b` on a _new 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 after `return`. You could see this as: + +```javascript + return; + a + b +``` + +This means that `a + b` is never reached, since a function stops running after the `return` keyword. If no value gets returned, like here, the function returns `undefined`. Note that there is no automatic insertion after `if/else` statements! + +
++ +#### Answer: B + +We can set classes equal to other classes/function constructors. In this case, we set `Person` equal to `AnotherPerson`. The name on this constructor is `Sarah`, so the name property on the new `Person` instance `member` is `"Sarah"`. + +
++ +#### Answer: D + +A Symbol is not _enumerable_. The Object.keys method returns all _enumerable_ 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 the `Object.getOwnPropertySymbols()` method). + +
++ +#### Answer: A + +The `getList` function receives an array as its argument. Between the parentheses of the `getList` 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 are `2`, `3` and `4` in this case. The value of `y` is an array, containing all the rest parameters. The value of `x` is equal to `1` in this case, so when we log `[x, y]`, `[1, [2, 3, 4]]` gets logged. + + The `getUser` function receives an object. With arrow functions, we don't _have_ to write curly brackets if we just return one value. However, if you want to return an _object_ from an arrow function, you have to write it between parentheses, otherwise no value gets returned! The following function would have returned an object: + +```const getUser = user => ({ name: user.name, age: user.age })``` + +Since no value gets returned in this case, the function returns `undefined`. + +
++ +#### Answer: C + +The variable `name` holds the value of a string, which is not a function, thus cannot invoke. + +TypeErrors get thrown when a value is not of the expected type. JavaScript expected `name` 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 word `return` as `retrun`. +ReferenceErrors get thrown when JavaScript isn't able to find a reference to a value that you're trying to access. + +
++ +#### 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. + +
++ +#### 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 past 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 `[]`. + +
++ +#### Answer: D + +With a promise, we basically say _I 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 the `await` keyword in an `async` function. Although we can get a promise's value with both `.then` and `await`, they work a bit differently. + +In the `firstFunction`, we (sort of) put the myPromise function aside while it was running, but continued running the other code, which is `console.log('second')` in this case. Then, the function resolved with the string `I have resolved`, which then got logged after it saw that the callstack was empty. + +With the await keyword in `secondFunction`, we literally pause the execution of an async function until the value has been resolved befoer moving to the next line. + +This means that it waited for the `myPromise` to resolve with the value `I have resolved`, and only once that happened, we moved to the next line: `second` got logged. + +
++ +#### 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 is `1`, which is a numerical value. `1 + 2` returns the number 3. + +However, the second one is a string `"Lydia"`. `"Lydia"` is a string and `2` 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"`. + +
++ +#### Answer: C + +We can pass any type of value we want to `Promise.resolve`, either a promise or a non-promise. The method itself returns a promise with the resolved value. 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 value `5`. It returns a resolved promise with the value `5`. + +
++ +#### Answer: B + +Objects are passed by reference. When we check objects for strict equality (`===`), we're comparing their references. + +We set the default value for `person2` equal to the `person` object, and passed the `person` object as the value for `person1`. + +This means that both values have a reference to the same spot in memory, thus they are equal. + +The code block in the `else` statement gets run, and `They are the same!` gets logged. + +
++ +#### 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 called `colors` on the `colorConfig` object. There is no proprety called `colors`, so this returns `undefined`. Then, we try to access the value of the first element by using `[1]`. We cannot do this on a value that's `undefined`, so it throws a `TypeError`: `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 used `colorConfig[colors[1]]`, it would have returned the value of the `red` property on the `colorConfig` object. + +
++ +#### 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. + +
++ +#### Answer: D + +With `splice` 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` and `slice` return a new array, `find` returns an element, and `reduce` returns a reduced value. + +
++ +#### Answer: A + +We set the value of the `favoriteFood` property on the `info` object equal to the string with the pizza emoji, `'🍕'`. A string is a primitive data type. In JavaScript, primitive data types act by reference + +In JavaScript, primitive data types (everything that's not an object) interact by _value_. In this case, we set the value of the `favoriteFood` property on the `info` object equal to the value of the first element in the `food` array, the string with the pizza emoji in this case (`'🍕'`). A string is a primitive data type, and interact by value (see my [blogpost](https://www.theavocoder.com/complete-javascript/2018/12/21/by-value-vs-by-reference) if you're interested in learning more) + +Then, we change the value of the `favoriteFood` property on the `info` object. The `food` array hasn't changed, since the value of `favoriteFood` was merely a _copy_ 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 on `food[0]`. When we log food, it's still the original array, `['🍕', '🍫', '🥑', '🍔']`. + +
++ +#### Answer: A + +With the `JSON.parse()` method, we can parse JSON string to a JavaScript value. + +```javascript +// Stringifying a number into valid JSON, then parsing the JSON string to a JavaScript value: +const jsonNumber = JSON.stringify(4) // '4' +JSON.parse(jsonNumber) // 4 + +// Stringifying an array value into valid JSON, then parsing the JSON string to a JavaScript value: +const jsonArray = 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: +const jsonArray = JSON.stringify({ name: "Lydia" }) // '{"name":"Lydia"}' +JSON.parse(jsonArray) // { name: 'Lydia' } +``` + +
++ +#### Answer: D + +Each function has its own _execution context_ (or _scope_). The `getName` function first looks within its own context (scope) to see if it contains the variable `name` we're trying to access. In this case, the `getName` function contains its own `name` variable: we declare the variable `name` with the `let` keyword, and with the value of `'Sarah'`. + +Variables with the `let` keyword (and `const`) are hoisted, but unlike `var`, don't get initialized. 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 a `ReferenceError`. + +If we wouldn't have declared the `name` variable within the `getName` function, the javascript engine would've looked down the _scope chain_. The outer scope has a variable called `name` with the value of `Lydia`. In that case, it would've logged `Lydia`. + +```javascript +let name = 'Lydia' + +function getName() { + console.log(name) +} + +getName() // Lydia +``` + +
++ +#### Answer: C + +With the `yield` keyword, we `yield` values in a generator function. With the `yield*` keyword, we can yield values from another generator function, or iterable object (for example an array). + +In `generatorOne`, we yield the entire array `['a', 'b', 'c']` using the `yield` keyword. The value of `value` property on the object returned by the `next` method on `one` (`one.next().value`) is equal to the entire array `['a', 'b', 'c']`. + +```javascript +console.log(one.next().value) // ['a', 'b', 'c'] +console.log(one.next().value) // undefined +``` + +In `generatorTwo`, we use the `yield*` keyword. This means that the first yielded value of `two`, is equal to the first yielded value in the iterator. The iterator is the array `['a', 'b', 'c']`. The first yielded value is `a`, so the first time we call `two.next().value`, `a` is returned. + +```javascript +console.log(two.next().value) // 'a' +console.log(two.next().value) // 'b' +console.log(two.next().value) // 'c' +console.log(two.next().value) // undefined +``` + +
++ +#### 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 the `x => x` arrow function. `x` is equal to `'I love'`, which gets returned. This results in `I love to program`. + +
++ +#### Answer: C + +Normally when we set objects equal to `null`, those objects get _garbage collected_ as there is no reference anymore to that object. However, since the callback function within `setInterval` is an arrow function (thus bound to the `config` object), the callback function still holds a reference to the `config` object. As long as there is a reference, the object won't get garbage collected. Since it's not garbage collected, the `setInterval` callback function will still get invoked every 1000ms (1s). + +
++ +#### Answer: B + +When adding a key/value pair using the `set` method, the key will be the value of the first argument passed to the `set` function, and the value will be the second argument passed to the `set` function. The key is the _function_ `() => '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 the `get` method. Object interact by _reference_. 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. + +
++ +#### Answer: C + +Both the `changeAge` and `changeAgeAndName` functions have a default parameter, namely a _newly_ created object `{ ...person }`. This object has copies of all the key/values in the `person` object. + +First, we invoke the `changeAge` function and pass the `person` object as its argument. This function increases the value of the `age` property by 1. `person` is now `{ name: "Lydia", age: 22 }`. + +Then, we invoke the `changeAgeAndName` function, however we don't pass a parameter. Instead, the value of `x` is equal to a _new_ object: `{ ...person }`. Since it's a new object, it doesn't affect the values of the properties on the `person` object. `person` is still equal to `{ name: "Lydia", age: 22 }`. + +
++ +#### Answer: C + +With the spread operator `...`, we can _spread_ iterables to individual elements. The `sumValues` function receives three arguments: `x`, `y` and `z`. `...[1, 2, 3]` will result in `1, 2, 3`, which we pass to the `sumValues` function. + +
++ +#### Answer: B + +With the `+=` operand, we're incrementing the value of `num` by `1`. `num` had the initial value `1`, so `1 + 1` is `2`. The item on the second index in the `list` array is 🥰, `console.log(list[2])` prints 🥰. + +
++ +#### 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 an `undefined` or `null` value (_nullish_), the expression short-circuits and returns `undefined`. + +`person.pet?.name`: `person` has a property named `pet`: `person.pet` is not nullish. It has a property called `name`, and returns `Mara`. +`person.pet?.family?.name`: `person` has a property named `pet`: `person.pet` is not nullish. `pet` does _not_ have a property called `family`, `person.pet.family` is nullish. The expression returns `undefined`. +`person.getFullName?.()`: `person` has a property named `getFullName`: `person.getFullName()` is not nullish and can get invoked, which returns `Lydia Hallie`. +`member.getLastName?.()`: `member` is not defined: `member.getLastName()` is nullish. The expression returns `undefined`. + +
++ +#### Answer: B + +We passed the condition `groceries.indexOf("banana")` to the if-statement. `groceries.indexOf("banana")` returns `0`, which is a falsy value. Since the condition in the if-statement is falsy, the code in the `else` block runs, and `We don't have to buy bananas!` gets logged. + +
++ +#### Answer: D + +The `language` method is a `setter`. Setters don't hold an actual value, their purpose is to _modify_ properties. When calling a `setter` method, `undefined` gets returned. + +
++ +#### Answer: C + +`typeof name` returns `"string"`. The string `"string"` is a truthy value, so `!typeof name` returns the boolean value `false`. `false === "object"` and `false === "string"` both return`false`. + +(If we wanted to check whether the type was (un)equal to a certain type, we should've written `!==` instead of `!typeof`) + +
++ +#### Answer: A + +The `add` function returns an arrow function, which returns an arrow function, which returns an arrow function (still with me?). The first function receives an argument `x` with the value of `4`. We invoke the second function, which receives an argument `y` with the value `5`. Then we invoke the third function, which receives an argument `z` with the value `6`. When we're trying to access the value `x`, `y` and `z` within the last arrow function, the JS engine goes up the scope chain in order to find the values for `x` and `y` accordingly. This returns `4` `5` `6`. + +
++ +#### Answer: C + +The generator function `range` returns an async object with promises for each item in the range we pass: `Promise{1}`, `Promise{2}`, `Promise{3}`. We set the variable `gen` equal to the async object, after which we loop over it using a `for await ... of` loop. We set the variable `item` equal to the returned Promise values: first `Promise{1}`, then `Promise{2}`, then `Promise{3}`. Since we're _awaiting_ the value of `item`, the resolved promsie, the resolved _values_ of the promises get returned: `1`, `2`, then `3`. + +
++ +#### Answer: D + +`myFunc` expects an object with properties `x`, `y` and `z` as its argument. Since we're only passing three separate numeric values (1, 2, 3) instead of one object with properties `x`, `y` and `z` ({x: 1, y: 2, z: 3}), `x`, `y` and `z` have their default value of `undefined`. + +
++ +#### Answer: B + +With the `Intl.NumberFormat` method, we can format numeric values to any locale. We format the numeric value `130` to the `en-US` locale as a `unit` in `mile-per-hour`, which results in `130 mph`. The numeric value `300` to the `en-US` locale as a `currentcy` in `USD` results in `$300.00`. + +
++ +#### 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 "💀" to `spookyItems[3]`. This means that we're modifying the `spookyItems` array, we're adding the "💀" to it. When logging `spookyItems`, `["👻", "🎃", "🕸", "💀"]` gets logged. + +
++ +#### Answer: C + +With the `Number.isNaN` method, you can check if the value you pass is a _numeric value_ and equal to `NaN`. `name` is not a numeric value, so `Number.isNaN(name)` returns `false`. `age` is a numeric value, but is not equal to `NaN`, so `Number.isNaN(age)` returns `false`. + +With the `isNaN` method, you can check if the value you pass is not a number. `name` is not a number, so `isNaN(name)` returns true. `age` is a number, so `isNaN(age)` returns `false`. + +
++ +#### Answer: D + +Variables declared with the `const` keyword are not referencable before their initialization: this is called the _temporal dead zone_. In the `getInfo` function, the variable `randomValue` is scoped in the functional scope of `getInfo`. On the line where we want to log the value of `typeof randomValue`, the variable `randomValue` isn't initialized yet: a `ReferenceError` gets thrown! The engine didn't go down the scope chain since we declared the variable `randomValue` in the `getInfo` function. + +
++ +#### Answer: C + +In the `try` block, we're logging the awaited value of the `myPromise` variable: `"Woah some cool data"`. Since no errors were thrown in the `try` block, the code in the `catch` block doesn't run. The code in the `finally` block _always_ runs, `"Oh finally!"` gets logged. + +
++ +#### Answer: B + +With the `flat` 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 value `1` (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 `['🥑', '✨', '✨', ['🍕', '🍕']]`. + +
+
+
+#### Answer: D
+
+`counterOne` is an instance of the `Counter` class. The counter class contains a `count` property on its constructor, and an `increment` method. First, we invoked the `increment` method twice by calling `counterOne.increment()`. Currently, `counterOne.count` is `2`.
+
+
+
+Then, we create a new variable `counterTwo`, and set it equal to `counterOne`. Since objects interact by reference, we're just creating a new reference to the same spot in memory that `counterOne` points to. Since it has the same spot in memory, any changes made to the object that `counterTwo` has a reference to, also apply to `counterOne`. Currently, `counterTwo.count` is `2`.
+
+We invoke the `counterTwo.increment()`, which sets the `count` to `3`. Then, we log the count on `counterOne`, which logs `3`.
+
+
+
+
+ +#### Answer: D + +First, we invoke `funcOne`. On the first line of `funcOne`, we call the `myPromise` promise, which is an _asynchronous_ operation. While the engine is busy completing the promise, it keeps on running the function `funcOne`. The next line is the _asynchronous_ `setTimeout` function, from which the callback is sent to the Web API. (see my article on the event loop here.) + +Both the promise and the timeout are asynchronous operations, the function keeps on running while it's busy completing the promise and handling the `setTimeout` callback. This means that `Last line!` gets logged first, since this is not an asynchonous operation. This is the last line of `funcOne`, the promise resolved, and `Promise!` gets logged. However, since we're invoking `funcTwo()`, the call stack isn't empty, and the callback of the `setTimeout` function cannot get added to the callstack yet. + +In `funcTwo` we're, first _awaiting_ the myPromise promise. With the `await` keyword, we pause the execution of the function until the promise has resolved (or rejected). Then, we log the awaited value of `res` (since the promise itself returns a promise). This logs `Promise!`. + +The next line is the _asynchronous_ `setTimeout` function, from which the callback is sent to the Web API. + +We get to the last line of `funcTwo`, which logs `Last line!` to the console. Now, since `funcTwo` popped off the call stack, the call stack is empty. The callbacks waiting in the queue (`() => console.log("Timeout!")` from `funcOne`, and `() => console.log("Timeout!")` from `funcTwo`) get added to the call stack one by one. The first callback logs `Timeout!`, and gets popped off the stack. Then, the second callback logs `Timeout!`, and gets popped off the stack. This logs `Last line! Promise! Promise! Last line! Timeout! Timeout!` + +
++ +#### Answer: C + +With the asterisk `*`, we import all exported values from that file, both default and named. If we had the following file: + +```javascript +// info.js +export const name = "Lydia"; +export const age = 21; +export default "I love JavaScript"; + +// index.js +import * as info from "./info"; +console.log(info); +``` + +The following would get logged: + +```javascript +{ + default: "I love JavaScript", + name: "Lydia", + age: 21 +} +``` + +For the `sum` example, it means that the imported value `sum` looks like this: + +```javascript +{ default: function sum(x) { return x + x } } +``` + +We can invoke this function, by calling `sum.default` + +
++ +#### Answer: C + +With a Proxy object, we can add custom behavior to an object that we pass to it as the second argument. In tis case, we pass the `handler` object which contained to properties: `set` and `get`. `set` gets invoked whenever we _set_ property values, `get` gets invoked whenever we _get_ (access) property values. + +The first argument is an empty object `{}`, which is the value of `person`. To this object, the custom behavior specified in the `handler` object gets added. If we add a property to the `person` object, `set` will get invoked. If we access a property on the `person` object, `get` gets invoked. + +First, we added a new property `name` 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, the `get` property on the handler object got invoked. `"Accessed a property!"` gets logged. + +
++ +#### Answer: A + +With `Object.seal` we can prevent new properies from being _added_, or existing properties to be _removed_. + +However, you can still modify the value of existing properties. + +
++ +#### Answer: C + +The `Object.freeze` method _freezes_ an object. No properties can be added, modified, or removed. + +However, it only _shallowly_ freezes the object, meaning that only _direct_ properties on the object are frozen. If the property is another object, like `address` in this case, the properties on that object aren't frozen, and can be modified. + +
++ +#### Answer: C + +The `Object.freeze` method _freezes_ an object. No properties can be added, modified, or removed. + +However, it only _shallowly_ freezes the object, meaning that only _direct_ properties on the object are frozen. If the property is another object, like `address` in this case, the properties on that object aren't frozen, and can be modified. + +
++ +#### Answer: A + +First, we invoked `myFunc()` without passing any arguments. Since we didn't pass arguments, `num` and `value` got their default values: num is `2`, and `value` the returned value of the function `add`. To the `add` function, we pass `num` as an argument, which had the value of `2`. `add` returns `4`, which is the value of `value`. + +Then, we invoked `myFunc(3)` and passed the value `3` as the value for the argument `num`. We didn't pass an argument for `value`. Since we didn't pass a value for the `value` argument, it got the default value: the returned value of the `add` function. To `add`, we pass `num`, which has the value of `3`. `add` returns `6`, which is the value of `value`. + +
++ +#### 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 log `counter.#number`, a SyntaxError gets thrown: we cannot acccess it outside the `Counter` class! + +
++ +#### Answer: B + +In order to iterate over the `members` in each element in the `teams` array, we need to pass `teams[i].members` to the `getMembers` generator function. The generator function returns a generator object. In order to iterate over each element in this generator object, we need to use `yield*`. + +If we would've written `yield`, `return yield`, or `return`, the entire generator function would've gotten returned the first time we called the `next` method. + +
++ +#### Answer: C + +The `addHobby` function receives two arguments, `hobby` and `hobbies` with the default value of the `hobbies` array on the `person` object. + +First, we invoke the `addHobby` function, and pass `"running"` as the value for `hobby` and an empty array as the value for `hobbies`. Since we pass an empty array as the value for `y`, `"running"` gets added to this empty array. + +Then, we invoke the `addHobby` function, and pass `"dancing"` as the value for `hobby`. We didn't pass a value for `hobbies`, so it gets the default value, the `hobbies` property on the `person` object. We push the hobby `dancing` to the `person.hobbies` array. + +Last, we invoke the `addHobby` function, and pass `"bdaking"` as the value for `hobby`, and the `person.hobbies` array as the value for `hobbies`. We push the hobby `baking` to the `person.hobbies` array. + +After pushing `dancing` and `baking`, the value of `person.hobbies` is `["coding", "dancing", "baking"]` + +
++ +#### Answer: B + +We create the variable `pet` which is an instance of the `Flamingo` class. When we instantiate this instance, the `constructor` on `Flamingo` gets called. First, `"I'm pink. 🌸"` gets logged, after which we call `super()`. `super()` calls the constructor of the parent class, `Bird`. THe constructor in `Bird` gets called, and logs `"I'm a bird. 🦢"`. + +
++ +#### Answer: D + +The `const` keyword simply means we cannot _redeclare_ the value of that variable, it's _read-only_. However, the value itself isn't immutable. The propeties on the `emojis` array can be modified, for example by pushing new values, splicing them, or setting the length of the array to 0. + +
++ +#### 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 the `Object.values` of the `person` object if we want it to return the array `["Lydia Hallie", 21]`: `yield* Object.values(this)`. + +
+* [English](./en-EN/README.md) @@ -25,7 +25,8 @@ * [Español](./es-ES/README-ES.md) * [Français](./fr-FR/README_fr-FR.md) * [日本語](./ja-JA/README-ja_JA.md) -* [한국어](./ko-KR/README-ko_KR.md) +* [한국어](./ko-KR/README-ko_KR.md) +* [Nederlands](./nl-NL/README.md) * [Português Brasil](./pt-BR/README_pt_BR.md) * [Русский](./ru-RU/README.md) * [Українська мова](./ua-UA/README-ua_UA.md) From ce3bc38324c75a737a60dd51f33ce8978bbd95d3 Mon Sep 17 00:00:00 2001 From: Tarabass
+ +#### 答案:C + +一元運算子 `++` 加在變數後方: + +1. 回傳值 (這個值是 `0`) +2. 新增值 (變數 `number` 的值現在是 `1`) + +一元運算子 `++` 加在變數前方: + +1. 新增值 (變數 `number` 的值現在是 `2`) +2. 回傳值 (這個值是 `2`) + +因此答案是 `0 2 2`. + +
++ +#### 答案:B + +若你使用標籤樣板字面值(Tagged template literals),第一個參數的值永遠會是一個裝載字串的陣列,函式中的剩下的參數會取得表達式中傳進的變數(`person`、`age`)的值(`'Lydia'`、`21`)! + +
++ +#### 答案:C + +驗證相等,一般型別只比較「值」,物件型別則是比較他們的「參考」。JavaScript 會確認不同物件的參考是否指向同一個記憶體位置。 + +題目中,我們比較的兩個物件擁有不同的記憶體位置:一個物件是作為參數傳遞的物件,它的記憶體位置與另一個拿來判斷是否相等的物件並不相同。 + +這就是 `{ age: 18 } === { age: 18 }` 與 `{ age: 18 } == { age: 18 }` 會回傳 `false` 的原因. + +
++ +#### 答案:C + +其餘參數(`...args`) 會蒐集傳進來剩下來未使用的參數,成為一個「陣列」。 陣列的型別是「物件」,所以透過 `typeof args` 將會回傳該值的型別,將是 `"object"`。 + +
++ +#### 答案:C + +`"use strict"` 可以避免妳意外地宣告全區域變數。使用 `"use strict"` 時,我們若沒有宣告 `age` 這個變數,就直接賦值的話,會拋出 `ReferenceError`,若沒有使用 `"use strict"`,屬性 `age` 就會新增到全域物件上(瀏覽器上的全域物件是 `window`)。 + +
++ +#### 答案:A + +`eval` 會去執行傳進去的「字串」。如果該字串是一個表達式,如題目中的程式碼,那麼 `eval` 會自動執行該表達式 `10 * 10 + 5`,所以答案會是 `105`。 + +
++ +#### 答案:B + +儲存在 `sessionStorage` 的資料會在使用者「關閉頁籤」後消失。 + +若是使用 `localStorage` 來儲存資料的話,資料則會永遠存在瀏覽器端,直到觸發了 `localStorage.clear()` 才可以清除資料。 + +
++ +#### 答案:B + +使用 `var` 關鍵字重複宣告的變數,該值會以最新賦予的值作為它的「值」。這件事情在 `let` or `const` 不會發生,因為這兩個關鍵字所宣告的變數作用域是塊級作用域(block-scoped)。 + +
++ +#### 答案:C + +除了 `Symbol` 以外的物件的 `key` 在底層都是字串類別,即使你建立該物件屬性時,並不是以字串來建立的,所以 `obj.hasOwnProperty('1')` 會回傳 `true`。不過 `set` 不是這樣的規則,在題目中的 `set` 並沒有字串 `'1'` 這個屬性名稱,所以 `set.has('1')` 會回傳 `false`,不過是有數字類別 `1` 的屬性值,`set.has(1)` 將會回傳 `true`。 + +
++ +#### 答案:C + +若物件中的屬性有重複名稱者,第一個屬性會保持它的位置,但值會被最後一個重複屬性名稱的值給取代。 + +
+
-#### 答案: D
+#### 答案:D
在函式內部,我們首先透過 `var` 關鍵字宣告了 `name` 變數。這表示變數被提升了(記憶體位置在創建時期就被設置好了),直到程式執行到定義變數的那行之前,預設值都是 `undefined`。因為當我們印出 `name` 變數時,還沒有執行到定義變數的那一行程式碼,因此變數的值保持為 `undefined`。
@@ -69,7 +70,7 @@ for (let i = 0; i < 3; i++) {
-#### 答案: C
+#### 答案:C
由於 JavaScript 的事件佇列(Event Queue),`setTimeout` 的 `callback` 會在*遍歷結束後*才執行。因為在第一個迴圈中,遍歷 `i` 是透過 `var` 關鍵字宣告的,`var` 屬於 Function scope(需要用 `function() {}` 才能將值鎖在作用域裡面)
,所以 `for` 迴圈會造成變數外流,變成全域變數。在遍歷過程中,我們透過一元運算子 `++` 來遞增 `i` 的值。當 `setTimeout` 的 `callback` 執行的時候,`i` 的值等於 3。
@@ -104,7 +105,7 @@ shape.perimeter()
-#### 答案: B
+#### 答案 B
注意 `diameter` 的值是一個一般的函式,但是 `perimeter` 的值是一個箭頭函式。
@@ -131,7 +132,7 @@ shape.perimeter()
-#### 答案: A
+#### 答案:A
一元運算子加號 `+`,嘗試將 boolean 布林值型別轉為 number 數字型別。`true` 轉為 number 數字型別的話為 `1`,`false` 爲 `0`。
@@ -164,7 +165,7 @@ const mouse = {
-#### 答案: A
+#### 答案:A
在 JavaScript 中,所有物件的 keys 都是字串型別(除非是 Symbol 物件)。儘管我們或許不會定義它們為字串,但它們在底層總會被轉換爲字串。
@@ -199,7 +200,7 @@ console.log(d.greeting)
-#### 答案: A
+#### 答案:A
在 JavaScript 中,當設定兩個物件彼此相等時,它們會經由*引用(reference)*進行互動。
@@ -234,7 +235,7 @@ console.log(b === c)
-#### 答案: C
+#### 答案:C
`new Number()` 是一個内建的函式建構子。它雖然看起來像是個 number,但它實際上並非真正的 number:它有一堆額外的功能,而且它是一個物件。
@@ -273,7 +274,7 @@ freddie.colorChange('orange')
-#### 答案: D
+#### 答案:D
`colorChange` 是一個靜態方法。靜態方法被設計爲只能被創造它們的建構子使用(也就是 `Chameleon` 中的 `constructor` ),並且不能傳遞給實例。因為 `freddie` 是一個實例,而靜態方法不能被實例使用,因此會抛出 `TypeError` 錯誤。
@@ -297,7 +298,7 @@ console.log(greetign)
-#### 答案: A
+#### 答案:A
程式碼印出了一個物件,這是因為我們在全域物件上創建了一個空物件!當我們將 `greeting` 寫錯成 `greetign` 時,JS 解譯器實際上將它視爲 `global.greetign = {}` (或者在瀏覽器中視為 `window.greetign = {}`)。
@@ -326,7 +327,7 @@ bark.animal = 'dog'
-#### 答案: A
+#### 答案:A
這在 JavaScript 中是可以的,因爲函式是物件!(除了基本型別之外其他都是物件)
@@ -361,7 +362,7 @@ console.log(member.getFullName());
-#### 答案: A
+#### 答案:A
你可以為一般物件新增屬性,但建構函式(constructor)無法透過上面的方式來新增屬性。若你想一次性在所有實例上都新增某個屬性,要使用原型的方式。因此本例中,使用以下的方式:
@@ -401,7 +402,7 @@ console.log(sarah)
-#### 答案: A
+#### 答案:A
對 `sarah` 而言,我們沒有使用 `new` 關鍵字。當使用 `new` 時,`this` 引用我們建立的空物件。沒有使用 `new` 的時候,`this` 引用的是**全域物件**(global object)。
@@ -422,7 +423,7 @@ console.log(sarah)
-#### 答案: D
+#### 答案:D
先捕獲,再冒泡!在**捕獲**(capturing)階段中,事件從祖先元素向下傳播到目標元素。當事件到達**目標**(target)元素後,**冒泡**(bubbling)才開始。
@@ -441,7 +442,7 @@ console.log(sarah)
-#### 答案: B
+#### 答案:B
除了**基本物件**(base object,使用 `new` 關鍵字建立的物件)以外,所有物件都有原型。基本物件可以使用一些方法和属性,比如 `.toString`,這就是為什麼你可以使用內建的 JavaScript 方法!所有這類在原型上的方法都是可被使用的。雖然 JavaScript 不能直接在物件上找到這些方法,但 JavaScript 會沿著原型鍊找到它們,以便使用。
@@ -468,7 +469,7 @@ sum(1, '2')
-#### 答案: C
+#### 答案:C
JavaScript 是一個**動態型別語言**:我們不指定變數的型別。值可以在你不知道的情况下自動轉換成另一種型別,稱為**隱含式轉型**(implicit type coercion)。**Coercion** 是指將一種型別轉換成另一種型別。
From 6a44db3f8b3b8595d5c1665bb9595381e741cfae Mon Sep 17 00:00:00 2001
From: Tarabass
* [English](../en-EN/README.md)
From 26d86ac4c27a41486e7bcdc1d6be6f5a520f85a2 Mon Sep 17 00:00:00 2001
From: Tarabass
-#### Answer: D
+#### Antwoord: D
-Within the function, we first declare the `name` variable with the `var` keyword. This means that the variable gets hoisted (memory space is set up during the creation phase) with the default value of `undefined`, 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 the `name` variable, so it still holds the value of `undefined`.
+In de functie declareren we eerst de `name` variabele met het keyword `var`. Dit betekent dat de variabele gehoisted wordt (geheugen wordt vrijgemaakt tijdens de Creation Phase) met de waarde `undefined`, tot het niveau waar we de variabele daadwerkelijk definiëren. We hebben de variable nog niet gedefinieerd tot op de lijn waar we proberen de `name` variabele te loggen naar het console. De variabele is dus wel al aanwezig, maar de waarde is nog steeds `undefined`.
-Variables with the `let` keyword (and `const`) are hoisted, but unlike `var`, don't get initialized. 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 a `ReferenceError`.
+Variabelen die gedeclareerd worden met het keyword `let` (en `const`) worden ook gehoisted, maar worden niet, in tegenstelling tot `var`, geïnitialiseerd. Ze zijn niet toegankelijk totaan de lijn waarop ze gedeclareerd (geïnitialiseerd) worden. Dit wordt de "temporal dead zone" genoemd. Wanneer we de variabele proberen te benaderen voordat deze gedeclareerd is gooit JavaScript een `ReferenceError`.
-#### Answer: C
+#### Antwoord: C
-Because of the event queue in JavaScript, the `setTimeout` callback function is called _after_ the loop has been executed. Since the variable `i` in the first loop was declared using the `var` keyword, this value was global. During the loop, we incremented the value of `i` by `1` each time, using the unary operator `++`. By the time the `setTimeout` callback function was invoked, `i` was equal to `3` in the first example.
+Vanwege de Event Queue in JavaScript wordt de `setTimeout` callback functie aangeroepen _nadat_ de volledige loop is uitgevoerd. Omndat in de eerste loop de variabele `i` gedeclareerd wordt met het keyword `var`, wordt deze global gemaakt. Tijdens de loop verhogen we de waarde van `i` met `1` door middel van de unary operator `++`. Tegen de tijd dat de `setTimeout` callback functie wordt aangeroepen is de waarde van `i` al `3`, zoals te zien is in het eerste voorbeeld.
-In the second loop, the variable `i` was declared using the `let` keyword: variables declared with the `let` (and `const`) 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.
+In de tweede loop wordt de variabele `i` gedeclareerd met het keyword `let`: variabelen die gedeclareerd worden met het keyword `let` (en `const`) zijn block-scoped (een scope is alles tussen `{ }`). Tijdens elke iteratie zal `i` een nieuwe waarde krijgen, en elke waarde is scoped (te gebruiken tussen `{ }`) in de loop.
-#### Answer: B
+#### Antwoord: B
-Note that the value of `diameter` is a regular function, whereas the value of `perimeter` is an arrow function.
+Merk op dat de waarde van `diameter` een gewone functie is, waarbij de waarde van `perimeter` een zogenaamde arrow functie is.
-With arrow functions, the `this` keyword refers to its current surrounding scope, unlike regular functions! This means that when we call `perimeter`, it doesn't refer to the shape object, but to its surrounding scope (window for example).
+Bij arrow functies refereert het `this` keyword naar z'n huidige omliggende scope, zo niet bij gewone functie! Dat betekent dat wanneer we `perimeter` aanroepen het niet refereert naar het shape object, maar naar de omliggende scope (window bijvoorbeeld).
-There is no value `radius` on that object, which returns `undefined`.
+Er is geen propertie `radius` op dat object, daarom wordt `undefined` teruggegeven.
-#### Answer: A
+#### Antwoord: A
-The unary plus tries to convert an operand to a number. `true` is `1`, and `false` is `0`.
+De unaire plus probeert een operand naar een nummer te converteren. `true` is `1`, en `false` is `0`.
-The string `'Lydia'` is a truthy value. What we're actually asking, is "is this truthy value falsy?". This returns `false`.
+De string `'Lydia'` is een truthy waarde. Wat we eigenlijk vragen, is "is deze truthy waarde falsy?". Dit geeft `false` terug.
-#### Answer: A
+#### Antwoord: A
-In JavaScript, all object keys are strings (unless it's a Symbol). Even though we might not _type_ them as strings, they are always converted into strings under the hood.
+In JavaScript zijn alle object keys strings (tenzij het een Symbol is). En ook al zijn ze niet van het _type_ string, onder de motorkap worden ze altijd geconverteerd naar een string.
-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.
+JavaScript interpreteert (of unboxed) statements. Wanneer we de bracket notatie gebruiken zal de interpreter de opening bracket `[` zien en net zolang doorgaan tot het een closing bracket `]` vindt. Alleen dan zal het de waarde bepalen van de declaratie.
-`mouse[bird.size]`: First it evaluates `bird.size`, which is `"small"`. `mouse["small"]` returns `true`
+`mouse[bird.size]`: Eerst wordt `bird.size` geëvalueerd, wat `"small"` teruggeeft. `mouse["small"]` geeft `true` terug.
-However, with dot notation, this doesn't happen. `mouse` does not have a key called `bird`, which means that `mouse.bird` is `undefined`. Then, we ask for the `size` using dot notation: `mouse.bird.size`. Since `mouse.bird` is `undefined`, we're actually asking `undefined.size`. This isn't valid, and will throw an error similar to `Cannot read property "size" of undefined`.
+Echter, met de dot notatie zal dit niet gebeuren. `mouse` heeft geen propertie genaamd `bird`, wat betekent dat `mouse.bird` `undefined` teruggeeft. Daarna vragen we de waarde op van `size` gebruikmakend van de dot notatie. Omdat `mouse.bird` `undefined` is vragen we eigenlijk de waarde op van `undefined.size`. Dit is ongeldig en zal een error gooien gelijk aan ``.
-#### Answer: A
+#### Antwoord: A
-In JavaScript, all objects interact by _reference_ when setting them equal to each other.
+In JavaScript worden alle objecten verwerkt _by reference_, ook wanneer we de waarde van een variabele vullen met een ander object.
-First, variable `c` holds a value to an object. Later, we assign `d` with the same reference that `c` has to the object.
+In de eerste instantie verwijst de variabele `c` naar een object. Daarna wordt de waarde van de variabele `d` gezet met de waarde van `c`. Daardoor verwijst `d` naar hetzelfde object als `c`.
-#### Answer: C
+#### Antwoord: 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.
+`new Number()` is een ingebouwde functie constructor. En ook al lijkt het misschien op een nummer, dat is het niet. Het is een object en bevat ten opzichte van een nummer veel extra opties.
-When we use the `==` operator, it only checks whether it has the same _value_. They both have the value of `3`, so it returns `true`.
+Wanneer we de `==` operator gebruiken wordt er alleen op de _waarde_ gecheckt. Zowel `a` als `b` bevatten de waarde `3`, dus geeft dit `true` terug.
-However, when we use the `===` operator, both value _and_ type should be the same. It's not: `new Number()` is not a number, it's an **object**. Both return `false.`
+Echter, wanneer we de `===` operator gebruiken wordt er zowel op de _waarde_ als op het _type_ gecheckt. Omdat `new Number()` een **object** is en geen nummer zal dit `false` teruggeven.
-#### Answer: D
+#### Antwoord: D
-The `colorChange` 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. Since `freddie` is a child, the function is not passed down, and not available on the `freddie` instance: a `TypeError` is thrown.
+De `colorChange` functie is static. Static methods zijn alleen toegankelijk binnen de class waarin ze gedefinieerd worden, en zijn niet toegankelijk voor instanties van deze class. Omdat `freddie` een instantie is van `Cameleon` zijn static functies niet beschikbaar op deze instantie: een `TypeError` wordt gegooid.
-#### Answer: A
+#### Antwoord: A
-It logs the object, because we just created an empty object on the global object! When we mistyped `greeting` as `greetign`, the JS interpreter actually saw this as `global.greetign = {}` (or `window.greetign = {}` in a browser).
+Het object wordt gelogd omdat we een leeg object hebben gedefinieerd op het global object! Wanneer we `greeting` verkeerd spellen als `greetign` ziet de JavaScript interpreter dit als `global.greetign = {}` (of `window.greetign = {}` in een browser).
-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.
+Om dit te voorkomen kunnen we gebruik maken van `"use strict"`. Dit vangt af dat de variabele gedeclareerd moet zijn voordat het een waarde krijgt.
-#### Answer: A
+#### Antwoord: A
-This is possible in JavaScript, because functions are objects! (Everything besides primitive types are objects)
+Dit is mogelijk in JavaScript, omdat functies objecten zijn! (Alles behalve primitives zijn objecten)
-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.
+Een functie is een speciaal object. De code die je schrijft is niet de uiteindelijke functie. De functie is een object met properties. Deze properties zijn gewoon benaderbaar.
-#### Answer: A
+#### Antwoord: A
-You can't add properties to a constructor like you can with regular objects. If you want to add a feature to all objects at once, you have to use the prototype instead. So in this case,
+Je kunt geen properties toevoegen aan een instantie van een object, zoals je kan met normale objecten. Als je een feature toe wilt voegen aan alle objecten in één keer zul je dit middels de prototype van een object moeten doen. In dit geval,
```js
Person.prototype.getFullName = function() {
@@ -392,7 +392,7 @@ Person.prototype.getFullName = function() {
};
```
-would have made `member.getFullName()` work. Why is this beneficial? Say that we added this method to the constructor itself. Maybe not every `Person` instance needed this method. This would waste a lot of memory space, since they would still have that property, which takes of memory space for each instance. Instead, if we only add it to the prototype, we just have it at one spot in memory, yet they all have access to it!
+Zou `member.getFullName()` aanroepbaar maken. Waarom is dit voordelig? Zeg dat we deze methode toe zouden kunnen voegen aan de instantie van een object. Misschien hebben niet alle instanties van `Person` deze methode nodig. Dit zou een hoop plaats innemen in het geheugen omdat alle objecten toch deze propertie krijgen. In plaats daarvan kunnen we het alleen aan de prototype van een object toevoegen, en wordt het maar één keer in het geheugen geplaatst, terwijl alle instanties er toch bij kunnen!
-#### Answer: A
+#### Antwoord: A
-For `sarah`, we didn't use the `new` keyword. When using `new`, it refers to the new empty object we create. However, if you don't add `new` it refers to the **global object**!
+Bij het declareren van `sarah` maakte we geen gebruik van het `new` keyword. Wanneer we `new` gebruiken refereert dit naar een nieuw object dat we aan willen maken. Als je geen gebruik maakt van `new` refereert het naar het **global object**!
-We said that `this.firstName` equals `"Sarah"` and `this.lastName` equals `"Smith"`. What we actually did, is defining `global.firstName = 'Sarah'` and `global.lastName = 'Smith'`. `sarah` itself is left `undefined`, since we don't return a value from the `Person` function.
+We zeiden dat `this.firstName` gelijk is aan `"Sarah"` en `this.lastName` gelijk is aan `"Smith"`. Wat we eigenlijk deden is `global.firstName = 'Sarah'` en `global.lastName = 'Smith'` defineren. `sarah` zelf blijft `undefined` omdat we geen waarde teruggeven van de `Person` functie.
-#### Answer: D
+#### Antwoord: D
-During the **capturing** phase, the event goes through the ancestor elements down to the target element. It then reaches the **target** element, and **bubbling** begins.
+Tijdens de **capturing** fase gaat het event door alle elementen in de boom naar beneden totaan het target element. Het komt dan bij het **target** element, en **bubbling** begint.
-#### Answer: B
+#### Antwoord: B
-All objects have prototypes, except for the **base object**. The base object is the object created by the user, or an object that is created using the `new` 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.
+Alle objecten bevatten een prototype, behalve het **base object**. Het base object is het object aangemaakt door de gebruiker, of een object dat is aangemaakt gebruikmakend van het `new` keyword. Het base object heeft toegang tot sommige methodes en properties, zoals `.toString`. Dit is de reden waarom je gebruik kan maken van ingebouwde JavaScript methodes! Al deze methodes zijn beschikbaar op het prototype. Wanneer JavaScript de methode niet direct kan vinden op het hoofd object zal het door de prototype chain naar beneden zoeken totdat het gevonden worden. Dit maakt het beschikbaar voor jou.
-#### Answer: C
+#### Antwoord: C
-JavaScript is a **dynamically typed language**: we don't specify what types certain variables are. Values can automatically be converted into another type without you knowing, which is called _implicit type coercion_. **Coercion** is converting from one type into another.
+JavaScript is een **dynamically typed language**: we specificeren niet van welk type variabelen zijn. Waarden kunnen automatisch worden geconverteerd naar andere typen zonder dat je het weet. Dit wordt _implicit type coercion_ genoemd. **Coercion** is converteren van het ene type naar het andere type.
-In this example, JavaScript converts the number `1` 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"`.
+In dit voorbeeld wordt het nummer `1` door JavaScript geconverteerd naar een string, dit om de functie logisch te maken, en de waarde teruggeven. Tijdens het optellen van het numerieke type (`1`) en een string (`'2'`) wordt het nummer gezien als een string. We kunnen strings aaneenschakelen zoals `"Hello" + "World"`. Wat er dus gebeurt hier is `"1" + "2"` wat `"12"` teruggeeft.
-#### Answer: C
+#### Antwoord: C
-The **postfix** unary operator `++`:
+De **postfix** unary operator `++`:
-1. Returns the value (this returns `0`)
-2. Increments the value (number is now `1`)
+1. Geeft de waarde terug (in dit geval `0`)
+2. Vermeerderd de waarde (number is nu `1`)
-The **prefix** unary operator `++`:
+De **prefix** unary operator `++`:
-1. Increments the value (number is now `2`)
-2. Returns the value (this returns `2`)
+1. Vermeerderd de waarde (number is nu `2`)
+2. Geeft de waarde terug (in dit geval `2`)
-This returns `0 2 2`.
+Dit geeft `0 2 2` terug.
-#### Answer: B
+#### Antwoord: 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!
+Als je gebruik maakt van taggedd template literals is de waarde van het eerste argument altijd een array van de meegegeven string waarden. De overgebleven argumenten krijgen de waarde van de doorgegeven expressies!
-#### Answer: C
+#### Antwoord: C
When testing equality, primitives are compared by their _value_, while objects are compared by their _reference_. 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 }` return `false`.
+This is why both `{ age: 18 } === { age: 18 }` en `{ age: 18 } == { age: 18 }` return `false`.
-#### Answer: C
+#### Antwoord: C
The rest parameter (`...args`.) lets us "collect" all remaining arguments into an array. An array is an object, so `typeof args` returns `"object"`
@@ -630,7 +630,7 @@ The rest parameter (`...args`.) lets us "collect" all remaining arguments into a
---
-###### 20. What's the output?
+###### 20. Wat is de uitkomst?
```javascript
function getAge() {
@@ -647,19 +647,19 @@ getAge();
- C: `ReferenceError`
- D: `TypeError`
-
-#### Answer: C
+#### Antwoord: C
-With `"use strict"`, you can make sure that you don't accidentally declare global variables. We never declared the variable `age`, 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 property `age` would have gotten added to the global object.
+With `"use strict"`, you can make sure that you don't accidentally declare global variables. We never declared the variable `age`, en since we use `"use strict"`, it will throw a reference error. If we didn't use `"use strict"`, it would have worked, since the property `age` would have gotten added to the global object.
-#### Answer: A
+#### Antwoord: A
`eval` evaluates codes that's passed as a string. If it's an expression, like in this case, it evaluates the expression. The expression is `10 * 10 + 5`. This returns the number `105`.
@@ -682,21 +682,21 @@ const sum = eval("10*10+5");
---
-###### 22. How long is cool_secret accessible?
+###### 22. Hoe lang is cool_secret benaderbaar?
```javascript
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.
+- A: Voor altijd, de data gaat niet verloren.
+- B: Wanneer de gebruiker de tab sluit.
+- C: Wanneer de gebruiker de gehele browser sluit, niet alleen de tab.
+- D: Wanneer de gebruiker zijn computer afsluit.
-
-#### Answer: B
+#### Antwoord: B
The data stored in `sessionStorage` is removed after closing the _tab_.
@@ -707,7 +707,7 @@ If you used `localStorage`, the data would've been there forever, unless for exa
---
-###### 23. What's the output?
+###### 23. Wat is de uitkomst?
```javascript
var num = 8;
@@ -721,10 +721,10 @@ console.log(num);
- C: `SyntaxError`
- D: `ReferenceError`
-
-#### Answer: B
+#### Antwoord: B
With the `var` keyword, you can declare multiple variables with the same name. The variable will then hold the latest value.
@@ -735,7 +735,7 @@ You cannot do this with `let` or `const` since they're block-scoped.
---
-###### 24. What's the output?
+###### 24. Wat is de uitkomst?
```javascript
const obj = { 1: "a", 2: "b", 3: "c" };
@@ -752,10 +752,10 @@ set.has(1);
- C: `true` `true` `false` `true`
- D: `true` `true` `true` `true`
-
-#### Answer: C
+#### Antwoord: C
All object keys (excluding Symbols) are strings under the hood, even if you don't type it yourself as a string. This is why `obj.hasOwnProperty('1')` also returns true.
@@ -766,7 +766,7 @@ It doesn't work that way for a set. There is no `'1'` in our set: `set.has('1')`
---
-###### 25. What's the output?
+###### 25. Wat is de uitkomst?
```javascript
const obj = { a: "one", b: "two", a: "three" };
@@ -778,10 +778,10 @@ console.log(obj);
- C: `{ a: "three", b: "two" }`
- D: `SyntaxError`
-
-#### Answer: C
+#### Antwoord: 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.
@@ -790,16 +790,16 @@ If you have two keys with the same name, the key will be replaced. It will still
---
-###### 26. The JavaScript global execution context creates two things for you: the global object, and the "this" keyword.
+###### 26. De JavaScript global execution context maakt twee dingen aan voor je: het globale object, en het "this" keyword.
- A: true
- B: false
-- C: it depends
+- C: het hangt er vanaf
-
-#### Answer: A
+#### Antwoord: A
The base execution context is the global execution context: it's what's accessible everywhere in your code.
@@ -808,7 +808,7 @@ The base execution context is the global execution context: it's what's accessib
---
-###### 27. What's the output?
+###### 27. Wat is de uitkomst?
```javascript
for (let i = 1; i < 5; i++) {
@@ -822,10 +822,10 @@ for (let i = 1; i < 5; i++) {
- C: `1` `2` `4`
- D: `1` `3` `4`
-
-#### Answer: C
+#### Antwoord: C
The `continue` statement skips an iteration if a certain condition returns `true`.
@@ -834,7 +834,7 @@ The `continue` statement skips an iteration if a certain condition returns `true
---
-###### 28. What's the output?
+###### 28. Wat is de uitkomst?
```javascript
String.prototype.giveLydiaPizza = () => {
@@ -851,10 +851,10 @@ name.giveLydiaPizza();
- C: `SyntaxError`
- D: `undefined`
-
-#### Answer: A
+#### Antwoord: A
`String` is a built-in constructor, which 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!
@@ -863,7 +863,7 @@ name.giveLydiaPizza();
---
-###### 29. What's the output?
+###### 29. Wat is de uitkomst?
```javascript
const a = {};
@@ -881,10 +881,10 @@ console.log(a[b]);
- C: `undefined`
- D: `ReferenceError`
-
-#### Answer: B
+#### Antwoord: B
Object keys are automatically converted into strings. We are trying to set an object as a key to object `a`, with the value of `123`.
@@ -897,7 +897,7 @@ Then, we log `a[b]`, which is actually `a["object Object"]`. We just set that to
---
-###### 30. What's the output?
+###### 30. Wat is de uitkomst?
```javascript
const foo = () => console.log("First");
@@ -914,24 +914,24 @@ baz();
- C: `Second` `First` `Third`
- D: `Second` `Third` `First`
-
-#### Answer: B
+#### Antwoord: B
-We have a `setTimeout` function and invoked it first. Yet, it was logged last.
+We have a `setTimeout` function en 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 a `WebAPI`. The `WebAPI` gives us the `setTimeout` function to start with, and for example the DOM.
+This is because in browsers, we don't just have the runtime engine, we also have something called a `WebAPI`. The `WebAPI` gives us the `setTimeout` function to start with, en for example the DOM.
After the _callback_ is pushed to the WebAPI, the `setTimeout` function itself (but not the callback!) is popped off the stack.
-#### Answer: C
+#### Antwoord: C
The deepest nested element that caused the event is the target of the event. You can stop bubbling by `event.stopPropagation`
@@ -979,7 +979,7 @@ The deepest nested element that caused the event is the target of the event. You
---
-###### 32. When you click the paragraph, what's the logged output?
+###### 32. Wat wordt er gelogd wanneer je op de paragraaf klikt?
```html
-#### Answer: A
+#### Antwoord: A
-If we click `p`, we see two logs: `p` and `div`. During event propagation, there are 3 phases: capturing, target, and bubbling. By default, event handlers are executed in the bubbling phase (unless you set `useCapture` to `true`). It goes from the deepest nested element outwards.
+If we click `p`, we see two logs: `p` en `div`. During event propagation, there are 3 phases: capturing, target, en bubbling. By default, event handlers are executed in the bubbling phase (unless you set `useCapture` to `true`). It goes from the deepest nested element outwards.
-#### Answer: D
+#### Antwoord: D
With both, we can pass the object to which we want the `this` keyword to refer to. However, `.call` is also _executed immediately_!
@@ -1038,7 +1038,7 @@ With both, we can pass the object to which we want the `this` keyword to refer t
---
-###### 34. What's the output?
+###### 34. Wat is de uitkomst?
```javascript
function sayHi() {
@@ -1053,20 +1053,20 @@ console.log(typeof sayHi());
- C: `"function"`
- D: `"undefined"`
-
-#### Answer: B
+#### Antwoord: B
The `sayHi` function returns the returned value of the immediately invoked function (IIFE). This function returned `0`, which is type `"number"`.
-FYI: there are only 7 built-in types: `null`, `undefined`, `boolean`, `number`, `string`, `object`, and `symbol`. `"function"` is not a type, since functions are objects, it's of type `"object"`.
+FYI: there are only 7 built-in types: `null`, `undefined`, `boolean`, `number`, `string`, `object`, en `symbol`. `"function"` is not a type, since functions are objects, it's of type `"object"`.
-#### Answer: A
+#### Antwoord: A
There are only six falsy values:
@@ -1096,14 +1096,14 @@ There are only six falsy values:
- `''` (empty string)
- `false`
-Function constructors, like `new Number` and `new Boolean` are truthy.
+Function constructors, like `new Number` en `new Boolean` are truthy.
-#### Answer: B
+#### Antwoord: B
`typeof 1` returns `"number"`.
`typeof "number"` returns `"string"`
@@ -1127,7 +1127,7 @@ console.log(typeof typeof 1);
---
-###### 37. What's the output?
+###### 37. Wat is de uitkomst?
```javascript
const numbers = [1, 2, 3];
@@ -1140,10 +1140,10 @@ console.log(numbers);
- C: `[1, 2, 3, 7 x empty, 11]`
- D: `SyntaxError`
-
-#### Answer: C
+#### Antwoord: 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 of `undefined`, but you will see something like:
@@ -1156,7 +1156,7 @@ depending on where you run it (it's different for every browser, node, etc.)
---
-###### 38. What's the output?
+###### 38. Wat is de uitkomst?
```javascript
(() => {
@@ -1177,46 +1177,46 @@ depending on where you run it (it's different for every browser, node, etc.)
- C: `1` `1` `2`
- D: `1` `undefined` `undefined`
-
-#### Answer: A
+#### Antwoord: A
The `catch` block receives the argument `x`. This is not the same `x` as the variable when we pass arguments. This variable `x` is block-scoped.
-Later, we set this block-scoped variable equal to `1`, and set the value of the variable `y`. Now, we log the block-scoped variable `x`, which is equal to `1`.
+Later, we set this block-scoped variable equal to `1`, en set the value of the variable `y`. Now, we log the block-scoped variable `x`, which is equal to `1`.
-Outside of the `catch` block, `x` is still `undefined`, and `y` is `2`. When we want to `console.log(x)` outside of the `catch` block, it returns `undefined`, and `y` returns `2`.
+Outside of the `catch` block, `x` is still `undefined`, en `y` is `2`. When we want to `console.log(x)` outside of the `catch` block, it returns `undefined`, en `y` returns `2`.
-#### Answer: A
+#### Antwoord: A
-JavaScript only has primitive types and objects.
+JavaScript only has primitive types en objects.
-Primitive types are `boolean`, `null`, `undefined`, `bigint`, `number`, `string`, and `symbol`.
+Primitive types are `boolean`, `null`, `undefined`, `bigint`, `number`, `string`, en `symbol`.
-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 a `TypeError`. This is because when you try to access a property or method on a primitive like a string, JavaScript will implicitly wrap the object using one of the wrapper classes, i.e. `String`, and then immediately discard the wrapper after the expression evaluates. All primitives except for `null` and `undefined` exhibit this behaviour.
+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'` en does not result in a `TypeError`. This is because when you try to access a property or method on a primitive like a string, JavaScript will implicitly wrap the object using one of the wrapper classes, i.e. `String`, en then immediately discard the wrapper after the expression evaluates. All primitives except for `null` en `undefined` exhibit this behaviour.
-#### Answer: C
+#### Antwoord: C
-`[1, 2]` is our initial value. This is the value we start with, and the value of the very first `acc`. During the first round, `acc` is `[1,2]`, and `cur` is `[0, 1]`. We concatenate them, which results in `[1, 2, 0, 1]`.
+`[1, 2]` is our initial value. This is the value we start with, en the value of the very first `acc`. During the first round, `acc` is `[1,2]`, en `cur` is `[0, 1]`. We concatenate them, which results in `[1, 2, 0, 1]`.
-Then, `[1, 2, 0, 1]` is `acc` and `[2, 3]` is `cur`. We concatenate them, and get `[1, 2, 0, 1, 2, 3]`
+Then, `[1, 2, 0, 1]` is `acc` en `[2, 3]` is `cur`. We concatenate them, en get `[1, 2, 0, 1, 2, 3]`
-#### Answer: B
+#### Antwoord: B
`null` is falsy. `!null` returns `true`. `!true` returns `false`.
@@ -1275,21 +1275,21 @@ Then, `[1, 2, 0, 1]` is `acc` and `[2, 3]` is `cur`. We concatenate them, and ge
---
-###### 42. What does the `setInterval` method return in the browser?
+###### 42. Wat geeft de `setInterval` methode terug in de browser?
```javascript
setInterval(() => console.log("Hi"), 1000);
```
-- A: a unique id
-- B: the amount of milliseconds specified
-- C: the passed function
+- A: een uniek id
+- B: het aantal opgegeven milliseconden
+- C: de doorgegeven functie
- D: `undefined`
-
-#### Answer: A
+#### Antwoord: A
It returns a unique id. This id can be used to clear that interval with the `clearInterval()` function.
@@ -1298,7 +1298,7 @@ It returns a unique id. This id can be used to clear that interval with the `cle
---
-###### 43. What does this return?
+###### 43. Wat geeft dit terug?
```javascript
[..."Lydia"];
@@ -1309,10 +1309,10 @@ It returns a unique id. This id can be used to clear that interval with the `cle
- C: `[[], "Lydia"]`
- D: `[["L", "y", "d", "i", "a"]]`
-
-#### Answer: A
+#### Antwoord: A
A string is an iterable. The spread operator maps every character of an iterable to one element.
@@ -1321,7 +1321,7 @@ A string is an iterable. The spread operator maps every character of an iterable
---
-###### 44. What's the output?
+###### 44. Wat is de uitkomst?
```javascript
function* generator(i) {
@@ -1338,25 +1338,25 @@ console.log(gen.next().value);
- A: `[0, 10], [10, 20]`
- B: `20, 20`
- C: `10, 20`
-- D: `0, 10 and 10, 20`
+- D: `0, 10 en 10, 20`
-
-#### Answer: C
+#### Antwoord: 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 a `yield` keyword, the function yields the value specified after it. Note that the generator function in that case doesn’t _return_ the value, it _yields_ the value.
+Regular functions cannot be stopped mid-way after invocation. However, a generator function can be "stopped" midway, en later continue from where it stopped. Every time a generator function encounters a `yield` keyword, the function yields the value specified after it. Note that the generator function in that case doesn’t _return_ the value, it _yields_ the value.
-First, we initialize the generator function with `i` equal to `10`. We invoke the generator function using the `next()` method. The first time we invoke the generator function, `i` is equal to `10`. It encounters the first `yield` keyword: it yields the value of `i`. The generator is now "paused", and `10` gets logged.
+First, we initialize the generator function with `i` equal to `10`. We invoke the generator function using the `next()` method. The first time we invoke the generator function, `i` is equal to `10`. It encounters the first `yield` keyword: it yields the value of `i`. The generator is now "paused", en `10` gets logged.
-Then, we invoke the function again with the `next()` method. It starts to continue where it stopped previously, still with `i` equal to `10`. Now, it encounters the next `yield` keyword, and yields `i * 2`. `i` is equal to `10`, so it returns `10 * 2`, which is `20`. This results in `10, 20`.
+Then, we invoke the function again with the `next()` method. It starts to continue where it stopped previously, still with `i` equal to `10`. Now, it encounters the next `yield` keyword, en yields `i * 2`. `i` is equal to `10`, so it returns `10 * 2`, which is `20`. This results in `10, 20`.
-#### Answer: B
+#### Antwoord: B
-When we pass multiple promises to the `Promise.race` method, it resolves/rejects the _first_ promise that resolves/rejects. To the `setTimeout` method, we pass a timer: 500ms for the first promise (`firstPromise`), and 100ms for the second promise (`secondPromise`). This means that the `secondPromise` resolves first with the value of `'two'`. `res` now holds the value of `'two'`, which gets logged.
+When we pass multiple promises to the `Promise.race` method, it resolves/rejects the _first_ promise that resolves/rejects. To the `setTimeout` method, we pass a timer: 500ms for the first promise (`firstPromise`), en 100ms for the second promise (`secondPromise`). This means that the `secondPromise` resolves first with the value of `'two'`. `res` now holds the value of `'two'`, which gets logged.
-#### Answer: D
+#### Antwoord: D
First, we declare a variable `person` with the value of an object that has a `name` property.
@@ -1419,14 +1419,14 @@ Then, we set the variable `person` equal to `null`.
-#### Answer: B
+#### Antwoord: B
-With a `for-in` loop, we can iterate through object keys, in this case `name` and `age`. Under the hood, object keys are strings (if they're not a Symbol). On every loop, we set the value of `item` equal to the current key it’s iterating over. First, `item` is equal to `name`, and gets logged. Then, `item` is equal to `age`, which gets logged.
+With a `for-in` loop, we can iterate through object keys, in this case `name` en `age`. Under the hood, object keys are strings (if they're not a Symbol). On every loop, we set the value of `item` equal to the current key it’s iterating over. First, `item` is equal to `name`, en gets logged. Then, `item` is equal to `age`, which gets logged.
-#### Answer: B
+#### Antwoord: 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 the _same_ precedence. We only have one type of operator: `+`. For addition, the associativity is left-to-right.
@@ -1483,7 +1483,7 @@ Operator associativity is the order in which the compiler evaluates the expressi
---
-###### 49. What's the value of `num`?
+###### 49. Wat is de waarde van `num`?
```javascript
const num = parseInt("7*6", 10);
@@ -1494,12 +1494,12 @@ const num = parseInt("7*6", 10);
- C: `7`
- D: `NaN`
-
-#### Answer: C
+#### Antwoord: C
-Only the first numbers in the string is returned. Based on the _radix_ (the second argument in order to specify what type of number we want to parse it to: base 10, hexadecimal, octal, binary, etc.), the `parseInt` 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.
+Only the first numbers in the string is returned. Based on the _radix_ (the second argument in order to specify what type of number we want to parse it to: base 10, hexadecimal, octal, binary, etc.), the `parseInt` 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 en ignores the following characters.
`*` is not a valid number. It only parses `"7"` into the decimal `7`. `num` now holds the value of `7`.
@@ -1508,7 +1508,7 @@ Only the first numbers in the string is returned. Based on the _radix_ (the seco
---
-###### 50. What's the output`?
+###### 50. Wat is de uitkomst?
```javascript
[1, 2, 3].map(num => {
@@ -1522,12 +1522,12 @@ Only the first numbers in the string is returned. Based on the _radix_ (the seco
- C: `[undefined, undefined, undefined]`
- D: `[ 3 x empty ]`
-
-#### Answer: C
+#### Antwoord: C
-When mapping over the array, the value of `num` is equal to the element it’s currently looping over. In this case, the elements are numbers, so the condition of the if statement `typeof num === "number"` returns `true`. The map function creates a new array and inserts the values returned from the function.
+When mapping over the array, the value of `num` is equal to the element it’s currently looping over. In this case, the elements are numbers, so the condition of the if statement `typeof num === "number"` returns `true`. The map function creates a new array en 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 returns `undefined`. For every element in the array, the function block gets called, so for each element we return `undefined`.
@@ -1536,7 +1536,7 @@ However, we don’t return a value. When we don’t return a value from the func
---
-###### 51. What's the output?
+###### 51. Wat is de uitkomst?
```javascript
function getInfo(member, year) {
@@ -1557,10 +1557,10 @@ console.log(person, birthYear);
- C: `{ name: "Lydia" }, "1998"`
- D: `{ name: "Sarah" }, "1997"`
-
-#### Answer: A
+#### Antwoord: A
Arguments are passed by _value_, unless their value is an object, then they're passed by _reference_. `birthYear` is passed by value, since it's a string, not an object. When we pass arguments by value, a _copy_ of that value is created (see question 46).
@@ -1573,7 +1573,7 @@ The value of `person` is an object. The argument `member` has a (copied) referen
---
-###### 52. What's the output?
+###### 52. Wat is de uitkomst?
```javascript
function greeting() {
@@ -1597,10 +1597,10 @@ sayHi();
- C: `SyntaxError: can only throw Error objects`
- D: `Oh no an error: Hello world!`
-
-#### Answer: D
+#### Antwoord: D
With the `throw` statement, we can create custom errors. With this statement, you can throw exceptions. An exception can be a string, a number, a boolean or an object. In this case, our exception is the string `'Hello world'`.
@@ -1611,7 +1611,7 @@ With the `catch` statement, we can specify what to do if an exception is thrown
---
-###### 53. What's the output?
+###### 53. Wat is de uitkomst?
```javascript
function Car() {
@@ -1628,10 +1628,10 @@ console.log(myCar.make);
- C: `ReferenceError`
- D: `TypeError`
-
-#### Answer: B
+#### Antwoord: B
When you return a property, the value of the property is equal to the _returned_ value, not the value set in the constructor function. We return the string `"Maserati"`, so `myCar.make` is equal to `"Maserati"`.
@@ -1640,7 +1640,7 @@ When you return a property, the value of the property is equal to the _returned_
---
-###### 54. What's the output?
+###### 54. Wat is de uitkomst?
```javascript
(() => {
@@ -1656,10 +1656,10 @@ console.log(typeof y);
- C: `"object", "number"`
- D: `"number", "undefined"`
-
-#### Answer: A
+#### Antwoord: A
`let x = y = 10;` is actually shorthand for:
@@ -1672,14 +1672,14 @@ When we set `y` equal to `10`, we actually add a property `y` to the global obje
Then, we declare a variable `x` with the value of `y`, which is `10`. Variables declared with the `let` keyword are _block scoped_, they are only defined within the block they're declared in; the immediately-invoked function (IIFE) in this case. When we use the `typeof` operator, the operand `x` is not defined: we are trying to access `x` outside of the block it's declared in. This means that `x` 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 variable `y` when setting `y` equal to `10`. This value is accessible anywhere in our code. `y` is defined, and holds a value of type `"number"`. `console.log(typeof y)` returns `"number"`.
+However, we created a global variable `y` when setting `y` equal to `10`. This value is accessible anywhere in our code. `y` is defined, en holds a value of type `"number"`. `console.log(typeof y)` returns `"number"`.
-#### Answer: A
+#### Antwoord: A
We can delete properties from objects using the `delete` keyword, also on the prototype. By deleting a property on the prototype, it is not available anymore in the prototype chain. In this case, the `bark` function is not available anymore on the prototype after `delete Dog.prototype.bark`, yet we still try to access it.
@@ -1720,7 +1720,7 @@ When we try to invoke something that is not a function, a `TypeError` is thrown.
---
-###### 56. What's the output?
+###### 56. Wat is de uitkomst?
```javascript
const set = new Set([1, 1, 2, 3, 4]);
@@ -1733,10 +1733,10 @@ console.log(set);
- C: `{1, 1, 2, 3, 4}`
- D: `{1, 2, 3, 4}`
-
-#### Answer: D
+#### Antwoord: D
The `Set` object is a collection of _unique_ values: a value can only occur once in a set.
@@ -1747,7 +1747,7 @@ We passed the iterable `[1, 1, 2, 3, 4]` with a duplicate value `1`. Since we ca
---
-###### 57. What's the output?
+###### 57. Wat is de uitkomst?
```javascript
// counter.js
@@ -1769,21 +1769,21 @@ console.log(myCounter);
- C: `Error`
- D: `NaN`
-
-#### Answer: C
+#### Antwoord: C
An imported module is _read-only_: you cannot modify the imported module. Only the module that exports them can change its value.
-When we try to increment the value of `myCounter`, it throws an error: `myCounter` is read-only and cannot be modified.
+When we try to increment the value of `myCounter`, it throws an error: `myCounter` is read-only en cannot be modified.
-#### Answer: A
+#### Antwoord: A
The `delete` operator returns a boolean value: `true` on a successful deletion, else it'll return `false`. However, variables declared with the `var`, `const` or `let` keyword cannot be deleted using the `delete` operator.
@@ -1812,7 +1812,7 @@ The `name` variable was declared with a `const` keyword, so its deletion is not
---
-###### 59. What's the output?
+###### 59. Wat is de uitkomst?
```javascript
const numbers = [1, 2, 3, 4, 5];
@@ -1826,10 +1826,10 @@ console.log(y);
- C: `1`
- D: `[1]`
-
-#### Answer: C
+#### Antwoord: C
We can unpack values from arrays or properties from objects through destructuring. For example:
@@ -1839,7 +1839,7 @@ We can unpack values from arrays or properties from objects through destructurin
-#### Answer: B
+#### Antwoord: 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 the `user` object, and add them to the `admin` object. The `admin` object now contains the copied key/value pairs, which results in `{ admin: true, name: "Lydia", age: 21 }`.
+It's possible to combine objects using the spread operator `...`. It lets you create copies of the key/value pairs of one object, en add them to another object. In this case, we create copies of the `user` object, en add them to the `admin` object. The `admin` object now contains the copied key/value pairs, which results in `{ admin: true, name: "Lydia", age: 21 }`.
-#### Answer: B
+#### Antwoord: B
With the `defineProperty` method, we can add new properties to an object, or modify existing ones. When we add a property to an object using the `defineProperty` method, they are by default _not enumerable_. The `Object.keys` method returns all _enumerable_ property names from an object, in this case only `"name"`.
-Properties added using the `defineProperty` method are immutable by default. You can override this behavior using the `writable`, `configurable` and `enumerable` properties. This way, the `defineProperty` method gives you a lot more control over the properties you're adding to an object.
+Properties added using the `defineProperty` method are immutable by default. You can override this behavior using the `writable`, `configurable` en `enumerable` properties. This way, the `defineProperty` method gives you a lot more control over the properties you're adding to an object.
-#### Answer: A
+#### Antwoord: A
-The second argument of `JSON.stringify` is the _replacer_. The replacer can either be a function or an array, and lets you control what and how the values should be stringified.
+The second argument of `JSON.stringify` is the _replacer_. The replacer can either be a function or an array, en lets you control what en how the values should be stringified.
-If the replacer is an _array_, 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 an _array_, 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"` en `"health"` are included, `"username"` is excluded. `data` is now equal to `"{"level":19, "health":90}"`.
If the replacer is a _function_, 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 is `undefined`, this property is excluded from the JSON string.
@@ -1944,7 +1944,7 @@ If the replacer is a _function_, this function gets called on every property in
---
-###### 63. What's the output?
+###### 63. Wat is de uitkomst?
```javascript
let num = 10;
@@ -1964,12 +1964,12 @@ console.log(num2);
- C: `11`, `11`
- D: `11`, `12`
-
-#### Answer: A
+#### Antwoord: A
-The unary operator `++` _first returns_ the value of the operand, _then increments_ the value of the operand. The value of `num1` is `10`, since the `increaseNumber` function first returns the value of `num`, which is `10`, and only increments the value of `num` afterwards.
+The unary operator `++` _first returns_ the value of the operand, _then increments_ the value of the operand. The value of `num1` is `10`, since the `increaseNumber` function first returns the value of `num`, which is `10`, en only increments the value of `num` afterwards.
`num2` is `10`, since we passed `num1` to the `increasePassedNumber`. `number` is equal to `10`(the value of `num1`. Again, the unary operator `++` _first returns_ the value of the operand, _then increments_ the value of the operand. The value of `number` is `10`, so `num2` is equal to `10`.
@@ -1978,7 +1978,7 @@ The unary operator `++` _first returns_ the value of the operand, _then incremen
---
-###### 64. What's the output?
+###### 64. Wat is de uitkomst?
```javascript
const value = { number: 10 };
@@ -1998,16 +1998,16 @@ multiply(value);
- C: `20`, `20`, `20`, `40`
- D: `NaN`, `NaN`, `20`, `40`
-
-#### Answer: C
+#### Antwoord: 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 the `value` object into a new object, so `x` has the default value of `{ number: 10 }`.
The default argument is evaluated at _call time_! Every time we call the function, a _new_ object is created. We invoke the `multiply` 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 is `20`.
-The third time we invoke multiply, we do pass an argument: the object called `value`. The `*=` operator is actually shorthand for `x.number = x.number * 2`: we modify the value of `x.number`, and log the multiplied value `20`.
+The third time we invoke multiply, we do pass an argument: the object called `value`. The `*=` operator is actually shorthand for `x.number = x.number * 2`: we modify the value of `x.number`, en log the multiplied value `20`.
The fourth time, we pass the `value` object again. `x.number` was previously modified to `20`, so `x.number *= 2` logs `40`.
@@ -2016,39 +2016,39 @@ The fourth time, we pass the `value` object again. `x.number` was previously mod
---
-###### 65. What's the output?
+###### 65. Wat is de uitkomst?
```javascript
[1, 2, 3, 4].reduce((x, y) => console.log(x, y));
```
-- A: `1` `2` and `3` `3` and `6` `4`
-- B: `1` `2` and `2` `3` and `3` `4`
-- C: `1` `undefined` and `2` `undefined` and `3` `undefined` and `4` `undefined`
-- D: `1` `2` and `undefined` `3` and `undefined` `4`
+- A: `1` `2` en `3` `3` en `6` `4`
+- B: `1` `2` en `2` `3` en `3` `4`
+- C: `1` `undefined` en `2` `undefined` en `3` `undefined` en `4` `undefined`
+- D: `1` `2` en `undefined` `3` en `undefined` `4`
-
-#### Answer: D
+#### Antwoord: D
The first argument that the `reduce` method receives is the _accumulator_, `x` in this case. The second argument is the _current 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.
+In this example, we are not returning any values, we are simply logging the values of the accumulator en 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 optional `initialValue` argument to the `reduce` method, the accumulator is equal to the first element on the first call.
-On the first call, the accumulator (`x`) is `1`, and the current value (`y`) is `2`. We don't return from the callback function, we log the accumulator and current value: `1` and `2` get logged.
+On the first call, the accumulator (`x`) is `1`, en the current value (`y`) is `2`. We don't return from the callback function, we log the accumulator en current value: `1` en `2` get logged.
-If you don't return a value from a function, it returns `undefined`. On the next call, the accumulator is `undefined`, and the current value is `3`. `undefined` and `3` get logged.
+If you don't return a value from a function, it returns `undefined`. On the next call, the accumulator is `undefined`, en the current value is `3`. `undefined` en `3` get logged.
-On the fourth call, we again don't return from the callback function. The accumulator is again `undefined`, and the current value is `4`. `undefined` and `4` get logged.
+On the fourth call, we again don't return from the callback function. The accumulator is again `undefined`, en the current value is `4`. `undefined` en `4` get logged.
-#### Answer: B
+#### Antwoord: B
-In a derived class, you cannot access the `this` keyword before calling `super`. If you try to do that, it will throw a ReferenceError: 1 and 4 would throw a reference error.
+In a derived class, you cannot access the `this` keyword before calling `super`. If you try to do that, it will throw a ReferenceError: 1 en 4 would throw a reference error.
With the `super` keyword, we call that parent class's constructor with the given arguments. The parent's constructor receives the `name` argument, so we need to pass `name` to `super`.
-The `Labrador` class receives two arguments, `name` since it extends `Dog`, and `size` as an extra property on the `Labrador` class. They both need to be passed to the constructor function on `Labrador`, which is done correctly using constructor 2.
+The `Labrador` class receives two arguments, `name` since it extends `Dog`, en `size` as an extra property on the `Labrador` class. They both need to be passed to the constructor function on `Labrador`, which is done correctly using constructor 2.
-#### Answer: B
+#### Antwoord: B
With the `import` keyword, all imported modules are _pre-parsed_. This means that the imported modules get run _first_, the code in the file which imports the module gets executed _after_.
-This is a difference between `require()` in CommonJS and `import`! With `require()`, you can load dependencies on demand while the code is being run. If we would have used `require` instead of `import`, `running index.js`, `running sum.js`, `3` would have been logged to the console.
+This is a difference between `require()` in CommonJS en `import`! With `require()`, you can load dependencies on demand while the code is being run. If we would have used `require` instead of `import`, `running index.js`, `running sum.js`, `3` would have been logged to the console.
-#### Answer: A
+#### Antwoord: 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 first `Symbol('foo')`, and the second `Symbol('foo')`. These two values are unique and not equal to each other, `Symbol('foo') === Symbol('foo')` returns `false`.
+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 first `Symbol('foo')`, en the second `Symbol('foo')`. These two values are unique en not equal to each other, `Symbol('foo') === Symbol('foo')` returns `false`.
-#### Answer: C
+#### Antwoord: C
With the `padStart` method, we can add padding to the beginning of a string. The value passed to this method is the _total_ length of the string together with the padding. The string `"Lydia Hallie"` has a length of `12`. `name.padStart(13)` inserts 1 space at the start of the string, because 12 + 1 is 13.
@@ -2185,7 +2185,7 @@ If the argument passed to the `padStart` method is smaller than the length of th
---
-###### 70. What's the output?
+###### 70. Wat is de uitkomst?
```javascript
console.log("🥑" + "💻");
@@ -2193,13 +2193,13 @@ console.log("🥑" + "💻");
- A: `"🥑💻"`
- B: `257548`
-- C: A string containing their code points
+- C: Een string die hun code points bevat
- D: Error
-
-#### Answer: A
+#### Antwoord: A
With the `+` operator, you can concatenate strings. In this case, we are concatenating the string `"🥑"` with the string `"💻"`, resulting in `"🥑💻"`.
@@ -2208,7 +2208,7 @@ With the `+` operator, you can concatenate strings. In this case, we are concate
---
-###### 71. How can we log the values that are commented out after the console.log statement?
+###### 71. Hoe kunnen we de waarden loggen die uitgecommentarieerd zijn achter de console.log statement?
```javascript
function* startGame() {
@@ -2224,28 +2224,28 @@ console.log(/* 1 */); // Do you love JavaScript?
console.log(/* 2 */); // JavaScript loves you back ❤️
```
-- A: `game.next("Yes").value` and `game.next().value`
-- B: `game.next.value("Yes")` and `game.next.value()`
-- C: `game.next().value` and `game.next("Yes").value`
-- D: `game.next.value()` and `game.next.value("Yes")`
+- A: `game.next("Yes").value` en `game.next().value`
+- B: `game.next.value("Yes")` en `game.next.value()`
+- C: `game.next().value` en `game.next("Yes").value`
+- D: `game.next.value()` en `game.next.value("Yes")`
-
-#### Answer: C
+#### Antwoord: C
A generator function "pauses" its execution when it sees the `yield` keyword. First, we have to let the function yield the string "Do you love JavaScript?", which can be done by calling `game.next().value`.
Every line is executed, until it finds the first `yield` keyword. There is a `yield` keyword on the first line within the function: the execution stops with the first yield! _This means that the variable `answer` is not defined yet!_
-When we call `game.next("Yes").value`, the previous `yield` is replaced with the value of the parameters passed to the `next()` function, `"Yes"` in this case. The value of the variable `answer` is now equal to `"Yes"`. The condition of the if-statement returns `false`, and `JavaScript loves you back ❤️` gets logged.
+When we call `game.next("Yes").value`, the previous `yield` is replaced with the value of the parameters passed to the `next()` function, `"Yes"` in this case. The value of the variable `answer` is now equal to `"Yes"`. The condition of the if-statement returns `false`, en `JavaScript loves you back ❤️` gets logged.
-#### Answer: C
+#### Antwoord: 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:
@@ -2269,7 +2269,7 @@ Which would result in:
`"C:DocumentsProjects able.html"`
-With `String.raw`, it would simply ignore the escape and print:
+With `String.raw`, it would simply ignore the escape en print:
`C:\Documents\Projects\table.html`
@@ -2280,7 +2280,7 @@ In this case, the string is `Hello\nworld`, which gets logged.
---
-###### 73. What's the output?
+###### 73. Wat is de uitkomst?
```javascript
async function getData() {
@@ -2296,10 +2296,10 @@ console.log(data);
- C: `Promise {答案
答案
答案
答案
答案
答案
答案
答案
答案
答案
答案
答案
答案
答案
-
JavaScript Questions
+ JavaScript Vragen
---
- I post multiple choice JavaScript questions on my [Instagram](https://www.instagram.com/theavocoder) **stories**, which I'll also post here! Last updated: December 24th
+ Ik plaats JavaScript meerkeuzevragen op mijn [Instagram](https://www.instagram.com/theavocoder) **stories**, welke ik ook hier zal plaatsen! Laatste update: 24 december
- From basic to advanced: test how well you know JavaScript, refresh your knowledge a bit, or prepare for your coding interview! :muscle: :rocket: 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! :heart:
+ Van beginner naar expert: test hoe goed je JavaScript kent, fris je kennis een beetje op, of bereid je voor op een sollicitatiegesprek! :muscle: :rocket: Ik zal deze repository regelmatig updaten met nieuwe vragen. Ik heb de antwoorden toegevoegd in de **ingeklapte secties** onder een vraag, zodat je er makkelijk op kan klikken om ze uit te klappen. Het is gewoon voor je plezier, veel succes! :heart:
- Feel free to reach out to me! 😊
+ Voel je vrij om contact met mij op te nemen! 😊
Instagram || Twitter || LinkedIn || Blog
See 17 Available Translations 🇪🇸🇮🇹🇩🇪 🇫🇷🇷🇺🇨🇳🇵🇹
+ Zie alle 17 beschikbare vertalingen
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
-When you change one object, you change all of them.
+Wanneer je één object veranderd, verander je ze allemaal.
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
From 24c8f75246d743771005d4dcd555dd97e1c74402 Mon Sep 17 00:00:00 2001
From: Tarabass
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
-Now, `foo` gets invoked, and `"First"` is being logged.
+Now, `foo` gets invoked, en `"First"` is being logged.
-`foo` is popped off the stack, and `baz` gets invoked. `"Third"` gets logged.
+`foo` is popped off the stack, en `baz` gets invoked. `"Third"` gets logged.
@@ -939,18 +939,18 @@ The WebAPI can't just add stuff to the stack whenever it's ready. Instead, it pu
-This is where an event loop starts to work. An **event 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.
+This is where an event loop starts to work. An **event loop** looks at the stack en task queue. If the stack is empty, it takes the first thing on the queue en pushes it onto the stack.
-`bar` gets invoked, `"Second"` gets logged, and it's popped off the stack.
+`bar` gets invoked, `"Second"` gets logged, en it's popped off the stack.
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
-We are only modifying the value of the `person` variable, and not the first element in the array, since that element has a different (copied) reference to the object. The first element in `members` still holds its reference to the original object. When we log the `members` array, the first element still holds the value of the object, which gets logged.
+We are only modifying the value of the `person` variable, en not the first element in the array, since that element has a different (copied) reference to the object. The first element in `members` still holds its reference to the original object. When we log the `members` array, the first element still holds the value of the object, which gets logged.
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
-The value of `a` is now `1`, and the value of `b` is now `2`. What we actually did in the question, is:
+The value of `a` is now `1`, en the value of `b` is now `2`. What we actually did in the question, is:
```javascript
[y] = [1, 2, 3, 4, 5];
@@ -1854,7 +1854,7 @@ This means that the value of `y` is equal to the first value in the array, which
---
-###### 60. What's the output?
+###### 60. Wat is de uitkomst?
```javascript
const user = { name: "Lydia", age: 21 };
@@ -1868,19 +1868,19 @@ console.log(admin);
- C: `{ admin: true, user: ["Lydia", 21] }`
- D: `{ admin: true }`
-
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
Answer
+Antwoord
`world`
-Answer
+Antwoord