diff --git a/README.md b/README.md index 07b0c2cf..b203a060 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,53 @@ -# List of (Advanced) JavaScript Questions +
+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:
-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 weekly with new questions. Last update: August 17th +Feel free to reach out to me! 😊
-The answers are in the collapsed sections below the questions, simply click on them to expand it. Good luck :heart: ++ Instagram || Twitter || LinkedIn || Blog +
-Want to get an email whenever I've added more questions?-List of available languages: -* [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) +- [🇸🇦 العربية](./ar-AR/README_AR.md) +- [🇪🇬 اللغة العامية](./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) +- [🇮🇩 Indonesia](./id-ID/README.md) +- [🇮🇹 Italiano](./it-IT/README.md) +- [🇯🇵 日本語](./ja-JA/README-ja_JA.md) +- [🇰🇷 한국어](./ko-KR/README-ko_KR.md) +- [🇳🇱 Nederlands](./nl-NL/README.md) +- [🇵🇱 Polski](./pl-PL/README.md) +- [🇧🇷 Português Brasil](./pt-BR/README_pt_BR.md) +- [🇷o Română](./ro-RO/README.ro.md) +- [🇷🇺 Русский](./ru-RU/README.md) +- [🇽🇰 Shqip](./sq-KS/README_sq_KS.md) +- [🇹🇭 ไทย](./th-TH/README-th_TH.md) +- [🇹🇷 Türkçe](./tr-TR/README-tr_TR.md) +- [🇺🇦 Українська мова](./uk-UA/README.md) +- [🇻🇳 Tiếng Việt](./vi-VI/README-vi.md) +- [🇨🇳 简体中文](./zh-CN/README-zh_CN.md) +- [🇹🇼 繁體中文](./zh-TW/README_zh-TW.md) +
+#### 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**! +For `sarah`, we didn't use the `new` keyword. When using `new`, `this` refers to the new empty object we create. However, if you don't add `new`, `this` 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. @@ -468,7 +493,7 @@ function sum(a, b) { return a + b; } -sum(1, "2"); +sum(1, '2'); ``` - A: `NaN` @@ -535,7 +560,7 @@ function getPersonInfo(one, two, three) { console.log(three); } -const person = "Lydia"; +const person = 'Lydia'; const age = 21; getPersonInfo`${person} is ${age} years old`; @@ -562,9 +587,9 @@ If you use tagged template literals, the value of the first argument is always a ```javascript function checkAge(data) { if (data === { age: 18 }) { - console.log("You are an adult!"); + console.log('You are an adult!'); } else if (data == { age: 18 }) { - console.log("You are still an adult."); + console.log('You are still an adult.'); } else { console.log(`Hmm.. You don't have an age I guess`); } @@ -613,7 +638,7 @@ getAge(21); #### 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"` +The rest parameter (`...args`) lets us "collect" all remaining arguments into an array. An array is an object, so `typeof args` returns `"object"`
@@ -2178,7 +2210,7 @@ If the argument passed to the `padStart` method is smaller than the length of th ###### 70. What's the output? ```javascript -console.log("🥑" + "💻"); +console.log('🥑' + '💻'); ``` - A: `"🥑💻"` @@ -2202,11 +2234,11 @@ With the `+` operator, you can concatenate strings. In this case, we are concate ```javascript function* startGame() { - const answer = yield "Do you love JavaScript?"; - if (answer !== "Yes") { - return "Oh wow... Guess we're gone here"; + const answer = yield 'Do you love JavaScript?'; + if (answer !== 'Yes') { + return "Oh wow... Guess we're done here"; } - return "JavaScript loves you back ❤️"; + return 'JavaScript loves you back ❤️'; } const game = startGame(); @@ -2274,7 +2306,7 @@ In this case, the string is `Hello\nworld`, which gets logged. ```javascript async function getData() { - return await Promise.resolve("I made it!"); + return await Promise.resolve('I made it!'); } const data = getData(); @@ -2311,7 +2343,7 @@ function addToList(item, list) { return list.push(item); } -const result = addToList("apple", ["banana"]); +const result = addToList('apple', ['banana']); console.log(result); ``` @@ -2359,7 +2391,7 @@ console.log(shape); `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. +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)` would return 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. @@ -2371,9 +2403,9 @@ Since `shape` is frozen, and since the value of `x` is not an object, we cannot ###### 76. What's the output? ```javascript -const { name: myName } = { name: "Lydia" }; +const { firstName: myName } = { firstName: 'Lydia' }; -console.log(name); +console.log(firstName); ``` - A: `"Lydia"` @@ -2386,11 +2418,45 @@ console.log(name); #### 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`. +By using [destructuring assignment](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) syntax we can unpack values from arrays, or properties from objects, into distinct variables: + +```javascript +const { firstName } = { firstName: 'Lydia' }; +// ES5 version: +// var firstName = { firstName: 'Lydia' }.firstName; + +console.log(firstName); // "Lydia" +``` + +Also, a property can be unpacked from an object and assigned to a variable with a different name than the object property: + +```javascript +const { firstName: myName } = { firstName: 'Lydia' }; +// ES5 version: +// var myName = { firstName: 'Lydia' }.firstName; + +console.log(myName); // "Lydia" +console.log(firstName); // Uncaught ReferenceError: firstName is not defined +``` + +Therefore, `firstName` does not exist as a variable, thus attempting to access its value will raise a `ReferenceError`. + +**Note:** Be aware of the `global scope` properties: -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. +```javascript +const { name: myName } = { name: 'Lydia' }; + +console.log(myName); // "lydia" +console.log(name); // "" ----- Browser e.g. Chrome +console.log(name); // ReferenceError: name is not defined ----- NodeJS + +``` -Since we try to log `name`, a variable that is not defined, a ReferenceError gets thrown. +Whenever Javascript is unable to find a variable within the _current scope_, it climbs up the [Scope chain](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/ch3.md) and searches for it and if it reaches the top-level scope, aka **Global scope**, and still doesn't find it, it will throw a `ReferenceError`. + +- In **Browsers** such as _Chrome_, `name` is a _deprecated global scope property_. In this example, the code is running inside _global scope_ and there is no user-defined local variable for `name`, therefore it searches the predefined _variables/properties_ in the global scope which is in the case of browsers, it searches through `window` object and it will extract the [window.name](https://developer.mozilla.org/en-US/docs/Web/API/Window/name) value which is equal to an **empty string**. + +- In **NodeJS**, there is no such property on the `global` object, thus attempting to access a non-existent variable will raise a [ReferenceError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Not_defined).
@@ -2499,7 +2565,7 @@ With a _for-in_ loop, we can iterate over **enumerable** properties. In an array 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. +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.
@@ -2525,7 +2591,7 @@ console.log(list) 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`. +The element will be equal to the returned value. `1 + 2` returns `3`, `1 * 2` returns `2`, and `1 / 2` returns `0.5`.
@@ -2568,21 +2634,21 @@ In this case, if we didn't pass a value or if we passed `undefined`, `name` woul ###### 82. What is the output? ```javascript -var status = "😎" +var status = '😎'; setTimeout(() => { - const status = "😍" + const status = '😍'; const data = { - status: "🥑", + status: '🥑', getStatus() { - return this.status - } - } + return this.status; + }, + }; - console.log(data.getStatus()) - console.log(data.getStatus.call(this)) -}, 0) + console.log(data.getStatus()); + console.log(data.getStatus.call(this)); +}, 0); ``` - A: `"🥑"` and `"😍"` @@ -2599,7 +2665,6 @@ The value of the `this` keyword is dependent on where you use it. In a **method* 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. -
@@ -2718,7 +2783,7 @@ function getName(name) { #### 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`. +With `!!name`, we determine whether the value of `name` is truthy or falsy. If the 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`. @@ -2731,10 +2796,10 @@ By setting `hasName` equal to `name`, you set `hasName` equal to whatever value --- -###### 87. What's the output? +###### 87. What's the output? ```javascript -console.log("I want pizza"[0]) +console.log('I want pizza'[0]); ``` - A: `"""` @@ -2747,9 +2812,9 @@ console.log("I want pizza"[0]) #### 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. +In order to get a character at a specific index of a string, you can use bracket notation. The first character in the string has index 0, and so on. In this case, we want to get the element with index 0, the character `"I'`, which gets logged. -Note that this method is not supported in IE7 and below. In that case, use `.charAt()` +Note that this method is not supported in IE7 and below. In that case, use `.charAt()`.
+ +#### 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` keywords 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 before 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 (`
+ +#### 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 property 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 don't interact 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 this is an interval, setting `config` to `null` or `delete`-ing `config.alert` won't garbage-collect the interval, so the interval will still be called. +It should be cleared with `clearInterval(config.alert)` to remove it from memory. +Since it was not cleared, 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 interacts 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 `+=` operator, 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?.()`: variable `member` is non-existent therefore a `ReferenceError` gets thrown! + +
++ +#### 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 promise, 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 `currency` 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 referenceable 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 `counterTwo.increment()`, which sets `count` to `3`. Then, we log the count on `counterOne`, which logs `3`.
+
+
+
+
+ +#### Answer: C + +First, we invoke `funcOne`. On the first line of `funcOne`, we call the _asynchronous_ `setTimeout` function, from which the callback is sent to the Web API. (see my article on the event loop here.) + +Then we call the `myPromise` promise, which is an _asynchronous_ operation. Pay attention, that now only the first then clause was added to the microtask queue. + +Both the promise and the timeout are asynchronous operations, the function keeps on running while it's busy completing the promise and handling the `setTimeout` callback. This means that `Last line 1!` gets logged first, since this is not an asynchonous operation. + +Since the callstack is not empty yet, the `setTimeout` function and promise in `funcOne` cannot get added to the callstack yet. + +In `funcTwo`, the variable `res` gets `Promise` because `Promise.resolve(Promise.resolve('Promise'))` is equivalent to `Promise.resolve('Promise')` since resolving a promise just resolves it's value. The `await` in this line stops the execution of the function until it receives the resolution of the promise and then keeps on running synchronously until completion, so `Promise 2!` and then `Last line 2!` are logged and the `setTimeout` is sent to the Web API. If the first then clause in `funcOne` had its own log statement, it would be printed before `Promise 2!`. Howewer, it executed silently and put the second then clause in microtask queue. So, the second clause will be printed after `Promise 2!`. + +Then the call stack is empty. Promises are _microtasks_ so they are resolved first when the call stack is empty so `Promise 1!` gets to be logged. + +Now, since `funcTwo` popped off the call stack, the call stack is empty. The callbacks waiting in the queue (`() => console.log("Timeout 1!")` from `funcOne`, and `() => console.log("Timeout 2!")` from `funcTwo`) get added to the call stack one by one. The first callback logs `Timeout 1!`, and gets popped off the stack. Then, the second callback logs `Timeout 2!`, and gets popped off the stack. + +
++ +#### 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 this case, we pass the `handler` object which contains two properties: `set` and `get`. `set` gets invoked whenever we _set_ property values, and `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, and the `get` property on the handler object is invoked. `"Accessed a property!"` gets logged. + +
++ +#### Answer: A + +With `Object.seal` we can prevent new properties 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: 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` is 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 access 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 `hobbies`, `"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 `"baking"` 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 properties 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 + +The `if` condition within the `forEach` loop checks whether the value of `num` is truthy or falsy. Since the first number in the `nums` array is `0`, a falsy value, the `if` statement's code block won't be executed. `count` only gets incremented for the other 3 numbers in the `nums` array, `1`, `2` and `3`. Since `count` gets incremented by `1` 3 times, the value of `count` is `3`. + +
++ +#### Answer: D + +The `?` allows us to optionally access deeper nested properties within objects. We're trying to log the item on index `1` within the subarray that's on index `1` of the `fruits` array. If the subarray on index `1` in the `fruits` array doesn't exist, it'll simply return `undefined`. If the subarray on index `1` in the `fruits` array exists, but this subarray doesn't have an item on its `1` index, it'll also return `undefined`. + +First, we're trying to log the second item in the `['🍍']` subarray of `[['🍊', '🍌'], ['🍍']]`. This subarray only contains one item, which means there is no item on index `1`, and returns `undefined`. + +Then, we're invoking the `getFruits` function without passing a value as an argument, which means that `fruits` has a value of `undefined` by default. Since we're conditionally chaining the item on index `1` of`fruits`, it returns `undefined` since this item on index `1` does not exist. + +Lastly, we're trying to log the second item in the `['🍊', '🍌']` subarray of `['🍍'], ['🍊', '🍌']`. The item on index `1` within this subarray is `🍌`, which gets logged. + +
++ +#### Answer: A + +We set the variable `calc` equal to a new instance of the `Calc` class. Then, we instantiate a new instance of `Calc`, and invoke the `increase` method on this instance. Since the count property is within the constructor of the `Calc` class, the count property is not shared on the prototype of `Calc`. This means that the value of count has not been updated for the instance calc points to, count is still `0`. + +
++ +#### Answer: B + +The `updateUser` function updates the values of the `email` and `password` properties on user, if their values are passed to the function, after which the function returns the `user` object. The returned value of the `updateUser` function is the `user` object, which means that the value of updatedUser is a reference to the same `user` object that `user` points to. `updatedUser === user` equals `true`. + +
++ +#### Answer: C + +First, we invoke the `slice` method on the fruit array. The slice method does not modify the original array, but returns the value that it sliced off the array: the banana emoji. +Then, we invoke the `splice` method on the fruit array. The splice method does modify the original array, which means that the fruit array now consists of `['🍊', '🍎']`. +At last, we invoke the `unshift` method on the `fruit` array, which modifies the original array by adding the provided value, ‘🍇’ in this case, as the first element in the array. The fruit array now consists of `['🍇', '🍊', '🍎']`. + +
++ +#### Answer: B + +Object keys are converted to strings. + +Since the value of `dog` is an object, `animals[dog]` actually means that we’re creating a new property called `"[object Object]"` equal to the new object. `animals["[object Object]"]` is now equal to `{ emoji: "🐶", name: "Mara"}`. + +`cat` is also an object, which means that `animals[cat]` actually means that we’re overwriting the value of `animals["[object Object]"]` with the new cat properties. + +Logging `animals[dog]`, or actually `animals["[object Object]"]` since converting the `dog` object to a string results `"[object Object]"`, returns the `{ emoji: "🐈", name: "Sara" }`. + +
++ +#### Answer: A + +The `updateEmail` function is an arrow function, and is not bound to the `user` object. This means that the `this` keyword is not referring to the `user` object, but refers to the global scope in this case. The value of `email` within the `user` object does not get updated. When logging the value of `user.email`, the original value of `my@email.com` gets returned. + +
++ +#### Answer: D + +The `Promise.all` method runs the passed promises in parallel. If one promise fails, the `Promise.all` method _rejects_ with the value of the rejected promise. In this case, `promise3` is rejected with the value `"Third"`. We’re catching the rejected value in the chained `catch` method on the `runPromises` invocation to catch any errors within the `runPromises` function. Only `"Third"` gets logged, since `promise3` is rejected with this value. + +
++ +#### Answer: C + +The `fromEntries` method turns a 2d array into an object. The first element in each subarray will be the key, and the second element in each subarray will be the value. In this case, we’re mapping over the `keys` array, which returns an array that the first element is the item on the key array on the current index, and the second element is the item of the values array on the current index. + +This creates an array of subarrays containing the correct keys and values, which results in `{ name: "Lydia", age: 22 }` + +
++ +#### Answer: C + +The default value of `address` is an empty object `{}`. When we set the variable `member` equal to the object returned by the `createMember` function, we didn't pass a value for the address, which means that the value of the address is the default empty object `{}`. An empty object is a truthy value, which means that the condition of the `address ? address : null` conditional returns `true`. The value of the address is the empty object `{}`. + +
++ +#### Answer: B + +The condition within the `if` statement checks whether the value of `!typeof randomValue` is equal to `"string"`. The `!` operator converts the value to a boolean value. If the value is truthy, the returned value will be `false`, if the value is falsy, the returned value will be `true`. In this case, the returned value of `typeof randomValue` is the truthy value `"number"`, meaning that the value of `!typeof randomValue` is the boolean value `false`. + +`!typeof randomValue === "string"` always returns false, since we're actually checking `false === "string"`. Since the condition returned `false`, the code block of the `else` statement gets run, and `Yay it's a string!` gets logged. + +
+-Die Antworten sind unterhalb der Fragen versteckt. Du kannst einfach darauf klicken um die Antworten anzuzeigen. Viel Glück :heart: +- [🇸🇦 العربية](../ar-AR/README_AR.md) +- [🇪🇬 اللغة العامية](../ar-EG/README_ar-EG.md) +- [🇧🇦 Bosanski](../bs-BS/README-bs_BS.md) +- [🇬🇧 English](../README.md) +- [🇪🇸 Español](../es-ES/README-ES.md) +- [🇫🇷 Français](../fr-FR/README_fr-FR.md) +- [🇮🇩 Indonesia](../id-ID/README.md) +- [🇮🇹 Italiano](../it-IT/README.md) +- [🇯🇵 日本語](../ja-JA/README-ja_JA.md) +- [🇰🇷 한국어](../ko-KR/README-ko_KR.md) +- [🇳🇱 Nederlands](../nl-NL/README.md) +- [🇵🇱 Polski](../pl-PL/README.md) +- [🇧🇷 Português Brasil](../pt-BR/README_pt_BR.md) +- [🇷o Română](../ro-RO/README.ro.md) +- [🇷🇺 Русский](../ru-RU/README.md) +- [🇽🇰 Shqip](../sq-KS/README_sq_KS.md) +- [🇹🇭 ไทย](../th-TH/README-th_TH.md) +- [🇹🇷 Türkçe](../tr-TR/README-tr_TR.md) +- [🇺🇦 Українська мова](../uk-UA/README.md) +- [🇻🇳 Tiếng Việt](../vi-VI/README-vi.md) +- [🇨🇳 简体中文](../zh-CN/README-zh_CN.md) +- [🇹🇼 繁體中文](../zh-TW/README_zh-TW.md) -### Alle verfügbaren Sprachen -* [English](../en-EN/README.md) -* [العربية](../ar-AR/README_AR.md) -* [اللغة العامية](../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) -* [Türkçe](../tr-TR/README-tr_TR.md) -* [Українська мова](../ua-UA/README-ua_UA.md) -* [Tiếng Việt](../vi-VI/README-vi.md) -* [中文版本](../zh-CN/README-zh_CN.md) +
+
@@ -2174,7 +2199,7 @@ Falls der Wert, der an `padStart` übergeben wurde kleiner ist, als die Länge d
---
-###### 70. Was ist der Output?
+###### 70. Was wird ausgegeben?
```javascript
console.log("🥑" + "💻");
@@ -2234,7 +2259,7 @@ Wenn wir `game.next("Yes").value` aufrufen wird das vorhergehende `yield` durch
---
-###### 72. Was ist der Output?
+###### 72. Was wird ausgegeben?
```javascript
console.log(String.raw`Hello\nworld`);
@@ -2269,7 +2294,7 @@ In unserem Fall ist das Ergebnis `Hello\nworld`, was geloggt wird.
---
-###### 73. Was ist der Output?
+###### 73. Was wird ausgegeben?
```javascript
async function getData() {
@@ -2303,7 +2328,7 @@ Das hätte `"I made it!"` ausgegeben.
---
-###### 74. Was ist der Output?
+###### 74. Was wird ausgegeben?
```javascript
function addToList(item, list) {
@@ -2333,7 +2358,7 @@ Die `push` Methode verändert das ursprüngliche Array. Wenn wir das _Array_ der
---
-###### 75. Was ist der Output?
+###### 75. Was wird ausgegeben?
```javascript
const box = { x: 10, y: 20 };
@@ -2368,7 +2393,7 @@ Da `shape` eingefroren ist und der Wert von `x` kein Objekt ist, können wir den
---
-###### 76. Was ist der Output?
+###### 76. Was wird ausgegeben?
```javascript
const { name: myName } = { name: "Lydia" };
@@ -2422,7 +2447,7 @@ Die `sum` Funktion gibt daher immer das gleiche Ergebnis aus. Wenn wir `1` und `
---
-###### 78. Was ist der Output?
+###### 78. Was wird ausgegeben?
```javascript
const add = () => {
@@ -2469,7 +2494,7 @@ Beim dritten Mal geben wir `5 * 2` als Argument in die Funktion ein, was `10` er
---
-###### 79. Was ist der Output?
+###### 79. Was wird ausgegeben?
```javascript
const myLifeSummedUp = ["☕", "💻", "🍷", "🍫"]
@@ -2506,7 +2531,7 @@ Mit einer _for-of_ Schleife können wir über **wiederholbare** Elemente iterier
---
-###### 80. Was ist der Output?
+###### 80. Was wird ausgegeben?
```javascript
const list = [1 + 2, 1 * 2, 1 / 2]
@@ -2532,7 +2557,7 @@ Das Element ist gleich dem ausgegebenen Wert. `1 + 2` ergibt `3`, `1 * 2` ergibt
---
-###### 81. Was ist der Output?
+###### 81. Was wird ausgegeben?
```javascript
function sayHi(name) {
@@ -2565,7 +2590,7 @@ In diesem Fall, falls wir kein Argument oder `undefined` eingeben ist `name` imm
---
-###### 82. Was ist der Output?
+###### 82. Was wird ausgegeben?
```javascript
var status = "😎"
@@ -2605,7 +2630,7 @@ Mit der `call` Methode können wir das Objekt, auf welches sich das `this` Keywo
---
-###### 83. Was ist der Output?
+###### 83. Was wird ausgegeben?
```javascript
const person = {
@@ -2642,7 +2667,7 @@ Wenn wir `person` loggen bekommen wir daher das unveränderte Objekt angezeigt.
---
-###### 84. Was ist der Output?
+###### 84. Was wird ausgegeben?
```javascript
function checkAge(age) {
@@ -2686,7 +2711,7 @@ fetch('http://github.com/service/https://www.website.com/api/user/1')
- A: Das Ergebnis der `fetch` Methode.
- B: Das Ergebnis des zweiten Aufrufs der `fetch` Methode.
- C: Das Ergebnis des Callbacks im vorhergehenden `.then()`.
-- D: Immer `undefined`.
+- D: Immer `undefined`.
@@ -2731,7 +2756,7 @@ Wenn wir `hasName` gleich `name` setzen, so beinhaltet `hasName` den Wert von `n
---
-###### 87. Was ist der Output?
+###### 87. Was wird ausgegeben?
```javascript
console.log("I want pizza"[0])
@@ -2756,7 +2781,7 @@ Diese Methode funktioniert nicht in IE7 und davor. Hier muss `.charAt()` verwend
---
-###### 88. Was ist der Output?
+###### 88. Was wird ausgegeben?
```javascript
function sum(num1, num2 = num1) {
@@ -2785,14 +2810,14 @@ Wenn man den Wert des Standard Paramenters gleich dem Parameter setztm der _dana
---
-###### 89. Was ist der Output?
+###### 89. Was wird ausgegeben?
```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)
@@ -2817,7 +2842,7 @@ Das `data` Objekt hat eine Standard Property für alle Standard Exporte, andere
---
-###### 90. Was ist der Output?
+###### 90. Was wird ausgegeben?
```javascript
class Person {
@@ -2855,7 +2880,7 @@ Das Aufrufen eines Funktionskonstruktors mit `new` hat zur Folge, dass eine Inst
---
-###### 91. Was ist der Output?
+###### 91. Was wird ausgegeben?
```javascript
let newList = [1, 2, 3].push(4)
@@ -2882,7 +2907,7 @@ Dann versuchen wir die `.push` Methode auf `newList` anzuwenden. Da `newList` de
---
-###### 92. Was ist der Output?
+###### 92. Was wird ausgegeben?
```javascript
function giveLydiaPizza() {
@@ -2895,8 +2920,8 @@ console.log(giveLydiaPizza.prototype)
console.log(giveLydiaChocolate.prototype)
```
-- A: `{ constructor: ...}` `{ constructor: ...}`
-- B: `{}` `{ constructor: ...}`
+- A: `{ constructor: ...}` `{ constructor: ...}`
+- B: `{}` `{ constructor: ...}`
- C: `{ constructor: ...}` `{}`
- D: `{ constructor: ...}` `undefined`
@@ -2905,14 +2930,14 @@ console.log(giveLydiaChocolate.prototype)
#### Antwort: D
-Reguläre Funktionen wie `giveLydiaPizza` haben eine `prototype` Property, die ein Objekt (Prototype Object) mit einem `constructor` ist. Arrow Funktionen dagegen (wie `giveLydiaChocolate`) haben keinen `prototype`. `undefined` wird ausgegeben, wenn wir versuchen den `prototype` mit `giveLydiaChocolate.prototype` aufzurufen.
+Reguläre Funktionen wie `giveLydiaPizza` haben eine `prototype` Property, die ein Objekt (Prototype Object) mit einem `constructor` ist. Arrow Funktionen dagegen (wie `giveLydiaChocolate`) haben keinen `prototype`. `undefined` wird ausgegeben, wenn wir versuchen den `prototype` mit `giveLydiaChocolate.prototype` aufzurufen.
Antwort
+ +#### 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 (`
+ +#### 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. + +
++ +#### 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 }`. + +
++ +#### 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. + +
++ +#### Antwort: B + +Mit der Methode `Intl.NumberFormat` können wir einen numerischen Wert in einen sprachabhängigen Wert formatieren. Wir formatieren den Zahlenwert `130` zu einem Wert der Sprache `en-US` mit der Einheit (`unit`) in `mile-per-hour`, was `130 mph` ergibt. Analog formatieren wir `300` als eine Währung (`currency`) der Sprache `en-US` in `USD`, was `$300.00` ergibt. + +
++ +#### Antwort: B + +Durch die destrukturierende Zuweisung können wir Werte des Ojekts von der rechten Seite der Zuweisung extrahieren und diese Werte einem Property mit dem selben Namen dem Objekt auf der linken Seite zuweisen. In diesem Fall wird der Wert "💀" an `spookyItems[3]` zugewiesen. Das bedeutet, dass wir das Array `spookyItems` modifizieren, in dem wir "💀" hinzufügen. Beim Loggen von `spookyItems` wird darum `["👻", "🎃", "🕸", "💀"]` ausgegeben. + +
++ +#### Antwort: C + +Mit der Methode `Number.isNaN` kann geprüft werden, ob der übergebene Parameter vom Typ _Number_ mit Wert `NaN` ist. `name` ist kein numerischer Wert, deswegen ist der Rückgabewert von `Number.isNaN(name)` in diesem Fall `false`. `age` ist zwar ein numerischer Wert, aber nicht gleich `NaN`, weswegen `Number.isNaN(age)` `false` ausgibt. + +Die Methode `isNaN` prüft, ob der Eingabeparameter nicht vom Typ _Number_ ist. `name` ist ein String, darum gibt `isNaN(name)` `true` zurück. `age` ist ein numerischer Wert, weswegen `isNaN(age)` `false` ausgibt. + +
++ +#### Antwort: D + +Variablen die mit `const` deklariert werden, können nicht vor ihrer Initialisierung referenziert werden, das ist die so genannte "zeitweilige tote Zone" (_temporal dead zone_). In der Funktion `getInfo` befindet sich die Variable `randomValue` im Geltungsbereich der Funktion. In der Zeile, in welcher der Wert von `typeof randomValue` geloggt werden soll, ist die Variable noch nicht initialisiert. Entsprechend wird ein `ReferenceError` geworfen! Die Engine versucht nicht in der Kette der Geltungsbereiche hinab zu steigen, da die Variable `randomValue` im Geltungsbereich von `getInfo` deklariert und damit gefunden wurde. + +
++ +#### Antwort: C + +Im `try`-Block loggen wir den mit dem `await`-Operator den Wert der Variable `myPromise`: `"Woah some cool data"`. Da in diesem Block kein Fehler geworfen wird, wird der Code im `catch`-Block nicht ausgeführt. Der Code im `finally`-Block wird _immer_ ausgeführt, `"Oh finally!"` wird geloggt. + +
++ +#### Antwort: B + +Mit der Methode `flat` erzeugen wir ein neues, "flacheres" Array. Die Tiefe des neuen Arrays hängt vom Parameter ab, den wir an `flat` übergeben. In diesem Fall wird der Wert `1` übergeben (welcher der Standardwert der Funktion ist, wir hätten ihn in diesem Fall also nicht explizit übergeben müssen). Das bedeutet, das alle Arrays bis zur ersten Tiefe zusammengefügt werden: `['🥑']` und `['✨', '✨', ['🍕', '🍕']]` in diesem Fall. Das Zusammenfügen dieser beiden Arrays resultiert in: `['🥑', '✨', '✨', ['🍕', '🍕']]`. + +
+
+
+#### Antwort: D
+
+`counterOne` ist eine Instanz der Klasse `Counter`. Diese Klasse enthält ein Property `count` in seinem Konstruktor, sowie eine Methode `increment`. Zuerst wird die Methode `increment` zweimal durch `counterOne.increment()` aufgerufen. Der Wert von `counterOne.count` ist danach `2`.
+
+
+
+Danach erzeugen wir eine neue Variable `counterTwo` und setzen sie gleich `counterOne`. Da Objekte via Referenz übergeben werden, erzeugen wir somit lediglich eine neue Referenz auf den selben Bereich im Speicher, auf den auch `counterOne` zeigt. Da der gleiche Speicherbereich verwendet wird, haben alle Änderungen, die am Objekt vorgenommen werden, auf das `counterTwo` zeigt, auch Auswirkungen auf `counterOne`. Aktuell ist `counterTwo.count` somit `2`.
+
+Wir rufen nun `counterTwo.increment()` auf, wodurch der Wert von `count` auf `3` gesetzt wird. Danach loggen wir den Zustand von `counterOne`, wodurch `3` ausgegeben wird.
+
+
+
+
+ +#### Antwort: D + +Zuerst rufen wir die Funktion `funcOne()` auf. In der ersten Zeile in `funcOne` wird das Promise `myPromise` aufgerufen, was eine _asynchrone_ Operation ist. Während die Engine damit beschäftigt ist dieses Promise zu erfüllen, wird die Funktion `funcOne` weiter ausgeführt. Die nächste Zeile ist die _asynchrone_ Funktion `setTimeout`, von welcher der Callback an die Web API geschickt wird (siehe mein Artikel zu Event Loops). + +Sowohl Promise als auch Timeout sind asynchrone Operationen. Die Funktion läuft also weiter, während sie parallel damit beschäfigt ist diese beiden Operationen zu bearbeiten. Das bedeutet, dass `Last line!` zuerst geloggt wird, da dies keine asynchrone Operation ist. Es ist die letzte Zeile von `funcOne`, das Promise wird erfüllt und `Promise!` geloggt. Da wir jedoch auch `funcTwo()` aufrufen, ist der Call Stack nicht leer und der Callback der Funktion `setTimeout` kann noch nicht zum Call Stack hinzugefügt werden. + +In `funcTwo` warten wir zuerst auf das Promise von `myPromise`. Mit dem `await`-Operator pausieren wir die Ausführung der Funktion bis das Promise erfüllt (oder zurück gewiesen) wurde. Anschließend loggen wir (wieder mit dem `await-Operator`, da das Promise selbst ein Promise zurückgibt) den Wert von `res`. Dadurch wird `Promise!` geloggt. + +Die nächste Zeile ist die _asynchrone_ Funktion `setTimeout`, deren Callback an die Web API gesendet wird. + +Wir kommen zur letzten Zeile in `funcTwo`, die `Last line!` in der Console ausgibt. Da `funcTwo` abgearbeitet und aus dem Call Stack entfernt wurde, ist der Call Stack leer. Die wartenden Callbacks (`() => console.log("Timeout!")` aus `funcOne` und `() => console.log("Timeout!")` aus `funcTwo`) werden dem Call Stack nacheinander hinzugefügt. Der erste Callback loggt `Timeout!` und wird aus dem Stack entfernt. Anschließend loggt der zweite Callback `Timeout!` und wird aus dem Stack entfernt. Somit ist das Ergebnis `Last line! Promise! Promise! Last line! Timeout! Timeout!` + +
++ +#### 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 (`
+ +#### 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!`. + +
++ +#### 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 }`. + +
+
@@ -474,7 +485,7 @@ sum(1, "2");
JavaScript est un **langage à types dynamiques** : nous n'avons pas besoin de spécifier le types des variables. Les valeurs peuvent être automatiquement converties vers les autres types sans que vous le sachiez, c'est ce que l'on appelle _la conversion de types implicites_ _(implicit type coercion)_.
-Dans cette exemple, JavaScript convertit le nombre `1` en un chaine de caractère, afin que la fonction ait du sens et puisse renvoyer une valeur. Durant l'addition d'un type numérique (`1`) et d'un type chaine de caractère (`'2'`), le nombre est traité comme une chaine de caractère. Nous pouvons concaténer les chaines de caractères comme `"Hello" + "World"`, c'est donc ce qui arrive ici avec `"1" + "2"` qui retourne `"12"`.
+Dans cette exemple, JavaScript convertit le nombre `1` en une chaîne de caractère, afin que la fonction ait du sens et puisse renvoyer une valeur. Durant l'addition d'un type numérique (`1`) et d'un type chaîne de caractère (`'2'`), le nombre est traité comme une chaîne de caractère. Nous pouvons concaténer les chaînes de caractères comme `"Hello" + "World"`, c'est donc ce qui arrive ici avec `"1" + "2"` qui retourne `"12"`.
@@ -541,7 +552,7 @@ getPersonInfo`${person} is ${age} years old`;
#### Réponse : B
-Si vous utilisez les littéraux de gabarits, la valeur du premier argument sera toujours un tableau de valeurs des chaines de caractère. Le reste des arguments seront les valeurs des expressions utilisées !
+Si vous utilisez les littéraux de gabarits, la valeur du premier argument sera toujours un tableau de valeurs des chaînes de caractère. Le reste des arguments seront les valeurs des expressions utilisées !
@@ -679,7 +690,7 @@ sessionStorage.setItem("cool_secret", 123);
#### Réponse : B
-La donnée stocké dans le `sessionStorage` est supprimée après la fermeture de l'onglet.
+La donnée stockée dans le `sessionStorage` est supprimée après la fermeture de l'onglet.
Si vous utilisez le `localStorage`, la donnée sera là pour toujours, jusqu'à ce que, par exemple, `localStorage.clear()` soit invoquée.
@@ -771,7 +782,7 @@ Si vous avez deux clés portant le même nom, la clé sera remplacée. Elle sera
---
-###### 26. Le contexte global d'exécution de JavaScript crée 2 choses pour vous : l'objet global and le mot-clé `this`.
+###### 26. Le contexte global d'exécution de JavaScript crée 2 choses pour vous : l'objet global et le mot-clé `this`.
- A: Vrai
- B: Faux
@@ -824,7 +835,7 @@ String.prototype.giveLydiaPizza = () => {
const name = "Lydia";
-name.giveLydiaPizza();
+console.log(name.giveLydiaPizza())
```
- A: `"Just give Lydia pizza already!"`
@@ -869,7 +880,7 @@ console.log(a[b]);
Les clés d'objet sont automatiquement converties en chaînes de caractères. Nous essayons de définir un objet en tant que clé de l'objet `a`, avec la valeur `123`.
-Cependant, lorsque nous transformons un objet en chaine de caractère, il devient `"[Objet objet]"`. Donc, ce que nous disons ici, c'est que un `a["Objet objet"] = 123`. Ensuite, nous pouvons essayer de refaire la même chose. `c` est un autre objet que nous sommes implicitement en train de transformer en chaine de carctère. Donc, `a["Objet objet"] = 456`.
+Cependant, lorsque nous transformons un objet en chaîne de caractère, il devient `"[Objet objet]"`. Donc, ce que nous disons ici, c'est que un `a["Objet objet"] = 123`. Ensuite, nous pouvons essayer de refaire la même chose. `c` est un autre objet que nous sommes implicitement en train de transformer en chaîne de caractère. Donc, `a["Objet objet"] = 456`.
Ensuite, nous affichons `a[b]`, qui est en fait `a["Objet objet"]`. Que nous venons de définir à `456`, nous renvoyons donc `456`.
@@ -1041,7 +1052,7 @@ typeof sayHi();
La fonction `sayHi` renvoie la valeur renvoyée par la fonction immédiatement appelée (IIFE). Cette fonction a renvoyé `0`, qui est du type `"nombre"`.
-Pour info : il n'y a que 7 types natifs : `null`, `undefined`, `boolean`, `number`, `string`, `object` et `symbol`. `"function"` n'est pas un type, puisque les fonctions sont des objets, il est de type `"object"`.
+Pour info : il n'y a que 7 types natifs : `null`, `undefined`, `boolean`, `number`, `string`, `object`, `symbol` et `bigint`. `"function"` n'est pas un type, puisque les fonctions sont des objets, il est de type `"object"`.
@@ -1062,7 +1073,7 @@ undefined;
- A: `0`, `''`, `undefined`
- B: `0`, `new Number(0)`, `''`, `new Boolean(false)`, `undefined`
- C: `0`, `''`, `new Boolean(false)`, `undefined`
-- D: All of them are falsy
+- D: Toutes sont fausses
@@ -1075,7 +1086,7 @@ Il n'y a que six valeurs de fausses : - `null` - `NaN` - `0` -- `''` (chaine de caractère vide) +- `''` (chaîne de caractère vide) - `false` Les constructeurs de fonctions, comme `new Number` et `new Boolean` sont la vraies. @@ -1544,7 +1555,7 @@ console.log(person, birthYear); #### Réponse : A -Les arguments sont passés par _valeur_, à moins que leur valeur ne soit un objet, ils sont passés par _réfèrence_. `birthYear` est passée par valeur, car c'est une chaîne, pas un objet. Lorsque nous passons des arguments par valeur, une copie de cette valeur est créée (voir question 46). +Les arguments sont passés par _valeur_, à moins que leur valeur ne soit un objet, ils sont passés par _référence_. `birthYear` est passée par valeur, car c'est une chaîne, pas un objet. Lorsque nous passons des arguments par valeur, une copie de cette valeur est créée (voir question 46). La variable `birthYear` a une référence à la valeur `"1997"`. L'argument `year` fait également référence à la valeur `"1997"`, mais il ne s'agit pas de la même valeur que celle de `birthYear`. Lorsque nous mettons à jour la valeur de `year` en plaçant `year` égal à `"1998"`, nous ne mettons à jour que la valeur de `year`. `birthYear` est toujours égal à `"1997"`. @@ -1798,7 +1809,7 @@ La variable `name` a été déclarée avec un mot-clé `const`. Par conséquent, ```javascript const numbers = [1, 2, 3, 4, 5]; -const [y] = numberes; +const [y] = numbers; console.log(y); ``` @@ -1919,7 +1930,7 @@ Le second argument de `JSON.stringify` est le _replaçant_. Le remplaçant peut Si le remplaçant est un _tableau_, seules les propriétés dont les noms sont inclus dans le tableau seront ajoutées à la chaîne JSON. Dans ce cas, seules les propriétés avec les noms `"level"` et `"health"` sont incluses, `"username"` est exclu. `data` est maintenant égal à `"{"level":19, "health":90}"`. -Si le remplaceur est une _fonction_, cette fonction est appelée sur chaque propriété de l'objet que vous personnalisez. La valeur renvoyée par cette fonction sera la valeur de la propriété lorsqu'elle sera ajoutée à la chaîne JSON. Si la valeur est `undefined`, cette propriété est exclue de la chaîne JSON. +Si le remplaçant est une _fonction_, cette fonction est appelée sur chaque propriété de l'objet que vous personnalisez. La valeur renvoyée par cette fonction sera la valeur de la propriété lorsqu'elle sera ajoutée à la chaîne JSON. Si la valeur est `undefined`, cette propriété est exclue de la chaîne JSON.
+ +#### Répondre: C + +Dans ES6, nous pouvons initialiser les paramètres avec une valeur par défaut. La valeur du paramètre sera la valeur par défaut, si aucune autre valeur n'a été passée à la fonction, ou si la valeur du paramètre est `"undefined"`. Dans ce cas, nous répartissons les propriétés de l'objet `value` dans un nouvel objet, donc `x` a la valeur par défaut `{number: 10}`. + +L'argument par défaut est évalué at _call time_! Chaque fois que nous appelons la fonction, un a _new_ object créé. Nous invoquons la fonction `multiply` les deux premières fois sans passer de valeur: `x` a la valeur par défaut `{number: 10}`. Nous enregistrons ensuite la valeur multipliée de ce nombre, qui est `20`. + +La troisième fois que nous invoquons multiplier, nous passons un argument: l'objet appelé `value`. L'opérateur `* =` est en fait un raccourci pour `x.number = x.number * 2`: nous modifions la valeur de `x.number`, et enregistrons la valeur multipliée `20`. + +La quatrième fois, nous passons à nouveau l'objet `value`. `x.number` a été précédemment modifié en `20`, donc `x.number * = 2` enregistre «40». + +
++ +- [🇸🇦 العربية](../ar-AR/README_AR.md) +- [🇪🇬 اللغة العامية](../ar-EG/README_ar-EG.md) +- [🇧🇦 Bosanski](../bs-BS/README-bs_BS.md) +- [🇩🇪 Deutsch](../de-DE/README.md) +- [🇬🇧 English](../README.md) +- [🇪🇸 Español](../es-ES/README-ES.md) +- [🇫🇷 Français](../fr-FR/README_fr-FR.md) +- [🇮🇹 Italiano](../it-IT/README.md) +- [🇯🇵 日本語](../ja-JA/README-ja_JA.md) +- [🇰🇷 한국어](../ko-KR/README-ko_KR.md) +- [🇳🇱 Nederlands](../nl-NL/README.md) +- [🇵🇱 Polski](../pl-PL/README.md) +- [🇧🇷 Português Brasil](../pt-BR/README_pt_BR.md) +- [🇷o Română](../ro-RO/README.ro.md) +- [🇷🇺 Русский](../ru-RU/README.md) +- [🇽🇰 Shqip](../sq-KS/README_sq_KS.md) +- [🇹🇭 ไทย](../th-TH/README-th_TH.md) +- [🇹🇷 Türkçe](../tr-TR/README-tr_TR.md) +- [🇺🇦 Українська мова](../uk-UA/README.md) +- [🇻🇳 Tiếng Việt](../vi-VI/README-vi.md) +- [🇨🇳 简体中文](../zh-CN/README-zh_CN.md) +- [🇹🇼 繁體中文](../zh-TW/README_zh-TW.md) + +
++ +#### Jawaban: D + +Di dalam function, kita membuat sebuah variabel `name` dan variabel tersebut di deklarasikan menggunakan `var`. Artinya variable tersebut di hoisting (dalam fase pembuatan ini menggunakan memory penyimpanan) dengan isi standar-nya `undefined`, saat javascript mengeksekusi baris code pembuatan variabel-nya. variabel `name` isinya masih undefined, jadi isi dari variabel tersebut `undefined` + +Mendeklarasikan varibel menggunakan `let` (dan `const`) juga terkena hoisting, tidak seperti `var`, variabel declaration `let` dan `const` tidak ditentukan isi standar-nya. `let` dan `const` tidak bisa diakses sebelum di tentukan dulu isi-nya. Kejadian ini disebut "temporal dead zone". Saat kita mencoba memanggil variabel yang belum ditentukan isi-nya, Javascript mengeluarkan error `ReferenceError`. +
++ +#### Jawaban: C + +Karena antrean peristiwa di JavaScript, fungsi callback `setTimeout` disebut _after_ loop telah dijalankan. Karena variabel `i` di loop pertama dideklarasikan menggunakan kata kunci` var`, nilai ini adalah global. Selama perulangan, kita menambah nilai `i` sebesar `1` setiap kali, menggunakan operator unary` ++ `. Pada saat fungsi callback `setTimeout` dipanggil,` i` sama dengan `3` di contoh pertama. + +Pada perulangan kedua, variabel `i` dideklarasikan menggunakan kata kunci` let`: variabel yang dideklarasikan dengan kata kunci `let` (dan` const`) memiliki cakupan blok (blok adalah apa saja di antara `{}`). Selama setiap iterasi, `i` akan memiliki nilai baru, dan setiap nilai dicakup di dalam loop. +
++ +#### Jawaban: B + +Perhatikan pada nilai 'diameter' adalah fungsi biasa, sedangkan nilai 'perimeter' yaitu fungsi panah. + +Dengan fungsi panah, kata kunci 'this' merujuk ke cakupan sekitarnya saat ini, tidak seperti fungsi biasa. Ini berarti bahwa ketika kita memanggil 'perimeter' itu tidak mengacu pada objek bentuk, tetapi pada lingkup sekitarnya. + +Tidak ada nilai 'radius' pada objek itu, yang mengembalikan 'tidak ditentukan'. + +
++ +#### Jawaban: A + +Tia unary plus mencoba mengonversi operan menjadi angka. `true` adalah` 1`, dan `false` adalah` 0`. + +String "'Lydia'` adalah nilai yang benar. Apa yang sebenarnya kami tanyakan adalah "apakah nilai kebenaran ini salah?". Ini mengembalikan `salah`. + + +
++ +#### Jawaban: A +Pada JavaScript, semua kunci objek adalah string (kecuali jika itu berupa Simbol). Meskipun kita mungkin tidak mengetiknya sebagai string, tetap saja mereka selalu berubah menjadi string didalamnya. + +JavaScript menginterpretasikan (atau membuka) pernyataan-pernyataan. Saat kita menggunakan notasi kurung siku, ia melihat kurung buka pertama `[` dan terus berjalan sampai menemukan kurung tutup `]`. Baru setelah itu akan mengevaluasi pernyataannya. `mouse[bird.size]`: Pertama, ini mengevaluasi `bird.size`, yang mana `"small"`. `mouse["small"]` mengembalikan nilai `true`. + +Namun, dengan notasi dot (.), hal ini tidak terjadi. `mouse` tidak memiliki kunci dengan nama `bird`, yang menyebabkan `mouse.bird` bernilai `undefined`. Kemudian, kita meminta `size` untuk menggunakan notasi dot (.): `mouse.bird.size`. Kita mengetahui bahwa `mouse.bird` bernilai `undefined`, yang sebenarnya kita minta adalah `undefined.size`. Yang mana hal ini tidak valid, dan akan memunculkan kesalahan yang mirip dengan `Cannot read property "size" of undefined`. + +
+
+
+#### Jawaban: A
+
+Dalam JavaScript, semua objek berinteraksi dengan _reference_ saat menyetelnya agar sama satu sama lain.
+
+Pertama, variabel `c` menyimpan nilai ke sebuah objek. Nanti, kita menetapkan `d` dengan referensi yang sama yang dimiliki` c` ke objek.
+
+
+
+Saat Anda mengubah satu objek, Anda mengubah semuanya.
+
+
+ +#### Jawaban: C + +`new Number()` adalah konstruktor fungsi bawaan pada JavaScript. Meskipun hasilnya terlihat seperti integer, namun sebenarnya itu bukan integer: aslinya memiliki banyak fitur tambahan dan merupakan sebuah objek. + +Saat kita menggunakan operator `==`, hal ini hanya akan memeriksa bahwa keduanya memiliki nilai yang sama. Pada kasus ini kedua variabel tersebut memiliki nilai yang sama, yaitu `3`, maka akan mengembalikan nilai `true`. + +Namun, saat kita menggunakan operator `===`, operator ini memeriksa bahwa kedua variabel memiliki nilai dan tipe yang sama. Bagaimanapun: `new Number()` bukanlah sebuah integer, ini adalah sebuah **object**. Keduanya akan mengembalikan nilai `false.` + +
++ +#### Jawaban: D + +Fungsi `colorChange` adalah statis. Metode statis dirancang hanya dapat aktif pada kontruktor dimana fungsi itu dibuat, dan tidak bisa dibawa ke-turunannya. Kita tahu bahwa `freddie` adalah sebuah turunan, maka fungsi itu tidak bisa turun, dan tidak tersedia pada instance `freddie`: sebuah pesan `TypeError` akan dikembalikan + +
++ +#### Jawaban: A + +Ini mencatat objek, karena kita baru saja membuat objek kosong di objek global! Saat kita salah mengetik `greeting` sebagai` greetign`, interpreter JS sebenarnya melihat ini sebagai `global.greetign = {}` (atau `window.greetign = {}` di browser). + +Untuk menghindari hal ini, kita bisa menggunakan `" use strict "`. Ini memastikan bahwa Anda telah mendeklarasikan variabel sebelum menetapkannya dengan apa pun. + +
++ +#### Jawaban: A + +Ini dimungkinkan dalam JavaScript, karena fungsi adalah objek! (Segala sesuatu selain tipe primitif adalah objek) + +Fungsi adalah jenis objek khusus. Kode yang Anda tulis sendiri bukanlah fungsi sebenarnya. Fungsinya adalah objek dengan properti. Properti ini tidak dapat dipanggil. + +
++ +#### Jawaban: A + +Anda tidak dapat menambahkan properti ke constructor seperti yang Anda lakukan dengan objek biasa. Jika Anda ingin menambahkan fitur ke semua objek sekaligus, Anda harus menggunakan prototipe sebagai gantinya. Jadi dalam kasus ini: + +```js +Person.prototype.getFullName = function() { + return `${this.firstName} ${this.lastName}`; +}; +``` + +Akan membuat `member.getFullName()` berfungsi. Mengapa ini bermanfaat? Katakanlah kita menambahkan metode ini ke konstruktor itu sendiri. Mungkin tidak setiap instance `Person` membutuhkan metode ini. Ini akan membuang banyak ruang memori, karena mereka masih memiliki properti itu, yang mengambil ruang memori untuk setiap instance. Sebaliknya, jika kita hanya menambahkannya ke prototipe, kita hanya memilikinya di satu tempat di memori, namun mereka semua memiliki akses ke sana! + +
++ +#### Jawaban: A + +Pada `sarah`, kita tidak menggunakan kata kunci `new`. Saat menggunakan `new`, Ini mengacu pada object kosong yang kita buat. Namun, jika Anda tidak menambahkan `new` ini merujuk pada **global object**! + +Kita tahu bahwa `this.firstName` setara dengan `"Sarah"` dan `this.lastName` sama dengan `"Smith"`. Apa yang sebenarnya kami lakukan adalah mendefinisikan `global.firstName = 'Sarah'` dan `global.lastName = 'Smith'`. `sarah` sendiri dibiarkan `undefined`, karena kita tidak mengembalikan nilai dari fungsi `Person`. + +
+
+
+#### Jawaban: D
+
+Selama fase **capturing**, event melewati elemen ancestor hingga ke elemen target. Kemudian mencapai element **target**, dan **bubbling** dimulai.
+
+
+
+
+ +#### Jawaban: B + +Semua objek memiliki prototypes, kecuali **objek dasar**. Objek dasar adalah objek yang dibuat oleh pengguna, atau objek yang dibuat dengan menggunakan kata kunci `baru`. Objek dasar memiliki akses ke beberapa metode dan properti, seperti `.toString`. Inilah alasan mengapa Anda dapat menggunakan metode JavaScript bawaan! Semua metode tersebut tersedia di prototipe. Meskipun JavaScript tidak dapat menemukannya secara langsung di objek Anda, JavaScript berada di rantai prototipe dan menemukannya di sana, yang membuatnya dapat diakses untuk Anda. + +
++ +#### Jawaban: C + +JavaScript adalah **Bahasa yang bersifat dinamis**: yang tidak menentukan jenis variabel tertentu. Values dapat secara otomatis diubah menjadi jenis lain tanpa Anda sadari, yang disebut _implicit type coercion_. **Coercion** adalah mengubah dari satu jenis ke jenis lainnya. + +Pada contoh ini, JavaScript mengubah number `1` menjadi sebuah string, agar fungsi tersebut masuk akal dan mengembalikan nilai. Selama penambahan tipe numerik (`1`) dan tipe string (`'2'`), angka tersebut diperlakukan sebagai string. Kita bisa menggabungkan string seperti `"Hello" + "World"`, jadi yang terjadi di sini adalah `"1" + "2"` yang mengembalikan `"12"`. + +
++ +#### Jawaban: C + +**Akhiran** operator unary `++`: + +1. Mengembalikan nilai (ini mengembalikan `0`) +2. Menambahkan nilai (angkanya sekarang `1`) + +**Awalan** operator unary `++`: + +1. Menambah nilai (angkanya sekarang `2`) +2. Mengembalikan nilai (ini mengembalikan `2`) + +Ini mengembalikan `0 2 2`. + +
++ +#### Jawaban: B + +Jika Anda menggunakan literal template yang diberi tag, nilai argumen pertama selalu berupa array bernilai string. Argumen yang tersisa mendapatkan nilai dari ekspresi yang diteruskan! + +
++ +#### Jawaban: C + +Saat menguji persamaan, primitif dibandingkan dengan nilainya, sedangkan objek dibandingkan dengan referensinya. JavaScript memeriksa apakah objek memiliki referensi ke lokasi yang sama di memori. + +Dua objek yang kita bandingkan tidak memiliki itu: objek yang kita lewati sebagai parameter merujuk ke lokasi yang berbeda dalam memori dari objek yang kita gunakan untuk memeriksa persamaan. + +Inilah mengapa `{age: 18} === {age: 18}` dan `{age: 18} == {age: 18}` mengembalikan nilai `false`. + +
++ +#### Jawaban: C + +Parameter sisanya (`... args`.) Memungkinkan kita "mengumpulkan" semua argumen yang tersisa ke dalam sebuah array. Array adalah sebuah objek, jadi `typeof args` mengembalikan "objek" + +
++ +#### Jawaban: C + +Dengan `" use strict "`, Anda dapat memastikan bahwa Anda tidak mendeklarasikan variabel global secara tidak sengaja. Kita tidak pernah mendeklarasikan variabel `age`, dan karena kita menggunakan `" use strict "`, ini akan memunculkan kesalahan referensi. Jika kita tidak menggunakan `" use strict "`, ini akan berhasil, karena properti `age` akan ditambahkan ke objek global. + +
++ +#### Jawaban: A + +`eval` mengevaluasi kode yang berlalu sebagai string. Jika itu adalah ekspresi, seperti dalam kasus ini, itu mengevaluasi ekspresi. Ungkapannya adalah `10 * 10 + 5`. Ini kembali nomor `105`. + +
++ +#### Jawaban: B + +Data yang disimpan di `sessionStorage` akan dihapus setelah menutup _tab_. + +Jika anda menggunakan `localStorage`, data tersebut akan tersimpan selamanya, kecuali misalnya _method_ `localStorage.clear()` dipanggil. + +
++ +#### Jawaban: B + +Dengan kata kunci `var`, anda dapat menyatakan beberapa variabel dengan nama yang sama. Variabelnya akan memegang nilai terakhir. + +Anda tidak dapat melakukan ini dengan `let` atau `const` karena mereka 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 + +Jika anda memiliki dua kunci dengan nama yang sama, kunci akan diganti. Ini masih dalam posisi pertama, tetapi dengan nilai terakhir yang ditentukan. + +
++ +#### Jawaban: A + +The base execution context is the global execution context: it's what's accessible everywhere in your code. + +
++ +#### Jawaban: C + +Pernyataan `continue` melewatkan iterasi jika kondisi tertentu mengembalikan `true`. + +
++ +#### Jawaban: A + +`String` adalah konstruksi dibangun, yang dapat kita tambahkan properti ke. Aku hanya menambahkan metode ke prototipe. String primitif string secara otomatis dikonversi menjadi objek string, dihasilkan oleh fungsi prototipe string. Jadi, semua string (objek string) memiliki akses ke metode itu! + +
++ +#### 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
+
+Kami memiliki fungsi `setTimeout` dan dimohonkan terlebih dahulu. Namun, itu login terakhir.
+
+Hal ini karena di browsers, kita tidak hanya memiliki mesin waktu runtime, kita juga memiliki sesuatu yang disebut `WebAPI`. `WebAPI` memberi kita fungsi `setTimeout`, dan misalnya DOM.
+
+Setelah _callback_ (panggilan balik) didorong ke WebAPI, fungsi `setTimeout` itu sendiri (tetapi tidak panggilan balik) muncul dari tumpukan.
+
+
+
+Sekarang, `foo` mendapat hambatan, dan `"First"` yang login.
+
+
+
+`foo` yang muncul dari tumpukan, dan `baz` mendapat perantara. `"Third"` akan login.
+
+
+
+WebAPI tidak bisa hanya menambahkan barang-barang ke tumpukan setiap kali siap. Sebaliknya, ia mendorong fungsi panggilan balik ke sesuatu yang disebut _queue_ (antrian).
+
+
+
+Di sinilah serangkaian acara mulai bekerja. Sebuah **event loop** (putaran kejadian/peristiwa) melihat tumpukan dan antrian tugas. Jika tumpukan kosong, itu mengambil hal pertama pada antrian dan mendorong ke tumpukan.
+
+
+
+`bar` bisa dipanggil, `"Second"` akan login, dan itu muncul dari tumpukan.
+
+
+ +#### 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`, `symbol`, and `bigint`. `"function"` is not a type, since functions are objects, it's of type `"object"`. + +
++ +#### Jawaban: A + +Hanya ada enam nilai yang salah: + +- `undefined` +- `null` +- `NaN` +- `0` +- `''` (string kosong) +- `false` + +Konstruktor fungsi, seperti Number baru dan Boolean baru, benar. + +
++ +#### Jawaban: B + +`typeof 1` returns `"number"`. +`typeof "number"` returns `"string"` + +
++ +#### Jawaban: C + +Saat Anda menyetel nilai ke elemen dalam larik yang melebihi panjang larik, JavaScript membuat sesuatu yang disebut "slot kosong". Ini sebenarnya memiliki nilai `tidak terdefinisi`, tetapi Anda akan melihat sesuatu seperti: + +`[1, 2, 3, 7 x empty, 11]` + +tergantung di mana Anda menjalankannya (berbeda untuk setiap browser, node, dll.) + +
++ +#### 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 + +Itu adalah mengembalikan sebuah id unik. id unik dapat digunakan untuk menghapus interval dengan menggunakan fungsi clearInterval() + +
++ +#### Jawaban: A + +Sebuah string adalah iterable. Operator memetakan setiap karakter dari sebuah iterable ke dalam satu elemen. + +
++ +#### 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.
+
+
+
+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: 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 + +Modul yang diimpor adalah _read-only_: Anda tidak dapat mengubah modul yang diimpor. Hanya modul yang mengekspornya yang dapat mengubah nilainya. + +Ketika kita mencoba untuk menambah nilai `myCounter`, itu melemparkan kesalahan: `myCounter` adalah baca-saja dan tidak dapat dimodifikasi. + + +
++ +#### 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];
+```
+
+
+
+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: 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 + +Elemen array dapat berisi beberapa nilai. angka, string, objek, array lain, null, nilai boolean, undefined, dan lainnya seperti tanggal, fungsi, dan kalkulasi. + +elemen akan sama dengan nilai hasilnya. `1 + 2` menghasilkan `3`, `1 * 2` menghasilkan `2`, dan `1 / 2` menghasilkan `0.5`. + +
++ +#### Jawaban: B + +Secara default, arguments memiliki nilai `undefined`, kecuali nilai telah diisi ke fungsi. Pada kasus ini, kita tidak mengisi nilai untuk argument `name`. `name` sama dengan `undefined` yang mana mendapat catatan. + +Di ES6, kita dapat menulis ulang nilai default `undefined` dengan parameter default. Sebagai contoh: + +`function sayHi(name = "Lydia") { ... }` + +Pada kasus ini, juka kita tidak mengisi nilai atau mengisi `undefined`, `name` akan selalu sama dengan 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 + +Kita dapat mengatur kelas yang sama dengan kelas / fungsi konstruktor lainnya. Dalam kasus ini, kita mengatur `Person` sama dengan `AnotherPerson`. Nama pada konstruktor ini adalah `Sarah`, jadi nama properti yang baru pada `Person` instance `member` adalah `"Sarah"`. + +
++ +#### Jawaban: D + +Simbol bukanlah merupakan suatu _enumerable_. Metode Object.keys akan mengembalikan semua properti kunci _enumerable_ pada sebuah objek. Simbol tidak akan terlihat, dan array kosong dikembalikan. Saat mencatat seluruh objek, semua properti akan terlihat, bahkan yang bukan non-enumerable. + +Ini adalah salah satu dari banyak kualitas simbol: Disamping selain mewakili nilai yang sepenuhnya unik (yang mencegah terjadinya benturan nama yang tidak disengaja pada objek, misalnya saat bekerja dengan 2 library yang ingin menambahkan properti ke objek yang sama), anda juga dapat "menyembunyikan" properti pada objek dengan cara ini (meskipun tidak seluruhnya. Anda masih dapat mengakses simbol menggunakan metode `Object.getOwnPropertySymbols()`). + +
++ +#### Jawaban: A + +Fungsi `getList` menerima array sebagai argumennya. Di antara tanda kurung pada fungsi `getList`, Kita akan menstruktur ulang. Anda dapat melihat ini sebagai: + +`[x, ...y] = [1, 2, 3, 4]` + +Dengan parameter sisa `...y`, kita akan meletakkan semua argumen "yang tersisa" dalam array. Dalam kasus ini argumen yang tersisa adalah `2`, `3` dan `4`. Nilai dari `y` merupakan suatu array, yang berisi semua parameter lainnya. Pada kasus ini nilai dari `x` sama dengan `1`, jadi saat kita mencatat `[x, y]`, maka catatannya `[1, [2, 3, 4]]`. + +Fungsi `getUser` menerima sebuah objek. Dengan fungsi tanda panah, kita tidak _perlu_ menulis tanda kurung kurawal jika hanya mengembalikan satu nilai. Namun, jika anda mengembalikan nilai _object_ dari fungsi tanda panah, Anda harus menuliskannya di antara tanda kurung, jika tidak maka tidak ada nilai yang dikembalikan! Fungsi berikut akan mengembalikan sebuah objek: + +`const getUser = user => ({ name: user.name, age: user.age })` + +Karena tidak ada nilai yang dikembalikan dalam kasus ini, maka fungsi akan mengembalikan `undefined`. + +
++ +#### Jawaban: C + +Variabel `name` menyimpan nilai string, yang bukan merupakan suatu fungsi, sehingga tidak dapat dipanggil. + +TypeErrors dilemparkan ketika nilai yang didapatkan bukan dari jenis yang kita harapkan. JavaScript mengharapkan `name` menjadi sebuah fungsi karena kita mencoba untuk memanggilnya. Namun itu adalah sebuah string, sehingga akan muncul TypeError gets thrown: name is not a function! + +SyntaxErrors muncul ketika anda salah menulis suatu Javascript, seperti `return` menjadi `retrun`. +ReferenceErrors muncul ketika JavaScript tidak dapat menemukan nilai referensi ke nilai yang anda coba akses. + +
++ +#### 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 (`
+ +#### 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 + +Di belakang layar, emoji adalah sebuah unicode. Unicode untuk emoji hati adalah `"U+2764 U+FE0F"`. Keduanya akan selalu sama untuk emoji yang sama, jadi sebetulnya kita telah membandingkan dua string yang sama satu sama lain, yang mana akan menghasilkan true. + +
++ +#### Jawaban: D + +Metode `splice`, akan memodifikasi array aslinya dengan cara menghapus, mengganti atau menambahkan elemen. Dalam kasus ini, kami menghapus 2 item dari indeks 1 (kami menghapus `'🥑'` dan`' 😍'`) dan menambahkan emoji ✨ sebagai penggantinya. + +`map`,` filter` dan `slice` akan mengembalikan array baru,` find` akan mengembalikan elemen yang dicari, dan `reduce` akan mengembalikan nilai yang telah dikurangi. + +
++ +#### 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`.
+
+
+
+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: 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 + +Untuk melakukan pengulangan pada `members` dalam setiap elemen array `tim`, kita perlu melemparkan `tim[i].members` ke fungsi generator `getMembers`. Fungsi generator akan mengembalikan objek hasil generator. Untuk mengulang setiap elemen dalam objek generator ini, kita perlu menggunakan `yield*`. + +Jika kita telah menulis `yield`, `return yield`, atau `return`, maka seluruh fungsi generator akan dikembalikan saat pertama kali kita memanggil metode `next`. + +
++ +#### 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 `hobbies`, `"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 + +Kita membuat variabel `pet` yang merupakan turunan dari class `Flamingo`. Saat kita membuat turunan, `constructor` pada `Flamingo` dipanggil. Pertama, `"I'm pink. 🌸"` ditampilkan, setelah itu kita memanggil `super()`. `super()` memanggil konstruktor class induk, `Bird`. Constructor pada `Bird` dipanggil, dan menampilkan `"I'm a bird. 🦢"`. + +
++ +#### Jawaban: D + +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. + +
++ +#### Jawaban: C + +Objek tidak dapat diulang secara default. Sebuah iterable adalah sebuah iterable jika protokol iterator ada. Kita dapat menambahkan ini secara manual dengan menambahkan simbol iterator + `[Symbol.iterator]`, dimana harus mengembalikan objek generator, sebagai contoh dengan membuat fungsi generator `*[Symbol.iterator]() {}`. Fungsi generator ini harus menghasilkan `Object.values` dari objek `person` jika kita mau mengembalikan array `["Lydia Hallie", 21]`: `yield* Object.values(this)`. + +
++ +#### Jawaban: C + +Pernyataan `if` didalam perulangan `forEach` akan mengecek apakah nilai dari `num` benar atau salah. Sejak nilai pertama dari array `nums` adalah `0`, yang merupakan nilai salah, pernyataan `if` tidak akan dieksekusi. maka `count` yang mendapat increment hanya untuk 3 nomor yang lain di array `nums`, `1`, `2` dan `3`. sejak `count` mendapat increment `1` 3 kali, maka nilai dari `count` adalah `3`. + +
++ +#### Jawaban: A + +Kami mengatur variabel `calc` sama dengan instance baru dari class `Calc`. Kemudian, kami membuat instance baru dari `Calc`, dan memanggil metode `increase` pada contoh ini. Karena properti count berada dalam konstruktor dari class `Calc`, properti count tidak dibagikan pada prototipe `Calc`. Ini berarti bahwa nilai hitungan belum diperbarui untuk contoh yang ditunjukkan kalk, hitung masih `0`. + +
++ +#### Jawaban: B + +Fungsi `updateUser` memperbarui nilai properti `email` dan `password` pada pengguna, jika nilainya diteruskan ke fungsi, setelah itu fungsi mengembalikan objek `user`. Nilai yang dikembalikan dari fungsi `updateUser` adalah objek `user`, yang berarti bahwa nilai updatedUser adalah referensi ke objek `user` yang sama dengan yang ditunjuk oleh `user`. `updatedUser === user` sama dengan `true`. + +
++ +#### Jawaban: C + +Pertama, kita memanggil metode `slice` pada array fruit. Metode slice tidak mengubah array asli, tetapi mengembalikan nilai yang dipotongnya dari array: banana emoji. +Kemudian, kita memanggil metode `splice` pada array fruit. Metode splice memang mengubah array asli, yang berarti array fruit sekarang terdiri dari `['🍊', '🍎']`. +Akhirnya, kita memanggil metode `unshift` pada array `fruit`, yang memodifikasi array asli dengan menambahkan nilai yang diberikan, ‘🍇’ dalam hal ini, sebagai elemen pertama dalam array. Susunan fruit sekarang terdiri dari `['🍇', '🍊', '🍎']`. + +
++ +#### Jawaban: B + +Kunci objek diubah menjadi string. + +Karena nilai `dog` adalah sebuah objek, `animals[dog]`sebenarnya berarti kita membuat properti baru bernama `"object Object"`yang sama dengan objek baru. `animals["object Object"]` sekarang sama dengan `{ emoji: "🐶", name: "Mara"}`. + +`cat` juga merupakan objek, yang berarti bahwa `animals[cat]` sebenarnya berarti bahwa kami menimpa nilai `animals[``"``object Object``"``]` dengan properti cat yang baru. + +Mencatat `animals[dog]`, atau sebenarnya `animals["object Object"]` karena mengonversi objek `dog` menjadi string menghasilkan `"object Object"`, mengembalikan `{emoji: "🐈", nama: "Sara"}`. + +
++ +#### Jawaban: A + +Fungsi `updateEmail` adalah fungsi panah, dan tidak terikat ke objek `user`. Artinya, kata kunci `this` tidak merujuk ke objek `user`, tetapi merujuk pada cakupan global dalam kasus ini. Nilai `email` dalam objek `user` tidak diperbarui. Saat memasukkan nilai `user.email`, nilai asli `my@email.com` akan dikembalikan. + +
++ +#### Jawaban: D + +Metode `Promise.all` menjalankan promise yang diberikan secara paralel. Jika satu promise gagal, metode `Promise.all` dengan nilai promise yang ditolak. Dalam kasus ini, `promise3` ditolak dengan nilai `"Third"`. Kami menangkap nilai yang ditolak dalam metode `catch` yang dirantai pada pemanggilan `runPromises` untuk menangkap setiap kesalahan dalam fungsi `runPromises`. Hanya `"Third"` yang dicatat, karena `promise3` ditolak dengan nilai ini. + +
++ +#### Jawaban: C + +Metode `fromEntries` mengubah array 2d menjadi objek. Elemen pertama di setiap subarray akan menjadi kuncinya, dan elemen kedua di setiap subarray akan menjadi nilainya. Dalam hal ini, kami memetakan di atas array `keys`, yang mengembalikan array yang elemen pertamanya adalah item pada array kunci pada indeks saat ini, dan elemen kedua adalah item dari array nilai pada indeks saat ini. + +Ini membuat array subarray yang berisi kunci dan nilai yang benar, yang menghasilkan `{name:" Lydia ", age: 22}` + +
++ +#### Jawaban: C + +Nilai default dari `address` adalah objek kosong `{}`. Saat kita menyetel variabel `member` sama dengan objek yang dikembalikan oleh fungsi `createMember`, kita tidak meneruskan nilai untuk address, yang berarti bahwa nilai address adalah objek kosong default `{}`.Objek kosong adalah nilai sebenarnya, yang berarti kondisi `address ? address: null` mengembalikan `true`. Nilai address adalah objek kosong `{}`. + +
++ +#### Jawaban: B + +Kondisi dalam pernyataan `if` memeriksa apakah nilai dari `!typeof randomValue` sama dengan `"string"`. Operator `!` Mengonversi nilai menjadi nilai boolean. Jika nilainya benar, nilai yang dikembalikan akan menjadi `false`, jika nilainya salah, nilai yang dikembalikan akan menjadi `true`. Dalam kasus ini, nilai yang dikembalikan dari `typeof randomValue` adalah nilai sebenarnya `"string"`, artinya nilai `!typeof randomValue` adalah nilai boolean `false`. + +`!typeof randomValue === "string"` selalu mengembalikan false, karena kita sebenarnya memeriksa `false === "string "`. Karena kondisi mengembalikan `false`, blok kode dari pernyataan `else` dijalankan, dan `Yay it's a string!` Akan dicatat. + +
++ +- [🇸🇦 العربية](../ar-AR/README_AR.md) +- [🇪🇬 اللغة العامية](../ar-EG/README_ar-EG.md) +- [🇧🇦 Bosanski](../bs-BS/README-bs_BS.md) +- [🇩🇪 Deutsch](../de-DE/README.md) +- [🇬🇧 English](../README.md) +- [🇪🇸 Español](../es-ES/README-ES.md) +- [🇫🇷 Français](../fr-FR/README_fr-FR.md) +- [🇮🇩 Indonesia](../id-ID/README.md) +- [🇯🇵 日本語](../ja-JA/README-ja_JA.md) +- [🇰🇷 한국어](../ko-KR/README-ko_KR.md) +- [🇳🇱 Nederlands](../nl-NL/README.md) +- [🇵🇱 Polski](../pl-PL/README.md) +- [🇧🇷 Português Brasil](../pt-BR/README_pt_BR.md) +- [🇷o Română](../ro-RO/README.ro.md) +- [🇷🇺 Русский](../ru-RU/README.md) +- [🇽🇰 Shqip](../sq-KS/README_sq_KS.md) +- [🇹🇭 ไทย](../th-TH/README-th_TH.md) +- [🇹🇷 Türkçe](../tr-TR/README-tr_TR.md) +- [🇺🇦 Українська мова](../uk-UA/README.md) +- [🇻🇳 Tiếng Việt](../vi-VI/README-vi.md) +- [🇨🇳 简体中文](../zh-CN/README-zh_CN.md) +- [🇹🇼 繁體中文](../zh-TW/README_zh-TW.md) + +
++ +#### Risposta: D + +All'interno della funzione, dichiariamo prima la variabile `name` con la parola chiave `var`. Ciò significa che la variabile viene sollevata all'interno del codice (ovvero lo spazio di memoria viene impostato durante la fase di creazione) e viene inizializzata con il valore predefinito di `undefined`, finché non arriviamo effettivamente alla riga in cui la definiamo. +Al momento in cui proviamo ad eseguire il log della variabile `name` non l'abbiamo ancora dichiarata, quindi mantiene il valore di `undefined`. + +Le variabili dichiarate con la chiave `let` (o `const`) vengono sollevate, ma a differenza delle variabili dichiarate con `var`, non vengono inizializzate. Per questo motivo non sono accessibili prima della loro dichiarazione (dove le inizializzaimo). Questa è chiamata "temporal dead zone". Quando proviamo ad accedere alle variabili prima che vengano dichiarate, JavaScript genera un `ReferenceError`. + +
++ +#### Risposta: C + +A causa della coda degli eventi in JavaScript la funzione di callback `setTimeout` viene chiamata _dopo_ che il loop è stato eseguito. Poiché la variabile `i` nel primo loop è stata dichiarata usando la chiave `var`, questo valore è globale. Durante il loop abbiamo incrementato ogni volta il valore di `i` di `1` usando l'operatore unario `++`. Quando è stata invocata la funzione di callback `setTimeout`, `i` nel primo esempio risultava sin dal principio uguale a `3`. + +Nel secondo loop, la variabile `i` è stata dichiarata usando la chiave `let`: le variabili dichiarate con la chiave `let` (e `const`) hanno lo scope del blocco (un blocco è qualsiasi cosa tra `{ }`). Durante ogni iterazione, `i` avrà un nuovo valore e ogni valore avrà lo scope all'interno del loop. + +
++ +#### Risposta: B + +Il valore di `diameter` è una funzione regolare, mentre il valore di `perimeter` è generato con una arrow function. + +Nelle arrow functions, la chiave `this` fa riferimento al suo scope interno a differenza delle funzioni regolari. Questo vuol dire che quando richiamiamo `perimeter` non stiamo facendo riferimento all'oggetto shape, ma al suo ambito circostante (ad esempio window). + +Non troviamo quindi alcun valore `radius` in quell'oggetto e quindi viene restituito `NaN`. + +
++ +#### Risposta: A + +Il + unario tenta di convertire un operando in un numero. `true` equivale ad `1` e `false` equivale a `0`. + +La stringa `'Lydia'` è un valore veritiero. Quello che in realtà ci stiamo chiedendo con `!'Lydia'` è "questo valore veritiero è falso?". Per cui la risposta è `false`. + +
++ +#### Risposta: A + +In JavaScript, tutte le chiavi degli oggetti sono stringhe (a meno che non sia un simbolo). Anche se potremmo non scriverle come stringhe, vengono sempre convertite come tali. + +JavaScript interpreta le istruzioni, quindi quando usiamo la bracket notation, vede la prima parentesi aperta `[` e continua finché non trova la parentesi chiusa `]`. Solo allora valuterà la dichiarazione. + +Quando in JavaScript richiamiamo `mouse[bird.size]`: per prima cosa viene valorizzato `bird.size`, che è `"small"`, per JS viene tradotto quindi come `mouse["small"]` che restituisce `true`. + +Con l'utilizzo del punto questo non accade perché `mouse` non ha una chiave chiamata `bird`, e questo significa che `mouse.bird` è `undefined`. Per JavaScript quindi l'istruzione `mouse.bird.size` viene tradotta con `mouse.undefined.size` che è un valore non valido e che quindi genererà un errore simile a `Cannot read property "size" of undefined`. + +
+
+
+#### Risposta: A
+
+In JavaScript, tutti gli oggetti interagiscono per _referenza_.
+
+La variabile `c` contiene come valore un oggetto. Alla variabile `d` assegniamo come valore il riferimento di `c` che quindi contiene l'oggetto (e non un suo clone).
+
+
+
+Quando modifichi il valore di questo oggetto, lo stai modificando sia per `c`che per `d`, che contiene il suo riferimento.
+
+
+ +#### Risposta: C + +`new Number()` è una funzione costruttore integrata. Nonostante sembri un numero, in realtà non lo è, si tratta infatti di un oggetto con un sacco di funzioni extra. + +Quando utilizziamo l'operatore `==`, stiamo verificando solo se il suo _valore_ è uguale. Entrambe le variabili hanno il valore di `3`, quindi il primo log restituisce `true`. + +Quando invece utilizziamo l'operatore `===`, stiamo verificando che sia il valore che il tipo di valore siano uguali. `new Number()` non è un numero, è un **oggetto** quindi entrambi i log restituiscono `false`. + +
++ +#### Risposta: D + +La funzione `colorChange` è statica. I metodi statici sono progettati per vivere solo nel costruttore in cui vengono creati e non possono essere passati a nessun figlio o richiamati su istanze di classe. Poiché `freddie` è un'istanza della classe `Chameleon`, la funzione non può essere chiamata su di essa. Viene restituito quindi un errore di tipo `TypeError`. + +
++ +#### Risposta: A + +Il nostro log restituisce un oggetto perché abbiamo appena creato un oggetto vuoto come oggetto globale nel momento in cui per errore abbiamo digitato `greetign` al posto di `greeting`. + +Il nostro interprete a quel punto ha letto `global.greetign = {}` (o `window.greetign = {}` se parliamo di un browser). + +Per evitare ciò, possiamo usare `"use strict"`. Questo assicura di aver dichiarato una variabile prima di impostarla uguale a qualsiasi cosa. + +
++ +#### Risposta: A + +In JavaScript non succede nulla, perché le funzioni sono oggetti! (Tutto tranne i tipi primitivi sono oggetti). + +Una funzione è un tipo speciale di oggetto. Il codice che scrivi non è la funzione effettiva. La funzione è un oggetto con delle proprietà e quindi questa proprietà è invocabile. + +
++ +#### Risposta: A + +In JavaScript, le funzioni sono oggetti e quindi il metodo `getFullName` viene aggiunto al costruttore della funzione stessa. Per questo motivo possiamo chiamare `Person.getFullName()`, mentre `member.getFullName` genera un `TypeError`. + +Se vuoi che un metodo sia disponibile per tutte le istanze dell'oggetto, devi aggiungerlo alla proprietà del prototipo: + + +```js +Person.prototype.getFullName = function() { + return `${this.firstName} ${this.lastName}`; +}; +``` + +
++ +#### Risposta: A + +Per la const `sarah`, non abbiamo usato la chiave `new`. Quando si usa `new`, `this` si riferisce al nuovo oggetto vuoto che creiamo. Tuttavia, se non aggiungiamo `new`, `this` si riferisce all'**oggetto globale**! + +Abbiamo quindi scritto che `this.firstName` equivale a `"Sarah"` e `this.lastName` equivale a `"Smith"`. Quello che abbiamo effettivamente fatto è definire `global.firstName = 'Sarah'` e `global.lastName = 'Smith'`. La `const` `sarah` viene lasciata come `non definita`, perché non restituiamo un valore dalla funzione `Persona`. + +
+
+
+#### Risposta: D
+
+Durante la fase di **capturing**, l'evento passa attraverso gli elementi predecessori fino all'elemento target. Quindi raggiunge l'elemento **target** e inizia il **bubbling**.
+
+
+
+
+ +#### Risposta: B + +Tutti gli oggetti hanno prototipi, ad eccezione dell'**oggetto base**. L'oggetto base è l'oggetto creato dall'utente, o un oggetto creato usando la parola chiave `new`. L'oggetto base ha accesso ad alcuni metodi e proprietà, come `.toString`. Questo è il motivo per cui puoi utilizzare i metodi JavaScript built-in! Tutti questi metodi sono disponibili sul prototype. Quindi, anche se JavaScript non riesce a trovarlo direttamente sul tuo oggetto, scende lungo la chain del prototype e lo trova lì, il che lo rende accessibile anche per l'oggetto creato da te. + +
++ +#### Risposta: C + +JavaScript è un **linguaggio tipizzato dinamicamente**: non specifichiamo quali tipi siano determinate variabili. I valori possono essere automaticamente convertiti in un altro tipo, questa azione è chiamata _coercizione implicita del tipo_. **Coercizione** è la conversione da un tipo all'altro. + +In questo esempio, JavaScript converte il numero `1` in una stringa, in modo che la funzione abbia un senso e restituisca un valore. Durante l'aggiunta di un tipo numerico (`1`) e di un tipo stringa (`'2'`), il numero viene trattato come una stringa. Possiamo concatenare stringhe come `"Hello" + "World"`, quindi quello che sta succedendo qui è `"1" + "2"` che restituisce `"12"`. + +
++ +#### Risposta: C + +Utilizzando l'operatore unario come **postfisso** `number++` succede che: + +1. Restituisce prima il suo valore (`0`) +2. Subito dopo incrementa il valore di 1 (quindi è ora `1`) + +Utilizzando l'operatore unario come **prefisso** `++number` succede che: + +1. Incrementa prima il valore (il numero è ora `2`) +2. Restituisce subito dopo il valore già incrementato (`2`) + +Quindi il nostro log sarà `0 2 2`. + +
++ +#### Risposta: B + +Utilizzando i template literals, il valore del primo argomento sarà un array di valori della stringa. Gli altri argomenti prenderanno i valori dell'espressione passata. + +
++ +#### Risposta: C + +Quando si verifica l'uguaglianza, i primitivi vengono confrontati in base al loro _valore_, mentre gli oggetti vengono confrontati in base al loro _riferimento_. JavaScript controlla se gli oggetti hanno un riferimento alla stessa posizione in memoria. + +I due oggetti che stiamo confrontando non lo hanno: l'oggetto che abbiamo passato come parametro si riferisce a una posizione di memoria diversa rispetto all'oggetto che abbiamo usato per verificare l'uguaglianza. + +Questo è il motivo per cui sia `{ age: 18 } === { age: 18 }` e `{ age: 18 } == { age: 18 }` restituiscono `false`. + +
++ +#### Risposta: C + +Il parametro rest (`...args`) ci permette di "collettare" tutti gli argomenti in un array. L'array è un oggetto, quindi `typeof args` restituisce `"oggetto"` + +
++ +#### Risposta: C + +Con `"use strict"`, puoi assicurarti di non dichiarare variabili globali per sbaglio. In questo caso la variabile `age` non è mai stata dichiarata, e siccome usiamo `"use strict"`, genererà un `ReferenceError`. Se non avessimo usato `"use strict"`, avrebbe funzionato perché la proprietà `age` sarebbe stata aggiunta all'oggetto globale. + +
++ +#### Risposta: A + +`eval` "valuta" i codici passati come stringa. Se è un'espressione, come in questo caso, valuta l'espressione. L'espressione è `10 * 10 + 5`. Quindi il valore restituito è il numero `105`. + +
++ +#### Risposta: B + +I dati memorizzati in `sessionStorage` vengono rimossi dopo aver chiuso la _tab_. + +Se avessi usato `localStorage`, i dati sarebbero rimasti lì per sempre, a meno che, ad esempio, non fosse stato invocato `localStorage.clear()`. + +
++ +#### Risposta: B + +Con la chiave `var` puoi dichiarare più variabili con lo stesso nome. La variabile conterrà quindi l'ultimo valore. + +Non puoi farlo con `let` o `const` poiché sono block-scoped. + +
++ +#### Risposta: C + +Tutte le chiavi degli oggetti (esclusi i simboli) sono stringhe, anche se non vengono scritte come tali. Questo è il motivo per cui anche `obj.hasOwnProperty('1')` restituisce true. + +Per i set non funziona allo stesso modo degli oggetti. Non c'è alcun `'1'` nel nostro set, per cui `set.has('1')` restituisce `false`, è però presente il tipo numerico `1` per cui `set.has(1)` restituisce `true`. + +
++ +#### Risposta: C + +Se hai due chiavi con lo stesso nome, questa verrà sostituita. Sarà quindi ancora nella sua prima posizione, ma con l'ultimo valore specificato. + +
++ +#### Risposta: A + +Il contesto di esecuzione di base è il contesto di esecuzione globale: è ciò che è accessibile ovunque nel codice. + +
++ +#### Risposta: C + +L'istruzione `continue` salta un'iterazione se una certa condizione restituisce `true`. + +
++ +#### Risposta: A + +`String` è un costruttore built-in, a cui possiamo aggiungere proprietà. In questo caso è stato appena aggiunto un metodo al suo prototipo. +Le stringhe primitive vengono automaticamente convertite in un oggetto stringa, generato dalla string prototype function. Quindi, tutte le stringhe hanno accesso a quel metodo! + +
++ +#### Risposta: B + +Le chiavi degli oggetti vengono automaticamente convertite in stringhe. Stiamo cercando di impostare un oggetto come chiave per l'oggetto `a` con il valore di `123`. + +Tuttavia, quando convertiamo in stringa un oggetto, diventa `"[object Object]"`. Quindi quello che stiamo dicendo qui è che `a["[object Object]"] = 123`. `c` è un altro oggetto che stiamo implicitamente stringendo. Quindi, `a["[object Object]"] = 456`. + +Quindi, quando facciamo console.log di `a[b]`, che in realtà è `a["[object Object]"]` che abbiamo appena valorizzato con `456`, restituisce `456`. + +
+
+
+#### Risposta: B
+
+Abbiamo una funzione `setTimeout` e l'abbiamo invocata per prima. Eppure, viene loggata per ultima.
+
+Questo succede perché nei browser non abbiamo solo il runtime engine, ma anche qualcosa chiamata `WebAPI`. La `WebAPI` ci fornisce la funzione `setTimeout` con cui iniziare, e per esempio il DOM.
+
+Dopo che la _callback_ è stata inviata alla `WebAPI`, la stessa funzione `setTimeout` (ma non la sua callback) viene eliminata dallo stack.
+
+
+
+Ora, `foo` viene invocato e `"First"` viene loggato.
+
+
+
+`foo` viene quindi tolto dallo stack e `baz` viene invocato. `"Third"` viene loggato.
+
+
+
+La WebAPI non può semplicemente aggiungere elementi allo stack ogni volta che è pronta, spinge quindi la funzione di callback in quella che chiamiamo _queue_.
+
+
+
+È qui che un ciclo di eventi inizia a funzionare. Un **event loop** esamina lo stack e la coda delle attività. Se lo stack è vuoto, prende la prima cosa in coda e la inserisce nello stack.
+
+
+
+`bar` viene invocato, `"Second"` viene registrato e viene tolto dallo stack.
+
+
+ +#### Risposta: C + +L'elemento annidato più in profondità è quello che ha causato l'evento ed è quindi l'event.target. Puoi stoppare la propagazione con `event.stopPropagation` + +
++ Click here! +
++ +#### Risposta: A + +Se clicchiamo su `p`, vediamo due log: `p` e `div`. Durante la propagazione dell'evento, ci sono 3 fasi: capturing, target, e bubbling. Di default, i gestori di eventi vengono eseguiti nella fase di bubbling (a meno che non si imposti `useCapture` su `true`) e va quindi dall'elemento annidato più profondo verso l'esterno. + +
++ +#### Risposta: D + +Con entrambi possiamo passare l'oggetto a cui vogliamo che la chiave `this` faccia riferimento. Tuttavia, anche `.call` viene _eseguito immediatamente_! + +`.bind.` restituisce una _copia_ della funzione, ma con un contesto vincolato! Non viene eseguito immediatamente. + +
++ +#### Risposta: B + +La funzione `sayHi` restituisce il valore dato dell'espressione della immediately invoked function expression (IIFE). Questa funzione ha restituito `0`, che è di tipo `"numero"`. + +Ci sono solo 7 tipi built-in: `null`, `undefined`, `boolean`, `number`, `string`, `object` e `symbol`. `"function"` non è un tipo, poiché le funzioni sono oggetti, è quindi di tipo "oggetto"`. + +
++ +#### Risposta: A + +Ci sono 8 valori falsi: + +- `undefined` +- `null` +- `NaN` +- `false` +- `''` (empty string) +- `0` +- `-0` +- `0n` (BigInt(0)) + +I costruttori di funzioni, come `new Number` e `new Boolean` sono veritieri. + +
++ +#### Risposta: B + +`typeof 1` ritorna `"number"`. +`typeof "number"` ritorna `"string"` + +
++ +#### Risposta: C + +Quando imposti un valore su un elemento in un array che supera la lunghezza dell'array JavaScript crea degli "slot vuoti". Questi in realtà hanno il valore di `undefined`, ma vedrai qualcosa come: + +`[1, 2, 3, 7 x empty, 11]` + +a seconda di dove lo esegui (è diverso per ogni browser, node, ecc.) + +
++ +#### Risposta: A + +Il blocco `catch` riceve l'argomento `x` ma non è la stessa `x` della variabile, bensì passiamo un argomento della funzione. Questa "variabile" `x` è block-scoped quindi ha un ambito di blocco. + +Subito dopo impostiamo il valore di variabile block-scoped a `1` e impostiamo il valore della variabile `y`. Ora facciamo un console.log della variabile block-scoped `x`, che è uguale a `1`. + +Fuori dal blocco `catch`, `x` è ancora `undefined` e `y` è `2` quindi quando facciamo `console.log(x)` al di fuori del blocco `catch`, otterremo `undefined` e `y` restituirà `2`. + +
++ +#### Risposta: A + +JavaScript ha solo tipi primitivi e oggetti. + +I tipi primitivi sono `boolean`, `null`, `undefined`, `bigint`, `number`, `string` e `symbol`. + +Ciò che differenzia un tipo primitivo da un oggetto è che i primitivi non hanno proprietà o metodi. Tuttavia, noterai che `'foo'.toUpperCase()` restituisce `'FOO'` e non genera un `TypeError`. Questo perché quando si tenta di accedere a una proprietà o a un metodo su di un tipo primitivo come lo è una stringa, JavaScript racchiuderà implicitamente il tipo primitivo utilizzando una delle classi wrapper, ovvero "String", valuterà l'espressione ed eliminerà il wrapper una volta terminato. Tutti i primitivi tranne `null` e `undefined` subiscono questo comportamento. + +
++ +#### Risposta: C + +`[1, 2]` rappresenta il nostro valore interno. Ovvero il valore con cui iniziamo e il valore del primo `acc`. Durante il primo round, `acc` è `[1,2]` e `cur` è `[0, 1]`. Li concateniamo ottenendo `[1, 2, 0, 1]`. + +A questo punto `acc` corrisponderà a `[1, 2, 0, 1]` e `cur` sarà ancora `[2, 3]`. Li concateniamo e otteniamo `[1, 2, 0, 1, 2, 3]` +
++ +#### Risposta: B + +`null` è falso. `!null` restituisce `true`. `!true` restituisce `false`. + +`""` è falso. `!""` restituisce `true`. `!true` restituisce `false`. + +`1` è vero. `!1` restituisce `falso`. `!false` restituisce `true`. + +
++ +#### Risposta: A + +Restituisce un ID univoco. Questo id può essere usato per cancellare quell'intervallo con la funzione `clearInterval()`. + +
++ +#### Risposta: A + +Una stringa è un iterabile. L'operatore spread mappa ogni carattere di una stringa rendendola parte di array. + +
++ +#### Risposta: C + +Le funzioni regolari non possono essere interrotte a metà dopo l'invocazione. Tuttavia, una funzione "generator" può essere stoppata a metà e in seguito continuare da dove si era interrotta. Ogni volta che una funzione generator incontra una parola chiave `yield`, la funzione restituisce il valore specificato dopo di essa. Nota che la funzione del generator in quel caso non _restituisce (return)_ il valore, _rende (yeld)_ il valore. + +Come prima cosa inizializziamo la funzione del generator con `i` uguale a `10`. Invochiamo la funzione usando il metodo `next()`. La prima volta che invochiamo la funzione generator, `i` è uguale a `10`, incontra la prima parola chiave `yield` quindi restituisce il valore di `i`. Il generatore è ora "in pausa" e `10` viene loggato. + +Invochiamo di nuovo la funzione con il metodo `next()`. Inizia a continuare da dove si era fermata in precedenza, sempre con `i` uguale a `10`. Ora incontra il secondo `yield` e restituisce `i * 2`, quindi restituisce `10 * 2`, che è `20`. Ciò risulta in `10, 20`. + +
++ +#### Risposta: B + +Quando passiamo più promises al metodo `Promise.race`, questo risolve/rifiuta la _prima_ promise. Al metodo `setTimeout` passiamo un timer: 500ms per la prima promise (`firstPromise`) e 100ms per la seconda promise (`secondPromise`). Ciò significa che `secondPromise` si risolve prima con il valore di `'due'`. `res` ora contiene il valore di `'two'`, che viene loggato. + +
+
+
+#### Risposta: D
+
+Per prima cosa, dichiariamo una variabile `person` con un oggetto che ha una proprietà `name`.
+
+
+
+Quindi, dichiariamo una variabile chiamata `members`. Impostiamo il primo elemento di quell'array uguale al valore della variabile `person`. Gli oggetti interagiscono per _riferimento_ quando vengono impostati uguali tra loro. Quando assegni un riferimento da una variabile all'altra, esegui una _copia_ di quel riferimento. (nota che non hanno lo _stesso_ riferimento!)
+
+
+
+Quindi, impostiamo la variabile `person` uguale a `null`.
+
+
+
+Stiamo modificando solo il valore della variabile `person`, e non il primo elemento nell'array, poiché quell'elemento ha un riferimento diverso (copiato) dall'oggetto. Il primo elemento in `members` mantiene ancora il suo riferimento all'oggetto originale. Quando logghiamo l'array `members`, il primo elemento contiene ancora il valore dell'oggetto, che viene loggato.
+
+
+ +#### Risposta: B + +Con il ciclo `for-in`, possiamo iterare le chiavi degli oggetti, in questo caso `name` e `age`. Le chiavi degli oggetti sono stringhe (se non sono un simbolo). In ogni ciclo, impostiamo il valore di `item` uguale alla chiave corrente su cui sta iterando. Il primo `item` è uguale a `name` e viene loggato, `item` sarà poi uguale a `age`, che viene loggato. + +
++ +#### Risposta: B + +L'associazione è l'ordine in cui il compilatore valuta le espressioni, da sinistra a destra o da destra a sinistra. Questo accade solo se tutti gli operatori hanno la _stessa_ precedenza. Abbiamo solo un tipo di operatore: `+`. Inoltre, l'associazione è da sinistra a destra. + +`3 + 4` viene valutato per primo. E risulta nell'addizione dei due valori che restituiscono quindi `7`. + +`7 + '5'` risulta in `"75"` per via della coercizione. JavaScript converte il numero `7` in una stringa, (vedi la domanda 15). Possiamo concatenare due stringhe usando l'operatore `+`. `"7" + "5"` risulta quindi in "75"`. + +
++ +#### Risposta: C + +Viene restituito solo il primo valore della stringa. In base alla _radice_ (ovvero il secondo argomento per specificare sulla base di quale tipo di numero vogliamo analizzarlo: base 10, esadecimale, ottale, binario, ecc.), `parseInt` controlla se i caratteri nella stringa sono validi. Una volta che incontra un carattere che non è un numero valido nella radice, interrompe l'analisi e ignora i seguenti caratteri. + +`*` non è un numero valido. Analizza solo `"7"` nel decimale `7`. `num` ora contiene il valore di `7`. + +
++ +#### Risposta: C + +Quando si esegue il mapping sull'array, il valore di `num` è uguale all'elemento su cui sta attualmente scorrendo. In questo caso, gli elementi sono numeri, quindi la condizione dell'istruzione if `typeof num === "number"` restituisce `true`. La funzione map crea un nuovo array e inserisce i valori restituiti dalla funzione. + +Tuttavia, non ritorniamo un valore. Quando non ritorniamo un valore dalla funzione, la funzione restituisce `undefined`. Per ogni elemento nell'array, viene chiamato il blocco funzione, quindi per ogni elemento restituiamo `undefined`. + +
++ +#### Risposta: A + +Gli argomenti vengono passati come _valori_, a meno che il loro valore non sia un oggetto, quindi vengono passati come _reference_. `birthYear` viene passato per valore, poiché è una stringa, non un oggetto. Quando passiamo argomenti per valore, viene creata una _copia_ di quel valore (vedi domanda 46). + +La variabile `birthYear` ha un riferimento al valore `"1997"`. Anche l'argomento `year` fa riferimento al valore `"1997"`, ma non è lo stesso valore a cui fa riferimento `birthYear`. Quando aggiorniamo il valore di `year` impostando `year` uguale a `"1998"`, stiamo solo aggiornando il valore di `year`. `birthYear` è ancora uguale a `"1997"`. + +Il valore di `person` è un oggetto. L'argomento `member` ha un riferimento (copiato) dello stesso oggetto. Quando modifichiamo una proprietà dell'oggetto a cui `member` fa riferimento, verrà modificato anche il valore di `person`, poiché entrambi hanno un riferimento allo stesso oggetto. La proprietà `name` di `person` è ora uguale al valore `"Lydia"` +
++ +#### Risposta: D + +Con l'istruzione `throw`, possiamo creare errori personalizzati. Con questa istruzione, puoi generare eccezioni. Un'eccezione può essere una stringa, un numero, un booleano o un oggetto. In questo caso, la nostra eccezione è la stringa `'Hello world!'`. + +Con l'istruzione `catch`, possiamo specificare cosa fare se viene generata un'eccezione nel blocco `try`. Viene generata un'eccezione: la stringa `'Hello world!'`. `e` è ora uguale a quella stringa, che logghiamo. Ciò si traduce in `'Oh an error: Hello world!'`. + +
++ +#### Risposta: B + +Quando si restituisce una proprietà, il valore della proprietà è uguale al valore _restituito_, non al valore impostato nella funzione di costruzione. Restituiamo la stringa `"Maserati"`, quindi `myCar.make` è uguale a `"Maserati"`. + +
++ +#### Risposta: A + +`let x = (y = 10);` in realtà è un'abbreviazione per: + +```javascript +y = 10; +let x = y; +``` + +Quando impostiamo `y` uguale a `10`, in realtà aggiungiamo una proprietà `y` all'oggetto globale (`window` nel browser, `global` in Node). In un browser, `window.y` ora è uguale a `10`. + +Quindi, dichiariamo una variabile `x` con il valore di `y`, che è `10`. Le variabili dichiarate con la parola chiave `let` sono _block scoped_, ovvero sono definite solo all'interno del blocco in cui sono dichiarate, l'espressione di funzione immediatamente invocata (IIFE) in questo caso. Quando utilizziamo l'operatore `typeof`, l'operando `x` non è definito: stiamo cercando di accedere a `x` al di fuori del blocco in cui è dichiarato. Ciò significa che `x` non è definito. I valori a cui non è stato assegnato un valore o dichiarati sono di tipo `"undefined"`. `console.log(typeof x)` restituisce `"undefined"`. + +Tuttavia, abbiamo creato una variabile globale `y` quando abbiamo impostato `y` uguale a `10`. Questo valore è accessibile ovunque nel nostro codice. `y` è definito e contiene un valore di tipo `"number"`. `console.log(typeof y)` restituisce `"number"`. + +
++ +#### Risposta: A + +Possiamo eliminare le proprietà dagli oggetti usando la parola chiave `delete`, anche sul prototype. Eliminando una proprietà sul prototipo, questa non è più disponibile nella catena di prototype. In questo caso, la funzione `bark` non è più disponibile sul prototipo dopo `delete Dog.prototype.bark`, ma proviamo comunque ad accedervi. + +Quando proviamo a invocare qualcosa che non è una funzione, viene lanciato un `TypeError`. In questo caso `TypeError: pet.bark is not a function`, poiché `pet.bark` è `undefined`. + +
++ +#### Risposta: D + +L'oggetto `Set` è una collezione di valori _unici_: un valore può verificarsi solo una volta in un set. + +Abbiamo passato l'array `[1, 1, 2, 3, 4]` con il valore duplicato `1`. Poiché non possiamo avere due valori uguali in un set, uno di essi viene rimosso. Ciò risulta in `{1, 2, 3, 4}`. + +
++ +#### Risposta: C + +Un modulo importato è di _sola lettura_: non è quindi possibile modificare il modulo importato. Solo il modulo che li esporta può cambiarne il valore. + +Quando proviamo ad incrementare il valore di `myCounter`, viene generato un errore: perché `myCounter` è di sola lettura e non può essere modificato. + +
++ +#### Risposta: A + +L'operatore `delete` restituisce un valore booleano: `true` su una cancellazione riuscita, altrimenti restituirà `false`. Tuttavia, le variabili dichiarate con la parola chiave `var`, `const` o `let` non possono essere cancellate usando l'operatore `delete`. + +La variabile `name` è stata dichiarata con la chiave `const`, quindi la sua cancellazione non va a buon fine e viene restituito `false`. Quando impostiamo `age` uguale a `21`, abbiamo effettivamente aggiunto una proprietà chiamata `age` all'oggetto globale. Puoi eliminare con successo le proprietà dagli oggetti in questo modo, anche l'oggetto globale, quindi `delete age` restituisce `true`. + +
+
+
+#### Risposta: C
+
+Possiamo spacchettare i valori da un array o proprietà dagli oggetti attraverso la destrutturazione. Per esempio:
+
+```javascript
+[a, b] = [1, 2];
+```
+
+
+
+Il valore di `a` ora è `1`, e il valore di `b` è ora `2`. Quello che abbiamo effettivamente fatto nella domanda è:
+
+```javascript
+[y] = [1, 2, 3, 4, 5];
+```
+
+
+
+Questo significa che il valore di `y` è uguale al primo valore nell'array, che è il numero `1`. Quando registriamo `y`, viene restituito `1`.
+
+
+ +#### Risposta: B + +È possibile combinare oggetti utilizzando l'operatore spread `...`. Questo ti consente di creare copie delle coppie chiave/valore di un oggetto e aggiungerle a un altro oggetto. In questo caso, creiamo copie dell'oggetto `user` e le aggiungiamo all'oggetto `admin`. L'oggetto `admin` ora contiene le coppie chiave/valore copiate, che risultano in `{ admin: true, name: "Lydia", age: 21 }`. + +
++ +#### Risposta: B + +Con il metodo `defineProperty`, possiamo aggiungere nuove proprietà a un oggetto o modificare quelle esistenti. Quando aggiungiamo delle proprietà a un oggetto usando il metodo `defineProperty`, queste per impostazione predefinita sono _non enumerabili_. Il metodo `Object.keys` restituisce tutti i nomi di proprietà _enumerabili_ da un oggetto, in questo caso solo `"name"`. + +Le proprietà aggiunte usando il metodo `defineProperty` sono immutabili per impostazione predefinita. Puoi ignorare questo comportamento usando le proprietà `writable`, `configurable` ed `enumerable`. In questo modo, il metodo `defineProperty` ti dà molto più controllo sulle proprietà che stai aggiungendo a un oggetto. + +
++ +#### Risposta: A + +Il secondo argomento di `JSON.stringify` è _replacer_. Il replacer può essere una funzione o un array e consente di controllare cosa e come i valori devono essere stringati. + +Se il replacer è un _array_, solo i nomi delle proprietà inclusi nell'array verranno aggiunti alla stringa JSON. In questo caso, sono incluse solo le proprietà con i nomi `"level"` e `"health"`, `"username"` è esclusa. `data` quindi ora è uguale a `"{"level":19, "health":90}"`. + +Se il replacer è una _funzione_, questa funzione viene chiamata su ogni proprietà nell'oggetto che stai stringendo. Il valore restituito da questa funzione sarà il valore della proprietà quando viene aggiunto alla stringa JSON. Se il valore è `undefined`, questa proprietà viene esclusa dalla stringa JSON. + +
++ +#### Risposta: A + +L'operatore unario `++` _prima_ restituisce il valore dell'operando, _poi_ incrementa il valore dell'operando. Il valore di `num1` è `10`, poiché la funzione `increaseNumber` restituisce prima il valore di `num`, che è `10`, e solo successivamente incrementa il valore di `num`. + +`num2` è `10`, poiché abbiamo passato `num1` a `increasePassedNumber`. `number` è uguale a `10` (il valore di `num1`. Anche in questo caso, l'operatore unario `++` _prima_ restituisce il valore dell'operando, _poi_ lo incrementa. Il valore di `number` è ` 10`, quindi `num2` è uguale a `10`. + +
++ +#### Risposta: C + +In ES6, possiamo inizializzare i parametri con un valore predefinito. Il valore del parametro sarà il valore predefinito se nessun altro valore è stato passato alla funzione o se è stato passato un valore `"undefined"`. In questo caso, distribuiamo le proprietà dell'oggetto `value` in un nuovo oggetto, quindi `x` ha il valore predefinito di `{ number: 10 }`. + +L'argomento predefinito viene valutato quando viene chiamato! Ogni volta che chiamiamo la funzione, viene creato un _nuovo_ oggetto. Invochiamo la funzione `multiply` le prime due volte senza passare un valore, quindi `x` ha il valore predefinito di `{ number: 10 }`. Quindi logghiamo il valore moltiplicato di quel numero, che è `20`. + +La terza volta che invochiamo la funzione multiply, passiamo un argomento: l'oggetto chiamato `value`. L'operatore `*=` è in realtà un'abbreviazione per `x.number = x.number * 2`: modifichiamo il valore di `x.number` e logghiamo il valore moltiplicato `20`. + +La quarta volta, passiamo di nuovo l'oggetto `value`, in questo caso `x.number` è stato precedentemente modificato in `20`, quindi `x.number *= 2` logga `40`. + +
++ +#### Risposta: D + +Il primo argomento che il metodo `reduce` riceve è l'_accumulatore_, in questo caso `x`. Il secondo argomento è il _valore corrente_ `y`. +Con il metodo reduce, eseguiamo una funzione di callback su ogni elemento dell'array, che alla fine potrebbe risultare in un singolo valore. + +In questo esempio, non stiamo restituendo alcun valore, stiamo semplicemente loggando i valori dell'accumulatore e il valore corrente. + +Il valore dell'accumulatore è uguale al valore restituito in precedenza dalla funzione di callback. Se non si passa l'argomento opzionale `initialValue` al metodo `reduce`, l'accumulatore è uguale al primo elemento della prima chiamata. + +Alla prima chiamata, l'accumulatore (`x`) è `1` e il valore corrente (`y`) è `2`. Non facciamo un return con la funzione di callback ma logghiamo l'accumulatore e il valore corrente: `1` e `2` vengono loggati. + +Se non restituisci un valore da una funzione questa restituisce `undefined`. Alla chiamata successiva, l'accumulatore è `undefined` e il valore corrente è "3". `undefined` e `3` vengono loggati. + +Alla quarta chiamata, di nuovo non facciamo un return dalla funzione di callback. L'accumulatore è di nuovo `undefined` e il valore corrente è "4". `undefined` e `4` vengono loggati. +
++ +#### Risposta: B + +In una classe derivata, non puoi accedere alla chiave `this` prima di chiamare `super`. Se provi a farlo, genererà un ReferenceError: 1 e 4 genererebbero un errore di riferimento. + +Con la chiave `super`, chiamiamo il costruttore di quella classe parent con gli argomenti forniti. Il costruttore del parent riceve l'argomento `name`, quindi passiamo `name` a `super`. + +La classe `Labrador` riceve due argomenti, `name` poiché estende `Dog`, e `size` come proprietà extra sulla classe `Labrador`. Entrambi devono essere passati alla funzione di costruzione su `Labrador`, cosa che viene eseguita correttamente usando il costruttore 2. + +
++ +#### Risposta: B + +Con la chiave `import` tutti i moduli importati sono _pre-parsed_. Ciò significa che i moduli importati vengono eseguiti _prima_, il codice nel file che importa il modulo viene eseguito _dopo_. + +Questa è una delle differenze tra `require()` in CommonJS e `import`. Con `require()`, puoi caricare le dipendenze su richiesta mentre il codice è in esecuzione. Se avessimo usato `require` invece di `import`, sulla console avremmo loggato `running index.js`, `running sum.js`, `3`. + +
++ +#### Risposta: A + +Ogni Simbolo è unico. Lo scopo dell'argomento passato a Symbol è di dargli una descrizione. Il valore del Symbol non dipende dall'argomento passato. Mentre testiamo l'uguaglianza, stiamo creando due simboli completamente nuovi: il primo `Symbol('foo')` e il secondo `Symbol('foo')`. Questi due valori sono unici e non uguali tra loro, `Symbol('foo') === Symbol('foo')` quindi restituisce `false`. + +
++ +#### Risposta: C + +Con il metodo `padStart`, possiamo aggiungere un riempimento all'inizio di una stringa. Il valore passato a questo metodo è la lunghezza _totale_ della stringa insieme al riempimento. La stringa `"Lydia Hallie"` ha una lunghezza di `12`. `name.padStart(13)` inserisce quindi 1 spazio all'inizio della stringa, perché 12 + 1 è 13. + +Se l'argomento passato al metodo `padStart` è inferiore alla lunghezza dell'array, non verrà aggiunto alcun riempimento. + +
++ +#### Risposta: A + +Con l'operatore `+` puoi concatenare stringhe. In questo caso, stiamo concatenando la stringa `"🥑"` con la stringa `"💻"`, ottenendo `"🥑💻"`. + +
++ +#### Risposta: C + +Una funzione generator "mette in pausa" la sua esecuzione quando incontra la parola chiave `yield`. Innanzitutto dobbiamo lasciare che la funzione produca la stringa "Ami JavaScript?", che può essere eseguita chiamando `game.next().value`. + +Ogni riga viene quindi eseguita, finché non trova la prima chiave `yield`. C'è una parola chiave `yield` sulla prima riga all'interno della funzione: l'esecuzione si interrompe con il primo rendimento! _Questo significa che la variabile `answer` non è ancora definita!_ + +Quando chiamiamo `game.next("Yes").value`, il precedente `yield` viene sostituito con il valore dei parametri passati alla funzione `next()`, in questo caso `"Yes"`. Il valore della variabile `answer` è ora uguale a `"Yes"`. La condizione dell'istruzione if restituisce `false` e `JavaScript loves you back ❤️` viene registrato. + +
++ +#### Risposta: C + +`String.raw` restituisce una stringa in cui gli escape (`\n`, `\v`, `\t` ecc.) vengono ignorati! I backslash possono essere un problema poiché potresti finire con qualcosa del tipo: + +`` const path = `C:\Documents\Projects\table.html` `` + +Il che risulterebbe in: + +`"C:DocumentsProjects able.html"` + +Con `String.raw`, il compilatore ignorerebbe semplicemente l'escape e stamperebbe: + +`C:\Documents\Projects\table.html` + +In questo caso, è la stringa `Hello\nworld` che viene loggata. + +
++ +#### Risposta: C + +Una funzione asincrona restituisce sempre una promise. L'`await` deve ancora attendere che la promise si risolva: una promise in sospeso viene restituita quando chiamiamo `getData()` per impostare `data` uguale ad essa. + +Se volessimo accedere al valore risolto `"I made it"`, potremmo usare il metodo `.then()` su `data`: + +`data.then(res => console.log(res))` + +Questo avrebbe loggato `"I made it!"` + +
++ +#### Risposta: B + +Il metodo `.push()` restituisce la _lunghezza_ del nuovo array! +Inizialmente, l'array conteneva un solo elemento (la stringa `"banana"`) e aveva una lunghezza di `1`. Dopo aver aggiunto la stringa `"apple"` allo stesso array, questo contiene due elementi e ha una lunghezza di `2` + +Attraverso la funzione `addToList`, il metodo `push` modifica l'array originale. +Per restituire l'_array_ dalla funzione invece della _lunghezza dell'array_, serve fare un return di `list` dopo aver inserito l'`item`. + +
++ +#### Risposta: B + +`Object.freeze` rende impossibile aggiungere, rimuovere o modificare le proprietà di un oggetto (a meno che il valore della proprietà non sia un altro oggetto). + +Quando creiamo la variabile `shape` e la impostiamo come all'oggetto congelato `box`, anche `shape` si riferisce ad un oggetto congelato. +Puoi controllare se un oggetto è congelato usando `Object.isFrozen`. In questo caso, `Object.isFrozen(shape)` restituisce true, poiché la variabile `shape` ha un riferimento a un oggetto congelato. + +Poiché `shape` è congelata, e poiché il valore di `x` non è un oggetto, non possiamo modificare la proprietà `x`. +`x` è ancora uguale a `10` e `{ x: 10, y: 20 }` viene loggato. + +
++ +#### Risposta: C + +Quando spacchettiamo la proprietà `name` dall'oggetto, assegniamo il suo valore `"Lydia"` a una variabile con il nome `myName`. + +Con `{ name: myName }`, diciamo a JavaScript che vogliamo creare una nuova variabile chiamata `myName` con il valore della proprietà `name`. + +Poiché proviamo a loggare `name`, una variabile che non è definita, viene restituito `undefined` nell'assegnazione. Successivamente, il valore di `Lydia` viene memorizzato tramite l'assegnazione di destrutturazione. + +
++ +#### Risposta: A + +Una funzione pura è una funzione che restituisce _sempre_ lo stesso risultato, se vengono passati gli stessi argomenti. + +La funzione `sum` restituisce sempre lo stesso risultato. Se le passiamo `1` e `2`, restituirà _sempre_ `3` senza effetti collaterali. Se passiamo `5` e `10`, restituirà _sempre_ `15` e così via. Questa è la definizione di funzione pura. + +
++ +#### Risposta: C + +La funzione `add` è una funzione _memoizzata_. Con la memorizzazione, possiamo memorizzare nella cache i risultati di una funzione per velocizzarne l'esecuzione. +In questo caso, creiamo un oggetto `cache` che memorizza i valori precedentemente restituiti. + +Se chiamiamo di nuovo la funzione `addFunction` con lo stesso argomento, prima controlla se ha già ottenuto quel valore nella sua cache, in tal caso, verrà restituito il valore della cache, consentendo di risparmiare tempo di esecuzione. Altrimenti, se non è memorizzato nella cache, calcolerà il valore e lo memorizzerà in seguito. + +Chiamiamo la funzione `addFunction` tre volte con lo stesso valore: alla prima chiamata, il valore della funzione quando `num` è uguale a `10` non è ancora memorizzato nella cache. +La condizione dell'istruzione if `num in cache` restituisce `false`, e il blocco else viene eseguito: `Calculated! 20` viene loggato e il valore del risultato viene aggiunto all'oggetto cache. +`cache` ora è uguale a `{ 10: 20 }`. + +La seconda volta, l'oggetto `cache` contiene il valore che viene restituito per `10`. La condizione dell'istruzione if `num in cache` restituisce `true` e `'From cache! 20'` viene loggato. + +La terza volta, passiamo `5 * 2` alla funzione che viene valutata a `10`. L'oggetto `cache` contiene il valore che viene restituito `10`. La condizione dell'istruzione if `num in cache` restituisce `true` e `'From cache! 20'` viene registrato. + +
++ +#### Risposta: A + +Con un ciclo _for-in_, possiamo scorrere su proprietà **enumerabili**. In un array, le proprietà enumerabili sono le "chiavi" degli elementi dell'array, che sono in realtà i loro indici. Potresti immaginare un array come: + +`{0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}` + +Dove le chiavi sono le proprietà enumerabili. `0` `1` `2` `3` viene quindi loggato. + +Con un ciclo _for-of_, possiamo iterare su **iterabili**. Un array è un iterabile. Quando iteriamo sull'array, la variabile "item" è uguale all'elemento su cui sta attualmente iterando, `"☕"` `"💻"` `"🍷"` `"🍫"` viene loggato. + +
++ +#### Risposta: C + +Gli elementi di un array possono contenere qualsiasi valore. Numeri, stringhe, oggetti, altri array, null, booleani, undefined e altre espressioni come date, funzioni e calcoli. + +L'elemento sarà uguale al valore restituito. `1 + 2` restituirà quindi `3`, `1 * 2` restituirà `2` e `1 / 2` restituirà `0.5`. + +
++ +#### Risposta: B + +Di default, gli argomenti hanno il valore di `undefined`, a meno che un valore non sia stato passato alla funzione. In questo caso, non abbiamo passato un valore per l'argomento `name`. `name` è uguale a `undefined` che viene loggato. + +In ES6, possiamo sovrascrivere questo valore predefinito `undefined` con dei parametri predefiniti. Per esempio: + +`function sayHi(name = "Lydia") { ... }` + +In questo caso, se non abbiamo passato un valore o se abbiamo passato `undefined`, `name` sarà sempre uguale alla stringa `Lydia` + +
++ +#### Risposta: B + +Il valore della parola chiave `this` dipende da dove la usi. In un **metodo**, come il metodo `getStatus`, la parola chiave `this` si riferisce all'_oggetto a cui appartiene il metodo_. Nel nostro caso il metodo appartiene all'oggetto `data`, quindi `this` si riferisce all'oggetto `data`. Quando logghiamo `this.status`, stiamo chiedendo la proprietà `status` sull'oggetto `data` che è `"🥑"`. + +Con il metodo `call` possiamo cambiare l'oggetto a cui fa riferimento la parola chiave `this`. Nelle **funzioni**, la parola chiave `this` si riferisce all'_oggetto a cui appartiene la funzione_. Abbiamo dichiarato la funzione `setTimeout` sull'_oggetto globale_, quindi all'interno della funzione `setTimeout`, la parola chiave `this` si riferisce all'_oggetto globale_. Sull'oggetto globale c'è una variabile chiamata _status_ con il valore di `"😎"`. Quando si fa un console.log di `this.status`, otteniamo `"😎"`. + +
++ +#### Risposta: A + +Impostiamo la variabile `city` uguale al valore della proprietà chiamata `city` sull'oggetto `person`. Non c'è alcuna proprietà su questo oggetto chiamato `city`, quindi la variabile `city` ha il valore di `undefined`. + +Nota che _non_ stiamo facendo riferimento all'oggetto `person`! Impostiamo semplicemente la variabile `city` uguale al valore corrente della proprietà `city` sull'oggetto `person`. + +Quindi, impostiamo `city` uguale alla stringa `"Amsterdam"`. Questo non cambia l'oggetto `person`: non c'è alcun riferimento a quell'oggetto. + +Quando si logga l'oggetto `person`, viene restituito l'oggetto non modificato. + +
++ +#### Risposta: C + +Le variabili con la chiave `const` e `let` sono _block-scoped_. Un blocco è qualsiasi cosa si trovi tra parentesi graffe (`{ }`). In questo caso, le parentesi graffe delle istruzioni if/else. Non puoi fare riferimento a una variabile al di fuori del blocco in cui è dichiarata, viene quindi generato un ReferenceError. + +
++ +#### Risposta: C + +Il valore di `res` nel secondo `.then` è uguale al valore restituito del precedente `.then`. Puoi continuare a concatenare i `.then` in questo modo, dove il valore viene passato al gestore successivo. + +
++ +#### Risposta: A + +Con `!!name`, determiniamo se il valore di `name` è vero o falso. Se il nome è vero, cosa che vogliamo testare, `!name` restituisce `false`. +`!false` (che è `!!name`) restituisce `true`. + +Impostando `hasName` uguale a `name`, imposti `hasName` uguale a qualsiasi valore passato alla funzione `getName`, non il valore booleano `true`. + +`new Boolean(true)` restituisce un oggetto wrapper, non il valore booleano stesso. + +`name.length` restituisce la lunghezza dell'argomento passato, non se è `true`. + +
++ +#### Risposta: B + +Per ottenere un carattere in un indice specifico di una stringa, puoi usare la notazione tra parentesi. Il primo carattere nella stringa ha indice 0 e così via. In questo caso, vogliamo ottenere l'elemento con indice 0, il carattere `"I'`, che viene loggato. + +Tieni presente che questo metodo non è supportato in IE7 e versioni precedenti. In tal caso, usa `.charAt()`. + +
++ +#### Risposta: B + +È possibile impostare il valore di un parametro predefinito uguale a un altro parametro della funzione, purché sia stato definito _prima_ del parametro predefinito. Passiamo il valore `10` alla funzione `sum`. Se la funzione `sum` riceve solo 1 argomento, significa che il valore di `num2` non è passato e il valore di `num1` è uguale al valore passato `10` in questo caso. Il valore predefinito di `num2` è il valore di `num1`, che è `10`. `num1 + num2` restituisce `20`. + +Se stai cercando di impostare il valore di un parametro predefinito uguale a un parametro che è definito _dopo_ (a destra), il valore del parametro non è stato ancora inizializzato, il che genererà un errore. +
++ +#### Risposta: A + +Con la sintassi `import * as name`, importiamo _tutte le esportazioni_ dal file `module.js` nel file `index.js` come nuovo oggetto chiamato `data`. Nel file `module.js` ci sono due esportazioni: l'esportazione predefinita e un'esportazione denominata. L'esportazione predefinita è una funzione che restituisce la stringa `"Hello World"`, e l'esportazione denominata è una variabile chiamata `name` che ha il valore della stringa `"Lydia"`. + +L'oggetto `data` ha una proprietà `default` per l'esportazione predefinita, altre proprietà hanno i nomi delle esportazioni e i loro valori corrispondenti. + +
++ +#### Risposta: C + +Le classi sono come caramelle sintattiche. L'equivalente della classe `Person` come funzione sarebbe: + +```javascript +function Person() { + this.name = name; +} +``` + +Instanziando un costruttore con `new` si ottiene la creazione di un'istanza di `Person`, la chiave `typeof` restituisce `"object"`. `typeof member` restituisce `"object"`. + +
++ +#### Risposta: D + +Il metodo `.push` restituisce la _nuova lunghezza_ dell'array, non l'array stesso! Impostando `newList` uguale a `[1, 2, 3].push(4)`, settiamo `newList` uguale alla nuova lunghezza dell'array: `4`. + +Quindi quando proviamo a usare il metodo `.push` su `newList` poiché `newList` è il valore numerico `4`, non possiamo usare il metodo `.push` e viene generato un TypeError. + +
++ +#### Risposta: D + +Le funzioni regolari, come la funzione `giveLydiaPizza`, hanno una proprietà `prototipo`, che è un oggetto (prototype object) con un `costruttore`. Tuttavia, le arrow functions, come la funzione `giveLydiaChocolate`, non hanno una proprietà `prototype`. Viene quindi restituito `undefined` quando si tenta di accedere alla proprietà `prototype` usando `giveLydiaChocolate.prototype`. +
++ +#### Risposta: A + +`Object.entries(person)` restituisce un array di array nidificati, contenente le chiavi e gli oggetti: + +`[ [ 'name', 'Lydia' ], [ 'age', 21 ] ]` + +Usando il ciclo `for-of`, possiamo scorrere ogni elemento nell'array, i sottoarray in questo caso. Possiamo destrutturare i sottoarray istantaneamente nel ciclo for-of, usando `const [x, y]`. `x` è uguale al primo elemento, `y` è uguale al secondo elemento. + +Il primo sottoarray è `[ "name", "Lydia" ]`, con `x` uguale a `"name"`, e `y` uguale a `"Lydia"`, che vengono loggati. +Il secondo sottoarray è `[ "age", 21 ]`, con `x` uguale a `"age"`, e `y` uguale a `21`, che vengono loggati. + +
++ +#### Risposta: D + +`...args` è un parametro rest. Il valore del parametro rest è un array contenente tutti gli argomenti, **e può essere solo l'ultimo parametro**! In questo esempio, il parametro rest è in seconda posizione. Questo non è possibile e genererà un errore di sintassi. + +```javascript +function getItems(fruitList, favoriteFruit, ...args) { + return [...fruitList, ...args, favoriteFruit]; +} + +getItems(['banana', 'apple'], 'pear', 'orange'); +``` + +L'esempio qui sopra invece funziona e restituisce l'array `[ 'banana', 'apple', 'orange', 'pear' ]` + +
++ +#### Risposta: B + +In JavaScript, non _è necessario_ scrivere il punto e virgola (`;`) in modo esplicito poiché il motore JavaScript li aggiunge comunque dopo le istruzioni. +Questo procedimento è chiamato **Automatic Semicolon Insertion**. Un'istruzione può ad esempio essere una variabile o parole chiave come `throw`, `return`, `break`, ecc. + +Qui, abbiamo scritto un'istruzione di `return` e un altro valore `a + b` su una _nuova riga_. Tuttavia, trattandosi di una nuova linea, il motore non sa che in realtà è il valore che volevamo restituire. Invece, ha aggiunto automaticamente un punto e virgola dopo `return`. + +Potresti considerare ad esempio: + +```javascript +return; +a + b; +``` + +`a + b` non viene mai raggiunto, poiché la funzione smette di funzionare dopo la parola chiave `return`. +Se non viene restituito alcun valore, come qui, la funzione restituisce `undefined`. Nota: non c'è un inserimento automatico dopo le istruzioni `if/else`! + +
++ +#### Risposta: B + +Possiamo impostare classi uguali ad altre classi/costruttori di funzioni. In questo caso, impostiamo `Person` uguale a `AnotherPerson`. Il name su questo costruttore è `Sarah`, quindi la proprietà del nome di`Person` sulla nuova istanza `member` è `"Sarah"`. + +
++ +#### Risposta: D + +Un simbolo non è _enumerabile_. Il metodo Object.keys restituisce tutte le proprietà _enumerabili_ su un oggetto. Il simbolo non sarà visibile e verrà restituito un array vuoto. Quando si logga l'intero oggetto, tutte le proprietà saranno visibili, anche quelle non enumerabili. + +Questa è una delle tante qualità di un simbolo: oltre a rappresentare un valore del tutto univoco (che evita collisioni accidentali di nomi sugli oggetti, ad esempio quando si lavora con 2 librerie che vogliono aggiungere proprietà allo stesso oggetto), puoi anche "nascondere" proprietà sugli oggetti in questo modo (anche se non del tutto. Puoi comunque accedere ai simboli usando il metodo `Object.getOwnPropertySymbols()`). + +
++ +#### Risposta: A + +La funzione `getList` riceve un array come argomento. Tra le parentesi della funzione `getList`, destrutturiamo subito questo array. Esempio: + +`[x, ...y] = [1, 2, 3, 4]` + +Con il parametro rest `...y`, mettiamo tutti gli argomenti "rimanenti" in un array. Gli argomenti rimanenti sono `2`, `3` e `4` in questo caso. +Il valore di `y` è un array, contenente tutti i parametri rimanenti. Il valore di `x` è uguale a `1` in questo caso, quindi quando facciamo un console.log di `[x, y]`, viene loggato `[1, [2, 3, 4]]`. + +La funzione `getUser` riceve un oggetto. Con le arrow functions, non _è necessario_ scrivere parentesi graffe se restituiamo solo un valore. Tuttavia, se vuoi restituire istantaneamente un _oggetto_ da una arrow function, devi scriverlo tra parentesi tonde, altrimenti tutto ciò che si trova tra le due parentesi graffe verrà interpretato come un'istruzione di blocco. In questo caso il codice tra parentesi non è un codice JavaScript valido, quindi viene generato un `SyntaxError`. + +La seguente funzione avrebbe restituito un oggetto: + +`const getUser = user => ({ name: user.name, age: user.age })` + +
++ +#### Risposta: C + +La variabile `name` contiene il valore di una stringa, che non è una funzione, quindi non può essere invocata. + +I TypeErrors vengono generati quando un valore non è del tipo previsto. JavaScript "prevede" che `name` è una funzione poiché stiamo cercando di invocarla. In realtà è una stringa, quindi viene generato un TypeError: name is not a function! + +I SyntaxErrors vengono generati quando si scrive qualcosa che non è valido in JavaScript, ad esempio quando si scrive la parola `return` come `rerun`. +I ReferenceErrors vengono generati quando JavaScript non è in grado di trovare un riferimento a un valore a cui stai tentando di accedere. + +
++ +#### Risposta: B + +`[]` è un valore vero. Con l'operatore `&&`, verrà restituito il valore di destra se il valore di sinistra è un valore reale. In questo caso, il valore di sinistra `[]` è un valore vero, quindi `"Im'` viene restituito. + +`""` è un valore falso. Se il valore di sinistra è falso, non viene restituito nulla. `n't` quindi non viene restituito. + +
++ +#### Risposta: C + +Con l'operatore `||` possiamo restituire il primo operando veritiero. Se tutti i valori sono falsi, viene restituito l'ultimo operando. + +`(false || {} || null)`: l'oggetto vuoto `{}` è un valore veritiero. Questo è il primo (e unico) valore veritiero, che viene restituito. `one` è uguale a `{}`. + +`(null || false || "")`: tutti gli operandi sono valori falsi. Ciò significa che viene restituito l'ultimo operando, `""`. `two` è uguale a `""`. + +`([] || 0 || "")`: l'array vuoto`[]` è un valore veritiero. Questo è il primo valore veritiero, che viene restituito. `three` è uguale a `[]`. + +
++ +#### Risposta: D + +Con una promise, in pratica diciamo _Voglio eseguire questa funzione, ma per ora la metto da parte mentre è in esecuzione poiché ciò potrebbe richiedere del tempo. Solo quando un determinato valore viene risolto (o rifiutato) e quando lo stack di chiamate è vuoto, voglio utilizzare questo valore._ + +Possiamo ottenere questo valore sia con `.then` che con la chiave `await` in una funzione `async`. Sebbene possiamo ottenere il valore di una promise sia con `.then` che con `await`, funzionano in modo leggermente diverso. + +Nella `first Function`, abbiamo (più o meno) messo da parte la funzione myPromise mentre era in esecuzione, ma abbiamo continuato a eseguire l'altro codice, che in questo caso è `console.log('second')`. Quindi, la funzione è stata risolta con la stringa `I have resolved`, che è stata quindi loggata dopo aver visto che lo stack di chiamate era vuoto. + +Con await in `secondFunction`, mettiamo letteralmente in pausa l'esecuzione di una funzione asincrona fino a quando il valore non è stato risolto prima di passare alla riga successiva. + +Ciò significa che ha aspettato che `myPromise` si risolvesse con il valore `I have resolved`, e solo allora, siamo passati alla riga successiva e `second` è stato loggato. + +
++ +#### Risposta: C + +L'operatore `+` non viene utilizzato solo per aggiungere valori numerici, ma possiamo anche usarlo per concatenare stringhe. Ogni volta che il motore JavaScript vede che uno o più valori non sono un numero, forza il numero in una stringa. + +Il primo è `1`, che è un valore numerico. `1 + 2` restituisce il numero 3. + +Tuttavia, la seconda è una stringa `"Lydia"`. `"Lydia"` è una stringa e `2` è un numero: `2` viene forzato in una stringa. `"Lydia"` e `"2"` vengono concatenati, il che risulta nella stringa `"Lydia2"`. + +`{ name: "Lydia" }` è un oggetto. Né un numero né un oggetto sono una stringa, quindi li rende stringhe entrambi. Ogni volta che stringhiamo un oggetto regolare, diventa `"[object Object]"`. `"[object Object]"` concatenato con `2` diventa `"[object Object]"`. + +
+
+
+#### Risposta: C
+
+Possiamo passare a `Promise.resolve` qualsiasi tipo di valore desideriamo, sia una promise che una non-promise. Il metodo stesso restituisce una promise con il valore risolto (`
+ +#### Risposta: B + +Gli oggetti vengono passati per riferimento. Quando controlliamo gli oggetti per strict equality (`===`), stiamo confrontando i loro riferimenti. + +Abbiamo impostato il valore predefinito per `person2` uguale all'oggetto `person` e abbiamo passato l'oggetto `person` come valore per `person1`. + +Ciò significa che entrambi i valori hanno un riferimento allo stesso punto in memoria, quindi sono uguali. + +Il blocco di codice nell'istruzione `else` viene eseguito e `They are the same!` viene loggato. + +
++ +#### Risposta: D + +In JavaScript, abbiamo due modi per accedere alle proprietà di un oggetto: le bracket notation o le dot notation. In questo esempio, utilizziamo la notazione con il punto (`colorConfig.colors`) invece della notazione tra parentesi (`colorConfig["colors"]`). + +Con la notazione del punto, JavaScript tenta di trovare la proprietà sull'oggetto con quel nome esatto. In questo esempio, JavaScript tenta di trovare una proprietà chiamata `colors` sull'oggetto `colorConfig`. Non esiste una proprietà chiamata `colors`, quindi restituisce `undefined`. Quando proviamo ad accedere al valore del primo elemento usando `[1]`, non possiamo farlo su un valore che è `undefined`, quindi genera un `TypeError`: `Cannot read property '1' of undefined`. + +JavaScript interpreta (o decomprime) le istruzioni. Quando usiamo la notazione tra parentesi, vede la prima parentesi aperta `[` e continua finché non trova la parentesi chiusa `]`. Solo allora valuterà la dichiarazione. Se avessimo usato `colorConfig[colors[1]]`, avrebbe restituito il valore della proprietà `red` sull'oggetto `colorConfig`. + +
++ +#### Risposta: A + +Le emoji sono unicode. L'unicode per l'emoji del cuore è `"U+2764 U+FE0F"`. Questi sono sempre gli stessi per gli stessi emoji, stiamo confrontando due stringhe uguali tra loro, e quindi restituisce true. + +
++ +#### Risposta: D + +Con il metodo `splice` modifichiamo l'array originale cancellando, sostituendo o aggiungendo elementi. In questo caso, abbiamo rimosso 2 elementi dall'indice 1 (abbiamo rimosso `'🥑'` e `'😍'`) e aggiunto invece l'emoji ✨. + +`map`, `filter` e `slice` restituiscono un nuovo array, `find` restituisce un elemento e `reduce` restituisce un valore ridotto. +
++ +#### Risposta: A + +Impostiamo il valore della proprietà `favoriteFood` sull'oggetto `info` uguale alla stringa con l'emoji della pizza, `'🍕'`. Una stringa è un tipo di dati primitivo. In JavaScript, i tipi di dati primitivi non interagiscono per riferimento. + +In JavaScript, i tipi di dati primitivi (tutto ciò che non è un oggetto) interagiscono per _value_. In questo caso, impostiamo il valore della proprietà `favoriteFood` sull'oggetto `info` uguale al valore del primo elemento nell'array `food`, in questo caso la stringa con l'emoji della pizza (`'🍕'`). Una stringa è un tipo di dati primitivo e interagisce per valore (vedi il mio [blogpost](https://www.theavocoder.com/complete-javascript/2018/12/21/by-value-vs-by-reference) se sei interessato a saperne di più). + +Quindi, cambiamo il valore della proprietà `favoriteFood` sull'oggetto `info`. L'array `food` non è cambiato, poiché il valore di `favoriteFood` era semplicemente una _copia_ del valore del primo elemento nell'array e non ha un riferimento allo stesso punto in memoria dell'elemento su ` food[0]`. Quando logghiamo food, è ancora l'array originale, `['🍕', '🍫', '🥑', '🍔']`. +
++ +#### Risposta: A + +Con il metodo `JSON.parse()`, possiamo analizzare la stringa JSON come un valore JavaScript. + +```javascript +// Stringhiamo un numero in un JSON valido, quindi analizziamo la stringa JSON come valore JavaScript: +const jsonNumber = JSON.stringify(4); // '4' +JSON.parse(jsonNumber); // 4 + +// Stringhiamo un array in un JSON valido, quindi analizziamo la stringa JSON come valore JavaScript: +const jsonArray = JSON.stringify([1, 2, 3]); // '[1, 2, 3]' +JSON.parse(jsonArray); // [1, 2, 3] + +// Stringhiamo un object in un JSON valido, quindi analizziamo la stringa JSON come valore JavaScript: +const jsonArray = JSON.stringify({ name: 'Lydia' }); // '{"name":"Lydia"}' +JSON.parse(jsonArray); // { name: 'Lydia' } +``` + +
++ +#### Risposta: D + +Ogni funzione ha il proprio _contesto di esecuzione_ (o _ambito_). La funzione `getName` cerca prima all'interno del proprio contesto (scope) per vedere se contiene la variabile `name` a cui stiamo cercando di accedere. In questo caso, la funzione `getName` contiene la propria variabile `name` perché dichiariamo la variabile `name` con la chiave `let`, e con il valore di `'Sarah'`. + +Le variabili con la chiave `let` (e `const`) vengono sollevate, ma a differenza di `var`, non vengono inizializzate. Non sono quindi accessibili prima della riga in cui le dichiariamo (inizializziamo). Questa è chiamata "temporal dead zone". Quando proviamo ad accedere alle variabili prima che vengano dichiarate, JavaScript genera un `ReferenceError`. + +Se non avessimo dichiarato la variabile `name` all'interno della funzione `getName`, JavaScript avrebbe esaminato la _scope chain_. Lo scope esterno ha una variabile chiamata `name` con il valore di `Lydia`. In tal caso, avrebbe loggato "Lydia". + +```javascript +let name = 'Lydia'; + +function getName() { + console.log(name); +} + +getName(); // Lydia +``` + +
++ +#### Risposta: C + +Con la parola chiave `yield`, otteniamo valori in una funzione generatore. Con la chiave `yield*`, possiamo produrre valori da un'altra funzione del generatore, o da un oggetto iterabile (per esempio un array). + +In `generatorOne`, produciamo l'intero array `['a', 'b', 'c']` usando la parola chiave `yield`. Il valore della proprietà `value` sull'oggetto restituito dal metodo `next` su `one` (`one.next().value`) è uguale all'intero array `['a', 'b', 'c']`. + +```javascript +console.log(one.next().value); // ['a', 'b', 'c'] +console.log(one.next().value); // undefined +``` + +In `generatorTwo`, utilizziamo la parola chiave `yield*`. Ciò significa che il primo valore ottenuto è `two`, ed è uguale al primo valore ottenuto nell'iteratore. L'iteratore è l'array `['a', 'b', 'c']`. Il primo valore ottenuto è `a`, quindi la prima volta che chiamiamo `two.next().value`, viene restituito `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 +``` + +
++ +#### Risposta: A + +Le espressioni all'interno dei template literals vengono valutate per prime. Ciò significa che la stringa conterrà il valore restituito dell'espressione, in questo caso la funzione immediatamente invocata `(x => x)('I love')`. Passiamo il valore `'I love'` come argomento alla funzione freccia `x => x`. `x` è uguale a `'I love'`, che viene restituito. Ciò si traduce in `I love to program`. + +
++ +#### Risposta: C + +Normalmente quando impostiamo oggetti uguali a `null`, quegli oggetti vengono _garbage collected_ poiché non c'è più alcun riferimento a quell'oggetto. Tuttavia, poiché la funzione di callback all'interno di `setInterval` è una funzione freccia (quindi legata all'oggetto `config`), la funzione di callback mantiene ancora un riferimento all'oggetto `config`. +Finché c'è un riferimento, l'oggetto non verrà raccolto. +Poiché si tratta di un intervallo, impostare `config` su `null` o `delete`-ing `config.alert` non raccoglierà l'intervallo, quindi l'intervallo verrà comunque chiamato. +Dovrebbe essere cancellato con `clearInterval(config.alert)` per rimuoverlo dalla memoria. +Dal momento che non è stato cancellato, la funzione di callback `setInterval` verrà comunque invocata ogni 1000 ms (1 s). + +
++ +#### Risposta: B + +Quando si aggiunge una coppia chiave/valore usando il metodo `set`, la chiave sarà il valore del primo argomento passato alla funzione `set`, e il valore sarà il secondo argomento. La chiave è _function_ `() => 'greeting'` in questo caso, e il valore `'Hello world'`. `myMap` ora è `{ () => 'greeting' => 'Hello world!' }`. + +1 è sbagliato, poiché la chiave non è `'greeting'` ma `() => 'greeting'`. +3 è sbagliato, poiché stiamo creando una nuova funzione passandola come parametro al metodo `get`. L'oggetto interagisce per _reference_. Le funzioni sono oggetti, che è il motivo per cui due funzioni non sono mai rigorosamente uguali, anche se identiche: hanno un riferimento a un punto diverso della memoria. + +
++ +#### Risposta: C + +Entrambe le funzioni `changeAge` e `changeAgeAndName` hanno un parametro predefinito, ovvero un oggetto _appena_ creato `{ ...person }`. Questo oggetto ha copie di tutte le chiavi/valori nell'oggetto `person`. + +Per prima cosa, invochiamo la funzione `changeAge` e passiamo l'oggetto `person` come argomento. Questa funzione aumenta il valore della proprietà `age` di 1. `person` ora è `{ name: "Lydia", age: 22 }`. + +Quindi, invochiamo la funzione `changeAgeAndName`, tuttavia non passiamo un parametro. Invece, il valore di `x` è uguale a un _nuovo_ oggetto: `{ ...person }`. Poiché si tratta di un nuovo oggetto, non influisce sui valori delle proprietà sull'oggetto `person`. `person` è ancora uguale a `{ name: "Lydia", age: 22 }`. +
++ +#### Risposta: C + +Con l'operatore spread `...`, possiamo _distribuire_ gli iterabili come singoli elementi. La funzione `sumValues` riceve tre argomenti: `x`, `y` e `z`. `...[1, 2, 3]` risulterà in `1, 2, 3`, che passiamo alla funzione `sumValues`. + +
++ +#### Risposta: B + +Con l'operando `+=`, stiamo incrementando il valore di `num` di `1`. `num` aveva il valore iniziale `1`, quindi `1 + 1` è `2`. L'elemento sul secondo indice nell'array `list` è 🥰, `console.log(list[2])` stampa 🥰. + +
++ +#### Risposta: B + +Con l'operatore di concatenamento opzionale `?.`, non è più necessario verificare esplicitamente se i valori annidati più profondi sono validi o meno. Se stiamo cercando di accedere a una proprietà su un valore `undefined` o `null` (_nullish_), l'espressione va in cortocircuito e restituisce `undefined`. + +`person.pet?.name`: `person` ha una proprietà denominata `pet`: `person.pet` non è nullo. Ha una proprietà chiamata `name` e restituisce `Mara`. +`person.pet?.family?.name`: `person` ha una proprietà denominata `pet`: `person.pet` non è nullo. `pet` _non_ ha una proprietà chiamata `family`, `person.pet.family` è nullo. L'espressione restituisce `undefined`. +`person.getFullName?.()`: `person` ha una proprietà denominata `getFullName`: `person.getFullName()` non è nullo e può essere invocato, il che restituisce `Lydia Hallie`. +`member.getLastName?.()`: la variabile `member` non esiste quindi viene generato un `ReferenceError`! + +
++ +#### Risposta: B + +Abbiamo passato la condizione `groceries.indexOf("banana")` all'istruzione if. `groceries.indexOf("banana")` restituisce `0`, che è un valore falso. Poiché la condizione nell'istruzione if è falsa, il codice nel blocco `else` viene eseguito e `We don't have to buy bananas!` viene registrato. + +
++ +#### Risposta: D + +Il metodo `language` è un `setter`. I setter non detengono un valore effettivo, il loro scopo è _modificare_ le proprietà. Quando si chiama un metodo `setter`, viene restituito `undefined`. + +
++ +#### Risposta: C + +`typeof name` restituisce `"string"`. La stringa `"string"` è un valore veritiero, quindi `!typeof name` restituisce il valore booleano `false`. `false === "object"` e `false === "string"` restituiscono entrambi `false`. + +(Se volessimo verificare se il tipo era (non)uguale a un certo tipo, avremmo dovuto scrivere `!==` invece di `!typeof`) +
++ +#### Risposta: A + +La funzione `add` restituisce una arrow function, che restituisce una arrow function, che restituisce arrow function (mi segui ancora?). +La prima funzione riceve un argomento `x` con il valore di `4`. Invochiamo la seconda funzione, che riceve un argomento `y` con il valore `5`. Quindi invochiamo la terza funzione, che riceve un argomento `z` con il valore `6`. Quando si tenta di accedere ai valori `x`, `y` e `z` all'interno dell'ultima arrow function, il motore JS risale la catena dell'ambito per trovare i valori per `x` e `y`. Questo restituisce `4` `5` `6`. + +
++ +#### Risposta: C + +La funzione `range` restituisce un oggetto asincrono con promises per ogni elemento nell'intervallo che passiamo: `Promise{1}`, `Promise{2}`, `Promise{3}`. Impostiamo la variabile `gen` uguale all'oggetto asincrono, dopodiché lo eseguiamo in loop usando un ciclo `for await ... of`. Impostiamo la variabile `item` uguale ai valori Promise restituiti: prima `Promise{1}`, poi `Promise{2}`, quindi `Promise{3}`. Poiché stiamo _attendendo_ il valore di `item`, la promise risolta, vengono restituiti i _valori_ risolti delle promises: `1`, `2` e quindi `3`. + +
++ +#### Risposta: D + +`myFunc` si aspetta un oggetto con le proprietà `x`, `y` e `z` come argomento. Poiché stiamo passando solo tre valori numerici separati (1, 2, 3) invece di un oggetto con le proprietà `x`, `y` e `z` ({x: 1, y: 2, z: 3}), `x`, `y` e `z` hanno il loro valore predefinito di `undefined`. + +
++ +#### Risposta: B + +Con il metodo `Intl.NumberFormat`, possiamo formattare i valori numerici in qualsiasi locale. Formattiamo il valore numerico `130` nella locale `en-US` come `unit` in `mile-per-hour`, che risulta in `130 mph`. Il valore numerico `300` nella locale `en-US` come `currency` in `USD` risulta in `$300.00`. + +
++ +#### Risposta: B + +Destrutturando gli oggetti, possiamo decomprimere i valori dall'oggetto di destra e assegnare il valore decompresso al valore dello stesso nome di proprietà sull'oggetto di sinistra. In questo caso, stiamo assegnando il valore "💀" a `spookyItems[3]`. Ciò significa che stiamo modificando l'array `spookyItems`, stiamo aggiungendo il "💀" ad esso. Quando facciamo console.log di `spookyItems`, `["👻", "🎃", "🕸", "💀"]` viene loggato. + +
++ +#### Risposta: C + +Con il metodo `Number.isNaN`, puoi controllare se il valore passato è un _valore numerico_ e uguale a `NaN`. `name` non è un valore numerico, quindi `Number.isNaN(name)` restituisce `false`. `age` è un valore numerico, ma non è uguale a `NaN`, quindi `Numero.isNaN(age)` restituisce `false`. + +Con il metodo `isNaN`, puoi verificare se il valore che passi non è un numero. `name` non è un numero, quindi `isNaN(name)` restituisce true. `age` è un numero, quindi `isNaN(age)` restituisce `false`. +
++ +#### Risposta: D + +Le variabili dichiarate con la chiave `const` non sono referenziabili prima della loro inizializzazione: questa viene chiamata _temporal dead zone_. Nella funzione `getInfo`, la variabile `randomValue` ha lo scopo nell'ambito funzionale di `getInfo`. Nella riga in cui vogliamo registrare il valore di `typeof randomValue`, la variabile `randomValue` non è ancora inizializzata: viene lanciato un `ReferenceError`! Il motore non è andato giù per la catena dell'ambito poiché abbiamo dichiarato la variabile `randomValue` nella funzione `getInfo`. +
++ +#### Risposta: C + +Nel blocco `try`, stiamo loggando il valore atteso della variabile `myPromise`: `"Woah some cool data"`. Poiché non sono stati generati errori nel blocco `try`, il codice nel blocco `catch` non viene eseguito. Il codice nel blocco `finally` viene eseguito _sempre_, `"Oh finally!"` viene loggato. + +
++ +#### Risposta: B + +Con il metodo `flat`, possiamo creare un nuovo array appiattito. La profondità dell'array appiattito dipende dal valore che passiamo. In questo caso, abbiamo passato il valore `1` (cosa che non dovevamo fare, questo è il valore predefinito), il che significa che solo gli array sulla prima profondità verranno concatenati. `['🥑']` e `['✨', '✨', ['🍕', '🍕']]` in questo caso. Concatenando questi due array si ottengono `['🥑', '✨', '✨', ['🍕', '🍕']]`. +
+
+
+#### Risposta: D
+
+`counterOne` è un'istanza della classe `Counter`. La classe counter contiene una proprietà `count` sul suo costruttore e un metodo `increment`. Per prima cosa, abbiamo invocato il metodo `increment` due volte chiamando `counterOne.increment()`. Attualmente, `counterOne.count` è `2`.
+
+
+
+Quindi, creiamo una nuova variabile `counterTwo` e la impostiamo uguale a `counterOne`. Poiché gli oggetti interagiscono per riferimento, stiamo semplicemente creando un nuovo riferimento allo stesso punto della memoria a cui punta `counterOne`. Poiché ha lo stesso punto in memoria, qualsiasi modifica apportata all'oggetto a cui fa riferimento `counterTwo`, si applica anche a `counterOne`. Attualmente, `counterTwo.count` è `2`.
+
+Invochiamo `counterTwo.increment()`, che imposta `count` su `3`. Quindi, logghiamo il conteggio su `counterOne`, che stampa `3`.
+
+
+
+
+ +#### Risposta: C + +Innanzitutto, invochiamo `funcOne`. Sulla prima riga di `funcOne`, chiamiamo la funzione _asincrona_ `setTimeout`, da cui la callback viene inviato all'API Web. (vedi l'articolo sul ciclo degli eventi [qui](https://dev.to/lydiahallie/javascript-visualized-event-loop-3dif)) + +Quindi chiamiamo la promise `myPromise`, che è un'operazione _asincrona_. + +Sia la promise che il timeout sono operazioni asincrone, la funzione continua a funzionare mentre è impegnata a completare la promise e a gestire la callback `setTimeout`. Ciò significa che `Last line 1!` viene registrato per primo, poiché questa non è un'operazione asincrona. + +Poiché la callstack non è ancora vuota, la funzione `setTimeout` e la promise in `funcOne` non possono ancora essere aggiunte al callstack. + +In `funcTwo`, la variabile `res` ottiene `Promise` perché `Promise.resolve(Promise.resolve('Promise'))` è equivalente a `Promise.resolve('Promise')` poiché risolvere una promise risolve il suo valore. L'"attesa" in questa riga interrompe l'esecuzione della funzione fino a quando non riceve la risoluzione della promise e quindi continua a funzionare in modo sincrono fino al completamento, quindi `Promise 2!` e poi `Last line 2!` vengono registrati e `setTimeout` viene inviato all'API Web. + +Quindi lo stack di chiamate è vuoto. Le promise sono _microattività_, quindi vengono risolte per prime quando lo stack di chiamate è vuoto, quindi `Promise 1!` viene registrato. + +Ora, da quando `funcTwo` è uscito dallo stack delle chiamate, lo stack delle chiamate è vuoto. Le callback in attesa nella coda (`() => console.log("Timeout 1!")` da `funcOne`, e `() => console.log("Timeout 2!")` da `funcTwo`) vengono aggiunti allo stack di chiamate uno per uno. Il primo callback registra `Timeout 1!` e viene eliminato dallo stack. Quindi, il secondo callback registra `Timeout 2!` e viene eliminato dallo stack. +
++ +#### Risposta: C + +Con l'asterisco `*`, importiamo tutti i valori esportati da quel file, sia predefinito che nominale. Se avessimo il seguente 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); +``` + +Verrebbe loggato quanto segue: + +```javascript +{ + default: "I love JavaScript", + name: "Lydia", + age: 21 +} +``` + +Per l'esempio `sum`, significa che il valore importato `sum` è simile a quanto segue: + +```javascript +{ default: function sum(x) { return x + x } } +``` + +Possiamo invocare questa funzione, chiamando `sum.default` + +
++ +#### Risposta: C + +Con un oggetto Proxy, possiamo aggiungere un comportamento personalizzato a un oggetto che gli passiamo come secondo argomento. In questo caso, passiamo all'oggetto `handler` che conteneva due proprietà: `set` e `get`. `set` viene invocato ogni volta che _settiamo_ valori di proprietà, `get` viene invocato ogni volta che _otteniamo_ (accediamo) valori di proprietà. + +Il primo argomento è un oggetto vuoto `{}`, che è il valore di `person`. A questo oggetto viene aggiunto il comportamento personalizzato specificato nell'oggetto `handler`. Se aggiungiamo una proprietà all'oggetto `person`, `set` verrà invocato. Se accediamo a una proprietà sull'oggetto `person`, `get` viene invocato. + +Innanzitutto, abbiamo aggiunto una nuova proprietà `name` all'oggetto proxy (`person.name = "Lydia"`). `set` viene invocato e registra `"Added a new property!"`. + +Quindi, accediamo a un valore di proprietà sull'oggetto proxy, la proprietà `get` sull'oggetto handler è stata invocata. `"Accessed a property!"` viene registrato. + +
++ +#### Risposta: A + +Con `Object.seal` possiamo impedire che nuove proprietà vengano _aggiunte_ o che proprietà esistenti vengano _rimosse_. + +Tuttavia, puoi comunque modificare il valore delle proprietà esistenti. + +
++ +#### Risposta: C + +Il metodo `Object.freeze` _congela_ un oggetto. Nessuna proprietà può essere aggiunta, modificata o rimossa. + +Tuttavia, blocca solo _poco profondamente_ l'oggetto, il che significa che solo le proprietà _direct_ sull'oggetto sono bloccate. Se la proprietà è un altro oggetto, come `address` in questo caso, le proprietà su quell'oggetto non vengono bloccate e possono essere modificate. + +
++ +#### Risposta: A + +Per prima cosa, abbiamo invocato `myFunc()` senza passare alcun argomento. Dal momento che non abbiamo passato argomenti, `num` e `value` hanno i loro valori predefiniti: num è `2` e `value` il valore restituito dalla funzione `add`. Alla funzione `add`, passiamo `num` come argomento, che aveva il valore di `2`. `add` restituisce `4`, che è il valore di `value`. + +Quindi, abbiamo invocato `myFunc(3)` e passato il valore `3` come valore per l'argomento `num`. Non abbiamo passato un argomento per `value`. +Poiché non abbiamo passato un valore per l'argomento `value`, ha ottenuto il valore predefinito: il valore restituito dalla funzione `add`. Ad `add` passiamo `num`, che ha il valore di `3`. `add` restituisce `6`, che è il valore di `value`. + +
++ +#### Risposta: D + +In ES2020, possiamo aggiungere variabili private nelle classi usando `#`. Non possiamo accedere a queste variabili al di fuori della classe. Quando proviamo a registrare `counter.#number`, viene generato un SyntaxError: non possiamo accedervi al di fuori della classe `Counter`! + +
++ +#### Risposta: B + +Per scorrere i `members` in ogni elemento dell'array `teams`, dobbiamo passare `teams[i].members` alla funzione `getMembers`. La funzione restituisce un oggetto. Per scorrere ogni elemento in questo oggetto generatore, dobbiamo usare `yield*`. + +Se avessimo scritto `yield`, `return yield` o `return`, l'intera funzione del generatore sarebbe stata restituita la prima volta che abbiamo chiamato il metodo `next`. + +
++ +#### Risposta: C + +La funzione `addHobby` riceve due argomenti, `hobby` e `hobby` con il valore predefinito dell'array `hobbies` sull'oggetto `person`. + +Per prima cosa, invochiamo la funzione `addHobby` e passiamo `"running"` come valore per `hobby` e un array vuoto come valore per `hobby`. Poiché passiamo un array vuoto come valore per `hobby`, `"running"` viene aggiunto a questo array vuoto. + +Quindi, invochiamo la funzione `addHobby` e passiamo a `"dancing"` come valore per `hobby`. Non abbiamo passato un valore per `hobbies`, quindi ottiene il valore predefinito, la proprietà `hobbies` sull'oggetto `person`. Spostiamo l'hobby `dancing` nell'array `person.hobbies`. + +Infine, invochiamo la funzione `addHobby` e passiamo `"baking"` come valore per `hobby`, e l'array `person.hobbies` come valore per `hobby`. Spostiamo l'hobby `baking` nell'array `person.hobbies`. + +Dopo aver fatto un push di `dancing` e `baking`, il valore di `person.hobbies` è `["coding", "dancing", "baking"]` + +
++ +#### Risposta: B + +Creiamo la variabile `pet` che è un'istanza della classe `Flamingo`. Quando istanziamo questa istanza, il `constructor` su `Flamingo` viene chiamato. Per prima cosa, `"I'm pink. 🌸"` viene loggato, dopodiché chiamiamo `super()`. + +`super()` chiama il costruttore della classe genitore, `Bird`. Il costruttore in `Bird` viene chiamato e registra `"I'm a bird. 🦢"`. + +
++ +#### Risposta: D + +La chiave `const` significa che non possiamo _ridichiarare_ il valore di quella variabile, è di _sola lettura_. Tuttavia, il valore stesso non è immutabile. Le proprietà dell'array `emojis` possono essere modificate, ad esempio facendo un push di nuovi valori, collegandoli o impostando la lunghezza dell'array su 0. + +
++ +#### Risposta: C + +Gli oggetti non sono iterabili per impostazione predefinita. Un iterabile è un iterabile se è presente il protocollo iteratore. +Possiamo aggiungerlo manualmente aggiungendo il simbolo dell'iteratore `[Symbol.iterator]`, che deve restituire un oggetto generatore, ad esempio trasformandolo in una funzione del generatore `*[Symbol.iterator]() {}`. Questa funzione di generazione deve fornire gli `Object.values` dell'oggetto `person` se vogliamo che restituisca l'array `["Lydia Hallie", 21]`: `yield* Object.values(this)`. + +
++ +#### Risposta: C + +La condizione `if` all'interno del ciclo `forEach` controlla se il valore di `num` è veritiero o falso. Poiché il primo numero nell'array `nums` è `0`, ovvero un valore falso, il blocco di codice dell'istruzione `if` non verrà eseguito. `count` viene incrementato solo per gli altri 3 numeri nell'array `nums`, `1`, `2` e `3`. Poiché `count` viene incrementato di `1` 3 volte, il valore di `count` è `3`. + +
++ +#### Risposta: D + +Il `?` ci consente di accedere opzionalmente a proprietà nidificate più profonde all'interno degli oggetti. Stiamo cercando di registrare l'elemento sull'indice `1` all'interno del sottoarray che si trova sull'indice `1` dell'array `fruits`. Se il sottoarray sull'indice `1` nell'array `fruits` non esiste, restituirà semplicemente `undefined`. Se il sottoarray sull'indice `1` nell'array `fruits` esiste, ma questo sottoarray non ha un elemento nel suo indice `1`, restituirà comunque `undefined`. + +Innanzitutto, stiamo cercando di registrare il secondo elemento nel sottoarray `['🍍']` di `[['🍊', '🍌'], ['🍍']]`. Questo sottoarray contiene solo un elemento, il che significa che non c'è alcun elemento nell'indice `1`, e restituisce `undefined`. + +Quindi, stiamo invocando la funzione `getFruits` senza passare un valore come argomento, il che significa che `fruits` ha un valore di `undefined` per impostazione predefinita. Poiché stiamo concatenando condizionatamente l'elemento sull'indice `1` di `fruits`, restituisce `undefined` poiché questo elemento sull'indice `1` non esiste. + +Infine, stiamo cercando di registrare il secondo elemento nel sottoarray `['🍊', '🍌']` di `['🍍'], ['🍊', '🍌']`. L'elemento nell'indice `1` all'interno di questo sottoarray è `🍌`, che viene registrato. +
++ +#### Risposta: A + +Impostiamo la variabile `calc` uguale a una nuova istanza della classe `Calc`. Quindi, istanziamo una nuova `Calc` e invochiamo il metodo `increase` su questa istanza. Poiché la proprietà count è all'interno del costruttore della classe `Calc`, la proprietà count non è condivisa sul prototipo di `Calc`. Ciò significa che il valore di count non è stato aggiornato per l'istanza a cui punta il calc, count è ancora `0`. +
++ +#### Risposta: B + +La funzione `updateUser` aggiorna i valori delle proprietà `email` e `password` sull'utente se i loro valori vengono passati alla funzione, dopodiché la funzione restituisce l'oggetto `user`. Il valore restituito dalla funzione `updateUser` è l'oggetto `user`, il che significa che il valore di `updateUser` è un riferimento allo stesso oggetto `user` a cui punta `user`. `updatedUser === user` è uguale a `true`. + +
++ +#### Risposta: C + +Per prima cosa, invochiamo il metodo `slice` sull'array fruit. Il metodo slice non modifica l'array originale, ma restituisce il valore che ha tagliato fuori dall'array: l'emoji banana. +Quindi, invochiamo il metodo `splice` sull'array fruit. Il metodo splice modifica l'array originale, il che significa che l'array fruit ora è composto da `['🍊', '🍎']`. +Infine, invochiamo il metodo `unshift` sull'array `fruit`, che modifica l'array originale aggiungendo il valore fornito, '🍇' in questo caso, come primo elemento nell'array. L'array fruit ora è composto da `['🍇', '🍊', '🍎']`. + +
++ +#### Risposta: B + +Le chiavi degli oggetti vengono convertite in stringhe. + +Poiché il valore di `dog` è un oggetto, `animals[dog]` significa in realtà che stiamo creando una nuova proprietà chiamata `"object Object"` uguale al nuovo oggetto. +`animals["object Object"]` è ora uguale a `{ emoji: "🐶", name: "Mara"}`. + +Anche `cat` è un oggetto, il che significa che `animals[cat]` in realtà stiamo sovrascrivendo il valore di `animals["object Object"]` con le nuove proprietà cat. + +Loggando `animals[dog]`, o effettivamente `animals["object Object"]`, poiché la conversione dell'oggetto `dog` in una stringa risulta `"object Object"`, restituisce `{ emoji: "🐈", name: "Sara" }`. + +
++ +#### Risposta: A + +La funzione `updateEmail` è una arrow function e non è legata all'oggetto `user`. Ciò significa che la parola chiave `this` non si riferisce all'oggetto `user`, ma in questo caso si riferisce allo scope globale. Il valore di `email` all'interno dell'oggetto `user` non viene aggiornato. Quando si stampa il valore di `user.email`, viene restituito il valore originale ovvero `my@email.com`. + +
++ +#### Risposta: D + +Il metodo `Promise.all` esegue le promise passate in parallelo. Se una promise fallisce, il metodo `Promise.all` effettua un _rejects_ con il valore della promise rifiutata. In questo caso, `promise3` ha rifiutato con il valore `"Third"`. Stiamo rilevando il valore rifiutato nel metodo `catch` concatenato sulla chiamata `runPromises` per rilevare eventuali errori all'interno della funzione `runPromises`. Solo `"Third"` viene registrato, poiché `promise3` viene rifiutato con questo valore. + +
++ +#### Risposta: C + +Il metodo `fromEntries` trasforma un array 2d in un oggetto. Il primo elemento in ogni sottoarray sarà la chiave e il secondo elemento in ogni sottoarray sarà il valore. In questo caso, stiamo mappando sull'array `keys`, che restituisce un array il cui primo elemento è l'elemento nell'array di chiavi sull'indice corrente e il secondo elemento è l'elemento dell'array di valori sull'indice corrente. + +Questo crea una matrice di sottoarray contenenti le chiavi e i valori corretti, che risulta in `{ nome: "Lydia", età: 22 }` + +
++ +#### Risposta: C + +Il valore predefinito di `address` è un oggetto vuoto `{}`. Quando abbiamo impostato la variabile `member` uguale all'oggetto restituito dalla funzione `createMember`, non abbiamo passato un valore per `address`, il che significa che il valore di `address` è l'oggetto vuoto predefinito `{}`. Un oggetto vuoto è un valore veritiero, il che significa che la condizione `address ? address : null` restituisce `true`. Il valore di `address` è l'oggetto vuoto `{}`. + +
++ +#### Risposta: B + +La condizione all'interno dell'istruzione `if` controlla se il valore di `!typeof randomValue` è uguale a `"string"`. L'operatore `!` converte il valore in un valore booleano. Se il valore è vero, il valore restituito sarà `false`, se il valore è falso, il valore restituito sarà `true`. In questo caso, il valore restituito di `typeof randomValue` è il vero valore `"number"`, il che significa che il valore di `!typeof randomValue` è il valore booleano `false`. + +`!typeof randomValue === "string"` restituisce sempre false, poiché stiamo effettivamente controllando `false === "string"`. Poiché la condizione ha restituito `false`, il blocco di codice dell'istruzione `else` viene eseguito e `Yay it's a string!` viene registrato. + +
+-정답은 질문 아래 접힌 부분에 있어요, 그냥 클릭하면 펼칠 수 있어요. 행운을 빌어요 :heart: +- [🇸🇦 العربية](../ar-AR/README_AR.md) +- [🇪🇬 اللغة العامية](../ar-EG/README_ar-EG.md) +- [🇧🇦 Bosanski](../bs-BS/README-bs_BS.md) +- [🇩🇪 Deutsch](../de-DE/README.md) +- [🇬🇧 English](../README.md) +- [🇪🇸 Español](../es-ES/README-ES.md) +- [🇫🇷 Français](../fr-FR/README_fr-FR.md) +- [🇮🇩 Indonesia](../id-ID/README.md) +- [🇮🇹 Italiano](../it-IT/README.md) +- [🇯🇵 日本語](../ja-JA/README-ja_JA.md) +- [🇳🇱 Nederlands](../nl-NL/README.md) +- [🇵🇱 Polski](../pl-PL/README.md) +- [🇧🇷 Português Brasil](../pt-BR/README_pt_BR.md) +- [🇷o Română](../ro-RO/README.ro.md) +- [🇷🇺 Русский](../ru-RU/README.md) +- [🇽🇰 Shqip](../sq-KS/README_sq_KS.md) +- [🇹🇭 ไทย](../th-TH/README-th_TH.md) +- [🇹🇷 Türkçe](../tr-TR/README-tr_TR.md) +- [🇺🇦 Українська мова](../uk-UA/README.md) +- [🇻🇳 Tiếng Việt](../vi-VI/README-vi.md) +- [🇨🇳 简体中文](../zh-CN/README-zh_CN.md) +- [🇹🇼 繁體中文](../zh-TW/README_zh-TW.md) -* [English](./README.md) -* [العربية](./README_AR.md) -* [اللغة العامية - Egyptian Arabic](./README_ar-EG.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) -* [Русский](./ru-RU/README.md) -* [Українська мова](./README-ua_UA.md) -* [Tiếng Việt](./README-vi.md) -* [中文版本](./README-zh_CN.md) -* [Türkçe](./README-tr_TR.md) +
+-#### 정답: D +#### 답: D -함수 내에서, 우선 `var` 키워드를 사용해 `name` 변수를 선언해요. 이것은 변수가 정의된 행에 실제로 도달할 때까지, `undefined`의 기본값으로 호이스팅 되(생성단계에 메모리 공간이 설정)는 것을 의미해요. `name` 변수를 출력하려는 줄에서 아직 변수를 정의하고 있지 않기 때문에, `undefined` 값을 유지하고 있어요. +함수 안에서, 우선 `var` 키워드를 사용해 `name` 변수를 선언해요. 이것은 변수를 정의한 줄에 실제로 도달할 때까지, 기본값 `undefined`으로 호이스팅 되는 것(생성단계에 메모리 공간이 설정)을 의미해요. `name` 변수를 출력하려는 줄에서 아직 변수를 정의하지 않았기 때문에, `undefined` 값을 유지해요. -`let` 키워드(그리고 `const`)를 가지는 변수들은, `var`와는 달리, 호이스팅 되지만 초기화 되지 않아요. 그것들을 선언(초기화)하는 줄 전에는 접근할 수 없어요. 이것은 "일시적 사각지대"라고 불려요. 선언되기 전 변수에 접근하려고 하면, JavaScript는 `ReferenceError`를 던져요. +`var`와는 다르게 `let` 키워드(그리고 `const`)를 가진 변수는 호이스팅 되지만, 초기화 되지 않아요. 변수를 선언(초기화)하는 줄 전에는 접근할 수 없어요. 이건 "일시적 사각지대"라고 불려요. 변수가 선언되기 전 변수에 접근하려고 하면, JavaScript는 `ReferenceError`를 던져요.
-#### 정답: C +#### 답: C -JavaScript의 이벤트 큐 때문에, `setTimeout`의 콜백 함수는 루프가 실행된 _후에_ 호출돼요. 첫 번째의 루프 변수 `i`는 `var` 키워드를 사용해 선언되어 있기 때문에, 이 값은 전역 변수가 돼요. 루프 동안, 단항 연산자 `++`를 사용하여, 매번 `i`의 값을 `1`씩 증가했어요. `setTimeout`콜백 함수가 호출되기까지, 첫 번째 예에서 `i`는 `3`이에요. +JavaScript의 이벤트 큐 때문에, `setTimeout`의 콜백 함수는 루프가 실행된 _후에_ 호출돼요. 첫 번째의 루프의 변수 `i`는 `var` 키워드를 사용해 선언되어 전역 값이 돼요. 루프 동안, 단항 연산자 `++`를 사용해 매번 `i`의 값을 `1`씩 증가시켰어요. `setTimeout`콜백 함수가 호출되기까지, 첫 번째 예시에서의 `i`는 `3`이에요. -두 번째 루프에서, 변수 `i`는 `let` 키워드를 사용해 선언되었어요: `let`(그리고 `const`) 키워드로 선언된 변수는 블록 범위예요(블록은 `{ }` 사이의 모든 것). 각각의 반복 동안, `i`는 새로운 값을 가지고, 각각의 값은 루프 안쪽 범위에 있어요. +두 번째 루프에서, 변수 `i`는 `let` 키워드를 사용해 선언되었어요: `let`(그리고 `const`) 키워드로 선언된 변수는 블록-스코프예요(블록은 `{ }` 사이의 모든 것). 각각을 반복하는 동안, `i`는 새로운 값을 갖게 되고, 각각의 값은 루프 스코프 안에 있어요.
-#### 정답: B +#### 답: B -`diameter`의 값은 정규 함수지만, `perimeter`의 값은 화살표 함수라는 점을 유의하세요. +`diameter`의 값은 일반 함수지만, `perimeter`의 값은 화살표 함수라는 점을 유의하세요. -화살표 함수에서, `this` 키워드는 통상적인 함수와는 다르게 현재 주위의 범위를 참조해요! 이것은 `perimeter`를 부르면, shape 객체가 아닌 그 주위의 범위(예를 들면 window)를 참조하는 것을 의미해요. +화살표 함수에서 `this` 키워드는 일반 함수와는 다르게 현재 주변 스코프를 참조해요! 이것은 `perimeter`를 부를 때 shape 객체가 아닌 그것을 둘러싼 스코프(예를 들면 window)를 참조하는 것을 의미해요. -그 객체에는 `radius`라는 값은 없기 때문에 `undefined`를 리턴해요. +그 객체에는 `radius`라는 값은 없기 때문에 `undefined`를 반환해요.
-#### 정답: A +#### 답: A -단항 더하기는 피연산자를 숫자로 변환하려 시도해요. `true`는 `1`이고, `false`는 `0`이에요. +단항 더하기는 피연산자를 숫자로 변환하려 해요. `true`는 `1`이고, `false`는 `0`이에요. -문자열 `'Lydia'`는 참 같은 값이에요. 실제로는, "이 참 같은 값이 거짓 같은 값인가?"를 물어보고 있어요. 이것은 `false`를 리턴해요. +문자열 `'Lydia'`는 참 같은 값이에요. 사실 우리가 물어본 건 "참 같은 이 값은 거짓인가?"예요. 이건 `false`를 반환해요.
-#### 정답: A +#### 답: A -JavaScript에서, 모든 객체 키는 문자열이에요 (심볼이 아닌 한). 비록 그것을 문자열 _형_ 으로 입력하지 않아도, 항상 내부적으로 문자열로 변환돼요. +JavaScript에서 모든 객체의 키는 문자열이에요(심볼이 아닌 한). 객체의 키를 문자열 _형_ 으로 입력하지 않더라도, 항상 내부적으로 문자열로 변환돼요. -JavaScript는 문장을 해석(또는 박스 해제)해요. 대괄호 표기를 사용하면, 첫 번째 열린 대괄호 `[`를 보고 닫힌 대괄호 `]`를 찾을 때까지 진행해요. 그때에만, 그 문장을 평가할 거예요. +JavaScript는 문장을 해석(또는 분)해요. 대괄호 표기를 사용하면 첫 번째 열린 대괄호 `[`를 보고 닫힌 대괄호 `]`를 찾을 때까지 진행해요. 다 찾은 후에만 문장을 평가할 거예요. -`mouse[bird.size]`: 먼저 `"small"`인 `bird.size`를 평가해요. `mouse["small"]` 은 `true`를 리턴해요. +`mouse[bird.size]`: 먼저 `'small'`인 `bird.size`를 평가해요. `mouse['small']` 은 `true`를 반환해요. -그러나, 닷 표기법에서, 이것은 발생하지 않아요, `mouse`는 `bird`라고 불리는 키를 가지고 있지 않아요. 즉, `mouse.bird`는 `undefined`를 의미해요. 그 후, 닷 표기법을 사용해 `size`를 물어봐요. `mouse.bird.size`. `mouse.bird`는 `undefined`로, 실제로는 `undefined.size`를 물어보고 있어요. 이것은 유효하지 않기 때문에, `Cannot read property "size" of undefined`와 비슷한 에러를 던질 거예요. +그러나 이것은 점 표기법에서 발생하지 않아요. `mouse`가 `bird`라고 불리는 키를 가지고 있지 않기 때문에, `mouse.bird`는 `undefined`임을 의미해요. 그다음에, 점 표기법을 사용해 `size`를 물어봐요: `mouse.bird.size`. `mouse.bird`는 `undefined`이기 때문에, 사실 우리가 물어보는 건 `undefined.size`에요. 이건 유효하지 않아요, 그리고 `Cannot read property 'size' of undefined`와 비슷한 오류를 던질 거예요.
-#### 정답: A
+#### 답: A
-JavaScript에서, 모든 객체는 서로 동일하게 설정하면 _참조_ 에 따라 상호작용해요.
+JavaScript에서 모든 객체는 서로를 동일하게 설정하면 _참조_로 상호작용해요.
-우선 변수 `c`는 객체에 대한 값을 유지해요. 그 후, `c`와 동일한 객체 참조를 `d`에 할당해요.
+우선, 변수 `c`는 객체에 대한 값을 갖고 있어요. 그 후 `c`가 객체에 가지고 있는 것과 동일한 참조를 `d`에 할당해요.
-한 개의 객체를 변경하면, 그것들 모두 변경해요.
+하나의 객체를 변경하면, 모든 객체가 변해요.
-#### 정답: C +#### 답: C -`new Number()`는, 내장 함수 생성자예요. 숫자처럼 보이지만, 실제로는 숫자가 아니에요: 많은 추가 특성이 있고 그것은 객체예요. +`new Number()`는, 내장 함수 생성자예요. 숫자처럼 보이지만, 사실 숫자가 아니에요: 많은 추가 특성이 있고 그것은 객체예요. -`==`연산자를 사용할 때, 그건 같은 _값_ 을 가졌는지 여부만 확인해요. 그것들은 모두`3`의 값을 가지고 있으므로, `true`를 리턴해요. +`==`연산자를 사용할 때는, 같은 _값_ 을 가졌는지 여부만 확인해요. 모두`3`의 값을 가지고 있음으로 `true`를 반환해요. -그러나, `===`연산자를 사용할 때, 값 _과_ 형 둘 다 같아야 해요. 이건 아니에요: `new Number()`는 숫자가 아니에요. **객체**에요. 그래서 둘 다 `false`를 리턴해요. +그러나, `===`연산자를 사용할 때는, 값 _그리고_ 형 둘 다 같아야 해요. 이건 아니에요: `new Number()`는 숫자가 아니에요. **객체**에요. 그래서 둘 다 `false`를 반환해요.
-#### 정답: D +#### 답: D -`colorChange`함수는 정적이에요. 정적 메소드는 그것들이 만들어지는 생성자 상에서만 살아있도록 설계되어 있어, 어떤 자식들도 상속받을 수 없어요. `freddie`는 자식이기 때문에, 이 함수는 상속되지 않고, `freddie`인스턴스에서는 이용할 수 없어요: `TypeError`가 던져져요. +`colorChange`함수는 정적이에요. 정적 메소드는 그것이 만들어지는 생성자에서만 살아있도록 설계되어, 어떤 자식들도 상속받을 수 없어요. `freddie`는 자식이기 때문에, 이 함수는 상속되지 않아 `freddie`인스턴스에서는 이용할 수 없어요: `TypeError`가 던져져요.
-#### 정답: A +#### 답: A -역 객체에 빈 객체를 방금 만들었기 때문에, 객체는 출력돼요. `greeting`을 `greettign`으로 잘못 입력했을 경우, JS 인터프리터는 실제로 이것을 `global.greettign = {}` (또는 브라우저의 `window.greetign = {}`) 라고 간주해요. +방금 전역 객체에 빈 객체를 만들었기 때문에, 객체는 출력돼요. `greeting`을 `greettign`으로 잘못 입력했을 때, JS 인터프리터는 `global.greettign = {}` (또는 브라우저의 `window.greetign = {}`)라고 간주해요. -이것을 피하기 위해서, `"use strict"`를 사용할 수 있어요. 이렇게 하면 변수를 어떤 것과 동일하게 설정하기 전에 변수를 선언했는지 확인할 수 있어요. +이것을 피하려면, `"use strict"`를 사용해요. 이렇게 하면 변수를 어떤 것과 동일하게 설정하기 전에 변수를 선언했는지 확인할 수 있어요.
-#### 정답: A
+#### 답: A
-함수는 객체이기 때문에, 이건 JavaScript에서는 가능해요! (윈시형 이외는 모두 객체)
+JavaScript에서는 가능한데, 함수는 객체이기 때문이에요! (원시형 이외는 모두 객체)
함수는 특별한 종류의 객체예요. 당신이 쓴 코드는 실제 함수가 아니에요. 함수는 속성을 가진 객체예요. 이 속성은 호출이 가능해요.
@@ -347,8 +374,8 @@ function Person(firstName, lastName) {
this.lastName = lastName;
}
-const member = new Person("Lydia", "Hallie");
-Person.getFullName = function() {
+const member = new Person('Lydia', 'Hallie');
+Person.getFullName = function () {
return `${this.firstName} ${this.lastName}`;
};
@@ -360,21 +387,21 @@ console.log(member.getFullName());
- C: `Lydia Hallie`
- D: `undefined` `undefined`
-
-#### 정답: A
+#### 답: A
-생성자에는 보통의 객체처럼 속성을 추가할 수 없어요. 한 번에 모든 객체에 기능을 추가하고 싶다면, 프로토타입을 사용해야 해요. 그래서 이 경우에,
+JavaScript에서, 함수는 객체이고 그렇기 때문에 메소드 `getFullName`은 생성자 함수 객체 자체에 추가돼요. 이런 이유로, 우리는 `Person.getFullName()`을 부를 수 있지만 `member.getFullName()`은 `TypeError`를 던져요.
+
+모든 객체 인스턴스에서 메소드를 사용할 수 있게 하려면, 메소드를 프로토타입 속성에 추가하세요.
```js
-Person.prototype.getFullName = function() {
+Person.prototype.getFullName = function () {
return `${this.firstName} ${this.lastName}`;
};
```
-`member.getFullName()`은 작동해요. 이것은 왜 유익할까요? 이 메소드를 생성자 자체에 추가했다고 할게요. 아마도 모든 `Person` 인스턴스는 이 메소드가 필요하지 않을 수도 있어요. 그 경우 그들은 계속해서 속성을 갖고 있기 때문에, 각각의 인스턴스를 위한 메모리 공간을 소비하게 되어, 많은 메모리 공간을 낭비하게 될 거예요. 대신에, 프로토타입을 추가하는 것만으로, 메모리의 한 지점을 가지지만, 모든 것들은 그것에 접근할 수 있어요.
-
-#### 정답: A
+#### 답: A
-`sarah`에게 `new` 키워드를 사용하지 않았어요. `new`를 사용한 경우, 이것은 우리가 만든 새로운 빈 객체를 참조해요. 그러나, `new`를 추가하지 않으면 **전역변수**를 참조해요!
+`sarah`에게 `new` 키워드를 사용하지 않았어요. `new`를 사용한 경우, `this`는 우리가 만든 새로운 빈 객체를 참조해요. 그러나, `new`를 추가하지 않으면 **전역 변수**를 참조해요!
-`this.firstName`은 `"Sarah"`이고, `this.lastName`은 `"Smith"`이리고 말했었어요. (그렇지만) 우리는 실제로 한 일은 `global.firstName = 'Sarah'` 그리고 `global.lastName = 'Smith'`를 정의하는 것이에요. `sarah` 자체는 `undefined`로 남아있어요. 따라서 `Person`함수의 값을 리턴하지 않아요.
+`this.firstName`은 `"Sarah"`이고, `this.lastName`은 `"Smith"`라고 말했었어요. (그렇지만)실제로는, `global.firstName = 'Sarah'` 그리고 `global.lastName = 'Smith'`를 정의한 거예요. `sarah` 자체는 `undefined`로 남아있어요, 그렇기 때문에 `Person`함수의 값을 반환하지 않아요.
-#### 정답: D
+#### 답: D
-**capturing** 단계 동안에, 이벤트는 조상 요소를 거쳐 목표 요소까지 내려가요. 그런 다음 **target** 요소에 도달하고, **bubbling**이 시작돼요.
+**capturing** 단계 동안에, 이벤트는 조상 요소를 거쳐 target 요소까지 내려가요. 그런 다음 **target** 요소에 도달하고, **bubbling**이 시작돼요.
-#### 정답: B
+#### 답: B
-**기본 객체**를 제외한, 모든 객체는 프로토타입을 가져요. 기본 객체는 사용자에 의해 만들어지거나 `new` 키워드를 사용하여 만들어져요. 기본 객체는 `.toString`과 같은 몇 개의 메소드와 속성에 접근할 수 있어요. 이것이 내장 JavaScript 메소드를 사용할 수 있는 이유죠! 이러한 모든 메소드는 프로토타입에서 이용할 수 있어요. JavaScript가 당신의 객체를 직접 찾을 수 없더라도, 당신이 접근할 수 있도록 프로토타입 체인으로 내려가서 찾을 거에요.
+**기본 객체**를 제외한, 모든 객체는 프로토타입을 가져요. 기본 객체는 사용자가 만든 객체이거나 `new` 키워드를 사용해 만들어진 객체예요. 기본 객체는 `.toString`과 같은 몇 개의 메소드와 속성에 접근할 수 있어요. 이것이 내장 JavaScript 메소드를 사용할 수 있는 이유죠! 이러한 모든 메소드는 프로토타입에서 사용할 수 있어요. JavaScript가 당신의 객체를 바로 찾을 수 없더라도, 당신이 접근할 수 있도록 프로토타입 체인으로 내려가 찾을 거예요.
-#### 정답: C
+#### 답: C
-JavaScript는 **동적으로 만들어진 언어**에요: 특정 변수가 어떤 형인지 지정하지 않아요. 변수는 당신이 모르는 사이에 자동으로 다른 형으로 변환될 수 있는데, 이걸 _암묵적 형 변환_ 이라고 불러요. **Coercion**은 하나의 형을 다른 형으로 변환해요.
+JavaScript는 **동적으로 유형화된 언어**에요: 특정 변수가 어떤 유형인지 명시하지 않아요. 변수는 당신이 모르는 사이에 자동으로 다른 유형으로 변환될 수 있는데, 이걸 _암묵적 형 변환_ 이라고 불러요. **Coercion**은 하나의 유형을 다른 유형으로 변환해요.
-이 예제에서, 함수가 이해하고 값을 리턴하도록, JavaScript는 숫자 `1`을 문자열로 변환해요. 수형 (`1`)와 문자열형 (`'2'`)의 추가 중에는, 숫자는 문자열로 취급해요. `"Hello" + "World"`처럼 문자열을 연결할 수 있어요, 따라서 여기 `"1" + "2"`는 `"12"`을 리턴하는 일이 발생해요.
+이 예제에서, JavaScript는 함수가 이해하고 값을 반환하도록 숫자 `1`을 문자열로 변환해요. 숫자 유형 (`1`)과 문자열 유형 (`'2'`)을 추가하는 동안, 숫자는 문자열로 취급돼요. `"Hello" + "World"`처럼 문자열을 연결해요, 따라서 여기서 일어나는 일은 `"1" + "2"`는 `"12"`에요.
-#### 정답: C
+#### 답: C
**접미사** 단항 연산자 `++`:
-1. 값 리턴 (이것은 `0`을 리턴해요)
-2. 값 증가 (number는 지금 `1`이에요)
+1. 값 반환 (`0`을 반환해요)
+2. 값 증가 (지금 number는 `1`이에요)
**접두사** 단항 연산자 `++`:
-1. 값 증가 (number는 지금 `2`이에요)
-2. 값 리턴 (이것은 `2`을 리턴해요)
+1. 값 증가 (지금 number는 `2`이에요)
+2. 값 반환 (`2`를 반환해요)
-이건 `0 2 2`를 리턴해요.
+`0 2 2`를 반환해요.
-#### 정답: B
+#### 답: B
-태그드 템플릿 리터럴을 사용하는 경우, 첫 번째 인수의 값은 항상 문자열 값의 배열이에요. 나머지 인수는 식을 통과한 값을 얻어요.
+태그가 지정된 템플릿 리터럴을 사용한다면, 첫 번째 인수의 값은 항상 문자열 값의 배열이에요. 나머지 인수는 표현식을 통과한 값을 가져요.
-#### 정답: C
+#### 답: C
-동등성을 테스트할 때, 원시형은 그 _값_ 에 따라 비교되며, 객체는 그들의 _참조_ 에 따라 비교돼요. JavaScript 객체가 메모리 내의 같은 장소를 참조하고 있는지를 확인해요.
+동등성을 테스트할 때, 원시형은 _값_ 으로 비교되고, 객체는 _참조_ 로 비교돼요. JavaScript는 객체가 메모리 내의 같은 장소를 참조하고 있는지를 확인해요.
비교하고 있는 두 개의 객체는 그것이 없어요: 파라미터로 전달된 객체와 동등성을 확인하기 위해 사용한 객체는 메모리 내의 다른 장소를 참조해요.
-이것이 `{ age: 18 } === { age: 18 }` 그리고 `{ age: 18 } == { age: 18 }` 두 개 다 `false`를 리턴하는 이유죠.
+`{ age: 18 } === { age: 18 }` 그리고 `{ age: 18 } == { age: 18 }` 두 개 다 `false`를 반환하는 이유예요.
-#### 정답: C
+#### 답: C
-스프레드 연산자 (`...args`.)는 인수를 가진 배열을 리턴해요. 배열은 객체이므로, `typeof args`는 `"object"`를 리턴해요.
+rest 파라미터 (`...args`)는 남아있는 모든 인수을 하나의 배열로 "집합" 해요. 배열은 객체이니까 `typeof args`는 `"object"`를 반환해요.
-#### 정답: C
+#### 답: C
-`"use strict"`을 사용하면, 실수로 전역 변수를 선언하지 않게 할 수 있어요. `age`라는 변수를 선언한 적이 전혀 없고, `"use strict"`을 사용하고 있으므로, 참조 에러를 던지게 될 거예요. 만약 `"use strict"`을 사용하지 않았다면, 이건 작동할 거예요, `age` 속성이 전역 객체에 추가된 것이기 때문이죠.
+`"use strict"`을 사용하면, 실수로 전역 변수를 선언하지 않게 해줘요. `age`라는 변수를 선언한 적이 전혀 없고, `"use strict"`을 사용하고 있으니, reference error를 던지게 될 거예요. 만약 `"use strict"`을 사용하지 않았다면 동작할 거예요, `age` 속성이 전역 객체에 추가된 것이기 때문이죠.
-#### 정답: A
+#### 답: A
-`eval` 문자열로서 통과된 코드를 평가해요. 이 경우와 같이 만약 그것이 표현식이라면, 표현 식을 평가해요. 표현 식은 `10 * 10 + 5`이에요. 이것은 숫자 `105`를 리턴해요.
+`eval` 문자열로 통과된 코드를 평가해요. 만약 그것이 이 경우처럼 표현 식이라면, 표현 식을 평가해요. 표현식은 `10 * 10 + 5`이에요. 이것은 숫자 `105`를 반환해요.
-#### 정답: B
+#### 답: B
`sessionStorage`에 저장된 데이터는 _탭_ 을 닫은 후에 삭제돼요.
@@ -702,12 +729,12 @@ console.log(num);
- C: `SyntaxError`
- D: `ReferenceError`
-
-#### 정답: B
+#### 답: B
-`var` 키워드를 사용하면, 같은 이름으로 복수의 변수를 선언할 수 있어요. 변수는 최신의 값을 유지해요.
+`var` 키워드를 사용하면, 같은 이름으로 복수의 변수를 선언할 수 있어요. 변수는 최신의 값을 가져요.
블록 스코프의 `let` 또는 `const`에서는 할 수 없어요.
@@ -719,12 +746,12 @@ console.log(num);
###### 24. 무엇이 출력 될까요?
```javascript
-const obj = { 1: "a", 2: "b", 3: "c" };
+const obj = { 1: 'a', 2: 'b', 3: 'c' };
const set = new Set([1, 2, 3, 4, 5]);
-obj.hasOwnProperty("1");
+obj.hasOwnProperty('1');
obj.hasOwnProperty(1);
-set.has("1");
+set.has('1');
set.has(1);
```
@@ -733,14 +760,14 @@ set.has(1);
- C: `true` `true` `false` `true`
- D: `true` `true` `true` `true`
-
-#### 정답: C
+#### 답: C
-모든 객체 키는(심볼 제외) 문자열로 직접 입력하지 않아도, 내부적으로는 문자열이에요. 이것이 `obj.hasOwnProperty('1')`도 true를 리턴하는 이유죠.
+모든 객체의 키는(심볼 제외) 문자열로 직접 입력하지 않았다고 해도 내부적으로는 문자열이에요. 이것이 `obj.hasOwnProperty('1')`도 true를 반환하는 이유예요.
-set에서는 작동하지 않아요. set에는 `'1'`이 없어요: `set.has('1')`는 `false`를 리턴해요. 그것은 수형인 `1`을 가지고 있어, `set.has(1)`는 `true`를 리턴해요.
+set에서는 동작하지 않아요. set에는 `'1'`이 없어요: `set.has('1')`은 `false`를 반환해요. 숫자 유형인 `1`을 가지고 있어, `set.has(1)`는 `true`를 반환해요.
-#### 정답: C
+#### 답: C
-같은 이름의 키를 두 개 가지고 있다면, 여전히 첫 번째 위치에 있지만, 마지막에 지정된 값으로 대체될 거예요.
+같은 이름의 키를 두 개 갖고 있다면, 키는 대체 될 거예요. 여전히 첫 번째 위치에 있지만, 마지막으로 지정된 값을 가져요.
-#### 정답: A
+#### 답: A
기본적인 실행 콘텍스트는 전역 실행 문장이에요: 당신의 코드 모든 곳에서 접근할 수 있어요.
@@ -803,12 +830,12 @@ for (let i = 1; i < 5; i++) {
- C: `1` `2` `4`
- D: `1` `3` `4`
-
-#### 정답: C
+#### 답: C
-`continue` 표현 식은 특정 조건이 `true`를 리턴하면 반복 처리를 건너뛰어요.
+`continue` 표현 식은 특정 조건이 `true`를 반환하면 반복 처리를 건너뛰어요.
-#### 정답: A
+#### 답: A
-`String`은 내장 생성자로 속성을 추가할 수 있어요. 단지 프로토타입이라는 메소드를 추가했어요. 원시형 문자열은 문자열 프로토타입 함수에 의해 생성된 문자열 객체로 자동 변환돼요. 그래서, 모든 문자열(문자열 객체)은 그 메소드에 접근할 수 있어요!
+`String`은 내장 생성자로 속성을 추가할 수 있어요. 그냥 문자열 프로토타입에 메소드를 추가한거예요. 원시형 문자열은 문자열 프로토타입 함수가 생성한 문자열 객체로 자동 변환돼요. 그래서, 모든 문자열(문자열 객체)은 그 메소드에 접근할 수 있어요!
-#### 정답: B
+#### 답: B
-객체 키는 자동으로 문자열로 변환돼요. 객체 `a`의 키 값으로 `123`을 세팅하려고 해요.
+객체 키는 자동으로 문자열로 변환돼요. 객체 `a`에 키는 객체(b), 값은 `123`으로 설정하려고 해요.
-그러나, 객체를 문자열화 하면 `"[Object object]"`가 돼요. 그래서 여기서 말하고자 하는 건 `a["Object object"] = 123`이라는 거예요. 그 후, 같은 일을 다시 시도해요. `c`는 암묵적으로 문자열화 한 다른 객체에요. 그래서 `a["Object object"] = 456`이 돼요.
+그러나, 객체를 문자열화 하면 `"[object Object]"`가 돼요. 그래서 여기서 말하고자 하는 건 `a["object Object"] = 123`이라는 거예요. 그 후, 같은 일을 다시 시도해요. `c`는 암묵적으로 문자열화 한 다른 객체에요. 그래서 `a["object Object"] = 456`이 돼요.
-그 후, `a[b]`는 출력하면 실제로는 `a["Object object"]`에요. 단지 `456`을 설정했기 때문에, `456`을 리턴해요.
+그 후, `a[b]`를 출력하면 실제로는 `a["object Object"]`예요. 그냥 `456`을 설정했기 때문에, `456`을 반환해요.
-#### 정답: B
+#### 답: B
처음에 `setTimeout`함수를 호출했어요. 그러나 그것은 마지막에 출력돼요.
-브라우저에는 런타임 엔진뿐만 아니라 `WebAPI`라고 불리는 것도 있기 때문이에요. `WebAPI`는 `setTimeout`함수를 최초에 부여하는데, DOM을 예로 들 수 있어요.
+브라우저에는 런타임 엔진뿐만 아니라 `WebAPI`라고 불리는 것도 존재해요. `WebAPI`는 `setTimeout`함수를 최초에 부여하는데, DOM을 예로 들 수 있어요.
_callback_ 이 WebAPI에 푸시된 후, `setTimeout`함수 자체(callback이 아니에요!)는 stack에 사라졌어요.
@@ -936,9 +963,7 @@ WebAPI는 준비가 될 때마다 stack에 항목을 추가할 수 없어요.
```html
-#### 정답: C
+#### 답: C
-가장 깊이 중첩된 요소가 이벤트를 발생시킬 이벤트 대상이에요. `event.stopPropagation`을 통해서 버블링을 중단할 수 있어요.
+가장 깊이 중첩된 요소가 이벤트를 발생시킬 이벤트 대상이예요. `event.stopPropagation`을 통해서 버블링을 중단할 수 있어요.
- Click here!
- Click here!
-#### 정답: A
+#### 답: A
-`p`를 클릭하면, 2개의 로그를 볼 수 있어요: `p` 그리고 `div`. 이벤트의 전파 중에는 3단계가 있어요: 캡처링, 타겟, 버블링. 기본적으로, 이벤트 핸들러는 버블링 단계에서 시작돼요. (`useCapture`를 `true`로 설정하지 않는 한). 가장 깊게 중첩된 요소로부터 바깥쪽으로 나가요.
+`p`를 클릭하면, 2개의 로그를 볼 수 있어요: `p` 그리고 `div`. 이벤트의 전파 중에는 3단계가 있어요: 캡처링, 타겟, 버블링. 기본적으로, 이벤트 핸들러는 버블링 단계에서 시작돼요. (`useCapture`를 `true`로 설정하지 않는 한). 가장 깊게 중첩된 요소에서 바깥쪽으로 가요.
-#### 정답: D
+#### 답: D
-두 개 모두, `this` 키워드를 참조하고자 하는 객체로 보낼 수 있어요. 그러나, `.call`은 _즉시 실행돼요_!
+두 개 모두, `this` 키워드를 참조하고자 하는 객체로 보낼 수 있어요. 그렇지만, `.call`은 _즉시 실행돼요_!
-`.bind.`는 함수의 _복사본_ 을 리턴하지만, 바인딩 콘텍스트죠! 이건 즉시 실행되지 않아요.
+`.bind.`는 함수의 _복사본_ 을 반환하지만, 바인딩된 콘텍스트죠! 즉시 실행되지 않아요.
-#### 정답: B
+#### 답: B
-`sayHi`함수는 즉시 호출 함수(IIFE)로서 리턴된 값을 리턴해요. 이 함수는 `0`을 리턴하고, 형은 `"number"`이에요.
+`sayHi`함수는 즉시 호출 함수 표현식(IIFE)으로서 반환된 값을 반환해요. 이 함수는 `0`을 반환하고, 형은 `"number"`이에요.
-참고: 단 7개의 내장형이 있어요: `null`, `undefined`, `boolean`, `number`, `string`, `object` 그리고 `symbol`. `"function"`은 객체이기 때문에 형이 아니라 `"object"`형이에요.
+참고: 내장된 형은 7개만 있어요: `null`, `undefined`, `boolean`, `number`, `string`, `object` 그리고 `symbol`. 함수는 객체이기 때문에 `"function"`은 형이 아니라 `"object"`형이에요.
-#### 정답: A
+#### 답: A
-단 6개의 거짓 같은 값이 있어요:
+8개의 거짓 같은 값이 있어요:
- `undefined`
- `null`
- `NaN`
-- `0`
-- `''` (빈 문자열)
- `false`
+- `''` (빈 문자열)
+- `0`
+- `-0`
+- `-0n` (BigInt(0))
`new Number` 그리고 `new Boolean`과 같은 생성자 함수는 참 같은 값이에요.
@@ -1096,13 +1121,13 @@ console.log(typeof typeof 1);
- C: `"object"`
- D: `"undefined"`
-
-#### 정답: B
+#### 답: B
-`typeof 1` 은 `"number"`를 리턴해요.
-`typeof "number"`은 `"string"`을 리턴해요.
+`typeof 1` 은 `"number"`를 반환해요.
+`typeof "number"`은 `"string"`을 반환해요.
-#### 정답: C
+#### 답: C
-배열의 길이를 초과한 값을 배열의 요소로 설정하고자 할 때, JavaScript는 "empty slots"라고 불리는 것을 생성해요. 이것은 실제로 `undefined`의 값을 가지고 있지만, 다음과 같은 것을 보게 될 거예요:
+배열의 길이를 초과한 값을 배열의 요소로 설정하고자 할 때, JavaScript는 "empty slots"라고 불리는 것을 생성해요. 이것은 사실 `undefined`의 값을 가지고 있지만, 다음과 같은 것을 보게 될 거예요:
`[1, 2, 3, 7 x empty, 11]`
-depending on where you run it (it's different for every browser, node, etc.)
실행 위치에 따라 달라요 (브라우저, node 등마다 달라요.)
-#### 정답: A
+#### 답: A
-`catch`블록은 `x`의 인수를 받아요. 이것은 인수를 전달할 때 변수로서의 `x`와는 달라요. 이 `x` 변수는 블록-스코프예요.
+`catch`블록은 인수`x`를 받아요. 이것은 인수를 전달할 때 변수로서의 `x`와는 달라요. 이 `x` 변수는 블록-스코프예요.
후에, 블록-스코프 변수는 `1`로 설정하고, 변수 `y`의 값을 설정해요. 여기서, 블록-스코프의 변수 `x`를 출력하는데, 이것은 `1`이에요.
-`catch` 블록 밖에서, `x`는 여전히 `undefined`이고 `y`는 `2`이에요. `catch` 블록 밖에서 `console.log(x)`를 출력하면, `undefined`를 리턴하고. 그리고 `y`는 `2`를 리턴해요.
+`catch` 블록 밖에서, `x`는 여전히 `undefined`이고 `y`는 `2`이에요. `catch` 블록 밖에서 `console.log(x)`를 출력하면, `undefined`를 반환하고. 그리고 `y`는 `2`를 반환해요.
-#### 정답: A
+#### 답: A
JavaScript는 원시형과 객체만 가지고 있어요.
원시형은 `boolean`, `null`, `undefined`, `bigint`, `number`, `string` 그리고 `symbol`이 있어요.
-원시형과 객체를 구별하는 법은 원시형에는 속성이나 메소드가 없어요. 그러나 `'foo'.toUpperCase()`는 `'FOO'`로 평가되어, `TypeError`의 결과가 되지 않아요. 문자열과 같은 원시형이 속성 또는 메소드에 접근하려고 할 때, JavaScript는 래퍼 클래스 중 하나인 `String`을 사용하여 암묵적으로 감싸고, 표현 식이 평가된 후 즉시 래퍼를 폐기하기 때문이에요. `null` 그리고 `undefined`를 제외한 모든 원시형은 이러한 행동을 합니다.
+원시형과 객체를 구별하는 법은 원시형에는 속성이나 메소드가 없어요. 그렇지만 `'foo'.toUpperCase()`는 `'FOO'`로 평가되어, 결과적으로 `TypeError`가 되지 않아요. 문자열과 같은 원시형이 속성 또는 메소드에 접근하려고 할 때, JavaScript는 래퍼 클래스 중 하나인 `String`을 사용하여 암묵적으로 감싸고, 표현 식이 평가된 후 즉시 래퍼를 폐기하기 때문이에요. `null` 그리고 `undefined`를 제외한 모든 원시형은 이러한 행동을 합니다.
-#### 정답: C
+#### 답: C
-`[1, 2]`은 초깃값이에요. 이것이 최초의 값으로, 제일 처음의 `acc`의 값이에요. 처음 라운드 동안에 `acc`는 `[1,2]`이며, `cur`은 `[0, 1]`이에요. 그것들을 연결하면 결과적으로 `[1, 2, 0, 1]`이 돼요.
+`[1, 2]`은 초기값이에요. 이것은 시작하는 최초의 값이고, `acc`의 제일 처음 값이에요. 처음 라운드 동안에 `acc`는 `[1,2]`이며, `cur`은 `[0, 1]`이에요. 그것을 연결하면 결과적으로 `[1, 2, 0, 1]`이 돼요.
-그 후, `[1, 2, 0, 1]`은 `acc`이고, `[2, 3]`은 `cur`이 에요. 그것들을 연결하면 `[1, 2, 0, 1, 2, 3]`을 얻게 돼요.
+그 후, `[1, 2, 0, 1]`은 `acc`이고, `[2, 3]`은 `cur`이에요. 그것을 연결하면 `[1, 2, 0, 1, 2, 3]`을 얻게 돼요.
-#### 정답: B
+#### 답: B
-`null`은 거짓 같은 값이에요. `!null`은 `true`를 리턴해요. `!true`는 `false`를 리턴해요.
+`null`은 거짓 같은 값이에요. `!null`은 `true`를 반환해요. `!true`는 `false`를 반환해요.
-`""` 은 거짓 같은 값이에요. `!""`은 `true`를 리턴해요. `!true`는 `false`를 리턴해요.
+`""` 은 거짓 같은 값이에요. `!""`은 `true`를 반환해요. `!true`는 `false`를 반환해요.
-`1`은 참 같은 값이에요. `!1`은 `false`를 리턴해요. `!false`는`true`를 리턴해요.
+`1`은 참 같은 값이에요. `!1`은 `false`를 반환해요. `!false`는 `true`를 반환해요.
-#### 정답: A
+#### 답: A
-이것은 유니크한 id를 리턴해요. 이 id는 `clearInterval()` 함수로 간격을 없애기 위해 사용될 수 있어요.
+이것은 유니크한 id를 반환해요. 이 id는 `clearInterval()` 함수의 간격을 없애기 위해 사용될 수 있어요.
-#### 정답: A
+#### 답: A
-문자열은 반복 가능한 객체예요. 스프레드 연산자는 반복 가능한 객체의 모든 문자를 1개의 요소로 매핑해요.
+문자열은 반복 가능한 객체예요. spread 연산자는 반복 가능한 객체의 모든 문자를 하나의 요소로 매핑해요.
-#### 정답: C
+#### 답: C
-보통의 함수는 호출 후에 중단할 수 없어요. 하지만, 제너레이터 함수는 중간에 "멈췄다가", 나중에 중단된 부분부터 계속할 수 있어요. 제너레이터 함수는 `yield` 키워드를 만날 때마다, yield 뒤에 지정된 값을 넘겨줘요. 제너레이터 함수에서는 값을 _리턴_ 하지 않고, _넘겨준다_ 는 것을 유의하세요.
+일반 함수는 호출 한 뒤 중간에 멈출 수 없어요. 하지만, 제너레이터 함수는 중간에 "멈췄다가", 나중에 중단된 부분부터 계속할 수 있어요. 제너레이터 함수는 `yield` 키워드를 만날 때마다, yield 뒤에 명시된 값을 넘겨줘요. 제너레이터 함수에서는 값을 _반환_ 하지 않고, 값을 _넘겨진다_ 는 것을 유의하세요.
우선, 제너레이터 함수에서 `i`를 `10`으로 초기화해요. `next()` 메소드를 사용해 제너레이터 함수를 호출해요. 처음에 제너레이터 함수를 호출하면, `i`은 `10`이에요. 첫 번째 `yield` 키워드를 만났어요: 그것은 `i`의 값을 넘겨줘요. 이제 제너레이터는 "멈추고", `10`을 출력해요.
-그 후, `next()` 메소드를 사용해 다시 한번 함수를 호출해요. `i`는 여전히 `10`이에요. 이제, 다음 `yield` 키워드를 만나 `i * 2`를 넘겨줘요. `i`는 `10`이므로, `10 * 2`, 즉 `20`을 리턴해요. 결과는 `10, 20`이에요.
+그 후, `next()` 메소드를 사용해 함수를 다시 호출해요. 이전에 멈춘 부분에서부터 다시 시작하고, `i`는 여전히 `10`이에요. 이제, 다음 `yield` 키워드를 만나 `i * 2`를 넘겨줘요. `i`는 `10`이므로, `10 * 2`, 즉 `20`을 반환해요. 결과는 `10, 20`이에요.
-#### 정답: B
+#### 답: B
-복수의 프로미스를 `Promise.race` 메소드에 넘겨주면, _최초_ 의 프로미스를 해결/거부해요. `setTimeout` 메소드에 타이머를 전달해요: 첫 번째 프로미스(`firstPromise`)에는 500ms, 두 번째 프로미스(`secondPromise`)에는 100ms. 이것은 `'two'`의 값을 가진 `secondPromise`가 최초로 해결한다는 것을 의미해요. 이제 `res`는 `'two'`의 값을 유지하고 출력돼요.
+복수의 프로미스를 `Promise.race` 메소드에 넘겨주면, _최초_ 의 프로미스를 해결/거부해요. `setTimeout` 메소드에 타이머를 전달해요: 첫 번째 프로미스(`firstPromise`)에는 500ms, 두 번째 프로미스(`secondPromise`)에는 100ms. 이것은 `'two'`의 값을 가진 `secondPromise`를 최초로 해결한다는 것을 의미해요. 이제 `res`는 `'two'`의 값을 갖고 출력돼요.
-#### 정답: D
+#### 답: D
우선, 변수 `person`의 값을 `name` 속성을 가진 객체로 선언해요.
-#### 정답: B
+#### 답: B
-`for-in` 루프를 사용하면, 객체 키를 통해서 반복할 수 있는데, 이 경우에서는 `name` 그리고 `age`에요. 내부적으로, 객체 키는 문자열이에요 (심볼이 아니라면 말이죠). 모든 루프에서, `item`의 값은 반복된 현재의 키 값으로 설정해요. 우선, `item`은 `name`으로 출력돼요. 그 후, `item`은 `age`로 출력돼요.
+`for-in` 루프를 사용하면, 객체의 키를 통해서 반복할 수 있는데, 이 경우에서는 `name` 그리고 `age`에요. 내부적으로, 객체의 키는 문자열이에요 (심볼이 아니라면 말이죠). 모든 루프에서, `item`의 값은 반복 중인 현재의 키 값으로 동일하게 설정해요. 우선, `item`은 `name`으로 출력돼요. 그 후, `item`은 `age`로 출력돼요.
-#### 정답: B
+#### 답: B
-연산자 결합성은 왼쪽에서 오른쪽 또는 오른쪽에서 왼쪽으로 컴파일러가 표현 식을 평가하는 순서가 돼요. 이것은 연산자가 _같은_ 우선순위를 가진 경우에만 해당돼요. 연산자의 종류는 한 개뿐이에요: `+`. 게다가, 결합성은 왼쪽에서 오른쪽이에요.
+연산자 결합성은 왼쪽에서 오른쪽 또는 오른쪽에서 왼쪽으로 컴파일러가 표현 식을 평가하는 순서가 돼요. 이것은 연산자가 _같은_ 우선순위를 가진 경우에만 해당돼요. 한 유형의 연산자만 있어요: `+`. 게다가, 결합성은 왼쪽에서 오른쪽이에요.
처음으로 `3 + 4`가 평가돼요. 결과는 숫자 `7`이에요.
-`7 + '5'`의 결과는 강제성 때문에 `"75"`가 돼요. JavaScript는 숫자 `7`을 문자열로 변환하고, (자세한 내용은) 질문 15를 보세요. `+` 연산자를 사용해서 두 개의 문자열을 연결할 수 있어요. `"7" + "5"`의 결과는 `"75"`이에요.
+`7 + '5'`의 결과는 강제성 때문에 `"75"`가 돼요. JavaScript는 숫자 `7`을 문자열로 변환하고, (관련된 자세한 설명은) 질문 15를 보세요. `+` 연산자를 사용해서 두 개의 문자열을 연결할 수 있어요. `"7" + "5"`의 결과는 `"75"`이에요.
-#### 정답: C
+#### 답: C
-문자열의 첫 번째 숫자만 리턴돼요. _진법_ 에 근거하여 (파싱하고자 하는 숫자의 기준을 명시하기 위한 두 번째 인수: 기본적인 10진수, 6진수, 8진수, 2진수 등), `parseInt`는 문자열 내의 문자가 타당한지 여부를 확인해요. 진수에 유효한 숫자가 아닌 문자를 만나면, 파싱을 멈추고, 다음 문자를 무시해요.
+문자열의 첫 번째 숫자만 반환돼요. _진법_ 에 근거해(파싱하고자 하는 숫자의 기준을 명시하기 위한 두 번째 인수: 기본 10진수, 6진수, 8진수, 2진수 등), `parseInt`는 문자열 내의 문자가 타당한지 여부를 확인해요. 진수에 유효한 숫자가 아닌 문자를 만나면, 파싱을 멈추고, 다음 문자를 무시해요.
-`*`은 유효한 숫자가 아니에요. `"7"`만 십진수의 `7`로 파싱 돼요. 이제 `num`은 `7`의 값을 유지해요.
+`*`은 유효한 숫자가 아니에요. `"7"`만 십진수의 `7`로 파싱 돼요. 이제 `num`은 `7`의 값을 가져요.
-#### 정답: C
+#### 답: C
-배열을 매핑할 때, `num`의 값은 헌재 순환하고 있는 요소예요. 이 경우, 요소는 숫자이기 때문에, if 문의 조건 `typeof num === "number"`는 `true`를 리턴해요. map 합수는 새로운 배열을 만들고 함수에서 리턴된 값을 삽입해요.
+배열을 매핑할 때, `num`의 값은 헌재 순환하고 있는 요소예요. 이 경우 요소는 숫자이기 때문에, if 문의 조건 `typeof num === "number"`는 `true`를 반환해요. map 함수는 새로운 배열을 만들고 함수에서 반환된 값을 삽입해요.
-그러나, 값을 리턴하지 않아요. 함수는 값을 리턴하지 않을 때, `undefined`를 리턴해요. 배열에서의 모든 요소에 대해 블록 함수가 호출되기 때문에, 각 요소에 대해 `undefined`를 리턴해요.
+그러나, 우리는 값을 반환하지 않아요. 함수는 값을 반환하지 않을 때 `undefined`를 반환해요. 배열에서의 모든 요소에 대해 함수 블록이 호출되므로, 각 요소에 대해 `undefined`를 반환해요.
-#### 정답: A
+#### 답: A
-인수들의 값이 객체가 아닌 한 _값_ 에 의해 전달돼요. 그 후 _참조_ 에 의해 전달돼요. `birthYear`는 객체가 아니라 문자열이기 때문에 값에 의해 전달돼요. 값으로 전달하면 값의 _복사본_ 이 만들어져요(질문 46을 보세요).
+인수는 값이 객체가 아니면 _값_ 으로 전달되고, 그렇지 않으면(값이 객체면) _참조_ 로 전달돼요. `birthYear`는 객체가 아니라 문자열이기 때문에 값으로 전달돼요. 값으로 전달하면 값의 _복사본_ 이 만들어져요(질문 46을 보세요).
변수 `birthYear`는 `"1997"`값에 대한 참조를 가져요. 인수 `year` 또한 `"1997"`에 대한 참조를 가지지만, `birthYear`가 가진 참조 값과는 달라요. `year`에 `"1998"`을 대입하여 `year`의 값을 업데이트할 때, `year`의 값만 업데이트해요. `birthYear`는 여전히 `"1997"`이에요.
-`person`의 값은 객체예요. 인수 `member`는 _같은_ 객체의 (복사된) 참조 값을 가져요. `member`객체의 속성이 갖는 참조를 변경하면, 두 개 모두 같은 객체를 참조 값을 가지고 있기 때문에, `person`의 값 또한 변경돼요. 이제 `person`'의 `name` 속성은값 `"Lydia"`에요.
+`person`의 값은 객체예요. 인수 `member`는 _같은_ 객체의 (복사된) 참조를 가져요. 참조를 가진 `member`객체의 속성을 변경하면, 두 개 모두 같은 객체의 참조를 가지고 있기 때문에, `person`도 변경돼요. 이제 `person`'의 `name` 속성의 값은 `"Lydia"`예요.
-#### 정답: D
+#### 답: D
-`throw`문을 사용해, 커스텀 에러를 만들 수 있어요. 이 표현 식을 사용해, 예외를 던질 수 있어요. 예외는 string, a number, a boolean or an object이 될 수 있어요. 이 경우, 예외는 `'Hello world'` 문자열이에요.
+`throw`문을 사용해, 사용자 지정 오류를 만들 수 있어요. 이 표현 식을 사용해, 예외를 던질 수 있어요. 예외는 문자열, 숫자, 불린 또는 객체가 될 수 있어요. 이 경우, 예외는 `'Hello world'` 문자열이에요.
-`catch` 문을 사용해, `try` 블록에서 예외가 던져졌을 경우에 무엇을 할지 명시할 수 있어요. 예외가 던져졌어요: 문자열 `'Hello world'`. `e`는 이제 문자열이고, 그것을 출력해요. 결과는 `'Oh an error: Hello world'`예요.
+`catch` 문을 사용해, `try` 블록에서 예외를 던진 경우 무엇을 할지 명시할 수 있어요. 예외가 던져졌어요: 문자열 `'Hello world'`. 이제 `e`는 문자열이고, 그것을 출력해요. 결과는 `'Oh an error: Hello world'`예요.
-#### 정답: B
+#### 답: B
-속성을 리턴할 때, 속성값은 생성자에 설정한 값이 아닌, _리턴된_ 값과 같아요. `"Maserati"` 문자열을 리턴하기 때문에, `myCar.make`는 `"Maserati"`에요.
+속성을 반환할 때, 속성값은 생성자에 설정한 값이 아닌, _반환된_ 값과 같아요. `"Maserati"` 문자열을 반환하기 때문에, `myCar.make`는 `"Maserati"`예요.
-#### 정답: A
+#### 답: A
`let x = y = 10;`은 다음의 단축형이에요:
@@ -1651,11 +1678,11 @@ y = 10;
let x = y;
```
-`y`에 `10`을 대입하면, 실제로는 전역 객체에 속성 `y`를 추가해요(브라우저에서는 `window`, Node에서는 `global`). 브라우저에서, `window.y`는 이제 `10`이에요.
+`y`에 `10`을 대입하면, 전역 객체에 속성 `y`를 추가해요(브라우저에서는 `window`, Node에서는 `global`). 브라우저에서, `window.y`는 이제 `10`이에요.
-그 후, 변수 `x`를 `10`인 `y`를 값으로 선언해요. `let`키워드로 선언된 변수는 _블록 스코프_ 로, 선언된 블록 내에서만 정의돼요: 이 경우 즉시 호출 함수예요(IIFE). `typeof`연산자를 사용할 때, 피연산자 `x`는 정의되지 않았어요: 선언된 블록 밖에서 접근하려 했어요. 이것은 `x`가 선언되지 않음을 의미해요. 값을 할당하거나 선언하지 않은 변수는 `"undefined"` 형이에요. `console.log(typeof x)`는 `"undefined"`를 리턴해요.
+그 후, 변수 `x`를 `10`인 `y`를 값으로 선언해요. `let`키워드로 선언된 변수는 _블록 스코프_ 로, 선언된 블록 내에서만 정의돼요: 이 경우에선 즉시 호출 함수예요(IIFE). `typeof`연산자를 사용할 때, 피연산자 `x`는 정의되지 않았어요: 우리는 선언된 블록 밖에서 접근하려 했어요. 이것은 `x`가 정의되지 않았음을 의미해요. 값을 할당하지 않거나 선언하지 않은 변수는 `"undefined"` 형이에요. `console.log(typeof x)`는 `"undefined"`를 반환해요.
-그러나, `y`를 `10`으로 설정할 때 전역 변수 `y`를 만들었어요. 이 값은 코드 내 어디에서나 접근할 수 있어요. `y`는 정의되었고, `"number"`형의 값을 유지해요. `console.log(typeof y)`는 `"number"`을 리턴해요.
+그러나, `y`를 `10`으로 설정할 때 전역 변수 `y`를 만들었어요. 이 값은 코드 내 어디에서나 접근할 수 있어요. `y`는 정의되어있고, `"number"`형의 값을 유지해요. `console.log(typeof y)`는 `"number"`을 반환해요.
-#### 정답: A
+#### 답: A
-프로토타입에서도 `delete`키워드를 사용해, 객체로부터 속성을 삭제할 수 있어요. 프로토타입에서 속성을 삭제하면, 프로토타입 체인에서 더는 사용할 수 없게 돼요. 이 경우, `bark` 함수는 `delete Dog.prototype.bark` 후에 프로토타입에서 더는 사용할 수 없게 되지만, 그래도 여전히 그것에 접근하려고 해요.
+프로토타입에서도 `delete`키워드를 사용해 객체의 속성을 삭제할 수 있어요. 프로토타입에서 속성을 삭제하면, 프로토타입 체인에서 더는 사용할 수 없어요. 이 경우, `bark` 함수는 `delete Dog.prototype.bark` 후에는 프로토타입에서 더는 사용할 수 없게 되었어요, 그러나 우리는 여전히 그것에 접근하려고 해요.
함수가 아닌 것을 호출하려고 할 때, `TypeError`가 던져져요. 이 경우 `pet.bark`는 `undefined`이기 때문에, `TypeError: pet.bark is not a function`예요.
@@ -1716,14 +1743,14 @@ console.log(set);
- C: `{1, 1, 2, 3, 4}`
- D: `{1, 2, 3, 4}`
-
-#### 정답: D
+#### 답: D
`Set`은 _unique_ 값의 집합 객체예요: 값은 set 내에서 단 한 번만 발생해요.
-중복 값 `1`을 가진 반복 가능한 `[1, 1, 2, 3, 4]`을 전달하기 때문에, 그들 중 하나는 삭제돼요. 이것은 결과적으로 `{1, 2, 3, 4}`돼요.
+중복 값 `1`을 가진 반복 가능한 `[1, 1, 2, 3, 4]`을 전달하기 때문에, 그 중 하나는 삭제돼요. 이것은 결과적으로 `{1, 2, 3, 4}`돼요.
-#### 정답: C
+#### 답: C
-import 된 모듈은 _read-only_ 예요 : import 된 모듈은 수정할 수 없어요. export 한 모듈만 값을 변경할 수 있어요.
+import 된 모듈은 _read-only_ 예요 : import 된 모듈은 수정할 수 없어요. export 한 모듈에서만 값을 변경할 수 있어요.
-`myCounter`의 값을 증가시키려고 할 때, 에러를 던져요: `myCounter`는 read-only이고 수정할 수 없어요.
+`myCounter`의 값을 증가시키려고 할 때, 오류를 던져요: `myCounter`는 read-only이고 수정할 수 없어요.
-#### 정답: A
+#### 답: A
-`delete`연산자는 불린 값을 리턴해요: 성공적으로 삭제를 한 경우 `true`를, 그렇지 않다면 `false`를 리턴해요. 그러나, `var`, `const` 또는 `let` 키워드로 선언된 변수들은 `delete`연산자를 사용해서 삭제될 수 없어요.
+`delete`연산자는 불린 값을 반환해요: 성공적으로 삭제를 한 경우 `true`를, 그렇지 않다면 `false`를 반환해요. 그러나, `var`, `const` 또는 `let` 키워드로 선언된 변수은 `delete`연산자를 사용해서 삭제될 수 없어요.
-`name` 변수는 `const`키워드로 선언되었기 때문에, 삭제에 실패해요. `age`를 `21`로 설정할 때, 실제로는 `age`라는 속성을 전역 객체에 추가한 거죠. 이 방법으로 객체, 전역 객체의 속성들을 성공적으로 삭제할 수 있어요. `delete age`는 `true`를 리턴해요.
+`name` 변수는 `const`키워드로 선언되었기 때문에, 삭제에 실패해요: `false`가 반환돼요. `age`를 `21`로 설정할 때, 사실은 `age`라는 속성을 전역 객체에 추가한 거죠. 이 방법으로 객체, 전역 객체의 속성을 성공적으로 삭제할 수 있어요, 그래서 `delete age`는 `true`를 반환해요.
-#### 정답: C
+#### 답: C
-구조 분해 할당을 통해 객체의 배열 또는 속성들로부터 변수를 해체할 수 있어요. 예를 들어:
+구조 분해 할당을 통해 객체의 배열 또는 속성으로부터 변수를 해체할 수 있어요. 예를 들어:
```javascript
[a, b] = [1, 2];
@@ -1822,7 +1849,7 @@ console.log(y);
-#### 정답: B
+#### 답: B
-스프레드 연산자 `...` 를 사용해 객체를 결합할 수 있어요. 이것은 하나의 객체의 키/값의 쌍들을 복사본들로 만들어, 다른 객체에 추가해요. 이 경우, `user` 객체의 복사본들을 만들어, `admin` 객체에 추가해요. `admin` 객체는 이제 복사된 키/값의 쌍들이 들어있고, 결과는 `{ admin: true, name: "Lydia", age: 21 }` 예요.
+spread 연산자 `...` 를 사용해 객체를 결합할 수 있어요. 이것은 한 객체의 키/값 쌍을 복사본으로 만들어, 다른 객체에 추가해요. 이 경우, `user` 객체의 복사본을 만들어, `admin` 객체에 추가해요. `admin` 객체는 이제 복사된 키/값 쌍이 들어있고, 결과는 `{ admin: true, name: "Lydia", age: 21 }` 예요.
-#### 정답: B
+#### 답: B
-`defineProperty`메소드로, 객체에 새로운 속성들을 추가하거나, 기존 것을 수정할 수 있어요. `defineProperty` 메소드를 사용해 객체의 속성을 추가할 때, 기본적으로 객체의 속성들은 _비 열거자_ 예요. `Object.keys`메소드는 모든 _열거자_ 객체의 속성 이름들을 리턴하는데, 이 경우는 `"name"` 뿐이에요.
+`defineProperty`메소드를 사용해, 객체에 새로운 속성을 추가하거나 기존 속성을 수정할 수 있어요. `defineProperty` 메소드를 사용해 객체의 속성을 추가할 때, 객체의 속성은 기본적으로 _비 열거자_ 예요. `Object.keys`메소드는 모든 _열거자_ 객체의 속성 이름을 반환하는데, 이 경우는 `"name"` 뿐이에요.
-`defineProperty`를 사용해 추가된 속성들은 기본적으로 변경할 수 없어요. `writable`, `configurable` 그리고 `enumerable` 속성들을 사용해 덮어쓰기 할 수 있어요. `defineProperty`메소드의 방법은 객체에 추가할 속성들을 훨씬 더 정교하게 제어하도록 해줘요.
+`defineProperty`를 사용해 추가된 속성은 기본적으로 변경할 수 없어요. `writable`, `configurable` 그리고 `enumerable` 속성을 사용해 덮어쓸 수 있어요. `defineProperty`메소드를 사용하는 방법은 객체에 추가하는 속성을 훨씬 더 많이 제어할 수 있어요.
-#### 정답: A
+#### 답: A
-`JSON.stringify` 두 번째 인수는 _replacer_ 예요. replacer는 함수 또는 배열 둘 중 하나가 될 수 있고, stringify 할 대상과 방법을 제어할 수 있게 해줘요.
+`JSON.stringify` 두 번째 인수는 _replacer_ 예요. replacer는 함수 또는 배열일 수 있고, 문자열로 변환 할 대상과 방법을 제어할 수 있게 해줘요.
-replacer가 _배열_ 이라면, 배열에 이름이 포함된 속성만 JSON 문자열에 추가될 거에요. 이 경우, 이름을 가진 `"level"` 그리고 `"health"`속성들만 포함되고, `"username"`은 제외 돼요. `data` 은 이제 `"{"level":19, "health":90}"`에요.
+replacer가 _배열_ 이라면, 배열에 포함된 속성의 이름만 JSON 문자열에 추가될 거에요. 이 경우, 이름을 가진 `"level"` 그리고 `"health"`속성만 포함되고, `"username"`은 제외 돼요. `data` 은 이제 `"{"level":19, "health":90}"`에요.
-replacer가 _함수_ 라면, stringifying 할 객체의 모든 속성에 호출돼요. 이 함수로부터 리턴된 값은 JSON 문자열에 추가될 때 속성의 값이 될 거예요. 만약 값이 `undefined`라면, 이 속성은 JSON 문자열로부터 제외돼요.
+replacer가 _함수_ 라면, 문자열로 변환 할 객체의 모든 속성에 호출돼요. 이 함수로부터 반환된 값은 JSON 문자열에 추가될 때 속성의 값이 될 거예요. 만약 값이 `undefined`라면, 이 속성은 JSON 문자열에서 제외돼요.
-#### 정답: A
+#### 답: A
-단항 연산자 `++`는 _우선_ 피연산자의 값을 _리턴하고_, _그 후_ 피연산자의 값을 _증가해요_. `increaseNumber` 함수가 처음으로 리턴 한 `num`의 값은 `10` 이기 때문에, `num1`의 값은 `10`이고, 그 후엔 `num`의 값만 증가해요.
+단항 연산자 `++`는 _우선_ 피연산자의 값을 _반환하고_, _그 후_ 피연산자의 값을 _증가시켜요_. `increaseNumber` 함수가 처음으로 반환 한 `num`의 값은 `10` 이기 때문에, `num1`의 값은 `10`이고, 그 후엔 `num`의 값만 증가해요.
-`num1`을 `increasePassedNumber`로 전달했기 때문에, `num2`는 `10`이에요. `number`는 `10`이에요(`num1`의 값은, 다시 한번, 단항 연산자가 `++`는 _우선_ 피연산자의 값을 _리턴하고_, _그 후_ 피연산자의 값을 _증가해요_. `number`의 값은 `10`이에요 즉, `num2`는 `10`이죠.
+`num1`을 `increasePassedNumber`로 전달했기 때문에, `num2`는 `10`이에요. `number`는 `10`이에요(`num1`의 값. 다시, 단항 연산자가 `++`는 _우선_ 피연산자의 값을 _반환하고_, _그 후_ 피연산자의 값을 _증가해요_. `number`의 값은 `10`이에요 즉, `num2`는 `10`이죠.
-#### 정답: C
+#### 답: C
-ES6에서는, 기본값으로 파라미터를 초기화할 수 있어요. 함수에 값이 없이 전달되거나, 파라미터의 값이 `"undefined"`라면, 파라미터의 값은 기본값이 될 거예요. 이 경우, `value` 객체의 속성들을 새로운 객체 안으로 전개해요. 따라서 `x`는 `{ number: 10 }`을 기본값으로 가져요.
+ES6에서, 기본값으로 파라미터를 초기화할 수 있어요. 함수에 값이 없이 전달되거나, 파라미터의 값이 `"undefined"`라면, 파라미터의 값은 기본값이 될 거예요. 이 경우, `value` 객체의 속성을 새로운 객체 안에 전개했어요. 따라서 `x`는 `{ number: 10 }`을 기본값으로 가져요.
-기본 인수는 _호출 시점_ 에 평가돼요! 함수를 부를 때마다, _새로운_ 객체를 만들어요. 처음에 두 번은 값 전달 없이 `multiply` 함수를 호출해요: `x`는 `{ number: 10 }`의 기본값을 가져요. 그다음 그 숫자를 곱셈한 값인 `20`을 출력해요.
+기본 인수는 _호출 시점_ 에 평가돼요! 함수를 부를 때마다, _새로운_ 객체를 만들어요. 처음 두 번은 값을 전달하지 않고, `multiply` 함수를 호출해요: `x`는 `{ number: 10 }`의 기본값을 가져요. 그다음 해당 숫자를 곱한 값인 `20`을 출력해요.
-세 번째로 곱셈을 호출할 때, 인수를 전달해요: 그 객체는 `value`를 불러요. `*=` 연산자는 실제로는 `x.number = x.number * 2`의 줄임말이에요: `x.number`의 값을 변경하고, 곱셈한 값 `20`을 출력해요
+세 번째로 곱셈을 호출할 때, 인수를 전달해요: 그 객체는 `value`라고 불려요. `*=` 연산자는 사실 `x.number = x.number * 2`의 줄임말이에요: `x.number`의 값을 변경하고, 곱셈한 값 `20`을 출력해요
-네 번째에는, `value` 객체를 다시 한번 전달해요. `x.number`는 이전에 `20`으로 바뀌었기 때문에, `x.number *= 2`는 `40`을 출력해요.
+네 번째엔, `value` 객체를 다시 한번 전달해요. `x.number`는 이전에 `20`으로 바뀌었기 때문에, `x.number *= 2`는 `40`을 출력해요.
-#### 정답: D
+#### 답: D
-`reduce` 메소드가 받은 첫 번째 인수는 _누산기_ 예요, 이 경우엔 `x`죠. 두 번째 인수 `y`는 _현재 값_ 예요. reduce 메소드에서, 배열에 있는 모든 요소에 콜백 함수를 실행하므로 궁극적으로는 하나의 값을 얻을 수 있어요.
+`reduce` 메소드가 받은 첫 번째 인수는 _누산기_ 예요, 이 경우엔 `x`죠. 두 번째 인수 `y`는 _현재 값_ 이에요. reduce 메소드에서, 배열에 있는 모든 요소에 콜백 함수를 실행하므로 궁극적으로는 하나의 값을 얻어요.
-이 예제에서는, 값을 리턴하지 않고, 단지 누적된 값과 현재 값을 출력해요.
+이 예제에서는, 값을 반환하지 않고, 단지 누적된 값과 현재 값을 출력해요.
-누산기의 값은 콜백 함수가 이전에 리턴한 값이에요. 만약 추가적인 `초기값` 인수를 `reduce` 메소드에 전달하지 않았다면, 누산기는 첫번째 부른 첫 번째 요소와 동일해요.
+누산기의 값은 콜백 함수가 이전에 반환한 값이에요. 만약 추가적인 `초기값` 인수를 `reduce` 메소드에 전달하지 않았다면, 누산기는 첫번째 부른 첫 번째 요소와 동일해요.
-첫 번째 부를 땐, 누산기 (`x`)는 `1` 이에요, 그리고 현재 값인 (`y`)는 `2`예요. 콜백 함수로부터 리턴되지 않았어요, 누산기와 현재 값을 출력해요: `1` 그리고 `2`가 출력돼요.
+첫 번째로 부를 땐, 누산기 (`x`)는 `1` 이에요, 그리고 현재 값인 (`y`)는 `2`예요. 콜백 함수로부터 반환되지 않았고, 누산기와 현재 값을 출력해요: `1` 그리고 `2`가 출력돼요.
-함수에서 값을 리턴하지 않았다면, `undefined`를 리턴해요. 다음번에 부를 때, 누산기는 `undefined`고, 그리고 현재 값은 `3`이에요. `undefined` 그리고 `3`이 출력돼요.
+함수에서 값을 반환하지 않았다면, `undefined`를 반환해요. 다음번에 부를 때, 누산기는 `undefined`고, 그리고 현재 값은 `3`이에요. `undefined` 그리고 `3`이 출력돼요.
-네 번째 부를 땐, 또 콜백 함수에서 리턴받지 않았어요. 누산기는 다시 `undefined`고, 현재 값은 `4`예요. `undefined` 그리고 `4`가 출력돼요.
+네 번째 부를 땐, 또 콜백 함수에서 반환받지 않았어요. 누산기는 다시 `undefined`고, 현재 값은 `4`예요. `undefined` 그리고 `4`가 출력돼요.
-#### 정답: B
+#### 답: B
-이 파생 클래스에서, `super`를 부르기 전에는 `this` 키워드에 접근할 수 없어요. 그렇게 하려고 한다면, 참조에러를 던질 거에요: 1과 4는 참조 에러를 던져요
+파생 클래스에서, `super`를 부르기 전에는 `this` 키워드에 접근할 수 없어요. 그렇게 하려고 한다면, ReferenceError를 던질 거에요: 1과 4는 reference error를 던져요
-`super` 키워드를 가지고, 부모 클래스 생성자에 주어진 인수들을 부를 수 있어요. 부모 생성자는 `name` 인수를 받아요, 그래서 `name`을 `super`로 전달해야 해요.
+`super` 키워드를 가지고, 부모 클래스 생성자에 주어진 인수를 부를 수 있어요. 부모 생성자는 `name` 인수를 받아요, 그래서 `name`을 `super`로 전달해야 해요.
-`Labrador` 클래스는 인수를 2개 받는데, `Dog`로 부터 확장된 `name`과 `Labrador` 클래스의 추가 속성인 `size`예요. 그 두 개는 `Labrador` 생성자 함수에 전달되어야 하는데, 올바르게 사용된 건 2번째 생성자예요.
+`Labrador` 클래스는 2개의 인수를 받는데, `Dog`로 부터 확장된 `name`과 `Labrador` 클래스의 추가 속성인 `size`예요. 그 두 개는 `Labrador` 생성자 함수에 전달되어야 하는데, 올바르게 사용된 건 2번째 생성자예요.
-#### 정답: B
+#### 답: B
`import` 키워드를 사용하면, 모든 import된 modules은 _우선-파싱_ 되어요. import된 모듈은 _처음에_ 실행되는 것을 의미하고, import한 파일 안에 있는 코드는 _나중에_ 실행돼요.
@@ -2121,9 +2148,9 @@ export const sum = (a, b) => a + b;
###### 68. 무엇이 출력 될까요?
```javascript
-console.log(Number(2) === Number(2))
-console.log(Boolean(false) === Boolean(false))
-console.log(Symbol('foo') === Symbol('foo'))
+console.log(Number(2) === Number(2));
+console.log(Boolean(false) === Boolean(false));
+console.log(Symbol('foo') === Symbol('foo'));
```
- A: `true`, `true`, `false`
@@ -2131,12 +2158,12 @@ console.log(Symbol('foo') === Symbol('foo'))
- C: `true`, `false`, `true`
- D: `true`, `true`, `true`
-
-#### 정답: A
+#### 답: A
-모든 심볼은 완전히 유니크해요. 심볼에 전달된 인수의 목적은, 심볼에 설명을 제공하는 거에요. 심볼의 값은 전달된 인수에 따라 달라지지 않아요. 동등성을 테스트할 때, 새로운 심볼 객체를 만들어요: 첫번째 `Symbol('foo')`와 두번째 `Symbol('foo')`. 이 두개의 값들은 유니크하며, 서로 같지 않아요, `Symbol('foo') === Symbol('foo')`는 `false`를 리턴해요.
+모든 심볼은 완전히 유니크해요. 심볼에 전달된 인수의 목적은 심볼에 설명을 제공하는 거에요. 심볼의 값은 전달된 인수에 따라 달라지지 않아요. 동등성을 테스트할 때, 완전히 새로운 두 개의 심볼을 만들어요: 첫번째 `Symbol('foo')`와 두번째 `Symbol('foo')`. 이 두개의 값은 유니크하고, 서로 같지 않아요, `Symbol('foo') === Symbol('foo')`는 `false`를 반환해요.
-#### 정답: C
+#### 답: C
-`padStart` 메소드를 사용하면, 문자열의 시작 부분에 패딩을 추가해 줄 수 있어요. 이 메소드에 전달된 값은 패딩을 포함한 문자열의 _전체_ 길이예요. 문자열 `"Lydia Hallie"`의 길이는 `12`예요. `name.padStart(13)`은 문자열의 시작점에 1 스페이스를 삽입해요, 따라서 12 + 1 은 13이죠.
+`padStart` 메소드를 사용해, 문자열의 시작 부분에 패딩을 추가해 줄 수 있어요. 이 메소드에 전달된 값은 패딩을 포함한 문자열의 _전체_ 길이예요. 문자열 `"Lydia Hallie"`의 길이는 `12`예요. `name.padStart(13)`은 문자열의 시작점에 1 스페이스를 삽입해요, 따라서 12 + 1 은 13이죠.
`padStart` 메소드에 전달된 인수가 배열의 길이보다 작다면, 패딩은 추가되지 않을 거예요.
@@ -2170,23 +2197,23 @@ console.log(name.padStart(2))
---
-###### 70. 무엇이 출력 될까요?
+###### 70. 무엇이 출력 될까요?
```javascript
-console.log("🥑" + "💻");
+console.log('🥑' + '💻');
```
- A: `"🥑💻"`
- B: `257548`
- C: 해당 코드 주소를 포함하는 문자열
-- D: 에러
+- D: 오류
-
-#### 정답: A
+#### 답: A
-`+` 연산자를 가지고, 문자열을 연결 시킬 수 있어요. 이 경우에는, 문자열 `"🥑"`과 문자열 `"💻"`을 연결해, 결과 `"🥑💻"`를 얻었어요.
+`+` 연산자를 사용해, 문자열을 연결 시킬 수 있어요. 이 경우에는, 문자열 `"🥑"`과 문자열 `"💻"`을 연결해, 결과 `"🥑💻"`를 얻었어요.
-#### 정답: C
+#### 답: C
제너레이터 함수는 `yield` 키워드를 보면 실행을 "멈춰"요. 첫 번째로, `game.next().value`를 불러, 함수가 "Do you love JavaScript?" 문자열을 넘겨주도록 할 수 있어요.
-`yield` 키워드를 처음으로 찾기 전까지, 모든 줄이 실행되요. 첫 번째 줄에 있는 함수는 `yield` 키워드를 가지고 있어요: 첫 번째 yield으로 실행을 멈춰요! _이것은 `answer` 변수가 아직 정의되지 않았는 뜻이에요_
+`yield` 키워드를 처음으로 찾기 전까지, 모든 줄이 실행되요. 함수 안 첫 번째 줄에 `yield` 키워드가 있어요: 첫 번째 yield으로 실행을 멈춰요! _이것은 `answer` 변수가 아직 정의되지 않았는 뜻이에요!_
-`game.next("Yes").value`을 부를때, `"Yes"`의 경우에서 이전 `yield`는 `next()` 함수가 전달한 파라미터의 값으로 대체돼요. `answer` 변수의 값은 이제 `"Yes"`에요. if문의 조건은 `false`를 리턴해, `JavaScript loves you back ❤️`를 출력돼요
+`game.next("Yes").value`을 부를 때, 이전 `yield`는 `next()` 함수가 전달한 파라미터의 값으로 대체 되는데, 이 경우에는 `"Yes"`로 대체 돼요. `answer` 변수의 값은 이제 `"Yes"`예요. if문의 조건은 `false`를 반환해, `JavaScript loves you back ❤️`이 출력돼요.
-#### 정답: C
+#### 답: C
-`String.raw`는 escapes (`\n`, `\v`, `\t` 등.)에서의 문자열을 무시해요! 백슬래시는 다음과 같이 끝나면 문제가 될 수 있어요
+`String.raw`는 escapes(`\n`, `\v`, `\t` 등.)가 무시되는 문자열을 반환해요! 백슬래시는 다음과 같이 끝나면 문제가 될 수 있어요:
-``console.log(`C:\Documents\Projects\table.html`)``
+`` const path = `C:\Documents\Projects\table.html` ``
이렇게 될 거예요:
-`C:DocumentsProjects able.html`
+`"C:DocumentsProjects able.html"`
`String.raw`을 사용하면, 간단하게 escape를 무시하고 출력해요:
`C:\Documents\Projects\table.html`
-이 경우, 문자열은 `Hello\nworld`이 출력되요.
+이 경우, 문자열 `Hello\nworld`이 출력되요.
-#### 정답: C
+#### 답: C
-async 함수는 항상 promise를 리턴해요. `await`는 promise가 resolve 할 때까지 기다려야 해요: pending promise는 `data`를 설정하기 위해 부른 `getData()`가 리턴한 것을 가져요.
+async 함수는 항상 promise를 반환해요. `await`는 promise가 resolve 할 때까지 기다려야 해요: pending promise는 `data`를 설정하기 위해 부른 `getData()`가 반환한 것을 가져요.
resolve된 값 `"I made it"`에 접근하고 싶다면, `data`에 `.then()` 메소드를 사용해야해요.
@@ -2306,7 +2333,7 @@ function addToList(item, list) {
return list.push(item);
}
-const result = addToList("apple", ["banana"]);
+const result = addToList('apple', ['banana']);
console.log(result);
```
@@ -2315,14 +2342,14 @@ console.log(result);
- C: `true`
- D: `undefined`
-
-#### 정답: B
+#### 답: B
-`.push()`메소드는 새로운 배열의 _길이_ 를 리턴해요! 이전에, 배열은 한 개의 요소(문자열 `"banana"`)를 포함되어있고 길이는 `1`예요. 배열에 문자열 `"apple"`을 추가한 후, 배열은 두 개 요소를 포함하고, 그리고 길이 `2`를 가져요. `addToList` 함수로부터 리턴돼요.
+`.push()`메소드는 새로운 배열의 _길이_ 를 반환해요! 이전에, 배열은 한 개의 요소(문자열 `"banana"`)를 포함하고 길이는 `1`예요. 배열에 문자열 `"apple"`을 추가한 후, 배열은 두 개 요소를 포함하고, 길이 `2`를 가져요. `addToList` 함수로부터 반환 받은거예요.
-`push` 메소드는 원본 배열을 수정해요. 만약 함수로부터 _배열의 길이_ 대신에 _배열_ 을 리턴하고 싶다면, `item`을 푸시한 후 `list`를 리턴해야해요.
+`push` 메소드는 원본 배열을 수정해요. 만약 함수로부터 _배열의 길이_ 대신에 _배열_ 을 반환하고 싶다면, `item`을 푸시한 후 `list`를 반환해야해요.
-#### 정답: B
+#### 답: B
-`Object.freeze`는 객체의 속성들을 추가, 삭제 혹은 수정하는 걸 불가능하게 만들어요(다른 객체로서의 속성들의 값이 아닌 한).
+`Object.freeze`는 객체의 속성을 추가, 삭제 혹은 수정하지 못하게 만들어요(다른 객체 속성의 값이 아닌 한).
-변수 `shape`을 생성할 때, 동결 객체 `box`와 동일하게 설정했고, `shape` 역시 동결 객체를 참조해요. `Object.isFrozen`을 사용해 객체의 동결 여부를 확인할 수 있어요. 이 경우, `Object.isFrozen(shape)`은 참을 리턴하고, 따라서 변수 `shape`는 동결 객체 참조를 가져요.
+변수 `shape`을 생성할 때, 동결 객체 `box`와 동일하게 설정했고, `shape` 역시 동결 객체를 참조해요. `Object.isFrozen`을 사용해 객체의 동결 여부를 확인할 수 있어요. 이 경우, `Object.isFrozen(shape)`은 true를 반환하고, 따라서 변수 `shape`는 동결 객체 참조를 가져요.
`shape`가 동결 상태이므로, `x`의 값은 객체가 아니며, `x`의 속성을 수정할 수 없어요. `x`는 여전히 `10`이고, `{ x: 10, y: 20 }`가 출력돼요.
@@ -2366,7 +2393,7 @@ console.log(shape);
###### 76. 무엇이 출력 될까요?
```javascript
-const { name: myName } = { name: "Lydia" };
+const { name: myName } = { name: 'Lydia' };
console.log(name);
```
@@ -2376,23 +2403,23 @@ console.log(name);
- C: `undefined`
- D: `ReferenceError`
-
-#### 정답: D
+#### 답: D
-오른쪽에 있는 객체로부터 속성 `name`을 unpack할 때, `myName`라는 이름을 가진 변수에 값 `"Lydia"`을 할당해요.
+오른쪽에 있는 객체로부터 속성 `name`을 분해할 때, `myName`라는 이름을 가진 변수에 값 `"Lydia"`을 할당해요.
-`{ name: myName }`은, JavaScript에게 오른쪽에 있는 `name`속성 값을 가진 `myName`이라고 불리는 새로운 변수를 만든다고 말하는 거예요.
+`{ name: myName }`은, JavaScript에게 오른쪽에 있는 `name`속성의 값을 가진 `myName`이라고 불리는 새로운 변수를 만든다고 말하는 거예요.
-`name`을 출력하려고 하면, 변수는 정의되지 않아, ReferenceError를 던질거예요.
+`name`을 출력하려고 하면, 변수는 정의되지 않아 ReferenceError를 던질거예요.
-#### 정답: A
+#### 답: A
-pure 함수는 _항상_ 같은 결과를 리턴하는 함수예요, 만약 같은 인수가 전달 된다면 말이죠.
+순수 함수는 _항상_ 같은 결과를 반환하는 함수예요, 만약 같은 인수가 전달 된다면 말이죠.
-`sum` 함수는 항상 같은 결과를 리턴해요. 만약 `1`과 `2`를 전달하면, _항상_ 부작용 없이 `3`을 리턴할 거예요. `5`와 `10`을 전달하면, _항상_ `15`를 리턴할 거예요. 이게 pure 함수의 정의예요.
+`sum` 함수는 항상 같은 결과를 반환해요. 만약 `1`과 `2`를 전달하면, 부작용 없이 _항상_ `3`을 반환할 거예요. `5`와 `10`을 전달하면, _항상_ `15`를 반환할 거예요. 이게 순수 함수의 정의예요.
+
+#### 답: C
+
+`add`함수는 _memoized_ 함수예요. memoization 사용하면, 함수 실행 속도를 높이기 위해 함수의 결과를 캐시할 수 있어요. 이 경우, 이전에 반환된 값을 저장한 `cache` 객체를 만들어요.
+
+같은 인수로 `addFunction` 함수를 다시 부르면, 우선 cache 안에 값을 갖고 있는지 확인해요. 만약 그렇다면, 캐시값이 반환되어 실행시간이 절약돼요. 캐시되지 않았다면, 값을 계산하고 나중에 저장해요.
+
+같은 값으로 `addFunction`함수를 세 번 불러요: 첫 번째 호출 때에는, `num`가 `10`일 때 함수의 값은 아직 저장되지 않았어요. if문의 조건 `num in cache` 은 `false`을 반환하고, else 블록이 실행돼요: `Calculated! 20`을 출력하고, 결과 값은 cache 객체에 추가돼요. `cache`는 이제 `{ 10: 20 }` 처럼 보여요.
+
+두 번째엔, `cache`객체는 `10`을 위해 반환될 값을 포함하고 있어요. if문의 조건 `num in cache`은 `true`를 반환하고, `'From cache! 20'`이 출력돼요.
+
+세 번째에는, `5 * 2`을 `10`으로 평가해 함수에 전달해요. `cache` 객체는 `10`을 위해 반환될 값을 포함하고 있어요. if문의 조건 `num in cache`은 `true`를 반환하고, `'From cache! 20'`이 출력돼요.
+
+
+
+#### 답: A
+
+_for-in_ 루프에서는, **열거 가능한** 속성에 대해 반복 할 수 있어요. 배열에서, 열거 가능한 속성은 배열 요소의 "키"이고, 사실 그들의 인덱스예요. 배열은 다음과 같이 볼 수 있어요:
+
+`{0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}`
+
+여기서 키는 열거 가능한 속성이에요. `0` `1` `2` `3`이 출력되요.
+
+_for-of_ 루프에서는, **반복 가능한** 속성을 가진 요소에 대해 반복 할 수 있어요. 배열은 반복 가능해요. 배열을 반복할 때, "item" 변수는 현재 반복중인 요소와 같고, `"☕"` ` "💻"` `"🍷"` `"🍫"`이 출력돼요.
+
+
+
+#### 답: C
+
+배열 요소은 모든 값을 가질 수 있어요. 숫자, 문자, 객체, 다른 배열, null, 불리언 값, undefined, 그리고 날짜, 함수, 연산자와 같은 표현식
+
+요소는 반환된 값과 같아질 거예요. `1 + 2`는 `3`을 반환하고, `1 * 2`는 `2`를 반환하고, `1 / 2` 는 `0.5`을 반환해요.
+
+
+
+#### 답: B
+
+기본적으로, 인수는 함수에 값이 전달되지 않으면 `undefined` 값을 가져요. 이 경우, `name` 인수를 위한 값을 전달하지 않았어요. `name`은 `undefined`로 출력돼요.
+
+ES6에서, 기본값 `undefined` 값을 기본값 매개변수로 덮어쓸 수 있어요. 예를 들면:
+
+`function sayHi(name = "Lydia") { ... }`
+
+이 경우, 값을 전달하지 않거나 `undefined`를 전달하면, `name`은 항상 문자열 `Lydia`가 될 거예요.
+
+
+
+#### 답: B
+
+`this`키워드의 값은 사용하는 곳에 따라 달라요. `getStatus`메소드 같은 **메소드**에서 `this`키워드는 _메소드가 속한 객체_ 를 참조해요. 이 메소드는 `data` 객체에 속해 있어, `this`는 `data`객체를 참조해요. `this.status`를 출력할 때, `data`객체의 `status` 속성 `"🥑"`이 출력돼요.
+
+`call` 메소드를 사용해, `this` 키워드가 참조하는 객체를 바꿀 수 있어요. **함수**에서, `this` 키워드는 _함수가 속한 객체_ 를 참조해요. `setTimeout` 함수를 _전역 객체_ 에 선언했어요, 따라서 `setTimeout` 함수 안에서 `this`키워드는 _전역 객체_ 를 참조해요. 전역 객체에는 `"😎"`값을 가진 _status_ 라는 변수가 있어요. `this.status`를 출력하면, `"😎"`이 출력돼요.
+
+
+
+#### 답: A
+
+`city` 변수를 `person` 객체의 `city`라고 불리는 속성 값으로 설정 했어요. 이 객체에서는 `city`라고 불리는 속성이 없기 때문에, 변수 `city`는 값 `undefined`를 가져요.
+
+`person`객체 자체를 참조 _하지않는다_ 는 걸 참고해요! 변수 `city`는 `person` 객체의 `city` 속성의 현재 값으로 설정 했을 뿐이에요.
+
+그 뒤, 우리는 `city`를 문자열 `"Amsterdam"`로 설정 했어요. 이건 person 객체를 바꾸지 않아요: 여기서 객체를 참조하는 건 없어요.
+
+`person`객체를 출력할 때, 수정되지 않은 객체를 반환 받아요.
+
+
+
+#### 답: C
+
+`const`와 `let` 키워드를 사용한 변수는 _블록-스코프_ 예요. 블록은 중괄호 (`{ }`) 사이에 있는 모든 것이에요. 이 경우, if/else 표현식의 중괄호를 의미해요. 변수가 선언된 블록 외부에서 참조할 수 없어요, ReferenceError를 던져요.
+
+
+
+#### 답: C
+
+두번째 `.then`에서의 `res`의 값은 이전`.then`에서 반환된 값이에요. 이것 처럼 `.then`을 계속해서 연결할 수 있고, 값은 계속해서 다음 핸들러로 전달 돼요.
+
+
+
+#### 답: A
+
+`!!name`에서, 우리는 `name`의 값이 참 같은지 거짓 같은지 여부를 결정해요. 만약 시험 하려는 name이 참 같다면, `!name`은 `false`를 반환해요. `!false`(실제로는 `!!name`)는 `true`를 반환해요.
+
+`hasName`을 `name`으로 설정하면, `hasName`은 불린 값 `true`가 아니라, `getName` 함수에 전달된 값으로 설정해요.
+
+`new Boolean(true)`은 불린 값 자체가 아닌, 감싼 객체를 반환해요.
+
+`name.length`은 그것의 `true`의 여부가 아닌, 전달된 인수의 길이를 반환해요.
+
+
+
+#### 답: B
+
+문자열의 특정 인덱스의 문자를 얻으려면, 대괄호 표기법을 사용하면 돼요. 문자열의 첫 번째 문자는 인덱스 0과 기타등등을 가지고 있어요. 이 경우엔 인덱스가 0이고 문자 `"I'`가 출력되는 요소를 갖길 원해요.
+
+이 방법은 IE7 이하에서는 지원되지 않는다는 것을 유의하세요. 이 경우, `.charAt()`를 사용하세요.
+
+
+
+#### 답: B
+
+기본값 매개변수를 이전에 정의한 함수의 다른 매개변수로 설정 할 수 있어요. 우리는 `sum` 함수에 값 `10`을 전달했어요. 만약 `sum` 함수에 인수의 값을 하나만 받았다면, `num2`의 값은 전달되지 않았고, `num1`은 전달된 값 `10`과 같다는 의미에요. `num2`의 기본값은 `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
+#### 답: C
-`add`함수는 _memoization_ 함수예요. memoization으로, 함수 실행 속도를 높이기 위해 함수의 결과를 캐시에 저장할 수 있어요. 이 경우, 이전에 리턴된 값을 저장한 `cache` 객체를 만들어요.
+Class는 함수 생성자를 위한 문법적 설탕이에요. 함수 생성자로서 `Person` 클래스와 동등한 것은 다음과 같아요:
-같은 인수로 `addFunction` 함수를 다시 부르면, 우선 cache 안에 값을 갖고 있는지 확인해요. 만약 그렇다면, 캐시에 저장된 값이 리턴되어, 실행시간이 절약돼요. 캐시에 저장되지 않았다면, 값을 계산하고 나중에 저장해요.
+```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`은 rest 파라미터예요. rest 파라미터의 값은 모든 나머지 인수을 포함한 배열이며, **마지막 파라미터만 될 수 있어요**! 지금 예시에서는, rest 파라미터는 두번째 파라미터예요. 이것은 불가능하고, syntax error를 던지게 될거에요.
+
+```javascript
+function getItems(fruitList, favoriteFruit, ...args) {
+ return [...fruitList, ...args, favoriteFruit];
+}
+
+getItems(['banana', 'apple'], 'pear', 'orange');
+```
+
+위의 예시는 동작해요. 배열 `[ 'banana', 'apple', 'orange', 'pear' ]`을 반환해요.
+
+
+
+#### 답: B
+
+JavaScript에서, 세미콜론을 (`;`)을 명시적으로 _포함하여_ 쓰지 않더라도, JavaScript 엔진은 여전히 문 뒤에 그들을 추가해요. 이것은 **자동 세미콜론 삽입**이라고 불려요. 예를 들어 문은 변수, 또는 `throw`, `return`, `break` 등과 같은 키워드가 될 수도 있어요.
+
+여기, `return`문을 썼고, 다른 값 `a + b`은 _새로운 줄_ 에 쓰였어요. 그러나, 새로운 줄이기 때문에, 엔진은 실제로 그 값이 반환되길 바라는지 알 수 없어요. 대신에, 자동적으로 `return` 뒤에 세미콜론을 더해요. 이것을 볼 수 있을거에요:
+
+```javascript
+return;
+a + b;
+```
+
+`return` 키워드 뒤에 함수가 실행되는 것이 중단되기 때문에, `a + b`의 의미는 도달되지 않아요. 여기서처럼, 만약 아무 값도 반환되지 않는다면 함수는 `undefined`를 반환해요. `if/else`문 뒤에는 아무것도 자동으로 삽입되지 않는다는 걸 유의해요!
+
+
+
+#### 답: B
+
+클래스를 다른 클래스/함수 생성자로 설정할 수 있어요. 이 경우, `Person`을 `AnotherPerson`로 설정했어요. 이 생성자의 name은 `Sarah`예요, 따라서 새로운 `Person`의 인스턴스 `member`의 name 속성은 `"Sarah"`예요.
+
+
+
+#### 답: D
+
+심볼은 _열거 불가능_ 해요. Object.keys 메소드는 객체의 모든 _열거 가능_ 한 키 속성을 반환해요. 심볼은 보이지 않고, 빈 객체가 반환돼요. 객체 전체를 출력하면, 심지어 열거 불가능한 것이라도 모든 속성을 볼 수 있어요.
+
+이것은 심볼의 많은 특성 중 하나에요: 완전히 고유한 값(예를 들어 작업중인 2개의 라이브러리를 같은 객체의 속성으로 추가하고 싶을 때, 객체의 우연한 이름 충돌을 방지해요)을 나타내는 것 외에, 이 방법으로 객체의 속성을 "숨길" 수 있어요(비록 완전히는 아닐지라도. 여전히 `Object.getOwnPropertySymbols()` 메소드를 사용해 심볼에 접근 할 수 있어요).
+
+
+
+#### 답: A
+
+`getList`함수는 배열을 인수로 받았어요. `getList` 함수의 괄호 사이에 있는 배열을 즉시 분해 했어요:
+
+`[x, ...y] = [1, 2, 3, 4]`
+
+rest 파라미터를 사용해 `...y`에 모든 "남은" 인수을 배열에 넣었어요. 이 경우에서 남아있는 인수는 `2`, `3` 그리고 `4`예요. `y`의 값은 배열이고, 모든 rest 파라미터를 포함하고 있어요. 이 경우 `x`의 값은 `1`이기 때문에, `[x, y]`는 `[1, [2, 3, 4]]`로 출력돼요.
+
+`getUser` 함수는 객체를 받았어요. 화살표 함수에서, 우리가 한개의 값을 반환한다면 중괄호를 사용할 _필요_ 가 없어요. 그러나, 만약 화살표 함수에서 _객체_ 를 반환하고 싶다면, 괄호 사이에 반환할 값을 써야해요, 그렇지 않다면 아무 값도 반환받을 수 없어요! 다음 함수에서는 객체가 반환 될 거에요:
+
+`const getUser = user => ({ name: user.name, age: user.age })`
+
+이 경우 값이 반환되는 값이 없으므로, 함수는 `undefined`을 반환해요.
+
+
+
+#### 답: C
+
+변수 `name`은 문자열을 값으로 가지고 있고, 함수가 아니에요, 따라서 호출할 수 없어요.
+
+TypeErrors는 값이 예상된 유형이 아닐 경우 던져져요. JavaScript는 `name`을 호출하려고 했기 때문에 함수일거라 예상했어요. 그러나 문자열이였기 때문에, TypeError가 던져져요: name은 함수가 아니에요!
+
+SyntaxErrors는 어떤 것을 썼을때 JavaScript에서 유효하지 않을 때 던져져요, 예를들어 `return`을 `retrun`로 썼을때 말이죠.
+ReferenceErrors는 JavaScript가 접근하려고 하는 값의 참조를 찾을 수 없을 때 던져져요.
+
+
+
+#### 답: B
+
+`[]`은 참 같은 값이에요. `&&` 연산자를 사용할 때, 왼쪽에 있는 값이 참 같은 값이라면 오른쪽 값은 반환될 거에요. 이 경우, 왼쪽의 값 `[]`은 참 같은 값이에요, 따라서 `'Im'`은 반환될 거예요.
+
+`""`은 거짓 같은 값이에요. 만약 왼쪽 값이 거짓 같은 값이라면, 반환되는 것은 없어요. `n't`은 반환되지 않아요.
+
+
+
+#### 답: C
+
+`||` 연산자를 사용하면, 첫번째로 참 같은 피연산자를 반환해요. 만약 모든 값이 거짓 같다면, 마지막 피연산자를 반환해요.
+
+`(false || {} || null)`: 빈 객체 `{}`는 진짜 같은 값이에요. 이것은 최초로(그리고 유일하게) 진짜 같은 값이라 반환돼요. `one`은 `{}`이에요.
+
+`(null || false || "")`: 모든 피연산자는 가짜 같은 값이에요. 이것은 마지막 피연산자 `""`가 반환된다는 것을 의미해요. `two`는 `""`이에요.
+
+`([] || 0 || "")`: 빈 배열 `[]`은 진짜 같은 값이에요. 이것은 첫번째로 진짜 같은 값이라 반환돼요. `three`은 `[]`이에요.
+
+
+
+#### 답: 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`을 resolve 할 때 까지 기다린다는 뜻이고, 단 한 번만 발생한 뒤, 다음라인으로 이동해요: `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를 반환해요 (`
+
+#### 답: 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` 는 감소된 값을 반환해요.
+
+
+
+#### 답: A
+
+`info` 객체의 `favoriteFood` 속성 값을 피자 이모지 `'🍕'`으로 설정했어요. 문자는 원시 데이터 형이에요. JavaScript에서 원시 데이터 형은 참조로 상호 작용 하지 않아요.
+
+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 값으로 생성해요.
+
+```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`를 던져요.
+
+`getName` 함수 안에 `name` 변수를 선언하지 않았다면, javaScript 엔진은 _스코프 체인_ 을 살펴봤을 거예요. 외부 범위에는 값이 `Lydia`인 `name`이라는 변수가 있어요. 이 경우 `Lydia`를 출력할 거예요.
+
+```javascript
+let name = 'Lydia';
+
+function getName() {
+ console.log(name);
+}
+
+getName(); // Lydia
+```
+
+
+
+#### 답: C
+
+`yield` 키워드를 사용해, 제너레이터 함수 안의 값을 `yield` 해요. `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` 객체를 참조 하고 있어요
+참조가 존재하는 한, 객체는 쓰레기 수집 되지 않아요.
+이것은 interval이므로, `config`를 `null` 또는 `delete`-ing `config.alert`로 설정하면 interval이 쓰레기 수집되지 않아, interval은 계속 호출됩니다
+메모리에서 제거하기 위해서 `clearInterval(config.alert)`로 지워야 합니다.
+지워지지 않았기 때문에, `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 }`와 같아요.
+
+
+
+#### 답: C
+
+연산자 `...`를 사용하면, 반복 가능한 객체를 개별요소로 _spread_ 펼칠 수 있어요. `sumValues` 함수는 인수 3개를 받았어요: `x`, `y` 그리고 `z`. `...[1, 2, 3]`를 `sumValues` 함수에 전달하면 `1, 2, 3` 가 될 거예요.
+
+
+
+#### 답: B
+
+`+=` 연산자를 사용하면, `num`의 값을 `1` 씩 증가시켜요. `num`은 초기값 `1`을 가지고 있어요, 그래서 `1 + 1` 은 `2`예요.`list` 배열의 2번째 인덱스 아이템은 🥰 예요, `console.log(list[2])` 는 🥰 을 출력해요.
+
+
+
+#### 답: B
+
+optional chaining 연산자 `?.`를 사용하면, 더 깊이 중첩된 값이 유효한지 여부를 더는 분명하게 확인하지 않아도 돼요.`undefined` 또는 `null` 값 (_nullish_) 속성에 접근 하려고 할 때, 표현식을 평가하지 않고 `undefined`을 반환해요.
+
+`person.pet?.name`: `person`은 속성이름 `pet`을 가지고 있어요: `person.pet`은 nullish(null 또는 undefined)가 아니에요. `name`이라는 속성 이름을 가지고 있어, `Mara`를 반환해요.
+`person.pet?.family?.name`: `person`은 속성이름 `pet`을 가지고 있어요: `person.pet`은 nullish가 아니에요. `pet`은 _not_ have a property called `family`라는 속성이 _없어요_, `person.pet.family`은 nullish예요. 표현식은 `undefined`을 반환해요.
+`person.getFullName?.()`: `person`은 속성이름`getFullName`을 가지고 있어요: `person.getFullName()` 은 nullish기 아니고 호출 할 수 있어요, 따라서 `Lydia Hallie`을 반환해요.
+`member.getLastName?.()`: `member`은 정의되지 않았어요: `member.getLastName()`은 nullish예요. 표현식은 `undefined`을 반환해요.
+
+
+
+#### 답: B
+
+if문에 조건 `groceries.indexOf("banana")`을 전달했어요. `groceries.indexOf("banana")`은 `0`을 반환하고, 이건 거짓 같은 값이에요. if문의 조건이 거짓 같은 값이기 때문에, 코드는 `else` 블록을 실행하고, `We don't have to buy bananas!`이 출력돼요.
+
+
+
+#### 답: D
+
+`language` 메소드는 `setter`예요. Setters는 실제 값을 유지하지 않아요, 그들의 목적은 속성을 _수정_ 하는 거예요. `setter` 메소드를 부르면, `undefined`가 반환돼요.
+
+
+
+#### 답: C
+
+`typeof name`은 `"string"`을 반환해요. 문자열 `"string"`은 진짜 같은 값이고, `!typeof name`은 불리언 값 `false`을 반환해요. `false === "object"` 그리고 `false === "string"` 둘다 `false`을 반환해요.
+
+(특정한 형과 같은지(다른지) 알고 싶다면, `!typeof` 대신 `!==`을 사용 해야 해요.)
+
+
+
+#### 답: A
+
+`add`함수는 화살표 함수를 반환하는 함수를 반환하고, 반환한 함수는 화살표 함수를 반환하고, 반환한 함수는 화살표 함수를 반환해요(아직 나와 함께인가요?). 첫 번째 함수는 값이 `4`인 인수 `x`를 받아요. 값이 `5`인 인수 `y`를 받은 두 번째 함수를 호출해요. 그리고 우리는 값이 `6`인 인수 `z`를 받은 세 번째 함수를 호출해요. 값 `x`, `y` 그리고 `z`를 가진 마지막 화살표 함수에 접근하려고 할 때, JS 엔진은 그에 따른 값 `x` 그리고 `y`를 찾기 위해 스코프 체인을 올라가요. 이건 `4` `5` `6`을 반환해요.
+
+
+
+#### 답: C
+
+제너레이터 함수 `range`은 range에 전달한 각각의 아이템에 promise를 가진 async 객체를 반환해요: `Promise{1}`, `Promise{2}`, `Promise{3}`. 변수 `gen`을 async 객체로 만들고, 그후에 `for await ... of` 루프를 사용해서 순환해요. 변수 `item`은 반환된 Promise 값 만들어요: 첫번째는 `Promise{1}`, 그다음은 `Promise{2}`, 그다음은 `Promise{3}`. `item`의 값인 프로미스를 resolved 하기 위해 _기다리고_, resolved 된 프로미스의 _값_ 은 반환돼요: `1`, `2`, 그리고 `3`.
+
+
+
+#### 답: D
+
+`myFunc`는 속성 `x`, `y` 그리고 `z`를 속성으로 가진 객체가 인수라고 예상해요. `x`, `y` 그리고 `z`의 속성을 가진 하나의 객체({x: 1, y: 2, z: 3}) 대신, 분리된 숫자 값 (1, 2, 3)을 전달했기 때문에 `x`, `y` 그리고 `z`는 기본값 `undefined`을 가져요.
+
+
+
+#### 답: B
+
+`Intl.NumberFormat` 메소드를 사용하면, 숫자 값을 원하는 로케일로 만들 수 있어요. 숫자 값 `130`을 `unit`이 `mile-per-hour`인 로케일 `en-US`로 만들면, `130 mph`가 돼요. 숫자 값 `300`을 `currency`가 `USD`인 로케일 `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` 메소드를 사용하면, 전달한 값이 숫자가 아닌지 확인할 수 있어요. `name`은 숫자가 아니에요, 따라서 `isNaN(name)`은 true를 반환해요. `age`은 숫자이고, 따라서 `isNaN(age)`은 `false`을 반환해요.
+
+
+
+#### 답: D
+
+`const` 키워드를 사용해 선언된 변수는 초기화 되기 전에 참조 할 수 없어요: 이건 _일시적 사각지대_ 라고 불려요. `getInfo`힘수에서, 변수 `randomValue`는 함수 `getInfo`의 스코프 안에 있어요. `typeof randomValue`의 값을 출력하고 싶은 줄에서, 변수 `randomValue`는 아직 초기화 되지 않았어요: `ReferenceError`가 던져져요! 변수 `randomValue`를 함수 `getInfo`안에 선언했기 때문에 엔진은 스코프 체인 아래로 내려가지 않아요.
+
+
+
+#### 답: C
+
+`try` 블록에서, `myPromise`의 awaited 값을 출력하고 있어요: `"Woah some cool data"`. `try` 블록에서 오류가 없기 때문에, `catch` 블록 안의 코드는 실행되지 않아요. `finally` 블록 안의 코드는 _항상_ 실행되고, `"Oh finally!"`가 출력돼요.
+
+
+
+#### 답: B
+
+`flat`를 사용하면, 새로운 평평한 배열을 만들어요. 평평한 배열의 깊이는 전달한 값에 달려있어요. 이 경우, 값 `1`(기본 값)을 전달했고,, 1번째 깊이에 있는 배열만 연결된다는 뜻이에요. 이 경우에선 `['🥑']` 그리고 `['✨', '✨', ['🍕', '🍕']]`. 두 배열을 연결하면 `['🥑', '✨', '✨', ['🍕', '🍕']]`가 돼요.
+
+
+
+#### 답: D
+
+`counterOne`는 클래스 `Counter`의 인스턴스예요. counter 클래스는 생성자 안에 속성 `count`와 `increment` 메소드를 포함해요. 우선, `counterOne.increment()`를 사용해 `increment` 메소드를 두 번 호출해요. 현재, `counterOne.count`는 `2`예요.
+
+
+
+#### 답: D
+
+우선, `funcOne`를 호출했어요. `funcOne`의 첫 번째 줄에서, _비동기_ 작업 `myPromise` 프로미스를 불러요. 엔진이 프로미스를 처리하느라고 바쁜 와중에도, 계속해서 `funcOne` 함수를 실행해요. 다음 줄은 _비동기_ `setTimeout` 함수이고, 콜백을 Web API로 보내요. (내가 작성한 이벤트 루프에 대한 글 보기 여기.)
+
+프라미스와 타임아웃 모두 비동기 작업이고, 함수는 프라미스 함수와 `setTimeout` 콜백을 처리하느라고 바쁜 와중에도 계속해서 실행해요. 이건 비동기 작업이 아닌 `Last line!`가 첫 번째로 출력된다는 걸 의미해요. 이건 `funcOne` 함수의 마지막 줄에 있고, 프라미스가 resolved 되어, `Promise!`가 출력돼요. 그러나, `funcTwo()`를 호출 했기 때문에, 콜 스택은 비어있지 않고, `setTimeout` 콜백 함수는 아직 콜 스택에 추가할 수 없어요.
+
+`funcTwo`에서, 우선 myPromise 프라미스를 _기다려요_. `await`키워드를 사용해서, 프라미스가 resolved (or rejected) 될 때까지 함수의 실행을 멈췄어요. 그리고서, `res`의 값을 기다렸다가 출력해요. (프라미스 자체가 프라미스를 반환하기 때문에). 이건 `Promise!`을 출력해요.
+
+다음 줄은 _비동기_ `setTimeout` 함수로, 콜백을 Web API로 보내요.
+
+`funcTwo`의 마지막 줄에서, `Last line!`가 콘솔에 출력돼요. 지금, `funcTwo`가 콜 스택에서 제거되었기 때문에, 콜 스택은 비어있어요. 대기열에서 대기 중인 콜백은(`funcOne`에서의 (`() => console.log("Timeout!")`, 그리고 `funcTwo`에서의 `() => console.log("Timeout!")`) 호출 스택에 하나씩 추가되어요. 첫 번째 콜백은 `Timeout!`을 출력하고, 스택에서 제거돼요. 그리고서, 두 번째 콜백은 `Timeout!`을 출력하고, 스택에서 제거돼요. 이건 `Last line! Promise! Promise! Last line! Timeout! Timeout!`을 출력해요.
+
+
+
+#### 답: C
+
+별표 `*`를 사용하면, 파일에서 내보낸 모든 값(기본값과 명명된 것 모두)을 가져와요. 만약 다음 파일을 가지고 있다면:
+
+```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);
+```
+
+아래와 같이 출력될 거예요:
+
+```javascript
+{
+ default: "I love JavaScript",
+ name: "Lydia",
+ age: 21
+}
+```
+
+`sum`을 예로 들자면, 가져온 `sum`의 값은 다음처럼 보인다는 의미에요:
+
+```javascript
+{ default: function sum(x) { return x + x } }
+```
+
+`sum.default`을 불러 함수를 호출 할 수 있어요.
+
+
+
+#### 답: C
+
+Proxy 객체를 사용하면, 두번째 인수로 전달 한 객체에 사용자 지정 동작을 추가 할 수 있어요. 이 경우엔, 두 개의 속성을 가진 `handler` 객체를 전달 했어요: `set` 과 `get` 속성 값을 _설정_ 할 때마다 `set`은 호출되고, `get`은 속성 값을 _얻을_ (접근)때 마다 호출되어요.
+
+첫 번째 인수는 빈 객체 `{}`고, `person`의 값이에요. 이 객체에 객체 `handler`의 사용자 지정 동작을 추가했어요. `person` 객체에 속성을 추가하면, `set` 이 호출 돼요. `person` 객체의 속성에 접근하면, `get` 이 호출 돼요.
+
+우선, 프록시 객체에 새로운 속성 `name`을 추가했어요(`person.name = "Lydia"`). `set`이 호출되고, `"Added a new property!"`을 출력 해요.
+
+그리고서, 프록시 객체의 속성 값에 접근하고, handler 객체의 속성 `get` 이 호출 돼요. `"Accessed a property!"`을 출력 해요.
+
+
+
+#### 답: A
+
+`Object.seal`을 사용하면, 새로운 속성이 _추가_ 되거나, 혹은 존재하는 속성이 _제거_ 되는 것을 막을 수 있어요.
+
+그러나, 여전히 존재하는 속성의 값을 수정 할 수 있어요.
+
+
+
+#### 답: C
+
+`Object.freeze` 메소드는 객체를 _얼려요_ . 속성을 추가, 수정, 제거 할 수 없어요.
+
+하지만, 객체를 _얕은_ 수준으로만 얼리고, 이건 객체의 _직접적인_ 속성만 얼려진다는 의미예요. 속성이 `address` 와 같은 객체인 경우, 객체의 속성은 얼려지지 않고, 수정될 수 있어요.
+
+
+
+#### 답: A
+
+우선, `myFunc()` 를 어떤 인수도 전달하지 않고 호출했어요. 인수를 전달하지 않았기 때문에, `num` 와 `value` 는 그들의 기본값을 가져요: num 는 `2`, `value` 함수 `add`에서 반환된 값. `add` 함수에서, 값이 `2`인 `num`를 인수로 전달했어요. `add`는 `value`의 값인 `4`를 반환해요.
+
+그리고서, `myFunc(3)`를 호출하고 인수 `num`의 값으로 값 `3`을 전달했어요. `value` 값은 전달하지 않았어요. 인수 `value`에 값을 전달하지 않았기 때문에, 기본값을 가져요: 함수 `add`에서 반환된 값. `add`에서, 값 `3`을 가진 `num`을 전달해요. `add`는 `value`의 값으로 `6`을 반환해요.
+
+
+
+#### 답: D
+
+ES2020에서, `#`을 사용한 private 변수를 추가 할 수 있어요. 클래스 외부에서 private 변수에 접근 할 수 없어요. `counter.#number`을 출력하려고 할 때, SyntaxError가 던져져요: `Counter` 클래스 외부에서 private 변수에 접근 할 수 없어요!
+
+
+
+#### 답: B
+
+`teams` 배열의 `members`의 각 요소를 계속해서 반복하기 위해선, `teams[i].members`를 제너레이터 함수 `getMembers`에 전달해야해요. 제너레이터 함수는 제너리에터 객체를 리턴해요. 제너레이터 객체의 각 요소를 계속해서 반복 하기 위해선, `yield*`를 사용해야 해요.
+
+`yield`, `return yield` 또는 `return`를 쓰면, 모든 제너레이터 함수는 첫번째로 호출한 `next` 메소드가 반환한 값을 가져요.
+
+
+
+#### 답: C
+
+`addHobby` 함수는 인수 두 개 `hobby` 와 `person` 객체의 배열 `hobbies`의 값을 기본값으로 가진 `hobbies`를 받아요.
+
+우선, `addHobby` 함수를 호출하고, `hobby`의 값으로 `"running"`을 그리고 `hobbies`의 값으로 빈 배열을 전달해요. `hobbies`의 값으로 빈 배열을 전달했기 때문에, `"running"`은 빈 배열에 추가돼요.
+
+그리고서, `addHobby` 함수를 호출하고, `hobby`의 값으로 `"dancing"`를 전달해요. `hobbies`에 값을 전달하지 않았고, `person` 객체의 속성 `hobbies`을 기본값으로 가져요. 배열 `person.hobbies`에 `dancing`를 추가해요.
+
+마지막으로, `addHobby` 함수를 호출해, `hobby`의 값으로 `"baking"`를 전달하고, `hobbies`의 값으로 배열 `person.hobbies`을 전달해요. 배열 `person.hobbies`에 `baking`을 추가해요.
+
+`dancing` 과 `baking`을 추가한 후, `person.hobbies`의 값은 `["coding", "dancing", "baking"]`예요.
+
+
+
+#### 답: B
+
+`Flamingo` 클래스의 인스턴스인 변수 `pet` 생성했어요. 인스턴스를 인스턴스화 할 때, `Flamingo`의 `constructor`를 불러요. 우선, `"I'm pink. 🌸"`가 출력되고, 그 후에 `super()`를 불러요. `super()`는 부모 클래스 `Bird`의 constructor를 불러요. `Bird`의 constructor 를 불러, `"I'm a bird. 🦢"`가 출력돼요.
+
+
+
+#### 답: D
+
+`const` 키워드는 단순히 변수의 값을 _재선언_ 할 수 없고, _읽기만_ 가능하다는 의미예요. 하지만, 값 자체가 불변하는 건 아니에요. 배열 `emojis`의 속성을 수정할 수 있는데, 예를 들자면 새로운 값을 추가하거나, 원본 배열 자체를 수정(splice)하거나, 배열의 길이를 0으로 설정 할 수 있어요.
+
+
+
+#### 답: C
+
+객체는 기본적으로 반복 불가능해요. 반복 가능한 객체는 iterator protocol이 제공되면 반복 가능해요. 제너레이터 함수 `*[Symbol.iterator]() {}`을 만드는 제너레이터 객체를 반환하는 iterator symbol `[Symbol.iterator]`을 수동으로 추가 할 수 있어요. 배열 `["Lydia Hallie", 21]`을 반환 하려면 제너레이터 함수는 `person` 객체의 `Object.values`를 yield 해야해요: `yield* Object.values(this)`.
+
+
+
+#### 답: C
+
+`forEach` 순환에 포함 된 `if` 조건문은 `num`의 값이 진짜 같은 값인지 또는 가짜 같은 값인지 확인해요. `nums`배열의 첫 번째 값은 거짓 같은 값 `0`이고, `if` 조건문의 코드 블럭은 실행되지 않아요. `count` 는 오직 `nums` 배열의 다른 숫자 3개에 대해서만 증가해요. `1`, `2` 그리고 `3`. `count`는 3번 동안 `1` 씩 증가하고, `count`의 값은 `3`이에요.
+
+
+
+#### 답: D
+
+`?`는 객체 내에서 더 깊이 중첩된 속성에 접근하는 것을 선택적으로 허용해요. `fruits`배열의 인덱스 `1`에 있는 하위 배열의 인덱스 `1`의 아이템을 출력하려해요. `fruits`배열의 인덱스 `1`에 하위 배열이 존재하지 않는다면, 간단히 `undefined`를 반환할 거예요. `fruits` 배열의 인덱스 `1`에 하위배열이 있지만, 하위 배열에 인덱스 `1` 의 아이템이 없다면, 그것 역시 `undefined`를 반환해요.
+
+우선, `[['🍊', '🍌'], ['🍍']]`의 하위 배열의 두 번째 아이템 `['🍍']`을 출력해요 . 하위 배열은 아이템 하나만 가지고 있고, 이건 인덱스 `1`에 대한 아이템을 갖고 있지 않다는 의미로 `undefined`를 반환해요.
+
+그리고서, 인수에 어떤 값도 전달하지 않은 `getFruits` 함수를 호출 하고, `fruits`은 기본값으로 값 `undefined`을 가져요. `fruits`의 인덱스 `1`의 아이템을 선택적으로 연결(conditionally chaining)하기 때문에, 인덱스 `1`에 아이템이 존재하지 않아 `undefined`를 반환해요.
+
+마지막으로, `['🍍'], ['🍊', '🍌']`의 하위 배열 `['🍊', '🍌']`의 두번째 아이템을 출력하려고 해요. 하위 배열의 인덱스 `1`의 아이템인 `🍌`이 출력돼요.
+
+
+
+#### 답: A
+
+변수 `calc`를 `Calc` 클래스의 새로운 인스턴스로 설정 했어요. 그리고서, 새로운 인스턴스 `Calc`를 인스턴스화 하고, 이 인스턴스의 `increase` 메소드를 호출 했어요. 속성 count은 `Calc` 클래스의 생성자 안에 있기 때문에 , 속성 count은 `Calc`의 프로토타입에 공유될 수 없어요. 인스턴스 calc이 가리키는 count의 값은 업데이트 되지 않고, count는 여전히 `0`예요.
+
+
+
+#### 답: B
+
+`updateUser` 함수는 값이 전달 되면 user의 속성 `email` 과 `password`의 값을 업데이트 하고, `user`객체를 반환해요. `updateUser` 함수의 반환된 값은 객체 `user` 이고, updateUser의 값은 `user`가 가리키는 `user` 객체의 참조와 같다는 의미예요. `updatedUser === user`는 `true`예요.
+
+
+
+#### 답: C
+
+우선, fruit 배열에 `slice` 메소드를 호출해요. slice 메소드는 원본 배열을 수정하지 않지만, 배열에서 잘라낸(slice) 값을 반환해요: 바나나 이모지.
+그리고서, fruit 배열에 `splice` 메소드를 호출해요. splice 메소드는 원본 배열을 수정하고, 이제 fruit 배열은 `['🍊', '🍎']`로 구성돼요.
+마지막엔, `fruit` 배열에 `unshift` 메소드를 호출하고, 이 경우엔 제공된 값 ‘🍇’을 배열의 첫 번째 요소로 추가해 원본 배열을 수정해요. 이제 fruit 배열은 `['🍇', '🍊', '🍎']`로 구성돼요.
+
+
+
+#### 답: B
+
+객체의 키는 문자열로 변환돼요.
+
+`dog`의 값은 객체 이므로, 사실 `animals[dog]`는 새로운 객체에 `"object Object"`라고 불리는 새로운 속성을 만든 걸 의미해요. 이제 `animals["object Object"]`는 `{ emoji: "🐶", name: "Mara"}`예요.
+
+`cat`도 물론 객체고, 사실 `animals[cat]`은 `animals[``"``object Object``"``]`을 새로운 속성 cat으로 덮어쓰고 있다는 것을 의미해요.
+
+`animals[dog]` 또는 `animals["object Object"]`(`dog` 객체를 문자열로 변환한 결과는 `"object Object"`)를 출력하면, `{ emoji: "🐈", name: "Sara" }`를 반환해요.
+
+
+
+#### 답: A
+
+`updateEmail`함수는 화살표 함수로, `user`객체에 바인딩 되지 않았어요. `this`키워드는 `user`객체를 참조하지 않지만, 이 경우엔 전역 범위를 참조하고 있다는 의미예요. `user` 객체의 `email` 는 업데이트 되지 않아요. `user.email`을 출력할 때, `my@email.com`의 원래의 값이 반환되어요.
+
+
+
+#### 답: D
+
+`Promise.all` 메소드는 프로미스를 병렬로 실행해요. 만약 하나의 프로미스가 실패하면, `Promise.all` 메소드는 rejected 프로미스의 값을 가지고 _rejects_ 되어요. 이 경우, `promise3`는 값 `"Third"`과 함께 rejected 되었어요. `runPromises` 호출에 연결되어 있고 `runPromises` 함수 안에서 모든 에러를 잡은 `catch` 메소드에서 rejected 값을 잡아요. `promise3`가 이 값과 함께 rejected 되어 `"Third"`만 출력돼요.
+
+
+
+#### 답: C
+
+`fromEntries` 메소드는 2차원 배열을 객체로 변환해요. 각 하위 배열의 첫번 째 요소는 키가 될거고, 각 하위 배열의 요소의 두번째 요소는 값이 될거에요. 이 경우엔, keys배열에서 현재 인덱스의 아이템을 첫 번재 요소로, values의 배열에서 현재 인덱스의 아이템을 두번째 요소로 반환하는 `keys` 배열을 매핑해요.
+
+키와 값의 집합을 포함하고 있는 하위 배열을 만들었고, `{ name: "Lydia", age: 22 }`가 되어.
+
+
+
+#### 답: C
+
+`address`의 기본 값은 빈 객체 `{}`예요. 변수 `member`의 값을 `createMember` 함수에서 반환한 값으로 설정하고, address의 값을 전달하지 않았어요, address의 값은 빈 객체 `{}`가 기본 값이예요. 빈객체는 진짜 같은 값으로, 조건 `address ? address : null`에서 `true`를 반환한다는 의미예요. address의 값은 빈 객체 `{}`예요.
+
+
-같은 값으로 `addFunction`함수를 세 번 불러요: 첫 번째 호출 때에는, `num`가 `10`일 때 함수의 값은 아직 저장되지 않았어요. if문의 조건 `num in cache` 은 `false`을 리턴하고, else 블록이 실행돼요: `Calculated! 20`을 출력하고, 결과 값은 cache 객체에 추가돼요. `cache` 이제 `{ 10: 20 }`와 같아요.
+#### 답: B
-두 번째엔, `cache`객체는 `10`을 위해 리턴될 값을 포함하고 있어요. if문의 조건 `num in cache`은 `true`를 리턴하고, `'From cache! 20'`이 출력돼요.
+`if`문 안에 조건은 `!typeof randomValue`값이 `"string"`와 같은지 여부를 확인해요. `!` 연산자는 값을 불리언 값으로 변환해요. 값이 진짜 같은 값이라면 반환될 값은 `false`가 될 거고, 만약 값이 가짜 같은 값이라면 반환될 값은 `true`가 될 거예요. 이 경우에서, `typeof randomValue`의 반환된 값은 진짜 같은 값인 `"number"`이고, `!typeof randomValue`의 값은 불리언 값 `false`라는 의미예요.
-세 번째에는, `5 * 2`을 `10`으로 평가하여 함수에 전달해요. `cache` 객체는 `10`을 위해 리턴될 값을 포함하고 있어요. if문의 조건 `num in cache`은 `true`를 리턴하고, `'From cache! 20'`이 출력돼요.
+`!typeof randomValue === "string"`은 실제로 `false === "string"`을 확인하기 때문에 항상 false를 반환해요. 조건은 `false`을 반환 하므로, `else`문의 코드 블록이 실행되어 `Yay it's a string!`가 출력돼요.
+
+- [🇸🇦 العربية](../ar-AR/README_AR.md)
+- [🇪🇬 اللغة العامية](../ar-EG/README_ar-EG.md)
+- [🇧🇦 Bosanski](../bs-BS/README-bs_BS.md)
+- [🇩🇪 Deutsch](../de-DE/README.md)
+- [🇬🇧 English](../README.md)
+- [🇪🇸 Español](../es-ES/README-ES.md)
+- [🇫🇷 Français](../fr-FR/README_fr-FR.md)
+- [🇮🇩 Indonesia](../id-ID/README.md)
+- [🇮🇹 Italiano](../it-IT/README.md)
+- [🇯🇵 日本語](../ja-JA/README-ja_JA.md)
+- [🇰🇷 한국어](../ko-KR/README-ko_KR.md)
+- [🇵🇱 Polski](../pl-PL/README.md)
+- [🇧🇷 Português Brasil](../pt-BR/README_pt_BR.md)
+- [🇷o Română](../ro-RO/README.ro.md)
+- [🇷🇺 Русский](../ru-RU/README.md)
+- [🇽🇰 Shqip](../sq-KS/README_sq_KS.md)
+- [🇹🇭 ไทย](../th-TH/README-th_TH.md)
+- [🇹🇷 Türkçe](../tr-TR/README-tr_TR.md)
+- [🇺🇦 Українська мова](../uk-UA/README.md)
+- [🇻🇳 Tiếng Việt](../vi-VI/README-vi.md)
+- [🇨🇳 简体中文](../zh-CN/README-zh_CN.md)
+- [🇹🇼 繁體中文](../zh-TW/README_zh-TW.md)
+
+
+
+#### Antwoord: D
+
+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`.
+
+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`.
+
+
+
+#### Antwoord: C
+
+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 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.
+
+
+
+#### Antwoord: B
+
+Merk op dat de waarde van `diameter` een gewone functie is, waarbij de waarde van `perimeter` een zogenaamde arrow functie is.
+
+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).
+
+Er is geen propertie `radius` op dat object, daarom wordt `undefined` teruggegeven.
+
+
+
+#### Antwoord: A
+
+De unaire plus probeert een operand naar een nummer te converteren. `true` is `1`, en `false` is `0`.
+
+De string `'Lydia'` is een truthy waarde. Wat we eigenlijk vragen, is "is deze truthy waarde falsy?". Dit geeft `false` terug.
+
+
+
+#### Antwoord: A
+
+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 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]`: Eerst wordt `bird.size` geëvalueerd, wat `"small"` teruggeeft. `mouse["small"]` geeft `true` terug.
+
+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 ``.
+
+
+
+#### Antwoord: A
+
+In JavaScript worden alle objecten verwerkt _by reference_, ook wanneer we de waarde van een variabele vullen met een ander 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`.
+
+
+
+#### Antwoord: C
+
+`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.
+
+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.
+
+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.
+
+
+
+#### Antwoord: D
+
+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.
+
+
+
+#### Antwoord: A
+
+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).
+
+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.
+
+
+
+#### Antwoord: A
+
+Dit is mogelijk in JavaScript, omdat functies objecten zijn! (Alles behalve primitives zijn objecten)
+
+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.
+
+
+
+#### Antwoord: A
+
+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() {
+ return `${this.firstName} ${this.lastName}`;
+};
+```
+
+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!
+
+
+
+#### Antwoord: A
+
+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 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.
+
+
+
+#### Antwoord: D
+
+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.
+
+
+
+#### Antwoord: B
+
+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.
+
+
+
+#### Antwoord: C
+
+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 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.
+
+
+
+#### Antwoord: C
+
+De **postfix** unary operator `++`:
+
+1. Geeft de waarde terug (in dit geval `0`)
+2. Vermeerderd de waarde (number is nu `1`)
+
+De **prefix** unary operator `++`:
+
+1. Vermeerderd de waarde (number is nu `2`)
+2. Geeft de waarde terug (in dit geval `2`)
+
+Dit geeft `0 2 2` terug.
+
+
+
+#### Antwoord: B
+
+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!
+
+
+
+#### Antwoord: C
+
+Wanneer we waarden vergelijken worden primitieven vergelijken _by value_, terwijl objecten vergelijken worden _by reference_. JavaScript bekijkt of de objecten een referentie hebben naar dezelfde lokatie in het geheugen.
+
+De twee objecten die we vergelijken hebben dat niet: het object die we doorgeven als een parameter refereert naar een andere lokatie in het geheugen dan het object waarmee we vergelijken.
+
+Dit is waarom `{ age: 18 } === { age: 18 }` en `{ age: 18 } == { age: 18 }` allebei `false` teruggeven.
+
+
+
+#### Antwoord: C
+
+De rest parameter (`...args`.) laat ons alle overgebleven argumenten "verzamelen" in een array. Een array is een object, dus `typeof args` geeft `"object"` terug.
+
+
+
+#### Antwoord: C
+
+Door gebruik te maken van `"use strict"` kun je er zeker van zijn dat je niet perongeluk globale variabelen declareert. We hebben de variabele `age` nooit gedeclareerd, en omdat we `"use strict"` gebruiken zal dit een reference error gooien. Als we geen gebruik hadden gemaakt van `"use strict"` had het wel gewerkt, omdat de propertie `age` dan was toegevoegd aan het globale object.
+
+
+
+#### Antwoord: A
+
+`eval` voert code uit dat is meegegeven als string. Als het een expressie is, zoals in dit geval, zal het de expressie uitvoeren. De expressie is `10 * 10 + 5`. Dit geeft het getal `105` terug.
+
+
+
+#### Antwoord: B
+
+De data opgeslagen in `sessionStorage` wordt verwijderd na het sluiten van de _tab_.
+
+Als je `localStorage` had gebruikt was de data wel voor altijd opgeslagen, zolang bijvoorbeeld `localStorage.clear()` wordt aangeroepen.
+
+
+
+#### Antwoord: B
+
+Met het `var` keyword kun je meerdere variabelen met dezelfde naam declareren. De variabele zal dan de laatst gezette waarde bevatten.
+
+Je kunt dit niet doen met `let` of `const`, omdat deze block-scoped zijn.
+
+
+
+#### Antwoord: C
+
+Alle object keys (Symbols uitgesloten) zijn onder de motorkap strings, zelfs als je het zelf niet een string gemaakt hebt. Dat is waarom `obj.hasOwnProperty('1')` ook `true` teruggeeft.
+
+Dit werkt niet op deze manier voor een set. Er is geen `'1'` in onze set: `set.has('1')` geeft `false` terug. Het heeft de numerieke waarde `1`, `set.has(1)` geeft `true` terug.
+
+
+
+#### Antwoord: C
+
+Als je twee properties met dezelfde naam hebt zal de waarde van de al bestaande propertie overschreven worden. Het zal dan ook in de eerste positie blijven, maar met de laatste waarde.
+
+
+
+#### Antwoord: A
+
+De base execution context is de global execution context: dit is benaderbaar overal in je code.
+
+
+
+#### Antwoord: C
+
+De `continue` statement slaat een iteratie over als een bepaalde conditie `true` teruggeeft.
+
+
+
+#### Antwoord: A
+
+`String` is een built-in constructor waaraan we properties kunnen toevoegen. Primitieve strings worden automatisch geconverteerd naar een string object, gegenereerd door de string prototype functie. Daarom hebben alle strings (string objecten) toegang tot de methode!
+
+
+
+#### Antwoord: B
+
+Object keys worden automatisch geconverteerd naar strings. We proberen een object aan een propertie toe te wijzen van object `a`, met de waarde `123`.
+
+Maar als we een object converteren naar een string krijgen we `"[object Object]"` terug. Wat we hier dus schrijven is `a["object Object"] = 123`. Dan kunnen we hetzelfde nog een keer proberen. `c` is een ander object dat converteren naar een string. En dan, `a["object Object"] = 456`.
+
+Dan loggen we `a[b]`, waar eigenlijk `a["object Object"]` staat. We overschrijven dat met `456`, en dit is ook wat gelogd wordt.
+
+
+
+#### Antwoord: B
+
+We hebben een `setTimeout` functie en roepen het als eerste aan. Toch wordt het als laatste gelogd.
+
+Dit komt doordat we in browsers niet alleen een runtime engine hebben, maar ook iets dat een `WebAPI` genoemd wordt. De `WebAPI` geeft ons een `setTimeout` functie, en bijvoorbeeld ook de DOM.
+
+Nadat de _calback_ naar de WebAPI is gestuurd wordt de `setTimeout` functie zelf (niet de callback functie) van de stack gegooid.
+
+
+
+#### Antwoord: C
+
+Het diepst geneste element dat het event afvuurt is de target van het event. Je kunt bubbling stoppen met `event.stopPropagation`.
+
+
+ Click here!
+
+
+#### Antwoord: A
+
+Als we op `p` klikken zien we twee logs: `p` en `div`. Tijdens de event propagation zijn er 3 fases: capturing, target, en bubbling. Standaard worden event handlers uitgevoerd in de bubbling fase (tenzij je `useCapture` op `true` zet). Bubbling begint bij het diepst geneste element omhoog.
+
+
+
+#### Antwoord: D
+
+Op beide manieren kunnen we een object doorgeven waarnaar het `this` keyword verwijst. Echter, `.call` wordt _direct uitgevoerd_!
+
+`.bind` geeft een _kopie_ terug van de functie, maar met een bound context! Het wordt niet direct uitgevoerd!
+
+
+
+#### Antwoord: B
+
+De `sayHi` functie geeft de waarde terug van de direct aangeroepen functie (IIFE). Deze functie geeft `0` terug, die het type `number` heeft.
+
+FYI: er zijn slechts 7 ingebouwde types: `null`, `undefined`, `boolean`, `number`, `string`, `object`, `symbol` en `bigint`. `"function"` is geen type omdat functies objecten zijn, en dus van het type `"object"`.
+
+
+
+#### Antwoord: A
+
+Er zijn slechts zes falsy waarden:
+
+- `undefined`
+- `null`
+- `NaN`
+- `0`
+- `''` (lege string)
+- `false`
+
+Functie constructors, zoals `new Number` en `new Boolean`, zijn truthy.
+
+
+
+#### Antwoord: B
+
+`typeof 1` geeft `"number"` terug.
+`typeof "number"` geeft `"string"` terug.
+
+
+
+#### Antwoord: C
+
+Wanneer je een element van een array een waarde geeft die buiten de lengte van de array ligt zal JavaScript voor de tussenliggende elementen zogenaamde "empty slots" aanmaken. Deze hebben eigenlijk de waarde `undefined`, maar je zult zoiets zien als:
+
+`[1, 2, 3, 7 x empty, 11]`
+
+afhankelijk van waar je de code uitvoert (het verschilt in alle browsers, node, etc.)
+
+
+
+#### Antwoord: A
+
+Het `catch` block krijgt het argument `x` mee. Dit is niet dezelfde `x` als de variabele zoals bovenaan gedefinieerd. De meegegeven `x` is block-scoped.
+
+Later vullen we deze block-scoped variabele met `1`, en zetten de waarde van de variabele `y`. Dan loggen we de block-scoped variabele `x`, die op dat moment `1` bevat.
+
+Buiten het `catch` block is de variable `x` nog steeds `undefined`, `y` is echter `2`. Wanneer we beide variabelen buiten de try...catch statement loggen zal `x` `undefined` teruggeven en `y` `2`.
+
+
+
+#### Antwoord: A
+
+JavaScript bestaat alleen uit primitieve types en objecten.
+
+Primitieve types zijn `boolean`, `null`, `undefined`, `bigint`, `number`, `string`, en `symbol`.
+
+Wat primitieven onderscheidt van objecten is dat primitieven geen properties of methodes bevatten. Echter, je zal opmerken dan `'foo'.toUpperCase()` resulteert in `'FOO'` en geen `TypeError` gooit. Dit komt doordat wanneer je een propertie of een methode benadert van een primitieve zoals een string, JavaScript impliciet het object wrapped gebruikmakend van één van de wrapper classen, in dit geval `String`, en daarna direct de wrapper weghaalt als de expressie heeft geresulteerd in een waarde. Alle primitieven vertonen dit gedrag, met uitzondering van `null` en `undefined`.
+
+
+
+#### Antwoord: C
+
+`[1, 2]` is onze initiële waarde. Dit is de waarde waarmee we starten, en de waarde van de allereerste `acc`. Tijdens de eerste iteratie, `acc` is `[1, 2]` en `cur` is `[0, 1]`. Deze waarden concateneren we, wat resulteerd in `[1, 2, 0, 1]`.
+
+Tijdens de volgende iteratie `acc` is `[1, 2, 0, 1]` en `cur` is `[2, 3]`. Deze worden wederom geconcateneerd en resulteerd in `[1, 2, 0, 1, 2, 3]`.
+
+
+
+#### Antwoord: B
+
+`null` is falsy. `!null` geeft `true` terug. `!true` geeft `false` terug.
+
+`""` is falsy. `!""` geeft `true` terug. `!true` geeft `false` terug.
+
+`1` is truthy. `!1` geeft `false` terug. `!false` geeft `true` terug.
+
+
+
+#### Antwoord: A
+
+Het geeft een uniek id terug. Dit id kan gebruikt worden om de interval te stoppen door het mee te geven aan de `clearInterval()` functie.
+
+
+
+#### Antwoord: A
+
+Een string is een iterable. The spread operator arrangeert elk karakter van een iterable naar één element.
+
+
+
+#### Antwoord: C
+Reguliere functies kunnen niet worden gestopt halverwege na de aanroep. Echter, een generator functie kan wel "gestopt" worden halverwege, en later verder gaan waar ik gestopt is. Elke keer als een generator functie het keyword `yield` aantreft levert de functie de waarde op gespecificeerd achter `yield`. Let op dat een generator functie in dat geval niet de waarde _teruggeeft_, maar de waarde _oplevert_.
+
+Eerst initialiseren we de generator functie met `i`, dat gelijk is aan `10`. We roepen de generator functie aan met de `next()` methode. De eerste keer dat we de generator functie aanroepen is `i` gelijk aan `10`. De eerste `yield` wordt aangetroffen: het levert de waarde op van `i`. De generator is nu "gepauzeerd" en `10` wordt gelogd.
+
+Dan roepen we de functie nog een keer aan met de `next()` methode. Het gaat verder waar het eerder gebleven is, waarbij `i` nog steeds gelijk is aan `10`. Nu wordt de volgende `yield` aangetroffen, en levert `i * 2` op. `i` is gelijk aan `10`, dus het levert `10 * 2` op, wat gelijk is aan `20`. Het resultaat is dus `10, 20`.
+
+
+
+#### Antwoord: B
+
+Wanneer we meerdere promises meegeven aan de `Promise.race` methode zal het de _eerste_ promise resolven/rejecten. Aan de `setTimeout` methodes geven we een timer mee: 500ms voor de eerste promise (`firstPromise`) en 100ms voor de tweede promise (`secondPromise`). Dit betekent dat de `secondPromise` als eerste resolved met de waarde `'two'`. `res` bevat nu de waarde `'two'`, wat dus gelogd wordt.
+
+
+
+#### Antwoord: D
+
+Allereerst declareren we een variabele `person` met de waarde van een object met een propertie `name`.
+
+
+
+#### Antwoord: B
+
+Met een `for-in` loop kunnen we itereren over object keys, in dit geval `name` en `age`. Onder de motorkap zijn object keys strings (als het geen Symbols zijn). Bij elke iteratie is de waarde van `item` gelijk aan de huidige key waarover wordt geïtereerd. Bj de eerste iteratie is `item` gelijk aan `name` en wordt gelogd. Bij de tweede iteratie is `item` gelijk aan `age` en wordt gelogd.
+
+
+
+#### Antwoord: B
+
+Operator associativiteit is de volgorde waarin de compiler de expressies evalueerd, of van links naar recht of van rechts naar links. Dat gebeurt alleen als alle operators _dezelfde_ prioriteit hebben. In dit geval hebben we maar één type operator: `+`. In beginsel, de associativiteit is van links naar rechts.
+
+`3 + 4` wordt eerst geëvalueerd. Dit levert het getal `7` op.
+
+`7 + '5'` resulteert in `"75"` door coersion. JavaScript converteert het getal `7` naar een string, zo ook te zien bij vraag 15. We kunnen twee stringen concateneren door gebruik te maken van de `+` operator. `"7" + "5"` resulteert in `"75"`.
+
+
+
+#### Antwoord: C
+
+Alleen het eerste getal in de string wordt geretourneerd. Gebaseerd op de _radix_ (het tweede argument om te speciferen naar welk type nummer we het willen parsen: base 10, hexadecimal, octal, binary, etc.), de `parseInt` methode checkt of de karakters in de string geldig zijn. Zodra het een karakter tegenkomt dat niet een geldig getal is in het eerste argument stopt het parsen en worden opvolgende karakters genegeerd.
+
+`*` is geen geldig getal. Alleen `"7"` wordt geparsed naar een decimal `7`. `num` bevat nu de waarde `7`.
+
+
+
+#### Antwoord: C
+
+Wanneer je iterate over een array gebruik makend van de `map()` methode is de waarde van `num` gelijk aan het huidige element dat verwerkt wordt. In dit geval zijn de elementen getallen en de conditie van de if statement `typeof num === "number"` geeft `true` terug. De `map()` methode maakt een nieuwe array aan met als inhoud het resultaat van het aanroepen van de meegegeven functie op elk van de elementen uit de originele array.
+
+Echter geven wij nooit een waarde terug. Wanneer we geen waarde toevoegen in de functie zal de functie `undefined` teruggeven. De functie wordt voor elk element in de originele array aangeroepen en voor elk element geven we `undefined` terug.
+
+
+
+#### Antwoord: A
+Argumenten worden meegegeven _by value_, tenzij de waarde een object is. Dan worden ze meegegeven _by reference_. `birthYear` is een string en geen object, waardoor het dus doorgegeven wordt _by value_. Wanneer we een argument meegeven _by value_ wordt er een _copy_ aangemaakt van het argument (zie vraag 46).
+
+De variabele `birthYear` heeft een referentie naar de waarde `"1997"`. Het argument `year` heeft ook een referentie naar de waarde '"1997"', maar het is niet dezelfde waarde als waar `birthYear` een referentie naar heeft. Wanneer we de waarde van `year` veranderen naar `"1998"`, veranderen we alleen de waarde van `year`. `birthYear` is nog steeds gelijk aan `"1997"`.
+
+De waarde van `person` is een object. Het argument `member` heeft een (gekopieerde) referentie naar _hetzelfde_ object. Wanneer we een propertie veranderen van het object waar `member` een referentie naartoe heeft zal de waarde van `person` ook veranderen, omdat beide een referentie hebben naar hetzelfde object. De propertie `name` van `person` is nu gelijk aan `"Lydia"`.
+
+
+
+#### Antwoord: D
+
+Met de `throw` statement kunnen we custom errors gooien. Een exceptie kan een string, een number, een boolean of een object zijn. In dit geval onze exceptie is aan string met de waarde `'Hello world'`.
+
+Met de `catch` statement kunnen we specificeren wat er moet gebeuren als er een exceptie is gegooid in het `try` blok. Een exceptie is gegooid: de string `'Hello world'`. `e` is nu gelijk aan deze string en wordt dus gelogd. Dat resulteert in `'Oh an error: Hello world'`.
+
+
+
+#### Antwoord: B
+
+Wanneer je een propertie teruggeeft zal de waarde van de propertie gelijk zijn aan de _geretourneerde_ waarde, niet de waarde die gezet wordt in de constructor. We geven de string `"Maserati"` terug, dus `myCar.make` is gelijk aan `"Maserati"`.
+
+
+
+#### Antwoord: A
+
+`let x = y = 10;` is een verkorte versie van:
+
+```javascript
+y = 10;
+let x = y;
+```
+
+Wanneer we de waarde van `y` vullen met `10` voegen we eigenlijk een propertie `y` toe aan het globale object (`window` in de browser, `global` in Node). In de browser is `window.y` nu gelijk aan `10`.
+
+Daarna declareren we de variabele `x` met de waarde van `y`, wat 10 is. Variabelen die gedeclareerd worden met het keyword `let` zijn _block scoped_, ze zijn alleen gedefinieerd binnen het blok waarin ze gedeclareerd zijn. In dit geval de direct aangeroepen functie (IIFE). Wanneer we de operator `typeof` gebruiken is `x` dus niet gedefinieerd; we proberen `x` te benaderen buiten de scope waarin het gedeclareerd is. Dat betekent dat `x` niet gedefinieerd is. variabelen die nog geen waarde toegewezen hebben gekregen zijn van het type `"undefined"`. `console.log(typeof x)` geeft `"undefined"` terug.
+
+Echter, we hebben een globale variabele `y` aangemaakt toen we 'y' vulde met `10`. Deze waarde is overal toegankelijk in onze code. `y` is gedefinieerd en bevat de waarde `"number"`. `console.log(typeof y)` geeft `"number"` terug.
+
+
+
+#### Antwoord: A
+
+We kunnen properties verwijderen van een object als we gebruik maken van het `delete` keyword, en ook op het prototype. Bij het verwijderen van een propertie op de prototype zal het niet meer beschikbaar zijn in de prototype chain. In dit geval is de `bark()` methode niet meer beschikbaar op de protoype na `delete Dog.prototype.bark`.
+
+Wanneer we iets proberen aan te roepen dat geen functie is zal er een `TypeError` gegooid worden. In dit geval `TypeError: pet.bark is not a function`, omdat `pet.bark` `undefined` is.
+
+
+
+#### Antwoord: D
+
+Het `Set` object is een collectie van _unieke_ waarden: een waarde kan maar één keer voorkomen in een set.
+
+We geven de array `[1, 1, 2, 3, 4]` mee met de dubbele waarde `1`. Omdat we niet twee keer dezelfde waarde kunnen hebben in een set zal één van deze dubbele waarden verwijderd worden. Dit resulteert in `{1, 2, 3, 4}`.
+
+
+
+#### Antwoord: C
+
+Een geïmporteerde module is _readonly_: je kunt de geïmporteerde module niet aanpassen. Alleen de module die de exports doet kan de waarde aanpassen.
+
+Wanneer we de waarde van `myCounter` aanpassen zal dit een error gooien: `myCounter` is read-only en cannot be modified.
+
+
+
+#### Antwoord: A
+
+De `delete` operatot geeft een boolean waarde terug: `true` bij een succesvolle verwijdering, anders zal het `false` teruggeven. Echter, variabelen die gedeclareerd worden met de keywords `var`, `const` en `let` kunnen niet verwijderd worden met de `delete` operator.
+
+De variabele `name` werd gedeclareerd met het keyword `const`, dus het verwijderen is niet succesvol: `false` wordt teruggegeven. Wanneer we `age` de waarde `21` geven voegen we eigenlijk een propertie `age` toe aan het globale object. Properties van objecten kunnen prima verwijderd worden op deze manier, ook van het globale object, dus `delete age` geeft `true` terug.
+
+
+
+#### Antwoord: C
+
+We kunnen waarden van arrays en objecten uitpakken door `destructuring`. Voorbeeld:
+
+```javascript
+[a, b] = [1, 2];
+```
+
+
+
+#### Antwoord: B
+
+Het is mogelijk om objecten samen te voegen door gebruik te maken van de spread operator `...`. Het geeft je de mogelijkheid om key/value pairs van het ene object te kopiëren naar een ander object. In dit geval maken we een kopie van het `user` object en voegen het samen met het `admin` object. Het `admin` object bevat nu de gekopieerde key/value pairs, wat resulteert in `{ admin: true, name: "Lydia", age: 21 }`.
+
+
+
+#### Antwoord: B
+
+Met de `defineProperty` methode kunnen we properties toevoegen aan een object, of bestaande properties aanpassen. Wanneer we properties toevoegen aan een object door gebruik te maken van `defineProperty` zijn deze standaard _not enumerable_. De `Object.keys` methode geeft alle _enumerable_ propertie namen terug van een object, in dit geval alleen `"name"`.
+
+Properties toegevoegd met de `defineProperty` methode zijn standaard onveranderbaar. Je kunt dit gedrag aanpassen door, in het derde argument, de `writable`, `configurable` en `enumerable` opties mee te geven. Op die manier geeft de `defineProperties` je veel controle over de properties die je wilt toevoegen aan een object.
+
+
+
+#### Antwoord: A
+
+Het tweede argument van `JSON.stringify` is de _replacer_. De replacer kan óf een functie zijn óf een array, en geeft je controle over wat en hoe de waarden gestringified worden.
+
+Als de replacer een _array_ is zullen alleen de propertie namen die in de array zitten toegevoegd worden aan de JSON string. In dit geval worden alleen de properties `"level"` en `"health"` toegevoegd, `"username"` niet. `data` is nu gelijk aan `"{"level":19, "health":90}"`.
+
+Als de replacer een _functie_ is zal die functie worden aangeroepen over elke propertie in het object dat je omzet naar een string. De waarde die teruggegeven wordt door die functie zal de waarde zijn van die propertie wanneer het wordt toegevoegd aan de JSON string. Als de waarde `undefined` is zal de property niet worden toegevoegd aan de JSON string.
+
+
+
+#### Antwoord: A
+
+De unary operator `++` geeft eerst de waarde van de variabele terug, en pas daarna de waarde verhogen van de variabele. De waarde van `num1` is `10` omdat de `increaseNumber` functie eerst de waarde van `num` teruggeeft, wat `10` is, en pas daarna de waarde van `num` verhogen met 1.
+
+`num2` is `10` omdat we `num1` meegeven aan de functie `increasePassedNumber`. `number` is gelijk aan `10` (de waarde van ` num1`). Nogmaals, de unary operator `++` zal _eerst_ de huidige waarde van de variabele teruggeven en pas _daarna_ de waarde verhogen. De waarde van `number` is `10`, dus de waarde van `num2` is ook `10`.
+
+
+
+#### Antwoord: C
+
+In ES6 kunnen we parameters initialiseren met een standaard waarde. De waarde van de parameter zal deze standaard waarde behouden zolang er geen andere waarde wordt meegegeven aan de functie, of als de waarde van de parameter `"undefined"` is. In dit geval kopiëren we de properties van het `value` object
+naar een nieuw object gebruikmakend van de spread operator, dus `x` heeft de standaard waarde `{ number: 10 }`.
+
+De standaard waarde wordt geëvalueerd tijdens _call time_ (aanroeptijd)! Elke keer wanneer we de functie aanroepen wordt er een nieuw object aangemaakt. We roepen de `multiply` functie de eerste twee keer aan zonder een waarde mee te geven: `x` heeft de standaard waarde van `{ number: 10 }`. We loggen dan de vermenigvuldigde waarde van dat getal, wat `20` is.
+
+De derde keer dat we de functie `multiply` aanroepen geven we wel een waarde mee: het object genaamd `value`. De `*=` operator is eigenlijk een verkorting van `x.number = x.number * 2`: we passen de waarde van `x.number` aan en loggen de vermenigvuldigde waarde `20`.
+
+De vierde keer geven we weer het `value` object mee. `x.number` was al aangepast naar `20`, en `x.number *= 2` logt `40`.
+
+
+
+#### Antwoord: D
+
+Het eerste argument van de `reduce` methode is de _accumulator_, in dit geval `x`. Het tweede argument is de _huidige waarde_, `y`. Met de `reduce` methode voeren we een functie uit op elk element in de array, wat uiteindelijk zal resulteren in een enkele waarde.
+
+In dit voorbeeld geven we geen waarde terug. We loggen enkel the waarden van de accumulator en de huidige waarde.
+
+De waarde van de accumulator is gelijk aan de vorige teruggegeven waarde van de callback functie. Als je niet de optionele `initialValue` meegeeft aan de `reduce` methode, de accumulator is gelijk aan het eerste element tijdens de eerste aanroep.
+
+Tijdens de eerste aanroep is de accumulator (`x`) `1` en de huidige waarde (`y`) `2`. We geven niets terug in de callback function, we loggen de accumulator en de huidige waarde: `1` en `2` worden gelogd.
+
+Als je niets teruggeeft in een functie, zal de functie `undefined` teruggeven. Tijdens de volgende aanroep is de accumulator `undefined` en de huidige waarde `3`. `undefined` en `3` worden gelogt.
+
+Tijdens de vierde aanroep geven we wederom niets terug in de callback functie. De accumulator is wederom `undefined`, en de huidige waarde `4`. `undefined` en `4` worden gelogt.
+
+
+
+#### Antwoord: B
+
+In de afgeleide class kun je het `this` keyword niet benaderen totdat je `super` hebt aangeroepen. Als je toch probeert zal dit een _ReferenceError_ gegooid worden: 1 en 4 zouden een reference error gooien.
+
+Met het `super` keyword roepen we de parent class zijn contructor aan met het meegegeven argument. De parent class' contructor verwacht het argument `name`, dus we moeten `name` meegeven aan `super`.
+
+De `Labrador` class verwacht twee argumenten, `name` omdat het een afgeleide is van `Dog`, en `size` als een propertie van de `Labrador` class zelf. Ze zullen allebei meegegeven moeten worden aan de contructor van `Labrador`, wat op de juiste manier gebeurt bij constructor 2.
+
+
+
+#### Antwoord: B
+
+Met het `import` keyword worden alle geïmporteerde modules _pre-parsed_. Dat betekent dat de geïmporteerde modules _als eerste_ uitgevoerd zal worden en de code waarin de module geïmporteerde wordt _als tweede_.
+
+Dit is een verschil tussen `require()` in CommonJS en `import`! Met `require()` kun je dependencies inladen tijdens dat de code uitgevoerd wordt. Als we `require` gebruikt hadden in plaats van `import` zou er `running index.js`, `running sum.js`, `3` gelogt worden in het console.
+
+
+
+#### Antwoord: A
+
+Elk Symbol is volledig uniek. Het doel van het argument dat meegegeven wordt aan de Symbol is om de Symbol een omschrijving te geven. De waarde van de Symbol is niet afhankelijk van het doorgegeven argument. Als we de waarden vergelijken creëeren we compleet nieuwe Symbols: de eerste `Symbol('foo')` en de tweede `Symbol('foo')`. Deze twee waarden zijn uniek en niet gelijk aan elkaar, `Symbol('foo') === Symbol('foo')` geeft `false` terug.
+
+
+
+#### Antwoord: C
+
+Met de `padStart` methode kunnen we witruimte toevoegen aan het begin van de string. De waarde die meegegeven wordt aan de methode is de _totale_ lengte van de string, samen met de witruimte. De string `"Lydia Hallie"` heeft een lengte van `13`. `name.padStart(13)` plaatst 1 spatie toe aan het begin van de string omdat 12 + 1 = 13.
+
+Als het argument dat we meegeven aan de `padStart` methode kleiner is dan de lengte van de string zullen er geen spaties worden toegevoegd.
+
+
+
+#### Antwoord: A
+
+Met de `+` operator kun je strings concateneren. In dit geval concateneren we de string `"🥑"` met de string `"💻"`, wat `"🥑💻"` oplevert.
+
+
+
+#### Antwoord: C
+
+Een generator functie "pauzeert" tijdens de uitvoering wanneer het het keyword `yield` tegenkomt. Allereerst laten we de functie de string "Do you love JavaScript?" opleveren. Dat kunnen we doen door `game.next().value` te gebruiken.
+
+Elke lijn van de functie wordt uitgevoerd totaan het eerste `yield` keyword. Er is een `yield` aanwezig op de eerste lijn van de functie: de uitvoering stopt bij de eerste `yield`! _Dat betekent dat de variabele `answer` nog niet gedefinieerd is!_
+
+Wanneer we `game.next("Yes").value` aanroepen wordt de vorige `yield` vervangen met de waarde van de parameters die zijn meegegeven aan de `next()` functie, `"Yes"` in dit geval. De waarde van de variabele `answer` is nu gelijk aan `"Yes"`. De conditie van de if-statement geeft `false` terug en `JavaScript loves you back ❤️` wordt gelogd.
+
+
+
+#### Antwoord: C
+
+`String.raw` geeft een string terug waarbij de escapes (`\n`, `\v`, `\t` etc.) genegeerd worden! Backslashes kunnen een probleem zijn omdat je kunt eindigen met zoiets als:
+
+`` const path = `C:\Documents\Projects\table.html` ``
+
+Wat resulteert in:
+
+`"C:DocumentsProjects able.html"`
+
+Met `String.raw` worden de escapes simpelweg genegeerd:
+
+`C:\Documents\Projects\table.html`
+
+In dit geval wordt `Hello\nworld` gelogd.
+
+
+
+#### Antwoord: C
+
+Een asynchrone functie geeft altijd een promise terug. De `await` moet nog steeds wachten op de oplossing van de promise: een wachtende promise wordt teruggegeven wanneer we `getData()` aanroepen om daarmee `data` te vullen.
+
+Als we de teruggegeven waarde van de promise `"I made it"` willen benaderen zouden we de `then()` method kunnen gebruiken op `data`:
+
+`data.then(res => console.log(res))`
+
+Dit zou wel `"I made it!"` loggen.
+
+
+
+#### Antwoord: B
+
+De `push()` methode geeft de _Lengte_ terug van de nieuwe array! In eerste instantie bevatte de array één element (de string `"banana"`) en had een lengte van `1`. Nadat de string `"apple"` toegevoegd wordt aan de array bevat de array twee elementen en heeft een lengte van `2`. Dit wordt dan ook teruggegeven door de `addToList` functie.
+
+De `push()` methode past de originele array aan. Als je de _array_ zelf terug zou willen geven in plaats van de _lengte van de array_ zou je de `list` moeten teruggeven nadat de `item` toegevoegd is.
+
+
+
+#### Antwoord: B
+
+`Object.freeze` maakt het onmogelijk om properties van een object toe te voegen, te verwijderen of aan te passen (tenzij de waarde van de propertie zelf een object is).
+
+Wanneer we de variabele `shape` aanmaken en hieraan het bevroren object `box` toewijzen zal de referentie naar het bevroren object blijven bestaan. Je kunt checken of een object bevroren is door `Object.isFrozen` te gebruiken. In dit geval geeft `Object.isFrozen(shape)` true terug omdat de referentie naar het bevroren object `box` is blijven bestaan.
+
+Omdat `shape` bevroren is en omdat de waarde van `x` geen object is kunnen we de propertie `x` niet aanpassen. `x` is nog steeds gelijk aan `10` en `{ x: 10, y: 20 }` wordt gelogd.
+
+
+
+#### Antwoord: D
+
+Wanneer we de propertie `name` opvragen van het object aan de rechterkant wijzen we de waarde `"Lydia"` toe aan de variabele met de naam `myName`.
+
+Met `{ name: myName }` zeggen we in JavaScript dat we een nieuwe variabele aan willen maken met de naam `myName` met de waarde van de `name` propertie van het object aan de rechterkant.
+
+Omdat we proberen `name` te loggen, een variabele die niet gedefinieerd is, wordt er een ReferenceError gegooid.
+
+
+
+#### Antwoord: A
+
+Een `pure function` is een functie die _altijd_ dezelfde waarde teruggeeft, zolang hetzelfde argument wordt meegegeven.
+
+De `sum` functie geeft altijd dezelfde waarde terug. Als we `1` en `2` meegeven zal het _altijd_ `3` teruggeven. Als we de waarde `5` en `10` meegeven zal het _altijd_ `15` teruggeven. Dit is de definitie van een `pure function`.
+
+
+
+#### Antwoord: C
+
+De `add` functie is een _memoized_ functie. Met memoization kunnen we het resultaat van een functie cachen om de uitvoering ervan te versnellen. In dit geval maken we een `cache` object aan waarin we de waarde van dat de vorige keer werd teruggegeven opslaan.
+
+Als we de functie `addFunction` aanroepen met hetzelfde argument wordt eerst gecheckt of de waarde al in de cache voorkomt. Als dat het geval is wordt de opgeslagen waarde teruggegeven, waardoor de functie niet helemaal hoeft te worden uitgevoerd. Anders, als de waarde nog niet is opgeslagen in de cache, zal het de waarde berekenen en daarna opslaan in de cache.
+
+We roepen de functie `addFunction` drie keer aan met dezelfde waarde: Tijdens de eerste aanroep is de waarde van de functie `num` wanneer het gelijk is aan `10` nog niet opgslagen in de cache. De conditie van de if-statement `num in cache` geeft `false` terug waardoor we in de else-statement komen: `Calculated! 20` wordt gelogd en de waarde van het resultaat wordt opgeslagen in het cache object. `cache` ziet er nu uit als `{ 10: 20 }`.
+
+De tweede keer bevat het object `cache` de waarde dat teruggegeven wordt wanneer `10` wordt meegegeven. De conditie van de if-statement `num in cache` geeft `true` terug en `'From cache! 20'` wordt gelogd.
+
+De derde keer geven we `5 * 2` mee aan de functie wat `10` oplevert. Het `cache` object bevat de waarde dat teruggegeven gaat worden voor `10`. De conditie van de if-statement `num in cache` geeft `true` terug en `'From cache! 20'` wordt gelogd.
+
+
+
+#### Antwoord: A
+
+Met de _for-in_ loop kunnen we itereren over de **enumerable** properties. In een array zijn de "keys" van de array elementen enumarable, wat eigenlijk hun indexen zijn. Je kunt een array zien als:
+
+`{0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}`
+
+Waar de keys de enumarable properties zijn. `0` `1` `2` `3` worden gelogd.
+
+Met de _for-of_ loop kunnen we itereren over **iterables**. Een array is een iterable. Wanneer we itereren over een array is de waarde van de variabele "item" gelijk aan het huidige element, `"☕"` ` "💻"` `"🍷"` `"🍫"` wordt gelogd.
+
+
+
+#### Antwoord: C
+
+Array elementen kunnen elke waarde bevatten. Nummers, strings, objecten, andere arrays, null, boolean waarden, undefined en andere expressies zoals datums, functies en berekeningen.
+
+Het element zal gelijk zijn aan de teruggegeven waarde. `1 + 2` geeft `3` terug, `1 * 2` geeft `2` terug en `1 / 2` geeft `0.5` terug.
+
+
+
+#### Antwoord: B
+
+Argumenten hebben standaard de waarde `undefined`, tenzij de waarde wordt meegegeven aan de functie. In dit geval hebben we geen waarde meegegeven voor het argument `name`. `name` is gelijk aan `undefined` wat gelogd wordt.
+
+In ES6 kunnen we argumenten een standaard waarde geven. Als voorbeeld:
+
+`function sayHi(name = "Lydia") { ... }`
+
+In dit geval zal de waarde van het argument `name`, als we geen waarde meegeven aan de functie, standaard `Lydia` bevatten.
+
+
+
+#### Antwoord: B
+
+De waarde van het keyword `this` hangt af van in welke scope je het gebruikt. In een **methode**, zoals de `getStatus` methode, het `this` keyword verwijst naar _het object waartoe de methode behoort_. De methode behoort toe aan het `data` object, dus `this` verwijst naar het `data` object. Wanneer we `this.status` loggen wordt de `status` propertie van het `data` object gelogd, wat `"🥑"` is.
+
+Met de `call` methode kunnen we het object veranderen waarnaar het keyword `this` verwijst. In **functies** refereert het keyword `this` naar _het object waartoe de function behoort_. We declareren de `setTimeout` functie op het _globale object_, dus binnen de `setTimeout` functie refereert het keyword `this` naar het _globale object_. Op het globale object bestaat de variabele genaamd _status_ met de waarde `"😎"`. Wanneer we `this.status` loggen wordt `"😎"` gelogd.
+
+
+
+#### Antwoord: A
+
+We vullen de variabele `city` met de waarde van de propertie `city` op het object `person`. Er is echter geen propertie `city` op dit object, dus de variabele `city` krijgt de waarde `undefined`.
+
+Let op dat we _niet_ refereren naar het object `person` zelf! We vullen de waarde van de variabele `city` enkel met de waarde van de propertie `city` op het `person` object.
+
+Daarna zetten we de waarde van `city` gelijk aan de string `"Amsterdam"`. Dit verandert niets aan het object `person`: we hebben geen referentie naar dat object.
+
+Wanneer we het object `person` loggen, wordt het onaangepaste object gelogd.
+
+
+
+#### Antwoord: C
+
+Variabelen gedeclareerd met de keywords `const` en `let` zijn _block-scoped_. Een block is alles tussen accolades (`{ }`). In dit geval de accolades van de if/else statements. Je kunt niet refereren naar een variabele buiten het block waarin het gedeclareerd is. Een ReferenceError wordt gegooid.
+
+
+
+#### Antwoord: C
+
+De waarde van `res` in de tweede `.then` is gelijk aan de geretourneerde waarde in de vorige `.then`. Je kunt `.then`s zoals dit blijven `chainen`, waarbij de waarde wordt meegegeven aan de volgende `handler`.
+
+
+
+#### Antwoord: A
+
+Met `!!name` stellen we vast of de waarde van `name` truthy of falsy is. Als `name` truthy is, dit is wat we willen testen, zal `!name` `false` teruggeven. `!false` (wat `!!name` feitelijk is) geeft `true` terug.
+
+Wanneer we `hasName` vullen met `name`, vullen we het met dat wat we meegeven aan de `getName` functie, niet de boolean waarde `true`.
+
+`new Boolean(true)` geeft een object wrapper terug, niet de boolean waarde zelf.
+
+`name.length` geeft de lengte terug van de meegegeven waarde, niet of het `true` is.
+
+
+
+#### Antwoord: B
+
+Om een karakter van een string op een specifieke index te krijgen kun je blokhaken gebruiken. Het eerste karakter in de string heeft de index 0. In dit geval willen we het element hebben met de index 0, het karakter `"I"`, wat gelogd wordt.
+
+Let op dat deze methode niet ondersteund wordt in IE7 en daaronder. In dat geval maak je gebruik van `.charAt()`.
+
+
+
+#### Antwoord: B
+
+Je kunt een parameters standaard waarde gelijk zetten aan een andere parameter van diezelfde functie, zolang deze definieerd is _voor_ de parameter met een standaard waarde. We geen de waarde `10` mee aan de `sum` functie. Als de `sum` functie maar één argument meekrijgt betekent dit dat de waarde van `num2` gevuld wordt met de waarde van `num1`. `10` in dit geval. De standaard waarde van `num2` is de waarde van `num1`, wat `10` is. `num1 + num2` geeft `20` terug.
+
+Als je probeert de standaard waarde van een parameter te vullen met de waarde van een parameter welke gedefinieerd is _na_ de standaard parameter, dan is de parameter nog niet geïnitialiseerd en wordt er een error gegooid.
+
+
+
+#### Antwoord: A
+Met de `import * as name` syntax importeren we _alle exports_ van `module.js` bestand in het bestand `index.js` als een nieuw object met de naam `data`. In het bestand `module.js` zijn er twee exports: de standaard export en de benoemde export. De standaard export is een functie dat de string `"Hello world"` teruggeeft, en de benoemde export is de variabele `name` wat de waarde van de string `"Lydia"` bevat.
+
+Het object `data` bevat een propertie `default` voor de standaard export. Andere properties hebben de naam van de benoemde exports en hun corresponderende waarden.
+
+
+
+#### Antwoord: C
+
+Classes zijn een syntactisch sausje voor functie constructors. Het equivalent van de class `Person` als een functie constructor zou zijn:
+
+```javascript
+function Person() {
+ this.name = name
+}
+```
+
+Het aanroepen van de functie contructor met `new` resulteert in het creëeren van een instantie van `Person`. Het keyword `typeof` geeft voor een instantie `"object"` terug. `typeof member` geeft `"object"` terug.
+
+
+
+#### Antwoord: D
+
+De `.push` methode retourneert de _nieuwe lengte_ van de array, niet de array zelf! Door `newList` te vullen met `[1, 2, 3].push(4)`, zetten we `newList` gelijk aan de nieuwe lengte van de array: `4`.
+
+Dan gebruiken we de `.push` methode op `newList`. Omdat `newList` nu de numerieke waarde `4` bevat, kunnen we de `.push` methode niet gebruiker: een TypeError wordt gegooid.
+
+
+
+#### Antwoord: D
+
+Reguliere functies zoals de `giveLydiaPizza` functie hebben een `prototype` propertie, wat een object is (prototype object) met een `constructor` propertie. Arrow functies zoals de `giveLydiaChocolate` functie hebben geen `prototype` functie. `undefined` wordt geretourneerd wanneer we proberen om de `prototype` propertie te benaderen door gebruik te maken van `giveLydiaChocolate.prototype`.
+
+
+
+#### Antwoord: A
+
+`Object.entries(person)` retourneert een array van geneste arrays, welke de keys en objecten bevat:
+
+`[ [ 'name', 'Lydia' ], [ 'age', 21 ] ]`
+
+Gebruikmakend van de `for-of` loop kunnen we itereren over elk element in de array, de subarrays in dit geval. We kunnen de subarrays direct destructureren door `const [x, y]` te gebruiken. `x` is gelijk aan het eerste element in de subarray, `y` is gelijk aan het tweede element in de subarray.
+
+De eerste subarray wat wordt gelogd is `[ "name", "Lydia" ]`, waarbij `x` gelijk is aan `"name"` en `y` gelijk is aan `"Lydia"`.
+De tweede subarray wat wordt gelogd is `[ "age", "21" ]`, waarbij `x` gelijk is aan `"age"` en `y` gelijk is aan `"21"`.
+
+
+
+#### Antwoord: D
+
+`...args` is een rest parameter. De waarde van een rest parameter is een array die alle overgebleven argumenten bevat, en om die reden **alleen de laatste parameter kan zijn**! In dit voorbeeld is de rest parameter niet de laatste parameter, wat niet mogelijk is. Er wordt een syntax error gegooid.
+
+```javascript
+function getItems(fruitList, favoriteFruit, ...args) {
+ return [...fruitList, ...args, favoriteFruit]
+}
+
+getItems(["banana", "apple"], "pear", "orange")
+```
+
+Het bovenstaande voorbeeld werkt. Dit geeft de array `[ 'banana', 'apple', 'orange', 'pear' ]` terug.
+
+
+
+#### Antwoord: B
+
+In JavaScript _hoeven_ we geen puntkomma's te schrijven, alhoewel de JavaScript engine ze toch zal toevoegen na statements. Dit wordt **Automatic Semicolon Insertion** genoemd. Een statement kan bijvoorbeeld een variabele zijn of een keyword zoals `throw`, `return`, `break`, etc.
+
+Hier schreven we een `return` statement en op de _nieuwe regel_ `a + b`. Maar omdat het een nieuwe regel betreft weet de engine niet wat we eigenlijk wilde retourneren. In plaats daarvan wordt er na `return` automatisch een puntkomma toegevoegd. Je kunt dit zien als:
+
+```javascript
+ return;
+ a + b
+```
+
+Dat betekent dat `a + b` nooit bereikt zal worden, omdat de functie stopt na het keyword `return`. Als er geen waarde wordt geretourneerd, zoals nu, zal de functie `undefined` teruggeven. Let op dat er geen automatisch insertion plaatsvindt na `if/else` statements!
+
+
+
+#### Antwoord: B
+
+We kunnen classes gelijk zetten tot andere classes/functie constructors. In dit geval zettten we `Person` gelijk aan `AnotherPerson`. De naam op deze constructor is `Sarah`, dus de propertie naam van de nieuwe `Person` instantie `member` is `"Sarah"`.
+
+
+
+#### Antwoord: D
+
+Een Symbol is geen _enumerable_. De Object.keys methode retourneert alle _enumerable_ key properties van een object. De Symbol zal niet zichtbaar zijn en een lege array zal geretourneerd worden. Wanneer we het hele object loggen zullen alle properties zichtbaar zijn, zelfs de niet enumarables.
+
+Dit is één van de goeie eigenschappen van een Symbol: naast dat het een compleet unieke waarde representeert (wat voorkomt dat namen op objecten per ongeluk conflecteren, bijvoorbeeld wanneer je werkt met 2 libraries die properties willen toevoegen aan één en hetzelfde object) kun je properties op objecten op deze manier ook verbergen (natuurlijk niet compleet verbergen. Je kunt de Symbolen altijd benaderen gebruikmakend van de `Object.getOwnPropertySymbols()` methode).
+
+
+
+#### Antwoord: A
+
+De `getList` functie ontvangt een array als argument. Tussen de haakjes van de `getList` functie destructureren we deze array direct. Je kunt het zien als:
+
+ `[x, ...y] = [1, 2, 3, 4]`
+
+Met de rest parameter `...y` stoppen we alle "overgebleven" argumenten in een array. De overgebleven argumenten zijn in dit geval `2`, `3` en `4`. De waarde van `y` is een array die alle rest parameters bevat. De waarde van `x` is gelijk aan `1` in dit geval, dus wanneer we `[x, y]` loggen wordt `[1, [2, 3, 4]]` gelogd.
+
+De `getUser` functie ontvangt een object. Met arrow functies _hoeven_ we geen accolades te gebruiken als we maar één waarde willen retourneren. Echter, als je een _object_ wilt retourneren in een arraow functie zal je het tussen haakjes moeten schrijven. Anders zal er geen waarde geretourneerd worden! De volgende functie zal wel een object geretourneerd hebben:
+
+```const getUser = user => ({ name: user.name, age: user.age })```
+
+Omdat er geen waarde geretourneerd wordt in dit geval zal de functie `undefined` retourneren.
+
+
+
+#### Antwoord: C
+
+De variabele `name` bevat de waarde van een string wat geen functie is, en dus niet aangeroepen kan worden.
+
+TypeErrors worden gegooid als een waarde niet van het verwachtte type is. JavaScript verwacht dat `name` een functie is omdat we het proberen aan te roepen. Omdat het een string is zal er een TypeError gegooid worden: `name` is geen functie!
+
+SyntaxErrors worden gegooid wanneer je iets hebt geschreven wat geen valide JavaScript is. Als je bijvoorbeeld het woord `return` als `retrun` hebt geschreven.
+ReferenceErrors worden gegooid wanneer JavaScript niet in staat is een referentie te vinden naar een waarde die je probeert te beanderen.
+
+
+
+#### Antwoord: B
+
+`[]` is een truthy waarde. Met de `&&` operator wordt de rechter waarde geretourneerd wanneer de linker waarde een truthy waarde bevat. In dit geval is de linker waarde `[]` een truthy waarde, daarom wordt `"Im'` geretourneerd.
+
+`""` is een falsy waarde. Als de linker waarde falsy is wordt er niets geretourneerd. `n't` wordt niet geretourneerd.
+
+
+
+#### Antwoord: C
+
+Met de `||` (or) operator kunnen we de eerste truthy waarde retourneren. Als alle waarden falsy zijn wordt de laatste waarde geretourneerd.
+
+`(false || {} || null)`: het lege object `{}` is een truthy waarde. Dit is de eerste (en enige) truthy waarde en zal worden geretourneerd. `one` is gelijk aan `{}`.
+
+`(null || false || "")`: alle waarden zijn falsy waarden. Dit betekent dat de laatste waarde, `""`, wordt geretourneerd. `two` is gelijk aan `""`.
+
+`([] || 0 || "")`: de lege array `[]` is een truthy waarde. Dit is de eerste truthy waarde en wordt geretourneerd. `three` is gelijk aan `[]`.
+
+
+
+#### Antwoord: D
+
+Met een promise zeggen we eigenlijk _Ik wil deze functie uitvoeren, maar voor nu zet ik hem even weg omdat de uitvoer even kan duren. Alleen wanneer een bepaalde waarde is opgelost (of afgewezen), en wanneer de call stack leeg is, wil ik deze waarde gebruiken._
+
+We kunnen deze waarde verkrijgen met `.then` en het keyword `await` is een `async` function. Ook al kunnen we de teruggegeven waarde verkrijgen met zowel `.then` als `await`, toch werken ze allebei anders.
+
+In de functie `firstFunction` zetten we de myPromise functie (soort van) even aan de kant terwijl het wordt uitgevoerd en voeren we de rest van de code uit, wat `console.log('second')` is in dit geval. Daarna wordt de promise opgelost en zal de string `I have resolved` worden geretourneerd, wat gelogd zal worden nadat het zag dat de callstack leeg was.
+
+Met de keyword `await` in de functie `secondFunction` pauzeren we letterlijk de executie van een async functie totdat de promise is opgelost voordat de rest van de functie wordt uitgevoerd.
+
+Dit betekent dat het wacht tot de `myPromise` is opgelost met de waarde `I have resolved`, en alleen als dat gebeurt gaan we naar de volgende regel: `second` wordt gelogd.
+
+
+
+#### Antwoord: C
+
+De `+` operator wordt niet alleen gebruikt voor het optellen van numerieke waarden, maar wordt ook gebruikt om strings te concateneren. Zodra de JavaScript engine ziet dat één van de waarden niet een numerieke waarde bevat, wordt het getal omgezet naar een string.
+
+De eerste is een `1`, wat een numerieke waarde is. `1 + 2` retourneert het getal 3.
+
+Echter, de tweede is de string `"Lydia"`. `"Lydia"` is een string en `2` is een getal: `2` wordt omgezet naar een string. `"Lydia"` en `"2"` worden geconcateneerd wat resulteert in de string `"Lydia2"`.
+
+`{ name: "Lydia" }` is een object. Een getal noch een object is een string, dus beide worden gestringified. Wanneer we een regulier object stringifiën levert dit `"[object Object]"` op. `"[object Object]"` geconcateneerd met `"2"` wordt `"[object Object]2"`.
+
+
+
+#### Antwoord: C
+
+We kunnen elk type of waarde meegeven aan `Promise.resolve`, zowel een promise als een niet-promise. De methode zelf retourneert een promise met een opgeloste waarde (`
+
+#### Antwoord: B
+
+Objecten worden doorgegeven _by reference_. Wanneer we objecten vergelijken op type en gelijkenis (`===`), vergelijken we hun referenties.
+
+We zetten de standaard waarde voor `person2` gelijk aan het object `person` en geven het object `person` door als de waarde voor het argument `person1`.
+
+Dit betekent dat beide waarden een referentie hebben naar dezelfde plek in het geheugen, dus zijn ze gelijk.
+
+De code in de `else` statement wordt uitgevoerd en `They are the same!` wordt gelogd.
+
+
+
+#### Antwoord: D
+
+In JavaScript kunnen we properties van een object op twee manieren benaderen: blokhaken of met een punt notitie. In dit voorbeeld gebruiken we de punt notatie (`colorConfig.colors`) in plaats van blokhaken (`colorConfig["colors"]`).
+
+Met de punt notatie zal JavaScript proberen om de propertie van een object te vinden met exact dezelfde naam. In dit voorbeeld probeert JavaScript een propertie te vinden met de naam `colors` uit het `colorConfig` object. Er is geen property genaamd `colors` dus wordt `undefined` geretourneerd. Dan proberen we de waarde van het eerste element te benaderen door gebruik te maken van `[1]`. We kunnen dit niet doen op een waarde die `undefined` is, dus wordt er een `TypeError` gegooid: `Cannot read property '1' of undefined`.
+
+JavaScript interpreteert (of beter gezegd unboxed) statements. Wanneer we blokhaken gebruiken ziet het de eerste blokhaak `[` en blijft doorgaan totdat het de tweede blokhaak `]` vindt. Alleen dan zal het het statement evalueren. Als we `colorConfig[colors[1]]` hadden gebruikt zou het de waarde van de `red` propertie teruggeven van het `colorConfig` object.
+
+
+
+#### Antwoord: A
+
+Onder de motorkap zijn emojis unicodes. De unicodes voor het hart zijn `"U+2764 U+FE0F"`. Deze zijn altijd hetzelfde voor dezelfde emojis. We vergelijken twee gelijke string met elkaar, wat true retourneert.
+
+
+
+#### Antwoord: D
+
+Met de `splice` methode passen we de originele array aan door elementen te verwijderen, te vervangen of toe te voegen. In dit geval hebben we 2 elementen verwijderd vanaf index 1 (we hebben `'🥑'` en `'😍'` verwijderd) en hebben in plaats daarvan ✨ toegevoegd.
+
+`map`, `filter` en `slice` geven een nieuwe array terug, `find` geeft een element terug en `reduce` geeft een gereduceerde waarde terug.
+
+
+
+#### Antwoord: A
+
+We zetten de waarde van de property `favoriteFood` op het object `info` gelijk aan de string met de pizza emoji, `'🍕'`. Een string is een primitief data type. In JavaScript zijn primitieve data types _by reference_.
+
+In JavaScript interacteren primitieve data types (alles dat geen object is) _by value_. In dit geval zetten we de waarde van de property `favoriteFood` op het object `info` gelijk aan de waarde van het eerste element in de `food` array, de string met de pizza emoji in dit geval (`'🍕'`). Een string is een primitief data type en interacteert _by value_ (neem een kijkje op mijn [blogpost](https://www.theavocoder.com/complete-javascript/2018/12/21/by-value-vs-by-reference) als je geïntereseerd bent om hierover meer te leren).
+
+Daarna veranderen we de waarde van de property `favoriteFood` op het object `info`. De `food` array is niet veranderd omdat de waarde van `favoriteFood` een _kopie_ bevat van de waarde van het eerste element van de array, en geen referentie heeft naar dezelfde plek in het geheugen van de element in `food[0]`. Wanneer we food loggen is het nog steeds dezelfde array, `['🍕', '🍫', '🥑', '🍔']`.
+
+
+
+#### Antwoord: A
+
+Met de `JSON.parse()` methode kunnen we een JSON string parsen naar een JavaScript waarde.
+
+```javascript
+// Stringifying een nummer naar valide JSON, daarna de JSON string parsen naar een JavaScript waarde:
+const jsonNumber = JSON.stringify(4) // '4'
+JSON.parse(jsonNumber) // 4
+
+// Stringifying een array waarde naar een valide JSON, daarna de JSON string parsen naar een JavaScript waarde:
+const jsonArray = JSON.stringify([1, 2, 3]) // '[1, 2, 3]'
+JSON.parse(jsonArray) // [1, 2, 3]
+
+// Stringifying een object naar valide JSON, daarna de JSON string parsen naar een JavaScript waarde:
+const jsonArray = JSON.stringify({ name: "Lydia" }) // '{"name":"Lydia"}'
+JSON.parse(jsonArray) // { name: 'Lydia' }
+```
+
+
+
+#### Antwoord: D
+
+Elke functie heeft zijn eigen _execution context_ (of _scope_). De `getName` functie zoekt eerst binnen zijn eigen context (scope) om te kijken of het de variabele `name` bevat, die we proberen te benaderen. In dit geval bevat de `getName` functie zijn eigen `name` variabele: we declareren de variabele `name` met het keyword `let` en met de waarde `'Sarah'`.
+
+Variabelen gedeclareerd met het keyword `let` (en `const`) worden gehoisted, maar worden niet, zoals met het keyword `var`, geïnitialiseerd. Ze zijn niet benaderbaar voor de lijn waar we ze declareren (initialiseren). Dit wordt de "temporal dead zone" genoemd. Wanneer we de variabelen proberen te benaderen voordat ze gedeclareerd zijn zal JavaScript een `ReferenceError` gooien.
+
+Als we de variabele `name` **niet** niet hadden gedeclareerd binnen de `getName` functie zou de JavaScript engine doorgezocht hebben door de _scope chain_. De bovenliggende scope heeft een variabele `name` met de waarde `Lydia`. In dat geval zou `Lydia` gelogged worden.
+
+```javascript
+let name = 'Lydia'
+
+function getName() {
+ console.log(name)
+}
+
+getName() // Lydia
+```
+
+
+
+#### Antwoord: C
+
+Met het keyword `yield` , we `yield` waarden in een generator functie. Met het keyword `yield*`, we `yield` waarden van een andere generator functie, of iterabel object (bijvoorbeeld een array).
+
+In `generatorOne` leveren we de volledige array `['a', 'b', 'c']` op, gebruikmakend van het keyword `yield`. De waarde van de propertie `value` op het object geretourneerd door de `next` methode op `one` (`one.next().value`) is gelijk aan de volledige array `['a', 'b', 'c']`.
+
+```javascript
+console.log(one.next().value) // ['a', 'b', 'c']
+console.log(one.next().value) // undefined
+```
+
+In `generatorTwo` gebruiken we het keyword `yield*`. Dit betekent dat de eerste opgeleverde waarde van `two` is gelijk aan de eerste opgeleverde waarde in de iterator. The iterator is de array `['a', 'b', 'c']`. De eerste opgeleverde waarde is `a`, dus de eerste keer dat we `two.next().value` aanroepen wordt `a` geretourneerd.
+
+```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
+```
+
+
+
+#### Antwoord: A
+
+Expressies binnen template literals worden eerste geëvalueerd. Dit betekent dat de string de geretourneerde waarde zal bevatten van de expressie, de direct aangeroepen functie `(x => x)('I love')` in dit geval. We geven de waarde `'I love'` mee als een argument aan de arrow functie `x => x`. `x` is gelijk aan `'I love'`, wat geretourneerd zal worden. Dit resulteert in `I love to program`.
+
+
+
+#### Antwoord: C
+
+Normaal als we objecten gelijk maken aan `null` worden deze objecten opgeruimd door de _garbage collector_, omdat er geen referentie meer is naar het object. Echter, omdat de callback functie binnen `setInterval` een arrow functie is (en dus verbonden is aan het `config` object) zal de callback functie nog steeds een referentie behouden naar het `config` object. Zolang er een referentie is zal de _garbage collector_ het object niet opruimen. Omdat het niet opgeruimd wordt door de _garbage collector_ zal de `setInterval` callback functie nog steeds iedere 1000ms (1s) aangeroepen worden.
+
+
+
+#### Antwoord: B
+
+Als een **key/value** paar wordt toegevoegd gebruikmakend van de `set` methode zal de **key** de waarde zijn van het eerste argument dat zal worden meegegeven aan de `set` functie, en de **value** zal het tweede argument zijn die wordt meegegeven aan de `set` functie. De **key** is de _functie_ `() => 'greeting'` in dit geval, en de waarde `'Hello world'`. `myMap` is nu `{ () => 'greeting' => 'Hello world!' }`.
+
+1 is verkeerd omdat de **key** niet `'greeting'` is, maar `() => 'greeting'`.
+3 is verkeerd omdat we een nieuwe functie creëeren door het mee te geven als een parameter aan de `get` methode. Object interacteert _by reference_. Een functie is een object, dit is ook waarom twee functies nooit strict gelijk zijn. Zelfs niet als ze identiek zijn: ze hebben een referentie naar een andere plek in het geheugen.
+
+
+
+#### Antwoord: C
+
+De functies `changeAge` en `changeAgeAndName` hebben beiden een standaard parameter, namelijk het _nieuw_ aangemaakte object `{ ...person }`. Dit object bevat kopieën van alle key/value paren in het `person` object.
+
+Als eerste roepen we de `changeAge` functie aan en geven het object `person` mee als argument. Deze functie verhoogt de waarde van de propertie `age` met 1. `person` is nu `{ name: "Lydia", age: 22 }`.
+
+Dan roepen we de functie `changeAgeAndName` aan, echter geven we geen parameter mee. In plaats daarvan is de waarde van `x` gelijk aan een _nieuw_ object: `{ ...person }`. Omdat het een nieuw object is heeft het geen effect op de waarden van de properties van het object `person`. `person` is nog steeds gelijk aan `{ name: "Lydia", age: 22 }`.
+
+
+
+#### Antwoord: C
+
+Met de spread operator `...` kunnen we iterabelen _ontplooien_ tot individuele elementen. De `sumValues` functie krijgt drie argumenten mee: `x`, `y` en `z`. `...[1, 2, 3]` zal resulteren in `1, 2, 3`, wat we meegeven aan de functie `sumValues`.
+
+
+
+#### Antwoord: B
+
+Met de `+=` operator verhogen we de waarde van `num` met `1`. `num` heeft een initiële waarde van `1`, dus `1 + 1` is `2`. Het element met de index 2 in de `list` array is 🥰, `console.log(list[2])` logt 🥰.
+
+
+
+#### Antwoord: B
+
+Met de _optional chaining operator_ `?.` hoeven we niet langer expliciet te checken of een dieper geneste waarde valide is, of niet. Als we een propertie proberen te benaderen op een `undefined` of `null` waarde (_nullish_) zal de expressie stoppen en `undefined` retourneren.
+
+`person.pet?.name`: `person` heeft een propertie genaamd `pet`: `person.pet` is niet _nullish_. Het heeft een propertie genaamd ``name` en retourneerd `Mara`.
+`person.pet?.family?.name`: `person` heeft een propertie genaamd `pet`: `person.pet` is niet _nullish_. `pet` heeft _geen_ propertie genaamd `family`, `person.pet.family` is _nullish_. De expressie geeft `undefined` terug.
+`person.getFullName?.()`: `person` heeft een propertie genaamd `getFullName`: `person.getFullName()` is niet __nullish__ en kan worden aangeroepen, wat `Lydia Hallie` retourneerd.
+`member.getLastName?.()`: `member` is niet gedefinieerd: `member.getLastName()` is _nullish_. The expressie geeft `undefined` terug.
+
+
+
+#### Antwoord: B
+
+We geven de conditie `groceries.indexOf("banana")` mee aan de if-statement. `groceries.indexOf("banana")` geeft `0` terug, wat een _falsy_ waarde is.Omdat de conditie in de if-statement _falsy_ is wordt de code in de else-statement uitgevoerd, en `We don't have to buy bananas!` wordt gelogd.
+
+
+
+#### Antwoord: D
+
+De `language` methode is een `setter`. Setters hebben geen werkelijke waarde. Hun doel is om properties te _wijzigen_. Wanneer een `setter` methode wordt aangeroepen wordt `undefined` geretourneerd.
+
+
+
+#### Antwoord: C
+
+`typeof name` retourneert `"string"`. De string `"string"` is een _truthy_ waarde, dus `!typeof name` retourneert de boolean waarde `false`. `false === "object"` en `false === "string"` retourneren beiden `false`.
+
+(Als we wilden checken of het type (on)gelijk is aan een bepaald type, zouden we `!==` moeten gebruiken in plaats van `!typeof`)
+
+
+
+#### Antwoord: A
+
+De `add` functie retourneert een arrow functie, die een arrow functie retourneert, die ook weer een arrow functie retourneert. De eerste functie krijgt een argument `x` mee met de waarde `4`. We roepen de tweede functie aan, welke een argument `y` meekrijgt met de waarde `5`. Dan roepen we de derde functie aan en die krijgt het argument `z` meet met de waarde `6`. Wanneer we de waarden proberen op te vragen van `x`, `y` en `z` ind e laatste arrow functie de JavaScript engine gaat omhoog in de _scope chain_ om de waarden van `x` en `y` te vinden. Dit retourneert `4` `5` `6`.
+
+
+
+#### Antwoord: C
+
+De generator functie `range` retourneert een async object met promises voor elk item in de range die we meegeven: `Promise{1}`, `Promise{2}`, `Promise{3}`. We zetten de variabele `gen` gelijk aan het async object, waarnaar we eroverheen iteraten gebruikmakend van een `for await ... of` loop. We zetten de variabele `item` gelijk aan de promises die geretourneerd worden: eerst `Promise{1}`, dan `Promise{2}` en dan `Promise{3}`. Omdat we de waarde van `item` _awaiten_, de opgeloste promise, worden de opgeloste _waarden_ van de promises geretourneerd: `1`, `2` en `3`.
+
+
+
+#### Antwoord: D
+
+De functie `myFunc` verwacht een object met de properties `x`, `y` en `z` als haar argument. Omdat we maar drie separate numerieke waarden (1, 2, 3) meegeven in plaats van één object met de properties `x`, `y` en `z` ({x: 1, y: 2, z: 3}), hebben `x`, `y` en `z` hun default waarde `undefined`.
+
+
+
+#### Antwoord: B
+
+Met de `Intl.NumberFormat` methode kunnen we numerieke waarden formatteren naar elke lokale format. We formatteren de numerieke waarde `130` naar de lokale waarde van `en-US` als een `unit` in `mile-per-hour`, wat resulteert in `130 mph`. De numerieke waarde `300` naar de lokale waarde van `en-US` als een `currency` in `USD`, wat resulteert in `€300.00`.
+
+
+
+#### Antwoord: B
+
+Door objecten te destructureren (_destructuring_) kunnen we de values van een object uitpakken en een uitgepakte waarde toewijzen aan de key van dezelfde property. In dit geval wijzen we de waarde "💀" toe aan `spookyItems[3]`. Dit betekent dat we de array `spookyItems` aanpassen, we voegen namelijk "💀" toe. Wanneer we de array `spookyItems` loggen wordt `["👻", "🎃", "🕸", "💀"]` gelogd.
+
+
+
+#### Antwoord: C
+
+Met de `Number.isNaN` methode kunnen je checken of de waarde die je meegeeft een _numerieke waarde_ is en gelijk is aan `NaN`. `name` is niet een numerieke waarde en `Number.isNaN(name)` zal `false` teruggeven. `age` is een numerieke waarde, maar is niet gelijk aan `NaN`. `Number.isNaN(age)` zal `false` teruggeven.
+
+Met de `isNaN` methode kun je checken of een waarde die je meegeeft geen numerieke waarde is. `name` is geen numerieke waarde, dus `isNaN(name)` geeft `true` terug. `age` is wel een numerieke waarde, dus `isNaN(age)` geeft `false` terug.
+
+
+
+#### Antwoord: 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.
+
+
+
+#### Antwoord: C
+
+In de `try` statement loggen we de _awaited_ waarde van de `myPromise` variabele: `"Woah some cool data"`. Omdat er geen errors gegooid worden in de `try` statement komt de code niet in de `catch`. De code in de `finally` statement wordt _altijd_ uitgevoerd, `"Oh finally!"` wordt gelogd.
+
+
+
+#### Antwoord: B
+
+Met de `flat` methode kunnen we een nieuwe platgemaakte array maken. De diepte van de platgemaakte array hangt af van de waarde die we meegeven. In dit geval geven we de waarde `1` mee (wat eigenlijk niet had gehoeven omdat dit de standaard waarde is), wat betekent dat alleen de arrays van het eerste niveau geconcateneerd worden. `['🥑']` en `['✨', '✨', ['🍕', '🍕']]` in dit geval. Het concateneren van deze twee arrays resulteert in `['🥑', '✨', '✨', ['🍕', '🍕']]`.
+
+
+
+#### Antwoord: D
+
+`counterOne` is een instantie van de `Counter` class. De counter class bevat een `count` propertie op de constructor en een `increment` methode.Eerst roepen we de `increment` methode twee keer aan door `counterOne.increment()` aan te roepen. Op dat moment is `counterOne.count` gelijk aan `2`.
+
+
+
+#### Antwoord: D
+
+Eerst roepen we `funcOne` aan. Op de eerste regel van `funcOne` roepen we de promise `myPromise` aan, wat een _asynchrone_ operatie is. Zolang de JavaScript engine bezig is met het afmaken van de promise wordt de rest van de functie `funcOne` uitgevoerd. De volgende regel is een _asynchrone_ `setTimeout` functie, waarvan de callback functie naar de Web API wordt gestuurd.
+
+Zowel de promise als de timeout zijn _asynchrone_ operaties en de functie worden uitgevoerd terwijl de engine bezig is om de promise uit te voeren en de `setTimeout` callback functie af te handelen. Dit betekent dat `Last line!` als eerste wordt gelogd, omdat dit geen _asynchrone_ operatie is. Dit is de laatste regel van `funcOne`. Ondertussen wordt de promise opgelost en `Promise!` wordt gelogd. Echter, omdat we `funcTwo()` aanroepen en de callstack nog niet leeg is kan de callback van de `setTimeout` functie nog niet toegevoegd worden aan de callstack.
+
+In `funcTwo` wachten we eerst op de promise `myPromise`. Met het keyword `await` pauzeren we de executie van de functie totdat de promise iets teruggeeft (of afwijst). Dan loggen we de _awaited_ waarde van `res` (omdat de promise zelf een promise retourneert). Dit logt `Promise!`.
+
+De volgende regel is de _asynchrone_ `setTimeout` functie waarvan de callback functie naar de Web API gestuurd wordt.
+
+We komen op de laatste regel van `funcTwo` wat `Last line!` logt naar het console. Omdat `funcTwo` van de callstack gaat is de callstack leeg. De callback functies die in de wachtrij stonden (`() => console.log("Timeout!")` van `funcOne` en `() => console.log("Timeout!")` van `funcTwo`) worden nu één voor één toegevoegd aan de callstack. De eerste callback functie logt `Timeout!` en wordt verwijderd van de callstack. De tweede callback functie logt dan `Timeout!` en wordt verwijderd van de callstack. Dit logt `Last line! Promise! Promise! Last line! Timeout! Timeout!`.
+
+
+
+#### Antwoord: C
+
+Met het sterretje `*` importeren we alle geëxporteerde waarden van een bestand, zowel de default als de benaamde. Als we het volgende bestand hadden:
+
+```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);
+```
+
+Het volgende zou gelogd worden:
+
+```javascript
+{
+ default: "I love JavaScript",
+ name: "Lydia",
+ age: 21
+}
+```
+
+Voor het `sum` voorbeeld betekent dit dat de geïmporteerde waarde `sum` eruit ziet als:
+
+```javascript
+{ default: function sum(x) { return x + x } }
+```
+
+We kunnen deze functie aanvoeren door `sum.default` aan te roepen.
+
+
+
+#### Antwoord: C
+
+Met het Proxy object kunnen we functionaliteit toevoegen aan een object als we dit meegeven als tweede argument. In dit geval geven we het object `handler` mee wat de volgende properties bevat: `set` en `get`. `set` wordt aangeroepen elke keer als we een waarde van een propertie _zetten_. `get` wordt aangeroepen elke keer als we een propertie waarde opvragen.
+
+Het eerste argument is een leeg object `{}` wat de waarde is van `person`. Aan dit object wordt de functionaliteit toegevoegd die gespecificeerd is in het object `handler`. Als we een propertie toevoegen aan het object `person` wordt `set` uitgevoerd. Als we een propertie benaderen op het object `person` wordt `get` uitgevoerd.
+
+Als eerste voegen we de propertie `name` toe aan het proxy object (`person.name = "Lydia"`). `set` wordt aangeroepen en `"Added a new property!"` wordt gelogd.
+
+Dan vragen we de waarde van een propertie op het proxy object op en `get` van het `handler` object wordt aangeroepen. `"Accessed a property!"` wordt gelogd.
+
+
+
+#### Antwoord: A
+
+Met `Object.seal` kunnen we voorkomen dat nieuwe properties kunnen worden _toegevoegd_ of bestaande properties worden _verwijderd_.
+
+Echter kunnen van de bestaande properties nog steeds aanpassen.
+
+
+
+#### Antwoord: C
+
+De `Object.freeze` methode _bevriest_ een object. Geen enkele propertie van worden toegevoegd, aangepast worden of worden verwijderd.
+
+Echter wordt het object enkel _oppervlakkig_ bevroren wat betekent dat alleen _directe_ properties bevroren zijn. Als de propertie een ander object is, zoals `address` in dit geval, zijn de properties van dat object niet bevroren en kunnen wel worden aangepast.
+
+
+
+#### Antwoord: A
+
+Eerst roepen we de functie `myFunc()` aan zonder argumenten mee te geven. Omdat we geen argumenten meegeven, `num` en `value` behouden hun standaard waarde: num is `2`, en `value` de geretourneerde waarde van de functie `add`. Aan de functie `add` geven we `num` als argument mee, wat de waarde `2` heeft. `add` retourneert `4` wat de waarde is van `value`.
+
+Daarna roepen we de functie `myFunc(3)` aan het geven `3` meet als de waarde voor het argument `num`. We geven het argument `value` niet mee. Omdat we geen waarde meegeven voor het argument `value` krijgt het de standaard waarde: het retourneert de waarde van de `add` functie. Aan de functie `add` geven we `num` mee, wat de waarde `3` bevat. `add` retourneert `6` wat op dat moment de waarde is van `value`.
+
+
+
+#### Antwoord: D
+
+In ES2020 kunnen we private variabelen toevoegen aan classes door gebruik te maken van `#`. We kunnen deze variabelen niet benaderen van buitenaf. Wanneer we `counter.#number` proberen te loggen wordt er een SuntaxError gegooid: we cannot acccess it outside the `Counter` class!
+
+
+
+#### Antwoord: B
+
+Om te kunnen itereren over de `members` in elk element in de array `teams` moeten we `teams[i].members` meegeven aan de `getMembers` generator functie. De generator functie retourneert een generator object. Om te kunnen itereren over elk element in het generator object moeten we `yield*` gebruiken.
+
+Als we `yield`, `return yield`, of `return` hadden geschreven zou de gehele generator functie geretourneerd worden tijdens de eerste keer dat we de `next` methode aanriepen.
+
+
+
+#### Antwoord: C
+
+De functie `addHobby` ontvangt twee arguemnten, `hobby` en `hobbies` met als standaard waarde de waarde van de array `hobbies` op het object `person`.
+
+Eerst roepen we de functie `addHobby` aan en geven `"running"` mee als de waarde voor `hobby`, en een lege array als de waarde voor `hobbies`. Omdat we een lege array meegeven als de waarde voor `hobbies` wordt `"running"` toegevoegd aan deze lege array.
+
+Daarna roepen we de functie `addHobby` aan en geven `"dancing"` mee als de waarde voor `hobby`. We gaven geen waarde mee voor `hobbies` dus krijgt het de standaard waarde, de propertie `hobbies` op het object `person`. We pushen daar de hobby `dancing` naar de array `person.hobbies`.
+
+Als laatste roepen we de functie `addHobby` aan en geven `"baking"` als de waarde voor `hobby` en de array `person.hobbies` als de waarde voor `hobbies`. We pushen de hobby `baking` naar de array `person.hobbies`.
+
+Na het pushen van `dancing` en `baking` is de waarde van `person.hobbies` gelijk aan `["coding", "dancing", "baking"]`.
+
+
+
+#### Antwoord: B
+
+We declareren de variabele `pet`, wat een instantie is van de class `Flamingo`. Wanneer we deze instantie instantiëren wordt de `constructor` op `Flamingo` aangeroepen. Als eerste wordt `"I'm pink. 🌸"` gelogd, waarna we `super()` aanroepen. `super()` roept de constructor van de bovenliggende class aan, `Bird` in dit geval. De constructor op `Bird` wordt aangeroepen en logt `"I'm a bird. 🦢"`.
+
+
+
+#### Antwoord: D
+
+Het keyword `const` betekent simpelweg dat we de waarde van de variabele niet opnieuw kunnen _declareren_. Het is _read-only_. Echter, de waarde zelf is niet onaanpasbaar. De properties van de array `emojis` kunnen worden aangepast, bijvoorbeeld door nieuwe waarden te pushen, te splicen of door de lengte van de array op 0 te zetten.
+
+
+
+#### Antwoord: C
+
+Objecten zijn standaard niet itereerbaar. Een _iterable_ is een _iterable_ als het _iterator protocol_ aanwezig is. We kunnen dit met de iterator symbol `[Symbol.iterator]` handmatig toevoegen, wat een generator object zal moeten teruggeven. Bijvoorbeeld door het een generator functie te maken: `*[Symbol.iterator]() {}`. Deze generator functie moet de `Object.values` afgeven van het object `person` als we de array `["Lydia Hallie", 21]`: `yield* Object.values(this)` terug willen geven.
+
+
+Od podstawowych do zaawansowanych: sprawdź, jak dobrze znasz JavaScript, odśwież swoją wiedzę lub przygotuj się do rozmowy kwalifikacyjnej! :muscle: :rocket: Regularnie aktualizuję to repozytorium nowymi pytaniami. Odpowiedzi znajdują się w ukrytych zakładkach poniżej pytań - po prostu kliknij, aby je rozwinięć. To dla zabawy, powodzenia! :heart: Nie krępuj się ze mną kontaktować! 😊
+Instagram || Twitter || LinkedIn || Blog
+
+
+- [🇸🇦 العربية](./ar-AR/README_AR.md)
+- [🇪🇬 اللغة العامية](./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)
+- [🇮🇩 Indonesia](./id-ID/README.md)
+- [🇮🇹 Italiano](./it-IT/README.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)
+- [🇷o Română](../ro-RO/README.ro.md)
+- [🇷🇺 Русский](./ru-RU/README.md)
+- [🇽🇰 Shqip](../sq-KS/README_sq_KS.md)
+- [🇹🇭 ไทย](./th-TH/README-th_TH.md)
+- [🇹🇷 Türkçe](./tr-TR/README-tr_TR.md)
+- [🇺🇦 Українська мова](./uk-UA/README.md)
+- [🇻🇳 Tiếng Việt](./vi-VI/README-vi.md)
+- [🇨🇳 简体中文](./zh-CN/README-zh_CN.md)
+- [🇹🇼 繁體中文](./zh-TW/README_zh-TW.md)
+
+
+
+#### Odpowiedź: D
+
+Wewnątrz funkcji najpierw deklarujemy zmienną `name` za pomocą słowa kluczowego `var`. Oznacza to, że zmienna jest "wyciągana" (przestrzeń pamięci jest tworzona) z domyślną wartością `undefined` podczas fazy tworzenia, aż do momentu, gdy naprawdę definiujemy zmienną. W linii, w której próbujemy wyświetlić w konsoli zmienną `name`, jeszcze jej nie zdefiniowaliśmy, więc nadal przechowuje wartość `undefined`.
+
+Zmienne zadeklarowane za pomocą słowa kluczowego `let` (i `const`) są wyciągane, ale w przeciwieństwie do `var`, nie są inicjalizowane. Nie są dostępne przed linią, na której je deklarujemy (inicjalizujemy). Nazywa się to "czasową strefą martwą" (temporal dead zone). Gdy próbujemy uzyskać dostęp do zmiennych przed ich zadeklarowaniem, JavaScript generuje błąd `ReferenceError`.
+
+
+
+#### Odpowiedź: C
+
+Ze względu na kolejkę zdarzeń w JavaScript, funkcja zwrotna `setTimeout` jest wywoływana _po_ wykonaniu pętli. Ponieważ zmienna `i` w pierwszej pętli została zadeklarowana za pomocą słowa kluczowego `var`, jej wartość była globalna. Podczas pętli inkrementowaliśmy wartość `i` o `1` za każdym razem, używając operatora jednoargumentowego `++`. W momencie wywołania funkcji zwrotnej `setTimeout`, `i` miało wartość `3` w pierwszym przykładzie.
+
+W drugiej pętli zmienna `i` została zadeklarowana za pomocą słowa kluczowego `let`: zmienne zadeklarowane za pomocą słowa kluczowego `let` (i `const`) mają zakres blokowy (blokiem jest cokolwiek między `{ }`). Podczas każdej iteracji `i` będzie miało nową wartość, a każda wartość będzie miała zakres wewnątrz pętli.
+
+
+
+#### Odpowiedź: B
+
+Zwróć uwagę, że wartość `diameter` jest zwykłą funkcją, podczas gdy wartość `perimeter` jest funkcją strzałkową.
+
+W przypadku funkcji strzałkowych, słowo kluczowe `this` odnosi się do bieżącego otaczającego zakresu, w przeciwieństwie do zwykłych funkcji! Oznacza to, że gdy wywołujemy `perimeter`, nie odnosi się ono do obiektu shape, ale do swojego otaczającego zakresu (np. okna).
+
+Na tym obiekcie nie ma wartości `radius`, co powoduje zwrócenie `NaN` (Not a Number).
+
+
+
+#### Odpowiedź: A
+
+Operator jednoargumentowy plus próbuje przekonwertować operand na liczbę. `true` jest równoważne `1`, a `false` jest równoważne `0`.
+
+Łańcuch znaków `'Lydia'` jest wartością prawdziwą. Tak naprawdę pytamy, "czy ta wartość prawdziwa jest fałszywa?". To zwraca `false`.
+
+
+
+#### Odpowiedź: A
+
+W JavaScript wszystkie klucze obiektów są stringami (chyba że są to symbole). Nawet jeśli nie wpisujemy ich jako stringi, zawsze są one konwertowane na stringi wewnątrz.
+
+JavaScript interpretuje (lub "odpakuowuje") instrukcje. Gdy używamy notacji nawiasów kwadratowych, interpreter widzi pierwszy otwierający nawias `[` i kontynuuje do momentu znalezienia zamykającego nawiasu `]`. Dopiero wtedy ocenia tę instrukcję.
+
+`mouse[bird.size]`: Najpierw ocenia `bird.size`, które wynosi `"small"`. `mouse["small"]` zwraca `true`.
+
+Jednakże, w przypadku notacji kropkowej, to się nie dzieje. `mouse` nie ma klucza o nazwie `bird`, co oznacza, że `mouse.bird` jest `undefined`. Następnie pytamy o `size` używając notacji kropkowej: `mouse.bird.size`. Ponieważ `mouse.bird` jest `undefined`, tak naprawdę pytamy o `undefined.size`. To nie jest poprawne i spowoduje błąd podobny do `Cannot read property "size" of undefined` (Nie można odczytać właściwości "size" z undefined).
+
+
+
+#### Odpowiedź: A
+
+W JavaScript wszystkie obiekty komunikują się ze sobą przez _referencje_, gdy są sobie przypisywane.
+
+Na początku zmienna `c` przechowuje referencję do obiektu. Później przypisujemy zmiennej `d` tę samą referencję, którą ma `c`, do tego obiektu.
+
+
+
+#### Odpowiedź: C
+
+`new Number()` jest wbudowanym konstruktorem funkcji. Chociaż wygląda jak liczba, nie jest faktycznie liczbą: ma wiele dodatkowych funkcji i jest obiektem.
+
+Gdy używamy operatora `==` (operator równości), sprawdza on jedynie, czy mają tą samą _wartość_. Oba mają wartość `3`, więc zwraca `true`.
+
+Jednak gdy używamy operatora `===` (operator ścisłej równości), zarówno wartość, jak i typ powinny być takie same. Tutaj nie są: `new Number()` nie jest liczbą, lecz **obiektem**. Oba zwracają `false`.
+
+
+
+#### Odpowiedź: D
+
+Funkcja `colorChange` jest statyczna. Metody statyczne są zaprojektowane tak, aby istniały tylko w konstruktorze, w którym zostały utworzone, i nie mogą być przekazywane do żadnych potomków (children) ani wywoływane na instancjach klasy. Ponieważ `freddie` jest instancją klasy Chameleon, funkcja nie może być na niej wywołana. Otrzymujemy błąd `TypeError`.
+
+
+
+#### Odpowiedź: A
+
+Kod wypisuje w konsoli obiekt, ponieważ właśnie utworzyliśmy pusty obiekt w obiekcie globalnym! Gdy pomyłkowo wpisaliśmy `greeting` jako `greetign`, interpreter JavaScript faktycznie zobaczył to jako:
+
+1. `global.greetign = {}` w Node.js.
+2. `window.greetign = {}`, `frames.greetign = {}` i `self.greetign` w przeglądarkach.
+3. `self.greetign` w web workerach.
+4. `globalThis.greetign` we wszystkich środowiskach.
+
+Aby temu zapobiec, możemy użyć `"use strict"`. Powoduje to, że musisz zadeklarować zmienną przed jej przypisaniem.
+
+
+
+#### Odpowiedź: A
+
+Jest to możliwe w JavaScript, ponieważ funkcje są obiektami! (Wszystko oprócz typów prymitywnych jest obiektem)
+
+Funkcja jest specjalnym rodzajem obiektu. Kod, który sam piszesz, nie jest właściwą funkcją. Funkcja jest obiektem posiadającym właściwość, która jest wywoływalna.
+
+
+
+#### Odpowiedź: A
+
+W JavaScript funkcje są obiektami, więc metoda `getFullName` jest dodawana do samego obiektu funkcji konstruktora. Dlatego możemy wywołać `Person.getFullName()`, ale `member.getFullName` zwraca błąd `TypeError`.
+
+Jeśli chcesz, aby metoda była dostępna dla wszystkich instancji obiektów, musisz dodać ją do właściwości prototype:
+
+```js
+Person.prototype.getFullName = function() {
+ return `${this.firstName} ${this.lastName}`;
+};
+```
+
+
+
+#### Odpowiedź: A
+
+Dla `sarah`, nie użyliśmy słowa kluczowego `new`. Kiedy używamy `new`, `this` odwołuje się do nowego pustego obiektu, który tworzymy. Jednak jeśli nie dodajemy `new`, `this` odwołuje się do **globalnego obiektu**!
+
+Mówiliśmy, że `this.firstName` równa się `"Sarah"`, a `this.lastName` równa się `"Smith"`. Czyli faktycznie zdefiniowaliśmy `global.firstName = 'Sarah'` i `global.lastName = 'Smith'`. `sarah` pozostaje `undefined`, ponieważ nie zwracaliśmy żadnej wartości z funkcji `Person`.
+
+
+
+#### Odpowiedź: D
+
+W fazie **capturing (przechwytywanie)**, zdarzenie przechodzi przez elementy nadrzędne w doł do elementu docelowego. Następnie dociera do elementu **target (cel)** i rozpoczyna się **bubbling (bąbelkowanie)**.
+
+
+
+#### Odpowiedź: B
+
+Wszystkie obiekty mają prototypy, z wyjątkiem **obiektu bazowego**. Obiekt bazowy jest obiektem utworzonym przez użytkownika lub obiektem utworzonym przy użyciu słowa kluczowego `new`. Obiekt bazowy ma dostęp do niektórych metod i właściwości, takich jak `.toString`. Jest to powód, dla którego można używać wbudowanych metod JavaScript! Wszystkie takie metody są dostępne w prototypie. Chociaż JavaScript nie może znaleźć ich bezpośrednio w twoim obiekcie, przechodzi w dół łańcucha prototypów i je tam znajduje, co czyni je dostępnymi dla ciebie.
+
+
+
+#### Odpowiedź: C
+
+JavaScript jest językiem **dynamicznie typowanym**: nie określamy typów niektórych zmiennych. Wartości mogą być automatycznie konwertowane na inny typ bez wiedzy użytkownika, co nazywa się _implicit type coercion_. **Koercja (Wymuszenie)** to konwersja z jednego typu na inny.
+
+W tym przykładzie JavaScript konwertuje liczbę `1` na string, aby funkcja miała sens i zwróciła wartość. Podczas dodawania typu liczbowego (`1`) i typu łańcuchowego (`'2'`), liczba traktowana jest jako string. Możemy łączyć stringi takie jak `"Hello" + "World"`, więc to co się tutaj dzieje to `"1" + "2"`, które zwraca `"12"`.
+
+
+
+#### Odpowiedź: C
+
+Operator jednoargumentowy **Postfix** `++`:
+
+1. Zwraca wartość (ten zwraca `0`)
+2. Zwiększa wartość (liczba wynosi teraz `1`)
+
+Operator jednoargumentowy **Prefix** `++`:
+
+1. Zwiększa wartość (liczba wynosi teraz `2`)
+2. Zwraca wartość (to zwraca `2`)
+
+number zwraca `0 2 2`.
+
+
+
+#### Odpowiedź: B
+
+W przypadku użycia `template strings`, wartością pierwszego argumentu jest zawsze tablica wartości łańcuchowych (string). Pozostałe argumenty otrzymują wartości przekazanych wyrażeń!
+
+
+
+#### Odpowiedź: C
+
+Podczas testowania równości, liczby i ciągi znaków są porównywane przez ich _wartości_, a obiekty są porównywane przez ich _referencję_. JavaScript sprawdza, czy obiekty mają odwołanie do tej samej lokalizacji w pamięci.
+
+Dwa obiekty, które porównujemy, nie mają tej samej lokalizacji w pamięci: obiekt, który przekazujemy jako parametr, odwołuje się do innej lokalizacji w pamięci niż obiekt, którego użyliśmy do sprawdzenia równości.
+
+Dlatego też zarówno `{ age: 18 } == { age: 18 }` i `{ age: 18 } == { age: 18 }` zwracają `false`.
+
+
+
+#### Odpowiedź: C
+
+Parametr reszty (`...args`) pozwala nam "zbierać" wszystkie pozostałe argumenty do tablicy. Tablica to obiekt, więc `typeof args` zwraca `"object"`.
+
+
+
+#### Odpowiedź: C
+
+Dzięki `"use strict"` możesz upewnić się, że przypadkowo nie zadeklarujesz zmiennych globalnych. Nigdy nie zadeklarowaliśmy zmiennej `age`, a ponieważ używamy `"use strict"`, zostanie zgłoszony błąd referencji. Gdybyśmy nie użyli `"use strict"`, to by zadziałało, ponieważ właściwość `age` zostałaby dodana do obiektu globalnego.
+
+
+
+#### Odpowiedź: A
+
+`eval` oblicza kod, który przekazywany jest jako ciąg znaków. Jeśli jest to wyrażenie, tak jak w tym przypadku, oblicza ono wyrażenie. Wyrażenie to `10 * 10 + 5`. Zwraca liczbę `105`.
+
+
+
+#### Odpowiedź: B
+
+Dane przechowywane w `sessionStorage` są usuwane po zamknięciu _zakładki_.
+
+Gdybyś użył `localStorage`, dane pozostałyby tam na zawsze, chyba że na przykład wywołano by `localStorage.clear()`.
+
+
+
+#### Odpowiedź: B
+
+Za pomocą słowa kluczowego `var` można zadeklarować wiele zmiennych o tej samej nazwie. Zmienna będzie wtedy przechowywać najnowszą wartość.
+
+Nie można tego zrobić za pomocą `let` lub `const`, ponieważ są one blokowe.
+
+
+
+#### Odpowiedź: C
+
+Wszystkie klucze obiektów (z wyjątkiem symboli) są łańcuchami znaków pod względem samego obiektu, nawet jeśli nie napiszesz ich samodzielnie jako łańcucha znaków. Dlatego `obj.hasOwnProperty('1')` również zwraca true.
+
+Nie działa to w ten sam sposób dla zbioru. W zbiorze nie ma klucza `'1'`:`set.has('1')`, dlatego zwraca wartość false. Zawiera on liczbę całkowitą `1`, `set.has(1)` zwraca wartość true.
+
+
+
+#### Odpowiedź: C
+
+Jeśli masz dwa klucze o takiej samej nazwie, zostanie on zastąpiony. Nadal będzie umieszczony na pierwszej pozycji, ale z ostatnią zdefiniowaną wartością.
+
+
+
+#### Odpowiedź: A
+
+Globalny kontekst wykonania jest dostępny wszędzie w kodzie.
+
+
+
+#### Odpowiedź: C
+
+Instrukcja `continue` pomija iterację, jeśli określony warunek zwróci `true`.
+
+
+
+#### Odpowiedź: A
+
+`String` jest wbudowanym konstruktorem, do którego możemy dodawać właściwości. Dodana została metoda do jego prototypu. Prymitywne ciągi znaków są automatycznie konwertowane na obiekt typu string, generowany przez funkcję prototypu ciągu znaków. Tak więc wszystkie ciągi (obiekty typu string) mają dostęp do tej metody!
+
+
+
+#### Odpowiedź: B
+
+Klucze obiektów są automatycznie konwertowane na ciągi znaków. Próbujemy ustawić obiekt jako klucz do obiektu `a`, z wartością `123`.
+
+Jednakże, kiedy stringujemy obiekt, staje się on `"[obiekt Object]"`. Mówimy więc, że `a["[obiekt Object]"] = 123`. Następnie próbujemy zrobić to samo. `c` jest kolejnym obiektem, który niejawnie stringujemy. Zatem `a["[obiekt Object]"] = 456`.
+
+Następnie wyświetlamy w konsoli `a[b]`, co w rzeczywistości jest `a["[obiekt Object]"]`, ustawiony wcześniej na `456`, więc zwraca `456`.
+
+
+
+#### Odpowiedź: B
+
+Mamy funkcję `setTimeout` i wywołaliśmy ją jako pierwszą. Została jednak wyświetlona jako ostatnia.
+
+Dzieje się tak, ponieważ w przeglądarkach mamy nie tylko silnik wykonawczy, ale także coś, co nazywa się `WebAPI`. Interfejs `WebAPI` daje nam na początek funkcję `setTimeout`.
+
+Po przesłaniu _callback_ do WebAPI, sama funkcja `setTimeout` (ale nie callback!) jest usuwana ze stosu.
+
+
+
+#### Odpowiedź: C
+
+Najgłębiej zagnieżdżony element, który spowodował zdarzenie jest celem zdarzenia. Możesz zatrzymać bąbelkowanie poprzez `event.stopPropagation`
+
+
+ Click here!
+
+
+#### Odpowiedź: A
+
+Jeśli klikniemy `p`, zobaczymy dwa logi: `p` i `div`. Podczas propagacji zdarzeń istnieją 3 fazy: przechwytywanie, cel i bąbelkowanie (capturing, target, and bubbling). Domyślnie, event handlery są wykonywane w fazie bąbelkowania (chyba że ustawisz `useCapture` na `true`). Przebiega ona od najgłębiej zagnieżdżonego elementu na zewnątrz.
+
+
+
+#### Odpowiedź: D
+
+W obu przypadkach możemy przekazać obiekt, do którego ma się odnosić słowo kluczowe `this`. Jednakże, `.call` jest _wykonywane natychmiast_!
+
+`.bind.` zwraca _kopię_ funkcji, ale z powiązanym kontekstem! Nie jest ona wykonywana natychmiast.
+
+
+
+#### Odpowiedź: B
+
+Funkcja `sayHi` zwraca zwróconą wartość natychmiast wywołanego wyrażenia funkcyjnego (IIFE). Ta funkcja zwróciła wartość `0`, która jest typu `"number"`.
+
+FYI: `typeof` może zwrócić następującą listę wartości: `undefined`, `boolean`, `number`, `bigint`, `string`, `symbol`, `function` i `object`. Zauważ, że `typeof null` zwraca `"object"`.
+
+
+
+#### Odpowiedź: A
+
+Istnieje 8 fałszywych wartości:
+
+- `undefined`
+- `null`
+- `NaN`
+- `false`
+- `''` (pusty ciąg)
+- `0`
+- `-0`
+- `0n` (BigInt(0))
+
+Konstruktory funkcji, takie jak `new Number` i `new Boolean` są prawdziwe.
+
+
+
+#### Odpowiedź: B
+
+`typeof 1` zwraca `"number"`.
+`typeof "number"` zwraca `"string"`.
+
+
+
+#### Odpowiedź: C
+
+Po ustawieniu wartości elementu w tablicy, która przekracza długość tablicy, JavaScript tworzy coś, co nazywa się "pustymi slotami". W rzeczywistości mają one wartość `undefined`, ale zobaczysz coś takiego jak:
+
+`[1, 2, 3, puste x 7, 11]`.
+
+w zależności od tego, gdzie go uruchomisz (jest inny dla każdej przeglądarki, node itp.).
+
+
+
+#### Odpowiedź: A
+
+Blok `catch` otrzymuje argument `x`. Nie jest to ten sam `x` co zmienna, gdy przekazujemy argumenty. Ta zmienna `x` jest blokowa.
+
+Później, ustawiamy tę blokową zmienną równą `1` i ustawiamy wartość zmiennej `y`. Teraz wyświetlamy w konsoli zmienną blokową `x`, która jest równa `1`.
+
+Poza blokiem `catch`, `x` jest wciąż `undefined`, a `y` wynosi `2`. Gdy chcemy wykonać `console.log(x)` poza blokiem `catch`, zwraca on `undefined`, a `y` zwraca `2`.
+
+
+
+#### Odpowiedź: A
+
+JavaScript ma tylko prymitywne typy i obiekty.
+
+Typy prymitywne to `boolean`, `null`, `undefined`, `bigint`, `number`, `string` i `symbol`.
+
+To, co odróżnia prymityw od obiektu, to fakt, że prymitywy nie mają żadnych właściwości ani metod; zauważysz jednak, że `'foo'.toUpperCase()` wylicza `'FOO'` i nie powoduje `TypeError`. Dzieje się tak dlatego, że gdy próbujesz uzyskać dostęp do właściwości lub metody na prymitywie takim jak ciąg znaków, JavaScript niejawnie opakuje prymitywny typ za pomocą jednej z klas opakowujących, tj. `String`, a następnie natychmiast odrzuci opakowanie po ocenie wyrażenia. Wszystkie prymitywy z wyjątkiem `null` i `undefined` wykazują to zachowanie.
+
+
+
+#### Odpowiedź: C
+
+`[1, 2]` jest naszą wartością początkową. Jest to wartość, z którą zaczynamy i wartość pierwszego `acc`.Podczas pierwszej rundy, `acc` to `[1, 2]`, a `cur` to `[0, 1]`.Łączymy je, co daje `[1, 2, 0, 1]`.
+
+Następnie `[1, 2, 0, 1]` to `acc`, a `[2, 3]` to `cur`. Łączymy je i otrzymujemy `[1, 2, 0, 1, 2, 3]`.
+
+
+
+#### Odpowiedź: B
+
+`null` jest fałszywe. `!null` zwraca `true`. `!true` zwraca `false`.
+
+`""` jest fałszywe. `!""` zwraca `true`. `!true` zwraca `false`.
+
+`1` jest prawdziwe. `!1` zwraca `false`. `!false` zwraca `true`.
+
+
+
+#### Odpowiedź: A
+
+Zwraca unikalny identyfikator. Ten identyfikator może być użyty do wyczyszczenia tego interwału za pomocą funkcji `clearInterval()`.
+
+
+
+#### Odpowiedź: A
+
+Łańcuch znaków jest iterowalny. Operator spread odwzorowuje każdy znak iterable na jeden element.
+
+
+
+#### Odpowiedź: C
+
+Zwykłe funkcje nie mogą zostać zatrzymane w połowie wywoływania. Jednak funkcja generatora może zostać "zatrzymana" w połowie, a następnie kontynuować od miejsca, w którym się zatrzymała. Za każdym razem, gdy funkcja generująca napotka słowo kluczowe `yield`, funkcja zwraca wartość określoną po nim.
+
+Najpierw inicjalizujemy funkcję generatora z `i` równym `10`. Wywołujemy funkcję generatora za pomocą metody `next()`. Przy pierwszym wywołaniu funkcji generatora, `i` jest równe `10`. Funkcja napotyka pierwsze słowo kluczowe `yield`: zwraca wartość `i`. Generator jest teraz "wstrzymany", a wartość `10` zostaje zarejestrowana.
+
+Następnie ponownie wywołujemy funkcję za pomocą metody `next()`. Kontynuuje ona tam, gdzie zatrzymała się poprzednio, wciąż z `i` równym `10`. Teraz napotyka następne słowo kluczowe `yield` i zwraca `i * 2`. `i` jest równe `10`, więc zwraca `10 * 2`, czyli `20`. Wynikiem jest `10, 20`.
+
+
+
+#### Odpowiedź: B
+
+Kiedy przekazujemy wiele 'promise' do metody `Promise.race`, rozwiązuje ona/odrzuca _pierwszą_ 'promise'. Do metody `setTimeout` przekazujemy timer: 500ms dla `firstPromise` i 100ms dla `secondPromise`. Oznacza to, że `secondPromise` zostanie rozwiązana jako pierwsza z wartością `'two'`. `res` przechowuje teraz wartość `'two'`, która jest wyświetlona w konsoli.
+
+
+
+#### Odpowiedź: D
+
+Najpierw deklarujemy zmienną `person` z wartością obiektu, który ma właściwość `name`.
+
+
+
+#### Odpowiedź: B
+
+Za pomocą pętli `for-in` możemy iterować po kluczach obiektów, w tym przypadku `name` i `age`. Klucze obiektów są łańcuchami (jeśli nie są symbolami). W każdej pętli ustawiamy wartość `item` równą bieżącemu kluczowi, który iterujemy. Najpierw `item` jest równy `name`. Następnie, `item` jest równy `age`.
+
+
+
+#### Odpowiedź: B
+
+Asocjatywność operatorów to kolejność, w jakiej kompilator ocenia wyrażenia, od lewej do prawej lub od prawej do lewej. Dzieje się tak tylko wtedy, gdy wszystkie operatory mają _takie samo_ pierwszeństwo. Mamy tylko jeden typ operatora: `+`. Dla dodawania, asocjatywność jest od lewej do prawej.
+
+`3 + 4` jest obliczane jako pierwsze. Wynikiem jest liczba `7`.
+
+`7 + '5'` skutkuje `"75"` z powodu przymusu. JavaScript konwertuje liczbę `7` na ciąg znaków, patrz pytanie 15. Możemy połączyć dwa ciągi znaków za pomocą operatora `+`. "7" + "5"` daje w wyniku "75"`.
+
+
+
+#### Odpowiedź: C
+
+Zwracana jest tylko pierwsza liczba w łańcuchu. W oparciu o _radix_ (drugi argument w celu określenia typu liczby, którą chcemy przetworzyć: podstawa 10, szesnastkowy, ósemkowy, binarny itp.), `parseInt` sprawdza, czy znaki w łańcuchu są prawidłowe. Gdy napotka znak, który nie jest prawidłową liczbą w radix, zatrzymuje parsowanie i ignoruje następujące znaki.
+
+`*` nie jest prawidłową liczbą. Przetwarza tylko `"7"` na dziesiętne `7`. `num` posiada teraz wartość `7`.
+
+
+
+#### Odpowiedź: C
+
+Podczas mapowania tablicy, wartość `num` jest równa elementowi, nad którym aktualnie wykonywana jest pętla. W tym przypadku elementami są liczby, więc warunek instrukcji if `typeof num == "number"` zwraca `true`. Funkcja map tworzy nową tablicę i wstawia do niej wartości zwrócone przez funkcję.
+
+Nie zwracamy jednak żadnej wartości. Gdy nie zwracamy wartości z funkcji, funkcja zwraca `undefined`. Dla każdego elementu w tablicy wywoływany jest blok funkcji, więc dla każdego elementu zwracamy `undefined`.
+
+
+
+#### Odpowiedź: A
+
+Argumenty są przekazywane przez _wartość_, chyba że ich wartość jest obiektem, wtedy są przekazywane przez _referencję_. Argument `birthYear` jest przekazywany przez wartość, ponieważ jest ciągiem znaków, a nie obiektem. Kiedy przekazujemy argumenty przez wartość, tworzona jest _kopia_ tej wartości (patrz pytanie 46).
+
+Zmienna `birthYear` posiada referencję do wartości `"1997"`. Argument `year` również posiada referencję do wartości `"1997"`, ale nie jest to ta sama wartość, do której odnosi się `birthYear`. Kiedy aktualizujemy wartość `year` ustawiając `year` na `"1998"`, aktualizujemy tylko wartość `year`. Wartość `birthYear` jest wciąż równa `1997`.
+
+Wartość `person` jest obiektem. Argument `member` posiada (skopiowaną) referencję do _tego samego_ obiektu. Gdy zmodyfikujemy właściwość obiektu, do którego odwołuje się `member`, wartość `person` również zostanie zmodyfikowana, ponieważ oba mają odwołanie do tego samego obiektu. Właściwość `name` obiektu `person` jest teraz równa wartości `"Lydia"`.
+
+
+
+#### Odpowiedź: D
+
+Za pomocą instrukcji `throw` możemy tworzyć niestandardowe błędy. Za pomocą tej instrukcji można rzucać wyjątki string, number, boolean lub object. W tym przypadku, naszym wyjątkiem jest ciąg znaków `'Hello world!".`
+
+Za pomocą instrukcji `catch` możemy określić, co należy zrobić, jeśli wyjątek zostanie rzucony w bloku `try`. Wyjątkiem może być: string `'Hello world!'`. `e` jest teraz równe temu ciągowi, który wyświetlamy w konsoli. Skutkuje to `'Oh an error: Hello world!'`.
+
+
+
+#### Odpowiedź: B
+
+Kiedy zwracasz właściwość, wartość właściwości jest równa _zwróconej_ wartości, a nie wartości ustawionej w funkcji konstruktora. Zwracamy ciąg `"Maserati"`, więc `myCar.make` jest równe `"Maserati"`.
+
+
+
+#### Odpowiedź: A
+
+`let x = (y = 10);` jest w rzeczywistości skrótem od:
+
+```javascript
+y = 10;
+let x = y;
+```
+
+Kiedy ustawiamy `y` równe `10`, w rzeczywistości dodajemy właściwość `y` do globalnego obiektu (`window` w przeglądarce, `global` w Node). W przeglądarce, `window.y` jest teraz równe `10`.
+
+Następnie deklarujemy zmienną `x` z wartością `y`, która wynosi `10`. Zmienne zadeklarowane za pomocą słowa kluczowego `let` są _block scoped_ i są definiowane tylko w bloku, w którym zostały zadeklarowane; w tym przypadku natychmiast wywołane wyrażenie funkcji (IIFE). Kiedy używamy operatora `typeof`, operand `x` nie jest zdefiniowany: próbujemy uzyskać dostęp do `x` poza blokiem, w którym został zadeklarowany. Oznacza to, że `x` nie jest zdefiniowane. Wartości, które nie zostały przypisane lub zadeklarowane są typu "undefined". `console.log(typeof x)` zwraca `"undefined"`.
+
+Jednakże, utworzyliśmy globalną zmienną `y` podczas ustawiania `y` równego `10`. Wartość ta jest dostępna w dowolnym miejscu naszego kodu. Zmienna `y` jest zdefiniowana i przechowuje wartość typu `"number"`. `console.log(typeof y)` zwraca `"number"`.
+
+
+
+#### Odpowiedź: A
+
+Możemy usuwać właściwości z obiektów za pomocą słowa kluczowego `delete`, również na prototypie. Usuwając właściwość z prototypu, nie jest ona już dostępna w łańcuchu prototypów. W tym przypadku funkcja `bark` nie jest już dostępna w prototypie po `delete Dog.prototype.bark`, a mimo to wciąż próbujemy uzyskać do niej dostęp.
+
+Kiedy próbujemy wywołać coś, co nie jest funkcją, rzucany jest `TypeError`. W tym przypadku `TypeError: pet.bark is not a function`, ponieważ `pet.bark` jest `undefined`.
+
+
+
+#### Odpowiedź: D
+
+Obiekt `Set` jest zbiorem _unikalnych_ wartości: wartość może wystąpić tylko raz w zbiorze.
+
+Przekazaliśmy iterowalne `[1, 1, 2, 3, 4]` ze zduplikowaną wartością `1`.Ponieważ nie możemy mieć dwóch takich samych wartości w zbiorze, jedna z nich jest usuwana. Wynikiem jest `{1, 2, 3, 4}`.
+
+
+
+#### Odpowiedź: C
+
+Zaimportowany moduł jest _tylko do odczytu_: nie można modyfikować zaimportowanego modułu. Tylko moduł, który go eksportuje może zmienić jego wartość.
+
+Kiedy próbujemy zwiększyć wartość `myCounter`, wyrzuca błąd: `myCounter` jest tylko do odczytu i nie może być modyfikowany.
+
+
+
+#### Odpowiedź: A
+
+Operator `delete` zwraca wartość logiczną: `true` po pomyślnym usunięciu, w przeciwnym razie zwróci `false`. Jednakże, zmienne zadeklarowane ze słowem kluczowym `var`, `const` lub `let` nie mogą być usunięte za pomocą operatora `delete`.
+
+Zmienna `name` została zadeklarowana ze słowem kluczowym `const`, więc jej usunięcie nie powiedzie się: Zwracane jest `false`. Kiedy ustawiliśmy wartość `age` równą `21`, w rzeczywistości dodaliśmy właściwość o nazwie `age` do obiektu globalnego. W ten sposób można pomyślnie usunąć właściwości z obiektów, również z obiektu globalnego, więc `delete age` zwraca `true`.
+
+
+
+#### Odpowiedź: C
+
+Możemy rozpakować wartości z tablic lub właściwości z obiektów poprzez destrukturyzację. Na przykład:
+
+```javascript
+[a, b] = [1, 2];
+```
+
+
+
+#### Odpowiedź: B
+
+Możliwe jest łączenie obiektów za pomocą operatora rozprzestrzeniania `...`.Umożliwia on tworzenie kopii par klucz/wartość jednego obiektu i dodawanie ich do innego obiektu. W tym przypadku tworzymy kopie obiektu `user` i dodajemy je do obiektu `admin`. Obiekt `admin` zawiera teraz skopiowane pary klucz/wartość, czego wynikiem jest `{ admin: true, name: "Lydia", age: 21 }`.
+
+
+
+#### Odpowiedź: B
+
+Za pomocą metody `defineProperty` możemy dodawać nowe właściwości do obiektu lub modyfikować istniejące. Kiedy dodajemy właściwość do obiektu za pomocą metody `defineProperty`, są one domyślnie _niewyliczalne_. Metoda `Object.keys` zwraca wszystkie _wyliczalne_ nazwy właściwości z obiektu, w tym przypadku tylko `"name"`.
+
+Właściwości dodane przy użyciu metody `defineProperty` są domyślnie niezmienne. Możesz nadpisać to zachowanie używając właściwości `writable`, `configurable` i `enumerable`. W ten sposób metoda `defineProperty` daje dużo większą kontrolę nad właściwościami dodawanymi do obiektu.
+
+
+
+#### Odpowiedź: A
+
+Drugim argumentem `JSON.stringify` jest _replacer_. Zamiennik może być funkcją lub tablicą i pozwala kontrolować, co i w jaki sposób wartości powinny być łańcuchowane.
+
+Jeśli zamiennik jest _tablicą_, tylko nazwy właściwości zawarte w tablicy zostaną dodane do łańcucha JSON. W tym przypadku tylko właściwości o nazwach `"level"` i `"health"` są uwzględnione, `"username"` jest wykluczone. `data` jest teraz równa `"{"level":19, "health":90}"`.
+
+Jeśli zamiennik jest _funkcją_, funkcja ta jest wywoływana na każdej właściwości obiektu, który stringujesz. Wartość zwrócona z tej funkcji będzie wartością właściwości, gdy zostanie ona dodana do łańcucha JSON. Jeśli wartość jest `undefined`, właściwość ta zostanie wykluczona z łańcucha JSON.
+
+
+
+#### Odpowiedź: A
+
+Operator jednoargumentowy `++` _najpierw zwraca_ wartość operandu, _potem zwiększa_ wartość operandu. Wartość `num1` to `10`, ponieważ funkcja `increaseNumber` najpierw zwraca wartość `num`, czyli `10`, a dopiero potem zwiększa wartość `num`.
+
+`num2` jest równe `10`, ponieważ przekazaliśmy `num1` do `increasePassedNumber`.`number` jest równe `10` (wartość `num1`). Ponownie, operator jednoargumentowy `++` _najpierw zwraca_ wartość operandu, _następnie zwiększa_ wartość operandu. Wartość `liczba` wynosi `10`, więc `liczba2` jest równa `10`.
+
+
+
+#### Odpowiedź: C
+
+W ES6 możemy inicjować parametry z wartością domyślną. Wartość parametru będzie wartością domyślną, jeśli żadna inna wartość nie została przekazana do funkcji lub jeśli wartość parametru jest `"undefined". W tym przypadku, rozkładamy właściwości obiektu `value` na nowy obiekt, więc `x` ma domyślną wartość `{ number: 10 }`.
+
+Domyślny argument jest obliczany w _call time_! Za każdym razem, gdy wywołujemy funkcję, tworzony jest _nowy_ obiekt. Wywołujemy funkcję `multiply` dwa pierwsze razy bez przekazywania wartości: `x` ma wartość domyślną `{ number: 10 }`. Następnie rejestrujemy pomnożoną wartość tej liczby, która wynosi `20`.
+
+Za trzecim razem, gdy wywołujemy multiply, przekazujemy argument: obiekt o nazwie `value`. Operator `*=` jest w rzeczywistości skrótem od `x.number = x.number * 2`: modyfikujemy wartość `x.number` i rejestrujemy pomnożoną wartość `20`.
+
+Za czwartym razem ponownie przekazujemy obiekt `value`. `x.number` zostało wcześniej zmodyfikowane do `20`, więc `x.number *= 2` loguje `40`.
+
+ s
+
+#### Odpowiedź: D
+
+Pierwszym argumentem, który otrzymuje metoda `reduce` jest _accumulator_, w tym przypadku `x`. Drugim argumentem jest _bieżąca wartość_, `y`. Za pomocą metody reduce wykonujemy funkcję wywołania zwrotnego na każdym elemencie tablicy, co ostatecznie może skutkować jedną wartością. W tym przykładzie nie zwracamy żadnych wartości, po prostu rejestrujemy wartości akumulatora i wartości bieżącej.
+
+Wartość akumulatora jest równa poprzednio zwróconej wartości funkcji zwrotnej. Jeśli nie przekażesz opcjonalnego argumentu `initialValue` do metody `reduce`, akumulator jest równy pierwszemu elementowi przy pierwszym wywołaniu.
+
+Przy pierwszym wywołaniu, wartość akumulatora (`x`) wynosi `1`, a wartość bieżąca (`y`) wynosi `2`. Nie wracamy z funkcji zwrotnej, rejestrujemy akumulator i bieżącą wartość: `1` i `2` są rejestrowane.
+
+Jeśli nie zwrócisz wartości z funkcji, zwróci ona `undefined`. Przy następnym wywołaniu, akumulatorem jest `undefined`, a bieżącą wartością jest `3`. `undefined` i `3` są rejestrowane.
+
+Przy czwartym wywołaniu ponownie nie wracamy z funkcji zwrotnej. Akumulator jest ponownie `undefined`, a aktualna wartość to `4`. `undefined` i `4` są rejestrowane.
+
+
+
+#### Odpowiedź: B
+
+W klasie pochodnej nie można uzyskać dostępu do słowa kluczowego `this` przed wywołaniem `super`. Jeśli spróbujesz to zrobić, zostanie wyświetlony ReferenceError: 1 i 4 wyrzuci błąd referencji.
+
+Za pomocą słowa kluczowego `super` wywołujemy konstruktor klasy nadrzędnej z podanymi argumentami. Konstruktor rodzica otrzymuje argument `name`, więc musimy przekazać `name` do `super`.
+
+Klasa `Labrador` otrzymuje dwa argumenty, `name` ponieważ rozszerza klasę `Dog`, oraz `size` jako dodatkową właściwość klasy `Labrador`. Oba muszą być przekazane do funkcji konstruktora na `Labrador`, co jest zrobione poprawnie przy użyciu konstruktora 2.
+
+
+
+#### Odpowiedź: B
+
+Ze słowem kluczowym `import`, wszystkie zaimportowane moduły są _pre-parsed_. Oznacza to, że zaimportowane moduły są uruchamiane _najpierw_, a kod w pliku, który importuje moduł jest wykonywany _potem_.
+
+Jest to różnica pomiędzy `require()` w CommonJS i `import`!
+Dzięki `require()` można ładować zależności na żądanie podczas wykonywania kodu. Jeśli użylibyśmy `require` zamiast `import`, w konsoli zostałoby wyświetlone `running index.js`, `running sum.js`, `3`.
+
+
+
+#### Odpowiedź: A
+
+Każdy Symbol jest całkowicie unikalny. Celem argumentu przekazywanego do Symbolu jest nadanie Symbolowi opisu. Wartość Symbolu nie zależy od przekazanego argumentu. Testując równość, tworzymy dwa zupełnie nowe symbole: pierwszy `Symbol('foo')` i drugi `Symbol('foo')`. Te dwie wartości są unikalne i nie są sobie równe, `Symbol('foo') == Symbol('foo')` zwraca `false`.
+
+
+
+#### Odpowiedź: C
+
+Za pomocą metody `padStart` możemy dodać dopełnienie na początku ciągu znaków. Wartością przekazywaną do tej metody jest _całkowita_ długość łańcucha wraz z dopełnieniem. Ciąg `"Lydia Hallie"` ma długość `12`. Metoda `name.padStart(13)` wstawia 1 spację na początku łańcucha, ponieważ 12 + 1 to 13.
+
+Jeśli argument przekazany do metody `padStart` jest mniejszy niż długość tablicy, dopełnienie nie zostanie dodane.
+
+
+
+#### Odpowiedź: A
+
+Za pomocą operatora `+` można łączyć ciągi znaków. W tym przypadku łączymy ciąg `"🥑"` z ciągiem `"💻"`, otrzymując `"🥑💻"`.
+
+
+
+#### Odpowiedź: C
+
+Funkcja generatora "wstrzymuje" swoje wykonanie, gdy widzi słowo kluczowe `yield`. Najpierw musimy pozwolić funkcji na wygenerowanie ciągu "Do you love JavaScript?", co można zrobić poprzez wywołanie `game.next().value`.
+
+Każda linia jest wykonywana, dopóki nie znajdzie pierwszego słowa kluczowego `yield`. W pierwszej linii funkcji znajduje się słowo kluczowe `yield`: wykonywanie zatrzymuje się wraz z pierwszym yield! Oznacza to, że zmienna `answer` nie jest jeszcze zdefiniowana!
+
+Kiedy wywołamy `game.next("Yes").value`, poprzedni `yield` zostanie zastąpiony wartością parametrów przekazanych do funkcji `next()`, w tym przypadku `"Yes``. Wartość zmiennej `answer` jest teraz równa `"Yes"`. Warunek instrukcji if zwraca `false`, a `JavaScript loves you back ❤️` zostaje zalogowany.
+
+
+
+#### Odpowiedź: C
+
+`String.raw` zwraca ciąg znaków, w którym znaki specjalne (`\n`, `\v`, `\t` itd.) są ignorowane! Backslashe mogą być problemem, ponieważ można skończyć z czymś takim jak:`` const path = `C:\Documents\Projects\table.html` ``
+
+Co skutkowałoby:
+
+`"C:DocumentsProjects able.html"`Z `String.raw`, po prostu zignorowałby ucieczkę i wyświetliłby:
+
+`C:\Documents\Projects\table.html`.
+
+W tym przypadku ciąg to `Hello\nworld`, który zostanie wyświetlony.
+
+
+
+#### Odpowiedź: C
+
+Funkcja asynchroniczna zawsze zwraca obietnicę. Funkcja `await` wciąż musi czekać na rozwiązanie obietnicy: oczekująca obietnica zostanie zwrócona, gdy wywołamy `getData()` w celu ustawienia `data` równym tej obietnicy.
+
+Jeśli chcielibyśmy uzyskać dostęp do rozwiązanej wartości `"I made it"`, moglibyśmy użyć metody `.then()` na `data`:`data.then(res => console.log(res))`.
+
+To wyświtliłoby w konsoli `"Udało mi się!"`.
+
+
+
+#### Odpowiedź: B
+
+Metoda `.push()` zwraca _długość_ nowej tablicy! Poprzednio tablica zawierała jeden element (string `"banan"`) i miała długość `1`. Po dodaniu stringa `"apple"` do tablicy, tablica zawiera dwa elementy i ma długość `2`. Jest to zwracane przez funkcję `addToList`. Metoda `push` modyfikuje oryginalną tablicę.
+
+Jeśli chciałeś zwrócić _array_ z funkcji, a nie _length of the array_, powinieneś był zwrócić `list` po dodaniu do niej `item`.
+
+
+
+#### Odpowiedź: B
+
+`Object.freeze` uniemożliwia dodawanie, usuwanie lub modyfikowanie właściwości obiektu (chyba że wartością właściwości jest inny obiekt).
+
+Kiedy tworzymy zmienną `shape` i ustawiamy ją jako równą zamrożonemu obiektowi `box`, `shape` również odnosi się do zamrożonego obiektu. Możesz sprawdzić czy obiekt jest zamrożony używając `Object.isFrozen`. W tym przypadku, `Object.isFrozen(shape)` zwróciłby true, ponieważ zmienna `shape` posiada referencję do zamrożonego obiektu.
+
+Ponieważ `shape` jest zamrożony, a wartość `x` nie jest obiektem, nie możemy modyfikować właściwości `x`.`x` jest nadal równe `10`, a `{ x: 10, y: 20 }` zostaje wyświetlone w konsoli.
+
+
-#### 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:
+Quando você define um valor para um elemento em um array que excede o tamanho do próprio array, o JavaScript cria algo chamado "empty slots" (espaços vazios). Na verdade, esses espaços vazios tem o valor de `undefined`, mas você verá algo como:
`[1, 2, 3, 7 x empty, 11]`
-depending on where you run it (it's different for every browser, node, etc.)
+dependendo de onde você o executa, pois é diferente para cada navegador, node etc.
+
+#### 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`.
+
+
+
+#### 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`.
+
+
+
+#### Resposta: A
+
+Os argumentos são passados por _valor_. Porém, se seu valor for um objeto, eles são passados por _referência_. `birthYear` é passado por valor, já que é uma string, não um objeto. Quando passamos argumentos por valor, uma _cópia_ desse valor é criada (consulte a pergunta 46).
+
+A variável `birthYear` tem uma referência ao valor `"1997"`. O argumento `year` também tem uma referência ao valor `"1997"`, mas não é o mesmo valor de referência de `birthYear`. Quando atualizamos o valor de `year`, definindo ` year` igual a `"1998"`, estamos apenas atualizando o valor de `year`. `birthYear` ainda é igual a `"1997"`.
+
+O valor de `person` é um objeto. O argumento `member` possui uma referência (copiada) do _mesmo_ objeto . Quando modificamos uma propriedade do objeto que `member` tem referência, o valor de `person` também será modificado, pois ambos tem referência ao mesmo objeto. A propriedade `name` de `person` agora é igual ao valor `"Lydia"`.
+
+
+
+#### Resposta: D
+
+Com a declaração `throw`, podemos criar erros personalizados. Com esta declaração, você pode lançar exceções. Uma exceção pode ser uma string, um número, um booleano ou um objeto. Nesse caso, nossa exceção é a string `'Hello world!'`.
+
+Com a declaração `catch`, podemos especificar o que fazer se uma exceção for lançada no bloco `try`. Uma exceção foi lançada: a string `'Hello world'`. `e` agora é igual a essa string que registramos. Isso resulta em `'Oh no an error: Hello world!'`.
+
+
+
+#### Resposta: B
+
+Quando você retorna uma propriedade, o valor da propriedade é igual ao valor _retornado_, não ao valor _definido_ na função do construtor. Retornamos a string `"Maserati"`, então `myCar.make` é igual a `"Maserati"`.
+
+
+
+#### Resposta: A
+
+`let x = y = 10;` é na realidade uma abreviação de:
+
+```javascript
+y = 10;
+let x = y;
+```
+
+Quando definimos `y` igual a `10`, adicionamos na verdade uma propriedade `y` ao objeto global (`window` no navegador, `global` no Node). Em um navegador, `window.y` agora é igual a `10`.
+
+Então, declaramos uma variável `x` com o valor de `y`, que é `10`. As variáveis declaradas com `let` tem _escopo definido no bloco_ ou seja, são definidas apenas dentro do bloco em que são declaradas, neste caso, _immediately-invoked function_ (IIFE). Quando usamos o operador `typeof`, o operando `x` não está definido: estamos tentando acessar `x` fora do bloco em que está declarado. Isso significa que `x` não está definido. Os valores que não foram atribuídos ou declarados a um valor são do tipo `"undefined"`. `console.log(typeof x)` retorna `"undefined"`.
+
+No entanto, criamos uma variável global `y` ao definir `y` igual a `10`. Este valor está acessível em qualquer lugar do nosso código. `y` é definido e mantém um valor do tipo `"number"`. `console.log(typeof y)` retorna `"number"`.
+
+
+
+#### Resposta: A
+
+Podemos excluir propriedades de objetos usando `delete`, também no prototype. Ao excluir uma propriedade no prototype, ela não está mais disponível na cadeia de prototypes. Nesse caso, a função `bark` não está mais disponível no prototype depois de `delete Dog.prototype.bark`, mas ainda tentamos acessá-lo.
+
+Quando tentamos invocar algo que não é uma função, um `TypeError` é lançado. Neste caso, `TypeError: pet.bark is not a function`, uma vez que `pet.bark` é `undefined`.
+
+
+
+#### Resposta: D
+
+O objeto `Set` é uma coleção de valores _exclusivos_ : um valor pode ocorrer apenas uma vez.
+
+Passamos o iterável `[1, 1, 2, 3, 4]` com um valor `1` duplicado. Como não podemos ter dois dos mesmos valores em um conjunto, um deles é removido. Isso resulta em `{1, 2, 3, 4}`.
+
+
+
+#### Resposta: C
+
+Um módulo importado é _somente leitura_: você não pode modificar o módulo importado. Somente o módulo que os exporta pode alterar seu valor.
+
+Quando tentamos aumentar o valor de `myCounter`, recebemos um erro: `myCounter` é somente leitura e não pode ser modificado.
+
+
+
+#### Resposta: A
+
+O operador `delete` retorna um valor booleano: `true` em uma exclusão bem-sucedida, caso contrário, ele retorna `false`. No entanto, variáveis declaradas com `var`, `const` ou `let` não podem ser excluídas usando o operador `delete`.
+
+A variável `name` foi declarada com `const`, portanto sua exclusão não é bem-sucedida: `false` é retornado. Quando definimos `age` igual a `21`, na verdade adicionamos uma propriedade chamada `age` para o objeto global. Dessa forma, você pode excluir propriedades dos objetos, portanto `delete age` returns `true`.
+
+
+
+#### Resposta: C
+
+Podemos descompactar valores de matrizes ou propriedades de objetos através da desestruturação. Por exemplo:
+
+```javascript
+[a, b] = [1, 2];
+```
+
+
+
+#### Resposta: B
+
+
+É possível combinar objetos usando o operador o spread operator `...`. Ele permite criar cópias dos pares de um objeto e adicioná-las a outro objeto. Nesse caso, criamos cópias do objeto `user` e as adicionamos ao objeto `admin`. O objeto `admin` agora contém os pares de chave/valor copiados, o que resulta em `{ admin: true, name: "Lydia", age: 21 }`.
+
+
+
+#### Resposta: B
+Com o método `defineProperty`, podemos adicionar novas propriedades a um objeto ou modificar propriedades já existentes. Quando adicionamos uma propriedade a um objeto usando o método `defineProperty`, ela é, por padrão, _não enumerável_. O método`Object.keys` retorna todos os nomes de uma propriedade _enumerável_ de um objeto. Nesse caso, apenas `"name"`.
+
+Propriedades adicionadas usando o método `defineProperty` são imutáveis por padrão. Você pode sobrepor esse comportamento usando as propriedade `writable`, `configurable` e `enumerable`.
+Assim, o método `defineProperty` dá a você muito mais controle sobre as propriedades que você está adicionando a um objeto.
+
+
+#### Resposta: A
+
+O segundo argumento de `JSON.stringify` é o _substituo_. O substituto pode ser uma função ou um array, e deixa você controlar o que deve ser "stringfied", isto é, ser usado pelo método `JSON.stringfy`.
+
+Se o substituto (replacer) for um _array_, apenas os nomes de propriedades incluídos no array serão adicionados à string JSON. Nesse caso, apenas as propriedades com os nomes `"level"` ed `"health"` são incluída, `"username"` é excluída. `data` agora é igual a `"{"level":19, "health":90}"`.
+
+Se o substituto (replacer) for uma _função_, essa função é chamada em c ada propriedade no objeto que está sendo "Stringfied". O valor retornado dessa função será o valor da propriedade quanto adicionado à string JSON. Se o valor for `undefined`, essa propriedade é excluída da string JSON.
+
+
+#### Resposta: A
+
+O operador unário `++` primeiro _retorna_ o valor do operando, depois _incrementa_ esse valor. O valor de `num1` é `10`, pois a função `increaseNumber` retorna primeiro o valor de` num`, que é `10`, e apenas incrementa o valor de `num` posteriormente.
+
+`num2` é `10`, já que passamos `num1` para o `increasePassedNumber`. `number` é igual a` 10` (o valor de `num1`. Novamente, o operador unário `++` primeiro _retorna_ o valor do operando, depois _aumenta_ esse valor. O valor de` number` é `10`, então `num2` é igual a `10`.
+
+
+
+#### Resposta: C
+
+No ES6, podemos inicializar parâmetros com um valor padrão. O valor do parâmetro será o valor padrão, se nenhum outro valor tiver sido passado para a função ou se o valor do parâmetro for `"undefined"`. Nesse caso, espalhamos (spread) as propriedades do objeto `value` para um novo objeto, para que `x` tenha o valor padrão de `{number: 10}`.
+
+O argumento padrão é executado _a cada chamada_! Toda vez que chamamos a função, um _novo_ objeto é criado. Invocamos a função `multiply` as duas primeiras vezes sem passar um valor: `x` tem o valor padrão de `{number: 10}`. Em seguida, registramos (log) o valor multiplicado desse número, que é `20`.
+
+Na terceira vez que invocamos multiply, passamos um argumento: o objeto chamado `value`. O operador `*=` é na verdade uma abreviação de `x.number = x.number * 2`: modificamos o valor de `x.number` e registramos (log) o valor multiplicado `20`.
+
+Na quarta vez, passamos o objeto `value` novamente. `x.number` foi modificado anteriormente para `20`, então `x.number *= 2` registra `40`.
+
+
+
+#### Resposta: D
+
+O primeiro argumento que o método `reduce` recebe é o _acumulador_, `x` neste caso. O segundo argumento é o _valor atual_, `y`. Com o método `reduce`, executamos uma função de retorno de chamada (callback function) em todos os elementos da matriz, o que pode resultar em um único valor.
+
+Neste exemplo, não estamos retornando nenhum valor, estamos simplesmente registrando os valores do acumulador e o valor atual.
+
+O valor do acumulador é igual ao valor retornado anteriormente da função de retorno de chamada (callback function). Se você não passar o argumento opcional `initialValue` para o método `reduce`, o acumulador será igual ao primeiro elemento na primeira chamada.
+
+Na primeira chamada, o acumulador (`x`) é `1` e o valor atual (`y`) é `2`. Não retornamos da função de retorno de chamada, registramos o acumulador e o valor atual: `1` e` 2` são registrados.
+
+Se você não retornar um valor de uma função, ele retornará `undefined`. Na próxima chamada, o acumulador é "undefined" e o valor atual é "3". `undefined` e `3` são registrados.
+
+Na quarta chamada, novamente não retornamos nada da função de retorno de chamada. O acumulador é novamente `undefined` e o valor atual é `4`. `undefined` e `4` são registrados.
+
+
+
+#### Resposta: B
+
+Em uma classe derivada, você não pode acessar a palavra-chave `this` antes de chamar `super`. Se você tentar fazer isso, ele lançará um erro de referência (ReferenceError): 1 e 4 lançará um erro de referência.
+
+Com a palavra-chave `super`, chamamos o construtor dessa classe pai com os argumentos fornecidos. O construtor do pai recebe o argumento `name`, portanto, precisamos passar `name` para `super`.
+
+A classe `Labrador` recebe dois argumentos, `name`, pois estende `Dog`, e `size` como uma propriedade extra na classe `Labrador`. Ambos precisam ser passados para a função construtora no `Labrador`, que é feita corretamente usando o construtor 2.
+
+
+
+#### Resposta: B
+
+Com a palavra-chave `import`, todos os módulos importados são _pre-parsed_. Isso significa que os módulos importados são executados _primeiro_, o código no arquivo que importa o módulo é executado _depois_.
+
+Esta é uma diferença entre `require()` no CommonJS e `import`! Com `require()`, você pode carregar dependências sob demanda enquanto o código está sendo executado. Se tivéssemos usado `require` em vez de `import`, `running index.js`,` running sum.js`, `3` teriam sido registrados no console.
+
+
+
+#### Resposta: A
+
+Todo símbolo (Symbol) é totalmente único. O objetivo do argumento passado ao símbolo é fornecer uma descrição ao símbolo. O valor do símbolo não depende do argumento passado. Ao testarmos a igualdade, estamos criando dois símbolos totalmente novos: o primeiro `Symbol('foo')` e o segundo `Symbol('foo')`. Esses dois valores são únicos e não são iguais entre si, `Symbol('foo') === Symbol('foo')` retorna `false`.
+
+
+
+#### Resposta: C
+
+Com o método `padStart`, podemos adicionar preenchimento (padding) ao início de uma string. O valor passado para esse método é o comprimento _total_ da string junto com o preenchimento. A string `"Lydia Hallie"` tem um comprimento de `12`. `name.padStart(13)` insere 1 espaço no início da string, porque 12 + 1 é 13.
+
+Se o argumento passado para o método `padStart` for menor que o comprimento da matriz, nenhum preenchimento será adicionado.
+
+
+
+#### Resposta: A
+
+Com o operador `+`, você pode concatenar seqüências de caracteres (strings). Neste caso, estamos concatenando a string `"🥑"` com a string `"💻"`, resultando em `"🥑💻"`.
+
+
+
+#### Resposta: C
+
+Uma função geradora "pausa" a sua execução quando encontra a palavra-chave `yield`. Primeiro, temos que deixar a função produzir a string "Você ama JavaScript?", o que pode ser feito chamando `jogo.next().value`.
+
+Cada linha é executada, até encontrar a primeira palavra-chave `yield`. Há uma palavra-chave `yield` na primeira linha da função: a execução para com o primeiro retorno! _Isso significa que a variável `resposta` ainda não foi definida!_
+
+Quando chamamos `jogo.next("Sim").value`, o `yield` anterior é substituído pelo valor dos parâmetros passados para a função `next()`, `"Sim"` neste caso. O valor da variável `"resposta"` agora é igual a `"Sim"`. A condição da instrução if retorna `false` e `JavaScript também ama você ❤️` é registrada.
+
+
+
+#### Answer: C
+
+`String.raw` retorna um texto onde os escape (`\n`, `\v`, `\t` etc.) são ignorados! As barras invertidas podem ser um problema, pois você pode acabar com algo como:
+
+`` caminho const = `C:\Documents\Projects\table.html` ``
+
+O que resultaria em:
+
+`"C:DocumentsProjectstable.html"`
+
+Com `String.raw`, ele simplesmente ignoraria o escape e imprimiria:
+
+`C:\Documents\Projects\table.html`
+
+Neste caso, a string é `Hello\nworld`, que é registrada.
+
+
+
+#### Resposta: C
+
+Uma função assíncrona sempre retorna uma promise. O `await` ainda tem que esperar que a promise seja resolvida: uma promise pendente é retornada quando chamamos `getData()` para definir `data` igual a ela.
+
+Se quiséssemos ter acesso ao valor resolvido `"I made it"`, poderíamos ter usado o método `.then()` em `data`:
+
+`data.then(res => console.log(res))`
+
+Isso teria registrado `"Consegui!"`
+
+
+
+#### Answer: B
+
+O método `.push()` retorna o _length_ do novo array! Anteriormente, a matriz continha um elemento (a string `"banana"`) e tinha um comprimento de `1`. Depois de adicionar a string `"apple"` ao array, o array contém dois elementos e tem um comprimento de `2`. Isso é retornado da função `addToList`.
+
+O método `push` modifica o array original. Se você quisesse retornar o _array_ da função ao invés do _tamanho do array_, você deveria ter retornado `list` depois de enviar `item` para ele.
+
+
+
+#### Answer: B
+
+`Object.freeze` torna impossível adicionar, remover ou modificar propriedades de um objeto (a menos que o valor da propriedade seja outro objeto).
+
+Quando criamos a variável `shape` e a definimos igual ao objeto congelado `box`, `shape` também se refere a um objeto congelado. Você pode verificar se um objeto está congelado usando `Object.isFrozen`. Neste caso, `Object.isFrozen(shape)` retorna true, pois a variável `shape` tem uma referência a um objeto congelado.
+
+Como `shape` está congelado, e como o valor de `x` não é um objeto, não podemos modificar a propriedade `x`. `x` ainda é igual a `10`, e `{ x: 10, y: 20 }` é registrado.
+
+
+
+#### Answer: D
+
+Quando descompactamos a propriedade `name` do objeto do lado direito, atribuímos seu valor `"Lydia"` a uma variável com o nome `myName`.
+
+Com `{ name: myName }`, informamos ao JavaScript que queremos criar uma nova variável chamada `myName` com o valor da propriedade `name` no lado direito.
+
+Quando tentamos mostrar o conteúdo de `name`, uma variável que não está definida, recebemos o erro `ReferenceError`.
+
+
+
+#### Answer: A
+
+Uma função pura é uma função que _sempre_ retorna o mesmo resultado, se os mesmos argumentos forem passados.
+
+A função `sum` sempre retorna o mesmo resultado. Se passarmos `1` e` 2`, ele _sempre_ retornará `3` sem efeitos colaterais. Se passarmos `5` e `10`, ele _sempre_ retornará `15`, e assim por diante. Esta é a definição de uma função pura.
+
+
+
+#### Answer: C
+
+A função `add` é uma função _memoized_ (memorizada). Com a memorização, podemos armazenar em cache os resultados de uma função para acelerar sua execução. Nesse caso, criamos um objeto `cache` que armazena os valores retornados anteriormente.
+
+Se chamarmos a função `addFunction` novamente com o mesmo argumento, ela primeiro verifica se já obteve esse valor em seu cache. Se for o caso, o valor dos caches será retornado, o que economiza tempo de execução. Caso contrário, se não estiver armazenado em cache, ele calculará o valor e o armazenará posteriormente.
+
+Chamamos a função `addFunction` três vezes com o mesmo valor: na primeira chamada, o valor da função quando `num` é igual a `10` ainda não é armazenado em cache. A condição da instrução if `num in cache` retorna `false`, e o bloco else é executado: `Calculated! 20` é registrado e o valor do resultado é adicionado ao objeto de cache. `cache` agora se parece com` {10:20} `.
+
+Na segunda vez, o objeto `cache` contém o valor que é retornado para `10`. A condição da instrução if `num in cache` retorna `true`, e `'From cache! 20'` é registrado.
+
+Na terceira vez, passamos `5 * 2` para a função que é avaliada como `10`. O objeto `cache` contém o valor que é retornado para `10`. A condição da instrução if `num in cache` retorna `true`, e `'From cache! 20'` é registrado.
+
+
+
+#### Answer: A
+
+Com um loop _for-in_, podemos iterar sobre propriedades **enumeráveis**. Em um array, as propriedades enumeráveis são as "chaves" dos elementos do array, que na verdade são seus índices. Você pode ver uma matriz como:
+
+`{0:" ☕ ", 1:" 💻 ", 2:" 🍷 ", 3:" 🍫 "}`
+
+Onde as chaves são as propriedades enumeráveis. `0`` 1` `2`` 3` são registrados.
+
+Com um loop _for-of_, podemos iterar sobre **iteráveis**. Um array é um iterável. Quando iteramos sobre o array, a variável "item" é igual ao elemento sobre o qual está iterando no momento, `" ☕ "` `" 💻 "` `" 🍷 "` `" 🍫 "` são registrados.
+
+
+
+#### Answer: C
+
+Os elementos da matriz podem conter qualquer valor. Números, strings, objetos, outras matrizes, valores nulos, booleanos, indefinidos e outras expressões, como datas, funções e cálculos.
+
+O elemento será igual ao valor retornado. `1 + 2` retorna` 3`, `1 * 2` retorna` 2` e `1 / 2` retorna` 0,5`.
+
+
+
+- [🇸🇦 العربية](./ar-AR/README_AR.md)
+- [🇪🇬 اللغة العامية](./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)
+- [🇮🇩 Indonesia](./id-ID/README.md)
+- [🇮🇹 Italiano](./it-IT/README.md)
+- [🇯🇵 日本語](./ja-JA/README-ja_JA.md)
+- [🇰🇷 한국어](./ko-KR/README-ko_KR.md)
+- [🇳🇱 Nederlands](./nl-NL/README.md)
+- [🇵🇱 Polski](./pl-PL/README.md)
+- [🇧🇷 Português Brasil](./pt-BR/README_pt_BR.md)
+- [🇷🇺 Русский](./ru-RU/README.md)
+- [🇽🇰 Shqip](./sq-KS/README_sq_KS.md)
+- [🇹🇭 ไทย](./th-TH/README-th_TH.md)
+- [🇹🇷 Türkçe](./tr-TR/README-tr_TR.md)
+- [🇺🇦 Українська мова](./uk-UA/README.md)
+- [🇻🇳 Tiếng Việt](./vi-VI/README-vi.md)
+- [🇨🇳 简体中文](./zh-CN/README-zh_CN.md)
+- [🇹🇼 繁體中文](./zh-TW/README_zh-TW.md)
+
+
+
+#### Răspuns: D
+
+În interiorul funcției, mai întâi declarăm variabila `name` cu cuvântul cheie `var`. Acest lucru înseamnă că variabila este hoisted (spațiul de memorie este configurat în faza de creare) cu valoarea implicită `undefined`, până când ajungem efectiv la linia în care definim variabila. Nu am definit încă variabila pe linia în care încercăm să înregistrăm variabila `name`, așa că aceasta păstrează încă valoarea `undefined`.
+
+Variabilele create cu cuvântul cheie `let` (și `const`) sunt hoisted, dar, spre deosebire de `var`, nu sunt inițializate. Acestea nu sunt accesibile înainte de linia în care le declarăm (initializăm). Aceasta se numește zona moartă temporală (temporal dead zone). Atunci când încercăm să accesăm variabilele înainte de a fi declarate, JavaScript aruncă o excepție de tip `ReferenceError`.
+
+
+
+#### Răspuns: C
+
+Datorită cozii de evenimente din JavaScript, funcția de callback `setTimeout` este apelată _după_ ce bucla a fost executată. Deoarece variabila `i` din prima buclă a fost declarată folosind cuvântul cheie `var`, această valoare a fost globală. În timpul buclei, am incrementat valoarea lui `i` cu `1` de fiecare dată, folosind operatorul unary `++`. Până când funcția de callback `setTimeout` a fost invocată, `i` era egal cu `3` în primul exemplu.
+
+În cea de-a doua buclă, variabila `i` a fost declarată folosind cuvântul cheie `let`: variabilele declarate cu cuvântul cheie `let` (și `const`) sunt cu scop la nivel de bloc (un bloc este orice între `{ }`). În fiecare iterație, `i` va avea o valoare nouă, iar fiecare valoare este în cadrul buclei.
+
+
+
+#### Răspuns: B
+
+Rețineți că valoarea lui `diameter` este o funcție obișnuită, în timp ce valoarea lui `perimeter` este o funcție arrow.
+
+Cu funcțiile arrow, cuvântul cheie `this` se referă la contextul său curent de încadrare, spre deosebire de funcțiile obișnuite! Acest lucru înseamnă că atunci când apelăm `perimeter`, acesta nu se referă la obiectul formei, ci la încadrarea sa curentă (de exemplu, fereastra).
+
+Nu există nicio valoare `radius` pe acel obiect, ceea ce returnează `NaN`.
+
+
+
+#### Răspuns: A
+
+Operatorul unary plus încearcă să convertească un operand într-un număr. `true` este `1`, și `false` este `0`.
+
+Șirul de caractere `'Lydia'` este o valoare adevărată. Ceea ce întrebăm de fapt, este "este această valoare adevărată falsă?". Acest lucru returnează `false`.
+
+
+
+#### Răspuns: A
+
+În JavaScript, toate cheile obiectelor sunt șiruri de caractere (cu excepția simbolurilor). Chiar dacă nu le _tipizăm_ ca șiruri de caractere, ele sunt întotdeauna convertite în șiruri de caractere în fundal.
+
+avaScript interpretează (sau dezambalează) instrucțiunile. Atunci când folosim notația cu paranteze pătrate, vede prima paranteză pătrată de deschidere `[` și continuă până când găsește paranteza pătrată de închidere `]`. Doar atunci va evalua instrucțiunea.
+
+`mouse[bird.size]`: Întâi evaluează `bird.size`, care este `"small"`. `mouse["small"]` returnează `true`
+
+Cu toate acestea, cu notația cu punct, acest lucru nu se întâmplă. `mouse` nu are o cheie numită `bird`, ceea ce înseamnă că `mouse.bird` este `undefined`. Apoi, cerem `size` folosind notația cu punct: `mouse.bird.size`. Deoarece `mouse.bird` este `undefined`, de fapt cerem `undefined.size`. Acest lucru nu este valid și va arunca o eroare similară cu `Cannot read property "size" of undefined` (Nu se poate citi proprietatea "size" a unei valori nedefinite).
+
+
+
+#### Răspuns: A
+
+În JavaScript, toate obiectele interacționează prin _referință_ atunci când sunt setate ca egale între ele.
+
+Mai întâi, variabila `c` deține o valoare care face referire la un obiect. Ulterior, atribuim variabilei `d` aceeași referință pe care o are `c` la obiect.
+
+
+
+#### Răspuns: C
+
+`new Number()` este un constructor de funcții încorporat. Deși arată ca un număr, nu este într-adevăr un număr: are o mulțime de funcționalități suplimentare și este un obiect.
+
+Atunci când folosim operatorul `==` (operatorul de egalitate), acesta verifică doar dacă au aceeași _valuare_. Ambele au valoarea `3`, șa că returnează `true`.
+
+Cu toate acestea, atunci când folosim operatorul `===` (operatorul de egalitate strictă), atât valoarea, cât _și_ tipul trebuie să fie la fel. Nu sunt: `new Number()` nu este un număr, este un **object**. Ambele returnează `false.`
+
+
+
+#### Răspuns: D
+
+Funcția `colorChange` este statică. Metodele statice sunt concepute să existe doar pe constructorul în care sunt create și nu pot fi transmise către niciun copil sau apelate pe instanțele clasei. Deoarece `freddie` este o instanță a clasei Chameleon, funcția nu poate fi apelată pe aceasta. Se aruncă o eroare de tip `TypeError`.
+
+
+
+#### Răspuns: A
+
+Se afișează obiectul, deoarece tocmai am creat un obiect gol pe obiectul global! Atunci când am greșit și am scris `greeting` în loc de `greetign`, interpretorul JavaScript a văzut efectiv acest lucru ca:
+
+1. `global.greetign = {}` în Node.js
+2. `window.greetign = {}`, `frames.greetign = {}` și `self.greetign` în browser-e.
+3. `self.greetign` în web workers.
+4. `globalThis.greetign` în toate mediile.
+
+Pentru a evita acest lucru, putem folosi `"use strict"`. Acest lucru se asigură că ai declarat o variabilă înainte de a-i atribui o valoare.
+
+
+
+#### Răspuns: A
+
+Acest lucru este posibil în JavaScript, deoarece funcțiile sunt obiecte! (Totul, în afară de tipurile primitive, sunt obiecte)
+
+O funcție este un tip special de obiect. Codul pe care îl scrii tu însuți nu este funcția efectivă. Funcția este un obiect cu proprietăți. Această proprietate este invocabilă.
+
+
+
+#### Răspuns: A
+
+În JavaScript, funcțiile sunt obiecte și, prin urmare, metoda `getFullName` este adăugată obiectului constructor al funcției în sine. Din acest motiv, putem apela `Person.getFullName()`, dar `member.getFullName` aruncă o eroare de tip `TypeError`.
+
+Dacă doriți ca o metodă să fie disponibilă pentru toate instanțele obiectului, trebuie să o adăugați la proprietatea prototype:
+
+```js
+Person.prototype.getFullName = function () {
+ return `${this.firstName} ${this.lastName}`;
+};
+```
+
+
+
+#### Răspuns: A
+
+Pentru `sarah`, nu am folosit cuvântul cheie `new`. Când folosim `new`, `this` se referă la noul obiect gol pe care îl creăm. Cu toate acestea, dacă nu adăugăm `new`, `this` se referă la **obiectul global**!
+
+Am spus că `this.firstName` este egal cu `"Sarah"` și `this.lastName` este egal cu `"Smith"`. Ceea ce am făcut de fapt este să definim `global.firstName = 'Sarah'` și `global.lastName = 'Smith'`. `sarah` în sine rămâne `undefined`, deoarece nu returnăm o valoare din funcția `Person`.
+
+
+
+#### Răspuns: D
+
+În timpul fazei de **capturing**, evenimentul trece prin elementele părinte până la elementul țintă. Apoi ajunge la elementul **target**, și începe **bubbling**.
+
+
+
+#### Răspuns: B
+
+Toate obiectele au prototipuri, cu excepția **obiectului de bază**. Obiectul de bază este obiectul creat de utilizator sau un obiect creat folosind cuvântul cheie `new`. Obiectul de bază are acces la unele metode și proprietăți, cum ar fi `.toString`. Acesta este motivul pentru care puteți utiliza metode JavaScript încorporate! Toate aceste metode sunt disponibile în prototip. Deși JavaScript nu le poate găsi direct în obiectul dvs., merge în jos pe lanțul prototip și le găsește acolo, ceea ce le face accesibile pentru dvs.
+
+
+
+#### Răspuns: C
+
+JavaScript este un limbaj **dinamic tipizat**: nu specificăm tipurile variabilelor. Valorile pot fi convertite automat în alt tip fără să știți, ceea ce se numește _coerție de tip implicită_. **Coerția** este conversia dintr-un tip în altul.
+
+În acest exemplu, JavaScript convertește numărul `1` într-un șir de caractere, pentru ca funcția să aibă sens și să returneze o valoare. În timpul adunării unui tip numeric (`1`) și unui tip șir de caractere (`'2'`), numărul este tratat ca un șir de caractere. Putem concatena șiruri de caractere, așa cum facem cu `"Hello" + "World"`, deci ceea ce se întâmplă aici este `"1" + "2"` care returnează `"12"`.
+
+
+
+#### Răspuns: C
+
+Operatorul unary **postfix** `++`:
+
+1. Returnează valoarea (aceasta returnează `0`)
+2. Incrementează valoarea (numărul este acum `1`)
+
+Operatorul unary **prefix** `++`:
+
+1. Incrementează valoarea (numărul este acum `2`)
+2. Returnează valoarea (aceasta returnează `2`)
+
+Aceasta returnează `0 2 2`.
+
+
+
+#### Răspuns: B
+
+Dacă utilizați șiruri template etichetate, valoarea primului argument este întotdeauna un șir de valori. Argumentele rămase primesc valorile expresiilor transmise!
+
+
+
+#### Răspuns: C
+
+Când se testează egalitatea, primitivele sunt comparate în funcție de valoarea lor, în timp ce obiectele sunt comparate în funcție de _referința_ lor. JavaScript verifică dacă obiectele au o referință către aceeași locație în memorie.
+
+Cele două obiecte pe care le comparăm nu au aceeași referință: obiectul pe care l-am trecut ca parametru se referă la o altă locație în memorie decât obiectul pe care l-am folosit pentru a verifica egalitatea.
+
+Acesta este motivul pentru care ambele `{ age: 18 } === { age: 18 }` și `{ age: 18 } == { age: 18 }` returnează `false`.
+
+
+
+#### Răspuns: C
+
+Parametrul rest (`...args`) ne permite să "colectăm" toate argumentele rămase într-un array. Un array este un obiect, așa că `typeof args` returnează `"object"`
+
+
+
+#### Răspuns: C
+
+Cu `"use strict"`, puteți asigura că nu declarați accidental variabile globale. Niciodată nu am declarat variabila `age`, și deoarece folosim `"use strict"`, va arunca o eroare de referință. Dacă nu am fi folosit `"use strict"`, ar fi funcționat, deoarece proprietatea `age` ar fi fost adăugată la obiectul global.
+
+
+
+#### Răspuns: A
+
+`eval` evaluează codul care este trecut ca un șir de caractere. Dacă este o expresie, așa cum este în acest caz, evaluează expresia. Expresia este `10 * 10 + 5`. Aceasta returnează numărul `105`.
+
+
+
+#### Răspuns: B
+
+Datele stocate în `sessionStorage` sunt eliminate după închiderea _filei_.
+
+Dacă ați fi folosit `localStorage`, datele ar fi rămas acolo pentru totdeauna, cu excepția cazului în care, de exemplu, este invocată comanda `localStorage.clear()`.
+
+
+
+#### Răspuns: B
+
+Cu cuvântul cheie `var`, puteți declara mai multe variabile cu același nume. Variabila va reține apoi cea mai recentă valoare.
+
+Nu puteți face acest lucru cu `let` sau `const` deoarece acestea sunt cu scop de bloc.
+
+
+
+#### Răspuns: C
+
+Toate cheile obiectelor (cu excepția simbolurilor) sunt șiruri de caractere în culise, chiar dacă nu le tastați ca șiruri de caractere. De aceea `obj.hasOwnProperty('1')` returnează de asemenea `true`.
+
+Acest lucru nu funcționează în același fel pentru un set. Nu există `'1'` în setul nostru: `set.has('1')` returnează `false`. Acesta are tipul numeric `1`, `set.has(1)` returnează `true`.
+
+
+
+#### Răspuns: C
+
+Dacă aveți două chei cu același nume, cheia va fi înlocuită. Va rămâne totuși în prima sa poziție, dar cu ultima valoare specificată.
+
+
+
+#### Răspuns: A
+
+Contextul de execuție de bază este contextul global de execuție: este ceea ce este accesibil peste tot în codul dvs.
+
+
+
+#### Răspuns: C
+
+Instrucțiunea `continue` sare peste o iterație dacă o anumită condiție returnează `true`.
+
+
+
+#### Răspuns: A
+
+`String` este un constructor încorporat, la care putem adăuga proprietăți. Am adăugat doar o metodă la prototipul său. Șirurile primitive sunt convertite automat într-un obiect șir, generat de funcția prototip a șirului. Prin urmare, toate șirurile (obiecte de șir) au acces la acea metodă!
+
+
+
+#### Răspuns: B
+
+Cheile obiectului sunt convertite automat în șiruri de caractere. Încercăm să setăm un obiect ca cheie pentru obiectul `a`, cu valoarea `123`.
+
+Cu toate acestea, când transformăm în șir un obiect, acesta devine `"[object Object]"`. Deci ceea ce spunem aici este că `a["[object Object]"] = 123`. Apoi, putem încerca să facem același lucru din nou. `c` este un alt obiect pe care îl transformăm implicit în șir. Așadar, `a["[object Object]"] = 456`.
+
+Apoi, afișăm înregistrarea `a[b]`, care de fapt este `a["[object Object]"]`. Am setat doar asta la `456`, deci returnează `456`.
+
+
+
+#### Răspuns: B
+
+Avem o funcție `setTimeout` și am invocat-o mai întâi. Cu toate acestea, a fost înregistrată în ultimul rând.
+
+Acest lucru se datorează faptului că în browsere, nu avem doar motorul de execuție, avem și ceva numit `WebAPI`.`WebAPI` ne oferă funcția `setTimeout` de exemplu, și DOM-ul.
+
+După ce _callback_-ul este trimis către WebAPI, funcția `setTimeout` în sine (dar nu și callback-ul!) este scos din stivă.
+
+
+
+#### Răspuns: C
+
+Cel mai profund element înglobat care a cauzat evenimentul este ținta evenimentului. Puteți opri propagarea acestuia prin `event.stopPropagation`
+
+
+ Click here!
+
+
+#### Răspuns: A
+
+Dacă facem clic pe `p`, vom vedea două înregistrări: `p` și `div`. În timpul propagării evenimentului, există 3 faze: capturare, țintă și propagare. În mod implicit, gestionarii de evenimente sunt executați în faza de propagare (cu excepția cazului în care setați `useCapture` la `true`). Aceștia se execută de la cel mai profund element înglobat către exterior.
+
+
+
+#### Răspuns: D
+
+Cu ambele metode, putem transmite obiectul la care dorim să se refere cuvântul cheie `this`. Cu toate acestea, `.call` este de asemenea _executat imediat_!
+
+`.bind.` returnează o _copie_ a funcției, dar cu un context legat! Nu este executat imediat.
+
+
+
+#### Răspuns: B
+
+Funcția `sayHi` returnează valoarea returnată de expresia funcției invocate imediat (IIFE). This function returned `0`, care este de tip `"number"`.
+
+Informație utilă: `typeof` poate returna următoarele valori: `undefined`, `boolean`, `number`, `bigint`, `string`, `symbol`, `function` și `object`. Notați că `typeof null` returnează `"object"`.
+
+
+
+#### Răspuns: A
+
+Există 8 valori considerate falsy:
+
+- `undefined`
+- `null`
+- `NaN`
+- `false`
+- `''` (șir de caractere gol)
+- `0`
+- `-0`
+- `0n` (BigInt(0))
+
+Constructorii de funcții, cum ar fi `new Number` și `new Boolean` sunt considerați truthy.
+
+
+
+#### Răspuns: B
+
+`typeof 1` returnează `"number"`.
+`typeof "number"` returnează `"string"`
+
+
+
+#### Răspuns: C
+
+Când setați o valoare pentru un element într-un array care depășește lungimea array-ului, JavaScript creează ceea ce se numește "slot-uri goale" (empty slots). Acestea au de fapt valoarea `undefined`, dar veți vedea ceva de genul:
+
+`[1, 2, 3, empty x 7, 11]`
+
+în funcție de locul în care îl rulați (este diferit pentru fiecare browser, Node.js, etc.)
+
+
+
+#### Răspuns: A
+
+Blocul `catch` primește argumentul `x`. Acesta nu este același `x` ca variabila când transmitem argumente. Această variabilă `x` este având domeniu de bloc (block-scoped).
+
+Mai târziu, setăm această variabilă cu domeniu de bloc la valoarea `1`, și stabilim valoarea variabilei `y`. Acum, înregistrăm în consolă variabila cu domeniu de bloc `x`, care este egală cu `1`.
+
+În afara blocului `catch`, `x` rămâne `undefined`, și `y` este `2`. Atunci când dorim să afișăm în consolă `console.log(x)` în afara blocului `catch`, acesta returnează `undefined`, și `y` returnează `2`.
+
+
+
+#### Răspuns: A
+
+JavaScript are doar tipuri primitive și obiecte.
+
+Tipurile primitive sunt `boolean`, `null`, `undefined`, `bigint`, `number`, `string`, și `symbol`.
+
+Ceea ce diferențiază un tip primitiv de un obiect este faptul că tipurile primitive nu au proprietăți sau metode. Cu toate acestea, veți observa că `'foo'.toUpperCase()` se evaluează la `'FOO'` și nu duce la o eroare `TypeError`. Acest lucru se întâmplă pentru că atunci când încercați să accesați o proprietate sau o metodă pe un tip primitiv, cum ar fi un șir de caractere (string), JavaScript va înconjura implicit tipul primitiv folosind una dintre clasele de înveliș, adică `String`, și apoi va renunța imediat la înveliș după ce expresia se evaluează. Toate tipurile primitive, cu excepția `null` și `undefined` prezintă acest comportament.
+
+
+
+#### Răspuns: C
+
+`[1, 2]` este valoarea noastră inițială. Aceasta este valoarea cu care începem și valoarea primului `acc`. În prima rundă, `acc` este `[1,2]`, și `cur` este `[0, 1]`. Le concatenăm, ceea ce duce la rezultatul `[1, 2, 0, 1]`.
+
+Atunci, `[1, 2, 0, 1]` este `acc` și `[2, 3]` este `cur`. Le concatenăm și obținem `[1, 2, 0, 1, 2, 3]`
+
+
+
+#### Răspuns: B
+
+`null` este falsy. `!null` returnează `true`. `!true` returnează `false`.
+
+`""` este falsy. `!""` returnează `true`. `!true` returnează `false`.
+
+`1` este truthy. `!1` returnează `false`. `!false` returnează `true`.
+
+
+
+#### Răspuns: A
+
+Aceasta returnează un identificator unic. Acest id poate fi utilizat pentru a opri intervalul respectiv cu ajutorul funcției `clearInterval()`.
+
+
+
+#### Răspuns: A
+
+Un șir de caractere este un obiect iterabil. Operatorul de răspândire (spread operator) mapează fiecare caracter dintr-un obiect iterabil la un element separat.
+
+
+
+#### Răspuns: C
+
+Funcțiile regulate nu pot fi oprite în mijlocul execuției după invocare. Cu toate acestea, o funcție generator poate fi "oprită" în mijloc și ulterior poate continua de la locul unde s-a oprit. De fiecare dată când o funcție generator întâlnește un cuvânt cheie `yield`, funcția furnizează valoarea specificată după el. Notați că funcția generator în acest caz nu _returnează_ the valoarea, ci _furnizează_ valoarea.
+
+Mai întâi, inițializăm funcția generator cu `i` egal cu `10`. Invocăm funcția generator folosind metoda `next()`. Prima dată când invocăm funcția generator, `i` este egal cu `10`. Aceasta întâlnește primul cuvânt cheie `yield`: furnizează valoarea lui `i`. Generatorul este acum "pauzat", și se înregistrează valoarea `10`.
+
+Apoi, invocăm din nou funcția cu metoda `next()`. Ea începe să continue de unde s-a oprit anterior, încă cu `i` egal cu `10`. Acum, întâlnește următorul cuvânt cheie `yield`, și furnizează `i * 2`. `i` este egal cu `10`, așa că returnează `10 * 2`, adică `20`. Acest lucru duce la rezultatul `10, 20`.
+
+
+
+#### Răspuns: B
+
+Atunci când transmitem mai multe promisiuni metodei `Promise.race`, ea rezolvă/rejectează _prima_ promisiune care se rezolvă/rejectează. Pentru metoda `setTimeout`, transmitem un cronometru: 500ms pentru prima promisiune (`firstPromise`), și 100ms pentru a doua promisiune (`secondPromise`). Acest lucru înseamnă că `secondPromise` se rezolvă primul cu valoarea `'two'`. `res` conține acum valoarea `'two'`, care se înregistrează în consolă.
+
+
+
+#### Răspuns: D
+
+În primul rând, declarăm o variabilă `person` cu valoarea unui obiect care are o proprietate `name`.
+
+
+
+#### Răspuns: B
+
+Cu un ciclu `for-in` putem itera prin cheile obiectului, în acest caz `name` și `age`. În interior, cheile obiectului sunt șiruri de caractere (dacă nu sunt de tip Symbol). În fiecare iterație, setăm valoarea lui `item` egală cu cheia curentă pe care o parcurge. Mai întâi, `item` este egal cu `name`, și este înregistrat în consolă. Apoi, `item` este egal cu `age`, care este, de asemenea, înregistrat în consolă.
+
+
+
+#### Răspuns: B
+
+Asociativitatea operatorilor este ordinea în care compilatorul evaluează expresiile, fie de la stânga la dreapta, fie de la dreapta la stânga. Acest lucru se întâmplă doar dacă toți operatorii au aceeași precedență. În cazul nostru, avem doar un tip de operator: `+`. Pentru adunare, asociativitatea este de la stânga la dreapta.
+
+`3 + 4` este evaluat mai întâi. Acest lucru duce la numărul `7`.
+
+`7 + '5'` duce la rezultatul `"75"` datorită coerției. JavaScript convertește numărul `7` într-un șir de caractere, așa cum am discutat în întrebarea 15. Putem concatena două șiruri de caractere folosind operatorul `+`. `"7" + "5"` rezultă în `"75"`.
+
+
+
+#### Răspuns: C
+
+Este returnat doar primul număr din șir. Bazat pe _radix_ (al doilea argument pentru a specifica în ce tip de număr dorim să-l parsăm: bază 10, hexazecimal, octal, binar, etc.), `parseInt` verifică dacă caracterele din șir sunt valide. Odată ce întâlnește un caracter care nu este un număr valid în baza specificată, oprește parsarea și ignoră caracterele ulterioare.
+
+`*` nu este un număr valid. Parsează doar `"7"` în numărul zecimal `7`. Acum, `num` conține valoarea `7`.
+
+
+
+#### Răspuns: C
+
+Când se parcurge array-ul, valoarea lui `num` este egală cu elementul prin care parcurge în acel moment. În acest caz, elementele sunt numere, astfel că condiția din instrucțiunea `typeof num === "number"` returnează `true`. Funcția map creează un nou array și introduce valorile returnate de funcție.
+
+Cu toate acestea, nu returnăm o valoare. Atunci când nu returnăm o valoare din funcție, funcția returnează `undefined`. Pentru fiecare element din array, blocul funcției este apelat, deci pentru fiecare element returnăm `undefined`.
+
+
+
+#### Răspuns: A
+
+Argumentele sunt transmise prin _valoare_, cu excepția cazului în care valoarea lor este un obiect, caz în care sunt transmise prin _referință_. `birthYear` este transmis prin valoare, deoarece este un șir de caractere (string), nu un obiect. Atunci când transmitem argumente prin valoare, se creează o _copie_ a acelei valori (consultați întrebarea 46).
+
+Variabila `birthYear` are o referință la valoarea `"1997"`. Argumentul `year` are, de asemenea, o referință la valoarea `"1997"`, dar nu este aceeași valoare la care se referă `birthYear`. Atunci când actualizăm valoarea lui `year` prin setarea lui `year` egal cu `"1998"`, actualizăm doar valoarea lui `year`. `birthYear` rămâne în continuare egal cu `"1997"`.
+
+Valoarea lui `person` este un obiect. Argumentul `member` are o referință (copiată) către _același_ obiect. Atunci când modificăm o proprietate a obiectului la care se referă `member` valoarea lui `person` va fi de asemenea modificată, deoarece ambele au o referință la același obiect. Proprietatea `name` a lui `person` este acum egală cu valoarea `"Lydia"`.
+
+
+
+#### Răspuns: D
+
+Cu instrucțiunea `throw` putem crea erori personalizate. Cu această instrucțiune, puteți arunca excepții. O excepție poate fi un șir de caractere, un număr, un boolean sau un obiect. În acest caz, excepția noastră este șirul `'Hello world!'`.
+
+Cu instrucțiunea `catch` putem specifica ce să facem dacă o excepție este aruncată în blocul `try`. O excepție este aruncată: șirul `'Hello world!'`. `e` este acum egal cu acel șir, pe care îl înregistrăm. Acest lucru duce la rezultatul `'Oh an error: Hello world!'`.
+
+
+
+#### Răspuns: B
+
+Atunci când o funcție constructor este apelată cu cuvântul cheie `new`, aceasta creează un obiect și stabilește cuvântul cheie `this` să se refere la acel obiect. În mod implicit, dacă funcția constructor nu returnează explicit nimic, va returna obiectul creat recent.
+
+În acest caz, funcția constructor `Car` returnează în mod explicit un obiect nou cu proprietatea `make` setată la `"Maserati"`, ceea ce suprascrie comportamentul implicit. Prin urmare, atunci când este apelat `new Car()` obiectul _returnat_ este atribuit lui `myCar`, ceea ce duce la rezultatul `"Maserati"` atunci când se accesează `myCar.make`.
+
+
+
+#### Răspuns: A
+
+`let x = (y = 10);` este de fapt o prescurtare pentru
+
+```javascript
+y = 10;
+let x = y;
+```
+
+Când setăm `y` egal cu `10`, adăugăm de fapt o proprietate `y` la obiectul global (`window` într-un browser, `global` în Node). Într-un browser, `window.y` este acum egal cu `10`.
+
+Apoi, declarăm o variabilă `x` cu valoarea `y`, care este `10`. Variabilele declarate cu cuvântul cheie `let` au domeniu de bloc _block scoped_, ele sunt definite doar în blocul în care sunt declarate; în cazul de față, în funcția expresie invocată imediat (IIFE). Atunci când folosim operatorul `typeof` operandul `x` nu este definit: încercăm să accesăm `x` în afara blocului în care este declarat. Acest lucru înseamnă că `x` nu este definit. Valorile care nu au primit o valoare sau nu au fost declarate sunt de tip `"undefined"`. `console.log(typeof x)` returnează `"undefined"`.
+
+Cu toate acestea, am creat o variabilă globală `y` atunci când am setat `y` egal cu `10`. Această valoare este accesibilă oriunde în codul nostru. `y` este definită și deține o valoare de tip `"number"`. `console.log(typeof y)` returnează `"number"`.
+
+
+
+#### Răspuns: A
+
+Putem șterge proprietăți din obiecte folosind cuvântul cheie `delete` inclusiv de pe prototip. Prin ștergerea unei proprietăți de pe prototip, aceasta nu mai este disponibilă în lanțul prototipului. În acest caz, funcția `bark` nu mai este disponibilă pe prototip după `delete Dog.prototype.bark`, dar încercăm totuși să o accesăm.
+
+Când încercăm să apelăm ceva care nu este o funcție, este aruncată o excepție `TypeError`. În acest caz, se generează eroarea `TypeError: pet.bark is not a function`, deoarece `pet.bark` este `undefined`.
+
+
+
+#### Răspuns: D
+
+Obiectul `Set` este o colecție de valori unice: o valoare poate apărea doar o singură dată într-un set.
+
+m transmis iterable-ul `[1, 1, 2, 3, 4]` cu o valoare duplicată `1`. Deoarece nu putem avea două valori identice într-un set, una dintre ele este eliminată. Acest lucru duce la rezultatul `{1, 2, 3, 4}`.
+
+
+
+#### Răspuns: C
+
+Un modul importat este _doar pentru citire_: nu puteți modifica modulul importat. Doar modulul care le exportă poate schimba valorile acestora.
+
+Când încercăm să incrementăm valoarea lui `myCounter`, apare o eroare: `myCounter` este doar pentru citire și nu poate fi modificat.
+
+
+
+#### Răspuns: A
+
+Operatorul `delete` returnează o valoare booleană: `true` în cazul ștergerii reușite, în caz contrar va returna `false`. Cu toate acestea, variabilele declarate cu cuvintele cheie `var`, `const` sau `let` nu pot fi șterse folosind operatorul `delete`.
+
+Variabila `name` a fost declarată cu cuvântul cheie `const` așa că ștergerea sa nu reușește: se returnează `false`. Atunci când setăm `age` egal cu `21`, de fapt am adăugat o proprietate numită `age` la obiectul global. În acest fel, puteți șterge cu succes proprietăți din obiecte, inclusiv din obiectul global, așa că `delete age` returnează `true`.
+
+
+
+#### Răspuns: C
+
+Putem dezasambla (unpack) valori din array-uri sau proprietăți din obiecte prin destructurare. De exemplu:
+
+```javascript
+[a, b] = [1, 2];
+```
+
+
+
+#### Răspuns: B
+
+Este posibil să combinăm obiecte folosind operatorul de răspândire`...`. Acesta vă permite să creați copii ale perechilor cheie/valoare dintr-un obiect și să le adăugați la alt obiect. În acest caz, creăm copii ale obiectului `user` și le adăugăm la obiectul `admin`. Obiectul `admin` conține acum perechile cheie/valoare copiate, ceea ce duce la rezultatul `{ admin: true, name: "Lydia", age: 21 }`.
+
+
+
+#### Răspuns: B
+
+Cu metoda `defineProperty` putem adăuga noi proprietăți la un obiect sau să modificăm cele existente. Atunci când adăugăm o proprietate la un obiect folosind metoda `defineProperty` aceasta nu este, în mod implicit, _nu enumerabilă_. Metoda `Object.keys` returnează toate numele de proprietăți _enumerabile_ dintr-un obiect, în acest caz doar `"name"`.
+
+Proprietățile adăugate folosind metoda `defineProperty` sunt, în mod implicit, imutabile (nu pot fi schimbate). Puteți anula acest comportament folosind proprietățile `writable`, `configurable` și `enumerable` În acest fel, metoda `defineProperty` vă oferă un control mai mare asupra proprietăților pe care le adăugați la un obiect.
+
+
+
+#### Răspuns: A
+
+Al doilea argument al funcției `JSON.stringify` este _replacer-ul_. Replacer-ul poate fi fie o funcție, fie un array, și vă permite să controlați ce și cum ar trebui să fie serializate (convertite în șir de caractere) valorile.
+
+Dacă replacer-ul este un _array_, în șirul JSON vor fi incluse doar numele de proprietăți care sunt prezente în array. În acest caz, doar proprietățile cu numele `"level"` și `"health"` sunt incluse, în timp ce `"username"` este exclus. Astfel, `data` devine egal cu `"{"level":19, "health":90}"`.
+
+Dacă replacer-ul este o _funcție_, această funcție este apelată pentru fiecare proprietate din obiectul pe care îl serializați. Valoarea returnată de această funcție va fi valoarea proprietății atunci când este adăugată în șirul JSON. Dacă valoarea este `undefined`, această proprietate este exclusă din șirul JSON.
+
+
+
+#### Răspuns: A
+
+Operatorul unary `++` _returnează mai întâi_ valoarea operandului și _apoi incrementează_ valoarea operandului. Valoarea lui `num1` este `10`, deoarece funcția `increaseNumber` returnează mai întâi valoarea lui `num`, care este `10`, și numai apoi incrementează valoarea lui `num`.
+
+`num2` este `10`, deoarece am transmis `num1` către funcția `increasePassedNumber`. `number` ieste egal cu `10`(valoarea lui `num1`). Iarăși, operatorul unary `++` _returnează mai întâi_ valoarea operandului și _apoi incrementeazăs_ valoarea operandului. Valoarea lui `number` este `10`, așa că `num2` este egal cu `10`.
+
+
+
+#### Răspuns: C
+
+În ES6, putem inițializa parametri cu o valoare implicită. Valoarea parametrului va fi valoarea implicită, dacă nu a fost furnizată nicio altă valoare funcției sau dacă valoarea parametrului este `"undefined"`. În acest caz, răspândim proprietățile obiectului `value` într-un obiect nou, astfel încât `x` are valoarea implicită `{ number: 10 }`.
+
+Argumentul implicit este evaluat la _momentul apelului_! De fiecare dată când apelăm funcția, se creează un obiect _nou_. Invocăm funcția `multiply` primele două ori fără a furniza o valoare: `x` are valoarea implicită `{ number: 10 }`. Apoi înregistrăm în consolă valoarea înmulțită a acelui număr, care este `20`.
+
+A treia oară când apelăm `multiply`, furnizăm un argument: obiectul numit `value`. Operatorul `*=` este, de fapt, o prescurtare pentru `x.number = x.number * 2`: modificăm valoarea lui`x.number`, și înregistrăm în consolă valoarea înmulțită, care este `20`.
+
+A patra oară, trecem din nou obiectul `value`. `x.number` a fost modificat anterior la `20`, deci `x.number *= 2` înregistrează `40`.
+
+
+
+#### Răspuns: D
+
+Primul argument pe care îl primește metoda `reduce` este _acumulator-ul_, `x` în acest caz. Al doilea argument este _valoarea curentă_, `y`. Cu metoda `reduce`, executăm o funcție de apel pe fiecare element din array, ceea ce poate duce în cele din urmă la o singură valoare.
+
+În acest exemplu, nu returnăm nicio valoare, ci doar înregistrăm valorile accumulatorului și valorii curente.
+
+Valoarea accumulatorului este egală cu valoarea returnată anterior de funcția de apel. Dacă nu furnizați argumentul opțional `initialValue` metodei `reduce`, accumulatorul este egal cu primul element la prima apelare.
+
+La prima apelare, accumulatorul (`x`) este `1`, iar valoarea curentă (`y`) este `2`. Nu returnăm din funcția de apel, ci înregistrăm valorile accumulatorului și valoarea curentă: se înregistrează `1` și `2`.
+
+Dacă nu returnați o valoare dintr-o funcție, aceasta va returna `undefined`. OLa următoarea apelare, accumulatorul este `undefined`, iar valoarea curentă este `3`. Se înregistrează `undefined` și `3`.
+
+La a patra apelare, din nou nu returnăm din funcția de apel. Accumulatorul este din nou `undefined`, iar valoarea curentă este `4`. Se înregistrează `undefined` și `4`.
+
+
+
+#### Răspuns: B
+
+Într-o clasă derivată, nu puteți accesa cuvântul cheie `this` înainte de a apela `super`. Dacă încercați să faceți acest lucru, va arunca o ReferenceError: 1 și 4 ar arunca o eroare de referință.
+
+Cu cuvântul cheie `super`, apelăm constructorul clasei părinte cu argumentele date. Constructorul părintelui primește argumentul `name`, deci trebuie să transmitem `name` la `super`.
+
+Clasa `Labrador` primește doi argumente, `name` deoarece extinde clasa `Dog`, și `size` ca o proprietate suplimentară în clasa `Labrador`. Ambele trebuie să fie transmise funcției constructor din clasa `Labrador`, ceea ce se face corect utilizând constructorul 2.
+
+
+
+#### Răspuns: B
+
+Cu cuvântul cheie `import`, toate modulele importate sunt _preparate în prealabil_. Acest lucru înseamnă că modulele importate sunt executate _mai întâi_, codul din fișierul care importă modulul este executat _după accea_.
+
+Acesta este un diferență între `require()` în CommonJS și `import`! Cu `require()`, puteți încărca dependențele la cerere în timp ce codul este în curs de desfășurare. Dacă am fi folosit `require` în loc de `import`, ar fi fost înregistrate în consolă mesajele `running index.js`, `running sum.js`, `3`.
+
+
+
+#### Răspuns: A
+
+Fiecare Symbol este complet unic. Scopul argumentului furnizat către Symbol este de a oferi Symbolului o descriere. Valoarea Symbolului nu depinde de argumentul furnizat. În timp ce testăm egalitatea, creăm două simboluri complet noi: primul `Symbol('foo')`, și al doilea `Symbol('foo')`. Aceste două valori sunt unice și nu sunt egale între ele, `Symbol('foo') === Symbol('foo')` returnează `false`.
+
+
+
+#### Răspuns: C
+
+Cu metoda `padStart` putem adăuga umplutură la începutul unui șir. Valoarea transmisă acestei metode este lungimea _totală_ a șirului împreună cu umplutura. Șirul `"Lydia Hallie"` are o lungime de `12`. `name.padStart(13)` introduce 1 spațiu la începutul șirului, deoarece 12 + 1 este 13.
+
+Dacă argumentul transmis metodei `padStart` este mai mic decât lungimea șirului, nu va fi adăugată nicio umplutură.
+
+
+
+#### Răspuns: A
+
+Cu operatorul `+`, puteți concatena șiruri. În acest caz, concatenăm șirul `"🥑"` cu șirul `"💻"`, rezultând `"🥑💻"`.
+
+
+
+#### Răspuns: C
+
+O funcție generator "pauzează" execuția când întâlnește cuvântul cheie `yield`. Mai întâi, trebuie să permitem funcției să emită șirul "Do you love JavaScript?", ceea ce poate fi făcut apelând `game.next().value`.
+
+Fiecare linie este executată până când găsește primul cuvânt cheie `yield`. Există un cuvânt cheie `yield` pe prima linie din funcție: execuția se oprește cu primul `yield`. _Acest lucru înseamnă că variabila `answer` nu este definită încă!_
+
+Când apelăm `game.next("Yes").value`, cuvântul cheie `yield` anterior este înlocuit cu valoarea parametrilor transmiși funcției `next()`, `"Yes"` în acest caz. Valoarea variabilei `answer` este acum egală cu `"Yes"`. Condiția declarației if returnează `false`, și `JavaScript loves you back ❤️` este înregistrat în consolă.
+
+
+
+#### Răspuns: C
+
+`String.raw` returnează un șir în care escape-urile (`\n`, `\v`, `\t` etc.) sunt ignorate! Backslash-urile pot fi o problemă, deoarece puteți ajunge cu ceva similar cu:
+
+`` const path = `C:\Documents\Projects\table.html` ``
+
+Acest lucru ar rezulta în:
+
+`"C:DocumentsProjects able.html"`
+
+Cu `String.raw`, acesta ar ignora pur și simplu escape-ul și ar afișa:
+
+`C:\Documents\Projects\table.html`
+
+În acest caz, șirul este `Hello\nworld`, care este înregistrat în consolă.
+
+
+
+#### Răspuns: C
+
+O funcție `async` întotdeauna returnează o promisiune. Instrucțiunea `await` încă trebuie să aștepte ca promisiunea să se rezolve: o promisiune în așteptare este returnată atunci când apelăm `getData()` pentru a o atribui variabilei `data`.
+
+Dacă dorim să avem acces la valoarea rezolvată `"I made it"`, am putea folosi metoda `.then()` pe `data`:
+
+`data.then(res => console.log(res))`
+
+Acest lucru ar fi înregistrat `"I made it!"`
+
+
+
+#### Răspuns: B
+
+Metoda`.push()` returnează _lungimea_ noului șir! Înainte, șirul conținea un element (șirul `"banana"`) și avea o lungime de `1`. După adăugarea șirului `"apple"` în șir, șirul conține două elemente și are o lungime de `2`. Aceasta este valoarea returnată de funcția `addToList`.
+
+Metoda `push` modifică șirul original. Dacă doreați să returnați _șirul_ din funcție în loc de _lungimea șirului_, ar fi trebuit să returnați `list` după ce ați adăugat `item` la el.
+
+
+
+#### Răspuns: B
+
+`Object.freeze` face imposibilă adăugarea, eliminarea sau modificarea proprietăților unui obiect (cu excepția cazului în care valoarea proprietății este un alt obiect).
+
+Când creăm variabila `shape` și o setăm egală cu obiectul înghețat `box`, `shape` de asemenea se referă la un obiect înghețat. Puteți verifica dacă un obiect este înghețat folosind `Object.isFrozen`. În acest caz, `Object.isFrozen(shape)` ar returna true, deoarece variabila `shape` are o referință către un obiect înghețat.
+
+Deoarece `shape` este înghețat și deoarece valoarea lui`x` nu este un obiect, nu putem modifica proprietatea `x`. `x` rămâne egal cu `10`, și `{ x: 10, y: 20 }` este afișat în consolă.
+
+
+
+#### Răspuns: D
+
+Folosind [destructuring assignment](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) cu sintaxa de mai jos putem extrage valori din array-uri sau proprietăți din obiecte în variabile distincte:
+
+```javascript
+const { firstName } = { firstName: 'Lydia' };
+// ES5 version:
+// var firstName = { firstName: 'Lydia' }.firstName;
+
+console.log(firstName); // "Lydia"
+```
+
+De asemenea, o proprietate poate fi extras dintr-un obiect și atribuită unei variabile cu un nume diferit decât proprietatea obiectului:
+
+```javascript
+const { firstName: myName } = { firstName: 'Lydia' };
+// ES5 version:
+// var myName = { firstName: 'Lydia' }.firstName;
+
+console.log(myName); // "Lydia"
+console.log(firstName); // Uncaught ReferenceError: firstName is not defined
+```
+
+Prin urmare, `firstName` nu există ca variabilă, astfel încât încercarea de a accesa valoarea sa va genera o eroare `ReferenceError`.
+
+**Notă:** Fiți conștienți de proprietățile în `global scope` (spațiul global):
+
+```javascript
+const { name: myName } = { name: 'Lydia' };
+
+console.log(myName); // "lydia"
+console.log(name); // "" ----- Browser e.g. Chrome
+console.log(name); // ReferenceError: name is not defined ----- NodeJS
+
+```
+
+În cazul în care JavaScript nu poate găsi o variabilă în _cadrul curent_, acesta urcă pe [Scope chain](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/ch3.md) și o caută. Dacă ajunge la nivelul superior al cadrului, adică la **spațiul global**, și tot nu o găsește, va arunca o excepție `ReferenceError`.
+
+- În **Browser-e** cum ar fi _Chrome_, `name` este o _proprietate de spațiu global depășită_. În acest exemplu, codul rulează în _spațiul global_ și nu există o variabilă locală definită de utilizator pentru `name`, așa că caută _variabilele/proprietățile_ predefinite în spațiul global, care în cazul browser-elor înseamnă că caută în obiectul `window` de unde extrage valoarea [window.name](https://developer.mozilla.org/en-US/docs/Web/API/Window/name) care este egală cu un **șir gol**.
+
+- În **NodeJS**, nu există o astfel de proprietate pe obiectul `global` așadar încercarea de a accesa o variabilă inexistentă va genera o [ReferenceError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Not_defined).
+
+
+
+#### Răspuns: A
+
+O funcție pură este o funcție care _întotdeauna_ returnează același rezultat, dacă aceleași argumente sunt furnizate.
+
+Funcția `sum` întotdeauna returnează același rezultat. Dacă îi furnizăm `1` și `2`, va returna _întotdeauna_ `3` fără efecte secundare. Dacă îi furnizăm `5` și `10`, va returna _întotdeauna_ `15`, și tot așa. Aceasta este definiția unei funcții pure.
+
+
+
+#### Răspuns: C
+
+Funcția `add` este o funcție _memoizată_. Cu ajutorul memoizării, putem să memorăm rezultatele unei funcții pentru a accelera execuția ulterioară. În acest caz, creăm un obiect `cache` care stochează valorile returnate anterior.
+
+Dacă apelăm din nou funcția `addFunction` cu același argument, funcția verifică mai întâi dacă a primit deja acea valoare în memoria sa cache. Dacă acest lucru este adevărat, se va returna valoarea din cache, economisind timp de execuție. Dacă nu este în cache, funcția va calcula valoarea și o va memora ulterior.
+
+Apelăm funcția `addFunction` de trei ori cu aceeași valoare: în prima invocare, valoarea funcției când `num` este egal cu `10` nu este încă în cache. Condiția instrucțiunii `num in cache` returnează `false`, iar blocul `else` este executat: se afișează `Calculated! 20` iar valoarea rezultatului este adăugată în obiectul de cache. Acum, `cache` arată astfel `{ 10: 20 }`.
+
+A doua oară, obiectul `cache` conține valoarea care este returnată pentru `10`. Condiția instrucțiunii `num in cache` returnează `true`, și se afișează `'From cache! 20'`.
+
+A treia oară, trecem `5 * 2` funcției, care este evaluat la `10`. Obiectul `cache` conține valoarea care este returnată pentru `10`. Condiția instrucțiunii `num in cache` returnează `true`, și se afișează `'From cache! 20'`.
+
+
+
+#### Răspuns: A
+
+Cu o buclă _for-in_, putem itera peste proprietățile **enumerabile**. Într-un șir, proprietățile enumerate sunt "cheile" elementelor din șir, care sunt de fapt indexurile lor. Puteți vedea un șir ca:
+
+`{0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}`
+
+Unde cheile sunt proprietățile enumerate. `0` `1` `2` `3` sunt afișate.
+
+Cu o buclă _for-of_, putem itera peste obiecte **iterabile**. Un șir este un obiect iterabil. Când iterăm peste șir, variabila "item" este egală cu elementul pe care îl parcurge în acel moment, sunt afișate `"☕"` `"💻"` `"🍷"` `"🍫"`.
+
+
+
+#### Răspuns: C
+
+Elementele dintr-un șir pot stoca orice valoare. Numere, șiruri, obiecte, alte șiruri, null, valori booleane, undefined și alte expresii precum date, funcții și calculații.
+
+Elementul va fi egal cu valoarea returnată. `1 + 2` returnează `3`, `1 * 2` returnează `2`, și `1 / 2` returnează `0.5`.
+
+
+
+#### Răspuns: B
+
+În mod implicit, argumentele au valoarea `undefined`, cu excepția cazului în care s-a transmis o valoare funcției. În acest caz, nu am transmis o valoare pentru argumentul `name`. `name` este egal cu `undefined` iar acesta este afișat.
+
+În ES6, putem suprascrie această valoare implicită `undefined` cu parametri impliciti. De exemplu:
+
+`function sayHi(name = "Lydia") { ... }`
+
+În acest caz, dacă nu am fi furnizat o valoare sau am fi furnizat `undefined`, `name` ar fi fost întotdeauna egal cu șirul `Lydia`.
+
+
+
+#### Răspuns: B
+
+Valoarea cuvântului cheie `this` depinde de locul în care este utilizat. Într-o **metodă**, cum ar fi metoda `getStatus`, cuvântul cheie `this` se referă la _obiectul la care aparține metoda_. Metoda aparține obiectului `data`, deci `this` se referă la obiectul `data`. Când înregistrăm `this.status`, se înregistrează proprietatea `status` de pe obiectul `data` care este `"🥑"`.
+
+Cu metoda `call` putem schimba obiectul la care se referă cuvântul cheie `this`. În **funcții**, cuvântul cheie `this` se referă la _obiectul la care aparține funcția_. Am declarat funcția `setTimeout` pe _obiectul global_, deci în interiorul funcției `setTimeout`, cuvântul cheie `this` se referă la _obiectul global_. Pe obiectul global există o variabilă numită status cu valoarea `"😎"`. Când înregistrați `this.status`, se înregistrează `"😎"`.
+
+
+
+#### Răspuns: A
+
+Am setat variabila `city` egală cu valoarea proprietății numită `city` pe obiectul `person`. Nu există o proprietate pe acest obiect numită `city`, astfel că variabila `city` are valoarea `undefined`.
+
+Rețineți că nu facem referire la obiectul `person` în sine! Pur și simplu am setat variabila `city` egală cu valoarea curentă a proprietății `city` de pe obiectul `person`.
+
+Apoi, am setat `city` egal cu șirul de caractere `"Amsterdam"`. Acest lucru nu schimbă obiectul `person` nu există o referință la acel obiect.
+
+Atunci când se afișează obiectul `person` se va afișa obiectul original, nealterat.
+
+
+
+#### Răspuns: C
+
+Variabilele declarate cu cuvintele cheie `const` și `let` au _domeniu de vizibilitate la nivel de bloc_. Un bloc poate fi definit între parantezele acolade (`{ }`). În acest caz, parantezele acolade ale instrucțiunilor if/else. Nu puteți face referire la o variabilă în afara blocului în care a fost declarată, va fi generată o eroare de tip ReferenceError.
+
+
+
+#### Răspuns: C
+
+Valoarea lui `res` în al doilea `.then` este egală cu valoarea returnată de `.then` anterior. Puteți continua să înșirați `.then`-uri în acest fel, unde valoarea este pasată către următorul manipulator.
+
+
+
+#### Răspuns: A
+
+Cu `!!name`, determinăm dacă valoarea lu `name` este adevărată sau falsă. Dacă `name` este adevărat, ceea ce dorim să testăm, `!name` returnează `false`. `!false` (practic, ceea ce este `!!name`) returnează `true`.
+
+Prin setarea lui `hasName` egal cu `name`, se face ca `hasName` să fie egal cu valoarea pe care ați furnizat-o funcției `getName`, nu cu valoarea booleană `true`.
+
+`new Boolean(true)` returnează un obiect încapsulator, nu valoarea booleană în sine.
+
+`name.length` returnează lungimea argumentului furnizat, nu dacă acesta este `true`.
+
+
+
+#### Răspuns: B
+
+Pentru a obține un caracter la un anumit index dintr-un șir de caractere, puteți utiliza notația cu paranteze pătrate. Primul caracter din șir are indexul 0, și așa mai departe. În acest caz, dorim să obținem elementul cu indexul 0, adică caracterul `"I'`, care va fi afișat în jurnal.
+
+Rețineți că această metodă nu este suportată în IE7 și versiunile anterioare. În acest caz, utilizați `.charAt()`.
+
+
+
+#### Răspuns: B
+
+Puteți seta valoarea implicită a unui parametru la valoarea altui parametru al funcției, atâta timp cât acestea sunt definite _înainte_ de parametrul cu valoarea implicită. Am transmis valoarea `10` funcției `sum`. Dacă funcția `sum` primește doar un argument, înseamnă că valoarea pentru `num2` nu este transmisă, iar valoarea lui `num1` este egală cu valoarea transmisă `10` în acest caz. Valoarea implicită a lui `num2` este valoarea lui `num1`, care este `10`. `num1 + num2` returnează `20`.
+
+Dacă încercați să setați valoarea implicită a unui parametru egală cu un parametru care este definit _după_ (în dreapta), valoarea parametrului nu a fost încă inițializată, ceea ce va genera o eroare.
+
+
+
+#### Răspuns: A
+
+Cu sintaxa `import * as name`, importăm _toate exporturile_ din fișierul `module.js` în fișierul `index.js` sub forma unui nou obiect numit `data`. În fișierul `module.js` există două exporturi: exportul implicit și un export cu nume. Exportul implicit este o funcție care returnează șirul de caractere `"Hello World"`, iar exportul cu nume este o variabilă numită `name` care are valoarea șirului de caractere `"Lydia"`.
+
+Obiectul `data` are o proprietate `default` pentru exportul implicit, iar celelalte proprietăți au numele exporturilor cu nume și valorile lor corespunzătoare.
+
+
+
+#### Răspuns: C
+
+Clasele sunt o sintaxă mai simplă pentru constructorii de funcții. Echivalentul clasei `Person` sub forma unui constructor de funcții ar fi:
+
+```javascript
+function Person(name) {
+ this.name = name;
+}
+```
+
+Apelarea unui constructor de funcții cu `new` duce la crearea unei instanțe a obiectului `Person`, iar cuvântul cheie `typeof` returnează `"object"` pentru o astfel de instanță. `typeof member` returnează `"object"`.
+
+
+
+#### Răspuns: D
+
+Metoda `.push` returnează _lungimea nouă_ a array-ului, nu array-ul însuși! Prin setarea `newList` egal cu `[1, 2, 3].push(4)`, am setat `newList` egal cu noua lungime a array-ului: `4`.
+
+Apoi, încercăm să folosim metoda `.push` pe `newList`. Deoarece `newList` este o valoare numerică `4`, nu putem folosi metoda `.push` se va genera o eroare de tip TypeError.
+
+
+
+#### Răspuns: D
+
+Funcțiile obișnuite, cum ar fi funcția `giveLydiaPizza` au o proprietate `prototype` care este un obiect (obiectul prototip) cu o proprietate `constructor`. Cu toate acestea, funcțiile arrow, cum ar fi funcția `giveLydiaChocolate`, nu au această proprietate `prototype`. `undefined` este returnat atunci când încearca să acceseze proprietatea `prototype` folosind `giveLydiaChocolate.prototype`.
+
+
+
+#### Răspuns: A
+
+`Object.entries(person)` returnează un array de array-uri imbricate, care conțin cheile și obiectele:
+
+`[ [ 'name', 'Lydia' ], [ 'age', 21 ] ]`
+
+Folosind bucla `for-of` putem itera prin fiecare element din array, în acest caz, subarray-urile. Putem dezasambla subarray-urile instantaneu în bucla `for-of`, folosind `const [x, y]`. Astfel, `x` este egal cu primul element din subarray, iar `y` este egal cu al doilea element din subarray.
+
+Primul subarray este `[ "name", "Lydia" ]`, cu `x` egal cu `"name"`, și `y` egal cu `"Lydia"`, care sunt afișate în jurnal.
+Al doilea subarray este `[ "age", 21 ]`, cu `x` egal cu `"age"`, și `y` egal cu `21`, care sunt afișate în jurnal.
+
+
+
+#### Răspuns: D
+
+`...args` este un parametru rest. Valoarea parametrului rest este un array care conține toate argumentele rămase și **poate fi doar ultimul parametru**! În acest exemplu, parametrul rest era al doilea parametru. Acest lucru nu este posibil și va genera o eroare de sintaxă.
+
+```javascript
+function getItems(fruitList, favoriteFruit, ...args) {
+ return [...fruitList, ...args, favoriteFruit];
+}
+
+getItems(['banana', 'apple'], 'pear', 'orange');
+```
+
+Exemplul de mai sus funcționează. Acesta returnează array-ul `[ 'banana', 'apple', 'orange', 'pear' ]`
+
+
+
+#### Răspuns: B
+
+În JavaScript, nu _trebuie_ să scriem explicit semnul punct și virgulă (`;`) totuși motorul JavaScript le adaugă automat după instrucțiuni. Acest lucru se numește **Inserția Automată a Semnelor de Punct și Virgulă**. O instrucțiune poate fi, de exemplu, variabile sau cuvinte cheie precum `throw`, `return`, `break`, etc.
+
+Aici, am scris o instrucțiune `return` și o altă valoare `a + b` pe o _linie nouă_. Cu toate acestea, deoarece este o linie nouă, motorul JavaScript nu știe că este de fapt valoarea pe care am dorit să o returnăm. În schimb, a adăugat automat un punct și virgulă după `return`. Puteți vedea acest lucru ca:
+
+```javascript
+return;
+a + b;
+```
+
+Acest lucru înseamnă că `a + b` nu este niciodată atins, deoarece o funcție se oprește din executare după cuvântul cheie `return`. Dacă nu se returnează nicio valoare, așa cum se întâmplă aici, funcția returnează `undefined`. Rețineți că nu există inserție automată a semnelor de punct și virgulă după instrucțiunile `if/else`!
+
+
+
+#### Răspuns: B
+
+Putem seta clasele egale cu alte clase sau constructori de funcții. În acest caz, am setat `Person` egal cu `AnotherPerson`. Numele în acest constructor este `Sarah`, astfel încât proprietatea `Person` de pe noua instanță `member` este `"Sarah"`.
+
+
+
+#### Răspuns: D
+
+Un simbol nu este _enumerabil_. Metoda `Object.keys` returnează toate proprietățile cheie _enumerabil_ ale unui obiect. Simbolul nu va fi vizibil, și va fi returnat un array gol. Atunci când se afișează întregul obiect, vor fi vizibile toate proprietățile, inclusiv cele care nu sunt enumerate.
+
+Asta este una dintre multele calități ale unui simbol: pe lângă faptul că reprezintă o valoare complet unică (ceea ce previne coliziunile accidentale de nume pe obiecte, de exemplu, atunci când lucrați cu două biblioteci care doresc să adauge proprietăți la același obiect), puteți "ascunde" proprietăți pe obiecte în acest fel (deși nu în întregime. Încă puteți accesa simbolurile folosind metoda `Object.getOwnPropertySymbols()`).
+
+
+
+#### Răspuns: A
+
+Funcția `getList` primește un array ca argument. Între parantezele funcției `getList` dezasamblăm acest array imediat. Puteți vedea acest lucru ca:
+
+`[x, ...y] = [1, 2, 3, 4]`
+
+Cu ajutorul parametrului rest `...y`, punem toți "parametrii rămași" într-un array. Parametrii rămași în acest caz sunt `2`, `3` și `4`. Valoarea lui `y` este un array care conține toți parametrii rămași. Valoarea lui `x` este egal cu `1` în acest caz, deci când afișăm `[x, y]`, va fi afișat `[1, [2, 3, 4]]`.
+
+Funcția `getUser` primește un obiect ca argument. Cu funcțiile arrow, nu _trebuie_ să scriem acolade dacă dorim să returnăm doar o valoare. Cu toate acestea, dacă doriți să returnați instantaneu un _obiect_ dintr-o funcție arrow, trebuie să-l scrieți între paranteze. Altfel, tot ce este între acolade va fi interpretat ca o instrucțiune bloc. În acest caz, codul dintre acolade nu este un cod JavaScript valid, așa că se va genera o eroare de sintaxă `SyntaxError`.
+
+Funcția următoare ar fi returnat un obiect:
+
+`const getUser = user => ({ name: user.name, age: user.age })`
+
+
+
+#### Răspuns: C
+
+Variabila `name` conține o valoare de tip șir de caractere (string), care nu este o funcție și, prin urmare, nu poate fi invocată.
+
+TypeError-urile sunt generate atunci când o valoare nu este de tipul așteptat. JavaScript e aștepta ca `name` să fie o funcție, deoarece încercăm să o apelăm. Cu toate acestea, era de tip șir de caractere (string), așa că a generat o eroare de tip TypeError: name nu este o funcție!
+
+SyntaxError-urile sunt generate atunci când ați scris ceva care nu este JavaScript valid, de exemplu, atunci când ați scris cuvântul `return` ca `retrun`.
+ReferenceError-urile sunt generate atunci când JavaScript nu poate găsi o referință la o valoare la care încercați să accesați.
+
+
+
+#### Răspuns: B
+
+`[]` este o valoare adevărată (truthy). Cu operatorul `&&` valoarea din partea dreaptă va fi returnată dacă valoarea din partea stângă este adevărată. În acest caz, valoarea din partea stângă, `[]` este adevărată, astfel că se va returna `"Im'`.
+
+`""` este o valoare falsă (falsy). Dacă valoarea din partea stângă este falsă, nu se returnează nimic. `n't` nu va fi returnat.
+
+
+
+#### Răspuns: C
+
+Cu operatorul `||` utem returna primul operand adevărat (truthy). Dacă toate valorile sunt false, se va returna ultimul operand.
+
+`(false || {} || null)`: obiectul go `{}` este o valoare adevărată (truthy). Aceasta este prima (și singura) valoare adevărată, care este returnată. `one` este egal cu `{}`.
+
+`(null || false || "")`: toate operanzii sunt valori false. Acest lucru înseamnă că ultimul operand `""` este returnat. `two` este egal cu `""`.
+
+`([] || 0 || "")`: array-ul gol `[]` este o valoare adevărată (truthy). Aceasta este prima valoare adevărată, care este returnată. `three` este egal cu `[]`.
+
+
+
+#### Răspuns: D
+
+Cu o promisiune, spunem în principiu _Vreau să execut această funcție, dar o pun deoparte pentru moment în timp ce rulează, deoarece acest lucru poate dura ceva timp. Doar atunci când o anumită valoare este rezolvată (sau respinsă), și atunci când stiva de apeluri este goală, doresc să folosesc această valoare._
+
+Putem obține această valoare atât cu `.then` cât și cu cuvântul cheie `await` într-o funcție `async`. Cu toate că putem obține valoarea unei promisiuni cu ambele metode `.then` și `await`, ele funcționează puțin diferit.
+
+În `firstFunction`, am pus (într-un fel) funcția `myPromise` deoparte în timp ce aceasta se executa, dar am continuat să executăm restul codului, care este `console.log('second')` în acest caz. Apoi, funcția a fost rezolvată cu șirul `I have resolved`, care a fost apoi înregistrat în jurnal după ce s-a constatat că stiva de apeluri era goală.
+
+Cu cuvântul cheie `await` în `secondFunction`, efectiv pauzăm execuția unei funcții asincrone până când valoarea a fost rezolvată înainte de a trece la următoarea linie.
+
+Acest lucru înseamnă că a așteptat ca `myPromise` să fie rezolvat cu valoarea `I have resolved`, și doar după ce s-a întâmplat acest lucru, s-a trecut la următoarea linie: a fost înregistrat `second`.
+
+
+
+#### Răspuns: C
+
+Operatorul `+` nu este folosit doar pentru adunarea valorilor numerice, ci îl putem utiliza și pentru concatenarea șirurilor de caractere. Ori de câte ori motorul JavaScript observă că una sau mai multe valori nu sunt de tip număr, va converti numărul într-un șir de caractere.
+
+Primul operand este `1`, care este o valoare numerică. `1 + 2` returnează numărul 3.
+
+Cu toate acestea, al doilea operand este un șir de caractere `"Lydia"`. `"Lydia"` este un șir de caractere și `2` este un număr: `2` este convertit într-un șir de caractere. `"Lydia"` și `"2"` sunt concatenate, rezultând șirul de caractere `"Lydia2"`.
+
+`{ name: "Lydia" }` este un obiect. Niciun număr, niciun obiect nu este un șir de caractere, astfel că sunt convertite în șiruri. Ori de câte ori convertim un obiect regulat în șir de caractere, devine `"[object Object]"`. `"[object Object]"` concatenat cu `"2"` devine `"[object Object]2"`.
+
+
+
+#### Răspuns: C
+
+Putem pasa orice tip de valoare dorim către `Promise.resolve`, fie o promisiune, fie o valoare non-promisiune. Metoda în sine returnează o promisiune cu valoarea rezolvată (`
+
+#### Răspuns: B
+
+Obiectele sunt pasate prin referință. Atunci când verificăm obiecte pentru egalitate strictă (`===`), comparăm referințele lor.
+
+Am setat valoarea implicită pentru `person2` egală cu obiectul `person` și am pasat obiectul `person` ca valoare pentru `person1`.
+
+Acest lucru înseamnă că ambele valori au o referință către aceeași locație în memorie, astfel că sunt egale.
+
+Blocul de cod din instrucțiunea `else` se execută, și este înregistrat mesajul`They are the same!`.
+
+
+
+#### Răspuns: D
+
+În JavaScript, avem două moduri de a accesa proprietăți pe un obiect: notare cu paranteze pătrate sau notare cu punct. În acest exemplu, folosim notarea cu punct (`colorConfig.colors`) în loc de notarea cu paranteze pătrate (`colorConfig["colors"]`).
+
+Cu notarea cu punct, JavaScript încearcă să găsească proprietatea pe obiect cu exact același nume. În acest exemplu, JavaScript încearcă să găsească o proprietate numită `colors` pe obiectul `colorConfig`. Nu există o proprietate numită `colors`, așa că acest lucru returnează `undefined`. Apoi, încercăm să accesăm valoarea primului element folosind `[1]`. Nu putem face acest lucru pe o valoare care este `undefined`, astfel că se generează o eroare de tip `TypeError`: `Cannot read property '1' of undefined`.
+
+JavaScript interpretează (sau deschide) declarațiile. Atunci când folosim notația cu paranteze pătrate, vede prima paranteză deschisă `[` și continuă până găsește paranteza de închidere `]`. Abia atunci va evalua declarația. Dacă am fi folosit `colorConfig[colors[1]]`, ar fi returnat valoarea proprietății `red` pe obiectul `colorConfig`.
+
+
+
+#### Răspuns: A
+
+În culise, emoji-urile sunt reprezentate ca coduri Unicode. Codurile Unicode pentru emoji-ul inimii sunt `"U+2764 U+FE0F"`. Acestea sunt întotdeauna aceleași pentru aceleași emoji-uri, așa că comparăm două șiruri identice între ele, ceea ce returnează
+
+
+
+#### Răspuns: D
+
+Cu metoda `splice` mmodificăm array-ul original prin ștergerea, înlocuirea sau adăugarea de elemente. În acest caz, am eliminat 2 elemente de la indexul 1 (am eliminat `'🥑'` și `'😍'`) și am adăugat emoji-ul ✨ în locul lor.
+
+`map`, `filter` și `slice` returnează un nou array, `find` returnează un element, ia `reduce` returnează o valoare redusă.
+
+
+
+#### Răspuns: A
+
+Am setat valoarea proprietății `favoriteFood` pe obiectul `info` egal cu șirul de caractere cu emoji-ul de pizza, `'🍕'`. Un șir de caractere este un tip de date primitiv. În JavaScript, tipurile de date primitive nu interacționează prin referință.
+
+În JavaScript, tipurile de date primitive (tot ceea ce nu este obiect) interacționează prin _valoare_. În acest caz, am setat valoarea proprietății `favoriteFood` pe obiectul `info` egală cu valoarea primului element din array-ul `food` care este un șir de caractere cu emoji-ul de pizza în acest caz (`'🍕'`). Un șir de caractere este un tip de date primitiv și interacționează prin valoare (vedeți [blogpost](https://www.theavocoder.com/complete-javascript/2018/12/21/by-value-vs-by-reference) meu dacă doriți să aflați mai multe).
+
+Apoi, schimbăm valoarea proprietății `favoriteFood` pe obiectul `info`. Array-ul `food` nu s-a schimbat, deoarece valoarea `favoriteFood` era doar o _copie_ a valorii primului element din array și nu are o referință la aceeași locație în memorie ca elementul din `food[0]`. Când înregistrăm array-ul `food`, acesta rămâne neschimbat, `['🍕', '🍫', '🥑', '🍔']`.
+
+
+
+#### Răspuns: A
+
+Cu metoda `JSON.parse()` putem parsa un șir JSON într-o valoare JavaScript.
+
+```javascript
+// Transformarea unui număr într-un JSON valid, apoi parsarea șirului JSON într-o valoare JavaScript:
+const jsonNumber = JSON.stringify(4); // '4'
+JSON.parse(jsonNumber); // 4
+
+// Transformarea unei valori de tip array într-un JSON valid, apoi parsarea șirului JSON într-o valoare JavaScript:
+const jsonArray = JSON.stringify([1, 2, 3]); // '[1, 2, 3]'
+JSON.parse(jsonArray); // [1, 2, 3]
+
+// Transformarea unui obiect într-un JSON valid, apoi parsarea șirului JSON într-o valoare JavaScript:
+const jsonArray = JSON.stringify({ name: 'Lydia' }); // '{"name":"Lydia"}'
+JSON.parse(jsonArray); // { name: 'Lydia' }
+```
+
+
+
+#### Răspuns: D
+
+Fiecare funcție are propriul său _context de execuție_ (sau _domeniu_). Funcția `getName` caută mai întâi în propriul său context (domeniu) pentru a vedea dacă conține variabila `name` pe care încercăm să o accesăm. În acest caz, funcția `getName` conține propria sa variabilă `name` declarăm variabila `name` cu cuvântul cheie `let`, și cu valoarea `'Sarah'`.
+
+Variabilele declarate cu cuvântul cheie `let` (și `const`) sunt hoisted, dar, spre deosebire de `var`, nu sunt inițializate. Ele nu sunt accesibile înainte de linia în care le declarăm (inițializăm). Acest lucru se numește "zona temporală moartă" (temporal dead zone). Atunci când încercăm să accesăm variabilele înainte de a fi declarate, JavaScript aruncă o eroare de tip `ReferenceError`.
+
+Dacă nu am fi declarat variabila `name` în interiorul funcției `getName` motorul JavaScript ar fi căutat în josul lanțului de _domenii_. Domeniul exterior are o variabilă numită `name` cu valoarea `Lydia`. În acest caz, ar fi afișat `Lydia`.
+
+```javascript
+let name = 'Lydia';
+
+function getName() {
+ console.log(name);
+}
+
+getName(); // Lydia
+```
+
+
+
+#### Răspuns: C
+
+Cu cuvântul cheie `yield`, cedăm valorile într-o funcție generator. Cu cuvântul cheie `yield*`, putem ceda valori dintr-o altă funcție generator sau dintr-un obiect iterabil (de exemplu, un array).
+
+În `generatorOne`, folosim cuvântul cheie `yield` pentru a ceda intrega mulțime `['a', 'b', 'c']`. Valoarea proprietății `value` a obiectului returnat de metoda `next` pe obiectul `one` (`one.next().value`) este egală cu întregul array `['a', 'b', 'c']`.
+
+```javascript
+console.log(one.next().value); // ['a', 'b', 'c']
+console.log(one.next().value); // undefined
+```
+
+În `generatorTwo`, folosim cuvântul cheie `yield*`. Acest lucru înseamnă că prima valoare cedată din `two`, este egală cu prima valoare cedată din iterator. Iteratorul este mulțimea `['a', 'b', 'c']`. Prima valoare cedată este `a`, așa că prima dată când apelăm `two.next().value`, este returnată valoarea `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
+```
+
+
+
+#### Răspuns: A
+
+Expresiile din șirurile șablon (template literals) sunt evaluate mai întâi. Acest lucru înseamnă că șirul va conține valoarea returnată de expresie, funcția imediat invocată `(x => x)('I love')` în acest caz. Trecem valoarea `'I love'` ca argument către funcția arrow `x => x`. `x` este egal cu `'I love'`, care este returnată. Aceasta duce la rezultatul `I love to program`.
+
+
+
+#### Răspuns: C
+
+În mod normal, atunci când setăm obiecte egal cu `null`, acele obiecte sunt _colectate de gunoi_ (garbage collected), deoarece nu mai există nicio referință către acel obiect. Cu toate acestea, deoarece funcția de callback din `setInterval` este o funcție arrow (și, prin urmare, legată de obiectul `config`), funcția de callback încă menține o referință la obiectul `config`.
+Atâta timp cât există o referință, obiectul nu va fi colectat de gunoi (garbage collected).
+Deoarece aceasta este o intervală de timp, setarea lui `config` la `null` sau `delete` lui `config.alert` nu va colecta intervalul de gunoi și intervalul va continua să fie apelat.
+Pentru a-l opri și a-l elimina din memorie, trebuie să folosiți `clearInterval(config.alert)`.
+Deoarece acest lucru nu a fost făcut, funcția de callback a `setInterval` va fi în continuare invocată la fiecare 1000 ms (1 secundă).
+
+
+
+#### Răspuns: B
+
+Când adăugăm o pereche cheie/valoare folosind metoda `set`, cheia va fi valoarea primului argument transmis funcției `set`, iar valoarea va fi cea de-a doua valoare transmisă funcție `set`. Cheia în acest caz este _funcția_ `() => 'greeting'`, iar valoarea `'Hello world'`. `myMap` este acum `{ () => 'greeting' => 'Hello world!' }`.
+
+1 este incorect pentru că cheia nu este `'greeting'` ci `() => 'greeting'`.
+3 este incorect pentru că creăm o nouă funcție prin transmiterea ei ca parametru către metoda `get`. Obiectele interacționează prin _referință_. Funcțiile sunt obiecte, motiv pentru care două funcții nu sunt niciodată strict egale, chiar dacă sunt identice: ele au o referință către un loc diferit în memorie.
+
+
+
+#### Răspuns: C
+
+Ambele funcții `changeAge` și `changeAgeAndName` au un parametru implicit, și anume un obiect _nou_ creat `{ ...person }`. Acest obiect conține copii ale tuturor cheilor/valorilor din obiectul `person`.
+
+În primul rând, apelăm funcția `changeAge` și transmitem obiectul `person` ca argument. Această funcție crește valoarea proprietății `age` cu 1. `person` devine `{ name: "Lydia", age: 22 }`.
+
+Apoi, apelăm funcția `changeAgeAndName`, însă nu transmitem un parametru. În schimb, valoarea lui `x` este egală cu un obiect _nou_: `{ ...person }`. Deoarece este un obiect nou, acesta nu afectează valorile proprietăților din obiectul `person`. `person` rămâne egal cu `{ name: "Lydia", age: 22 }`.
+
+
+
+#### Răspuns: C
+
+Cu operatorul spread `...`, putem _răspândi_ obiecte iterabile în elemente individuale. Funcția `sumValues` primește trei argumente: `x`, `y` și `z`. `...[1, 2, 3]` va rezulta în `1, 2, 3`, pe care le transmitem funcției `sumValues`.
+
+
+
+#### Răspuns: B
+
+Cu operandul `+=` incrementăm valoarea lui `num` cu `1`. Inițial, `num` avea valoarea `1`, deci `1 + 1` este `2`. Elementul de pe al doilea index în mulțimea `list` este 🥰, `console.log(list[2])` va afișa 🥰.
+
+
+
+#### Răspuns: B
+
+Cu operatorul de verificare opțională `?.`, nu mai este necesar să verificăm explicit dacă valorile mai profunde încorporate sunt valide sau nu. Dacă încercăm să accesăm o proprietate pe o valoare `undefined` sau `null` valoarea (_nullish_), expresia face un scurtcircuit și returnează `undefined`.
+
+`person.pet?.name`: `person` are o proprietate numită `pet`: `person.pet` nu este `nullish`. Are o proprietate numită `name`, și returnează `Mara`.
+`person.pet?.family?.name`: `person` are o proprietate numită `pet`: `person.pet` nu este `nullish`. `pet` _nu_ are o proprietate numită `family`, `person.pet.family` este `nullish`. Expresia returnează `undefined`.
+`person.getFullName?.()`: `person` are o proprietate `getFullName`: `person.getFullName()` nu este `nullish` și poate fi invocată, care returnează `Lydia Hallie`.
+`member.getLastName?.()`: variabila `member` nu există, prin urmare se va genera o excepție de tip `ReferenceError` gets thrown!
+
+
+
+#### Răspuns: B
+
+Am trecut condiția `groceries.indexOf("banana")` în instrucțiunea `if`. `groceries.indexOf("banana")` returnează `0`, care este o valoare falsă. Deoarece condiția din instrucțiunea `if` este falsă, se execută codul din blocul `else`, și `We don't have to buy bananas!` se afișează.
+
+
+
+#### Răspuns: D
+
+Metoda `language` este un `setter`. Setter-urile nu rețin o valoare reală; scopul lor este să _modifice_ proprietăți. Atunci când apelați o metodă `setter`, aceasta va returna `undefined`.
+
+
+
+#### Răspuns: C
+
+`typeof name` returnează `"string"`. Șirul de caractere `"string"` este o valoare adevărată (truthy), așa că `!typeof name` returnează valoarea booleană `false`. `false === "object"` și `false === "string"` ambele returnează `false`.
+
+(Dacă dorim să verificăm dacă tipul este (ne)egal cu un anumit tip, ar trebui să folosim `!==` în loc de `!typeof`)
+
+
+
+#### Răspuns: A
+
+Funcția `add` returnează o funcție arrow, care returnează o altă funcție arrow, care la rândul ei returnează o altă funcție arrow (încă sunteți cu mine?). Prima funcție primește un argument `x` cu valoarea `4`. Apelăm a doua funcție, care primește un argument `y` cu valoarea `5`. Apoi apelăm a treia funcție, care primește un argument `z` cu valoarea `6`. Când încercăm să accesăm valorile `x`, `y` și `z` în ultima funcție arrow, motorul JavaScript urcă lanțul de domenii pentru a găsi valorile pentru `x` și `y` în consecință. Aceasta returnează `4` `5` `6`.
+
+
+
+#### Răspuns: C
+
+Funcția generator `range` returnează un obiect asincron cu promisiuni pentru fiecare element din intervalul pe care îl transmitem: `Promise{1}`, `Promise{2}`, `Promise{3}`. Setăm variabila `gen` egală cu obiectul asincron, după care facem o buclă peste el folosind o buclă `for await ... of`. Setăm variabila `item` eegală cu valorile promisiunilor returnate: mai întâi `Promise{1}`, apoi `Promise{2}`, apoi `Promise{3}`. Deoarece _așteptăm_ valoarea lui `item`, adică promisiunea rezolvată, _valorile_ rezolvate ale promisiunilor sunt returnate: `1`, `2`, apoi `3`.
+
+
+
+#### Răspuns: D
+
+`myFunc` așteaptă ca argument un obiect cu proprietățile `x`, `y` și `z`. Deoarece transmitem doar trei valori numerice separate (1, 2, 3) în loc de un obiect cu proprietățile `x`, `y` și `z` ({x: 1, y: 2, z: 3}), `x`, `y` și `z` primesc valoarea lor implicită, care este `undefined`.
+
+
+
+#### Răspuns: B
+
+Cu metoda `Intl.NumberFormat` putem formata valorile numerice în orice locație. Formatez valoarea numerică `130` pentru locația `en-US` ca o `unitate` în `mile-per-hour`, ceea ce rezultă în `130 mph`. Valoarea numerică `300` pentru locația `en-US` ca `monedă` în `USD` rezultă în `$300.00`.
+
+
+
+#### Răspuns: B
+
+Prin destrucțurarea obiectelor, putem extrage valorile din obiectul din partea dreaptă și le atribui valorii cu același nume de proprietate din obiectul din partea stângă. În acest caz, atribuim valoarea "💀" lui `spookyItems[3]`. Acest lucru înseamnă că modificăm array-ul `spookyItems`, adăugăm "💀" la el. La afișarea în consolă a lui `spookyItems`, se va afișa `["👻", "🎃", "🕸", "💀"]`.
+
+
+
+#### Răspuns: C
+
+Cu metoda `Number.isNaN` puteți verifica dacă valoarea pe care o transmiteți este o _valoare numerică_ și este egală cu `NaN`. `name` nu este o valoare numerică, așa că `Number.isNaN(name)` returnează `false`. `age` este o valoare numerică, dar nu este egală cu `NaN`, astfel că `Number.isNaN(age)` returnează `false`.
+
+Cu metoda `isNaN` puteți verifica dacă valoarea pe care o transmiteți nu este un număr. `name` nu este un număr, așa că `isNaN(name)` returnează `true`. `age` este un număr, astfel că `isNaN(age)` returnează `false`.
+
+
+
+#### Răspuns: D
+
+Variabilele declarate cu cuvântul cheie `const` nu pot fi referite înainte de inițializare: acest lucru se numește _zona temporală moartă_ (temporal dead zone). În funcția `getInfo`, variabila`randomValue` este de domeniu în domeniul funcțional al funcției `getInfo`. Pe linia în care dorim să afișăm valoarea `typeof randomValue`, variabila `randomValue` nu este încă inițializată: se va genera o eroare de tip `ReferenceError`! Motorul nu a căutat în josul lanțului de domenii deoarece am declarat variabila `randomValue` în funcția `getInfo`.
+
+
+
+#### Răspuns: C
+
+În blocul `try` înregistrăm valoarea așteptată a variabilei `myPromise`: `"Woah some cool data"`. Deoarece nu s-au generat erori în blocul `try` codul din blocul `catch` nu se execută. Codul din blocul `finally` se execută _întotdeauna_, și se va afișa `"Oh finally!"`.
+
+
+
+#### Răspuns: B
+
+Cu metoda `flat` putem crea un nou array aplatizat. Adâncimea array-ului aplatizat depinde de valoarea pe care o transmitem. În acest caz, am transmis valoarea `1` (care nu era necesară, deoarece aceasta este valoarea implicită), ceea ce înseamnă că vor fi concatenate doar array-urile de pe primul nivel de adâncime. `['🥑']` și `['✨', '✨', ['🍕', '🍕']]`. Concatenarea acestor două array-uri rezultă în `['🥑', '✨', '✨', ['🍕', '🍕']]`.
+
+
+
+#### Răspuns: D
+
+`counterOne` este o instanță a clasei `Counter`. Clasa `Counter` conține o proprietate `count` în constructorul său și o metodă `increment`. Mai întâi, am invocat metoda `increment` de două ori, apelând `counterOne.increment()`. În prezent, `counterOne.count` este `2`.
+
+
+
+#### Răspuns: C
+
+În primul rând, apelăm `funcOne`. Pe prima linie a lui `funcOne`, apelăm funcția _asincronă_ `setTimeout`, din care funcția de apel se trimite către API-ul Web. (vezi articolul meu despre bucla evenimentelor aici.)
+
+Apoi apelăm promisiunea `myPromise` care este o operațiune _asincronă_.
+
+Ambele promisiuni și întârzierile (timeout) sunt operațiuni asincrone, iar funcția continuă să ruleze în timp ce finalizează promisiunea și gestionează apelul de întârziere `setTimeout`. Acest lucru înseamnă că se va afișa mai întâi `Last line 1!`, deoarece aceasta nu este o operațiune asincronă.
+
+Deoarece stiva de apel nu este încă goală, funcția `setTimeout` și promisiunea din `funcOne` nu pot fi adăugate încă la stiva de apel.
+
+În `funcTwo`, variabila `res` primește o `Promise` pentru că `Promise.resolve(Promise.resolve('Promise'))` este echivalent cu `Promise.resolve('Promise')` deoarece rezolvarea unei promisiuni rezolvă doar valoarea acesteia. Cuvântul cheie `await` din această linie oprește execuția funcției până când primește rezoluția promisiunii și apoi continuă să ruleze sincron până la finalizare, așa că sunt afișate `Promise 2!` apoi `Last line 2!` iar apelul `setTimeout` este trimis către API-ul Web.
+
+Apoi stiva de apel este goală. Promisiunile sunt _microtask-uri_ astfel că sunt rezolvate în primul rând atunci când stiva de apel este goală, așa că se afișează `Promise 1!`.
+
+Acum, deoarece `funcTwo` pa fost scoasă din stiva de apel, stiva de apel este goală. Callback-urile așteptând în coadă (`() => console.log("Timeout 1!")` din `funcOne`, și `() => console.log("Timeout 2!")` din `funcTwo`) sunt adăugate pe stivă unul câte unul. Primul callback afișează `Timeout 1!`, și este eliminat din stivă. Apoi, al doilea callback afișează `Timeout 2!`, și este eliminat din stivă.
+
+
+
+#### Răspuns: C
+
+Cu asteriscul `*`, importăm toate valorile exportate din acel fișier, atât exporturile implicite, cât și cele numite. Dacă avem următorul fișierȘ
+
+```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);
+```
+
+Acesta ar fi rezultatul înregistrărilor:
+
+```javascript
+{
+ default: "I love JavaScript",
+ name: "Lydia",
+ age: 21
+}
+```
+
+Pentru exemplul cu funcția `sum`, înseamnă că valoarea importată `sum` arată în felul următor:
+
+```javascript
+{ default: function sum(x) { return x + x } }
+```
+
+Putem invoca această funcție, apelând `sum.default`
+
+
+
+#### Răspuns: C
+
+Cu un obiect Proxy, putem adăuga comportament personalizat unui obiect pe care îl transmitem ca al doilea argument. În acest caz, transmitem obiectul `handler` care conține două proprietăți: `set` și `get`. `set` este invocată ori de câte ori _set_ (setăm) valori de proprietate, `get` este invocată ori de câte ori _get_ (accesăm) valori de proprietate.
+
+Primul argument este un obiect gol `{}`, care este valoarea lui `person`. La acest obiect, se adaugă comportamentul personalizat specificat în obiectul `handler`. Dacă adăugăm o proprietate la obiectul `person`, `set` va fi invocată. Dacă accesăm o proprietate a obiectului `person`, `get` va fi invocată.
+
+În primul rând, am adăugat o nouă proprietate `name` la obiectul proxy (`person.name = "Lydia"`). `set` este invocată și înregistrează mesajul `"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.
+
+
+
+#### Răspuns: A
+
+Cu `Object.seal` putem preveni _adăugarea_ de noi proprietăți sau _eliminarea_ proprietăților existente.
+
+Cu toate acestea, puteți încă să modificați valoarea proprietăților existente.
+
+
+
+#### Răspuns: C
+
+Metoda `Object.freeze` _îngheață_ un obiect. Nu se pot adăuga, modifica sau elimina proprietăți.
+
+Cu toate acestea, aceasta îngheață obiectul doar în mod _superficial_, ceea ce înseamnă că numai proprietățile _directe_ ale obiectului sunt înghețate. Dacă proprietatea este un alt obiect, cum ar fi `address` în acest caz, proprietățile de pe acel obiect nu sunt înghețate și pot fi modificate.
+
+
+
+#### Răspuns: A
+
+În primul rând, am apelat `myFunc()` fără a transmite niciun argument. Deoarece nu am transmis argumente, `num` și `value` au primit valorile lor implicite: `num` este `2`, și `value` este valoarea returnată de funcția `add`. Funcției `add` îi transmitem `num` ca argument, care avea valoarea `2`. `add` returnează `4`, care este valoarea lui `value`.
+
+Apoi, am apelat `myFunc(3)` și am transmis valoarea `3` ca valoare pentru argumentul `num`. Nu am transmis un argument pentru `value`. Deoarece nu am transmis o valoare pentru argumentul `value` acesta a primit valoarea implicită: valoarea returnată de funcția `add`. Funcției `add`, îi transmitem `num`, care are valoarea `3`. `add` returnează `6`, care este valoarea lui `value`.
+
+
+
+#### Răspuns: D
+
+În ES2020, putem adăuga variabile private în clase folosind simbolul `#`. Nu putem accesa aceste variabile în afara clasei. Atunci când încercăm să înregistrăm `counter.#number`, se aruncă o eroare de sintaxă (SyntaxError): nu putem accesa această variabilă în afara clasei `Counter`!
+
+
+
+#### Răspuns: B
+
+Pentru a itera prin `membrii` din fiecare element din array-ul `members` trebuie să transmitem `teams[i].members` către funcția generator `getMembers`. Funcția generator returnează un obiect generator. Pentru a itera prin fiecare element din acest obiect generator, trebuie să folosim `yield*`.
+
+Dacă am fi scris `yield`, `return yield`, sau `return`, întreaga funcție generator ar fi fost returnată prima dată când am apelat metoda `next`.
+
+
+
+#### Răspuns: C
+
+Funcția `addHobby` primește două argumente, `hobby` și `hobbies` cu valoarea implicită a array-ului `hobbies` din obiectul `person`.
+
+În primul rând, apelăm funcția `addHobby`, și transmitem `"running"` ca valoare pentru `hobby` și un array gol ca valoare pentru `hobbies`. Deoarece transmitem un array gol ca valoare pentru `hobbies`, `"running"` este adăugat la acest array gol.
+
+Apoi, apelăm funcția `addHobby` și transmitem `"dancing"` ca valoare pentru `hobby`. Nu am transmis o valoare pentru `hobbies`, astfel că aceasta primește valoarea implicită, adică proprietatea `hobbies` din obiectul `person`. Adăugăm hobby-ul `dancing` în array-ul `person.hobbies`.
+
+În final, apelăm funcția `addHobby`, și transmitem `"baking"` ca valoare pentru `hobby`, și array-ul `person.hobbies` ca valoare pentru `hobbies`. Adăugăm hobby-ul `baking` în array-ul `person.hobbies`.
+
+După adăugarea lui `dancing` și `baking`, valoarea lui `person.hobbies` este `["coding", "dancing", "baking"]`
+
+
+
+#### Răspuns: B
+
+Creăm variabila `pet` care este o instanță a clasei `Flamingo`. Când instantiem această instanță, `constructor` din clasa `Flamingo` este apelat. Mai întâi, se înregistrează `"I'm pink. 🌸"` după care apelăm `super()`. `super()` apelează constructorul clasei părinte, `Bird`. Constructorul din clasa `Bird` este apelat și înregistrează `"I'm a bird. 🦢"`.
+
+
+
+#### Răspuns: D
+
+Cuvântul cheie `const` înseamnă pur și simplu că nu putem _redeclara_ valoarea acelei variabile, aceasta este _numai pentru citire_ (read-only). Cu toate acestea, valoarea în sine nu este imutabilă. Proprietățile din array-ul `emojis` pot fi modificate, de exemplu, prin adăugarea de valori noi, prin decuparea lor sau prin setarea lungimii array-ului la 0.
+
+
+
+#### Răspuns: C
+
+Obiectele nu sunt iterabile în mod implicit. Un obiect devine iterabil atunci când protocolul iterator este prezent. Putem adăuga acest protocol manual prin adăugarea simbolului iterator `[Symbol.iterator]`, care trebuie să returneze un obiect generator, de exemplu, prin definirea unei funcții generator `*[Symbol.iterator]() {}`. Această funcție generator trebuie să furnizeze `Object.values` ale obiectulu `person` pentru a obține array-ul `["Lydia Hallie", 21]`: `yield* Object.values(this)`.
+
+
+
+#### Răspuns: C
+
+Condiția `if` din interiorul buclei `forEach` verifică dacă valoarea lui `num` este adevărată (truthy) sau falsă (falsy). Deoarece primul număr din array-ul `nums` este `0`, o valoare falsă, blocul de cod al instrucțiunii `if` nu va fi executat. `count` se incrementează doar pentru celelalte 3 numere din array-ul `nums`, adică `1`, `2` și `3`. Deoarece `count` se incrementează cu `1` de 3 ori, valoarea lui `count` este `3`.
+
+
+
+#### Răspuns: D
+
+Simbolul `?` ne permite să accesăm opțional proprietăți mai adânc în obiecte. Încercăm să înregistrăm elementul de pe indexul `1` din sub-array-ul de pe indexul `1` al array-ului `fruits`. Dacă sub-array-ul de pe indexul `1` din array-ul `fruits` nu există, va returna pur și simplu `undefined`. Dacă sub-array-ul de pe indexul `1` din array-ul `fruits` există, dar acest sub-array nu are un element pe indexul `1` va returna, de asemenea, `undefined`.
+
+În primul rând, încercăm să înregistrăm al doilea element din sub-array-ul`['🍍']` din `[['🍊', '🍌'], ['🍍']]`. Acest sub-array conține doar un singur element, ceea ce înseamnă că nu există niciun element pe indexul `1`, și va returna `undefined`.
+
+Apoi, apelăm funcția `getFruits` fără a transmite o valoare ca argument, ceea ce înseamnă că `fruits` are implicit o valoare de `undefined`. Deoarece facem o verificare condițională pentru accesarea elementului de pe indexul `1` al `fruits`, aceasta va returna `undefined` deoarece acest element de pe indexu `1` nu există.
+
+În cele din urmă, încercăm să înregistrăm al doilea element din sub-array-ul `['🍊', '🍌']` din `['🍍'], ['🍊', '🍌']`. Elementul de pe indexul `1` în acest sub-array este `🍌`, are este înregistrat.
+
+
+
+#### Răspuns: A
+
+Am setat variabila `calc` gal cu o nouă instanță a clasei `Calc`. Apoi, am creat o altă instanță nouă a clasei `Calc`, și am apelat metoda `increase` pe această instanță. Deoarece proprietatea `count` se află în constructorul clasei `Calc`, proprietatea `count` nu este partajată în prototipul clasei `Calc`. Acest lucru înseamnă că valoarea lui `count` nu a fost actualizată pentru instanța către care arată `calc` astfel încât `count` rămâne `0`.
+
+
+
+#### Răspuns: B
+
+Funcția `updateUser` actualizează valorile proprietăților `email` și `password` ale obiectului `user`, dacă aceste valori sunt transmise funcției, după care funcția returnează obiectul `user`. Valoarea returnată a funcției `updateUser` este obiectul `user`, ceea ce înseamnă că valoarea lui `updatedUser` este o referință către același obiect `user` la care face referință și `user`. `updatedUser === user` este egal cu `true`.
+
+
+
+#### Răspuns: C
+
+În primul rând, apelăm metoda `slice` pe array-ul `fruit`. Metoda `slice` nu modifică array-ul original, ci returnează valoarea pe care a tăiat-o din array: emoji-ul de banană.
+Apoi, apelăm metoda `splice` pe array-ul `fruit`. Metoda `splice` modifică array-ul original, ceea ce înseamnă că array-ul `fruit` acum conține `['🍊', '🍎']`.
+În cele din urmă, apelăm metoda `unshift` pe array-u `fruit`, care modifică array-ul original prin adăugarea valorii furnizate, în acest caz, ‘🍇’ ca prim element în array. Array-ul `fruit` acum conține `['🍇', '🍊', '🍎']`.
+
+
+
+#### Răspuns: B
+
+Cheile obiectelor sunt convertite în șiruri de caractere.
+
+Deoarece valoarea lui `dog` este un obiect, `animals[dog]` înseamnă de fapt că creăm o nouă proprietate numită `"object Object"` egală cu noul obiect. `animals["object Object"]` este acum egal cu `{ emoji: "🐶", name: "Mara"}`.
+
+`cat` este, de asemenea, un obiect, ceea ce înseamnă că `animals[cat]` înseamnă de fapt că suprascriem valoarea lui `animals["object Object"]` cu noile proprietăți ale pisicii.
+
+Înregistrarea `animals[dog]`, sau mai exact `animals["object Object"]` deoarece convertirea obiectului `dog` într-un șir rezultă în `"object Object"`, returnează `{ emoji: "🐈", name: "Sara" }`.
+
+
+
+#### Răspuns: A
+
+Funcția `updateEmail` este o funcție săgeată și nu este legată de obiectul `user`. Acest lucru înseamnă că cuvântul cheie `this` nu se referă la obiectul `user`, ci se referă la domeniul global în acest caz. Valoarea `email` din obiectul `user` nu se actualizează. Când se înregistrează valoarea `user.email`, se returnează valoarea originală `my@email.com`.
+
+
+
+#### Răspuns: D
+
+Metoda `Promise.all` rulează promisiunile transmise în paralel. Dacă o promisiune eșuează, metoda `Promise.all` se _respinge_ cu valoarea promisiunii respinse. În acest caz, `promise3` a fost respinsă cu valoarea `"Third"`. Prindem valoarea respinsă în metoda `catch` lantată în invocarea `runPromises` pentru a prinde orice erori din interiorul funcției `runPromises`. Se înregistrează doar `"Third"` deoarece `promise3` a fost respinsă cu această valoare.
+
+
+
+#### Răspuns: C
+
+Metoda `fromEntries` transformă o matrice 2D într-un obiect. Primul element din fiecare submatrice va fi cheia, iar al doilea element din fiecare submatrice va fi valoarea. În acest caz, facem mapare peste matricea `keys` care returnează o matrice în care primul element este elementul din matricea cheilor la indexul curent, iar al doilea element este elementul din matricea valorilor la indexul curent.
+
+Acest lucru creează o matrice de submatrici care conțin cheile și valorile corecte, rezultând în `{ name: "Lydia", age: 22 }`
+
+
+
+#### Răspuns: C
+
+Valoarea implicită a lui `address` este un obiect gol `{}`. Când setăm variabila `member` egală cu obiectul returnat de funcția `createMember`, nu am transmis o valoare pentru `address`, ceea ce înseamnă că valoarea lui `address` este obiectul gol implicit `{}`. Un obiect gol este o valoare adevărată (truthy), ceea ce înseamnă că condiția din expresia ternară `address ? address : null` returnează `true`. Prin urmare, valoarea lui `address` este obiectul gol `{}`.
+
+
+
+#### Răspuns: B
+
+Condiția din instrucțiunea `if` verifică dacă valoarea lui `!typeof randomValue` este egală cu `"string"`. Operatorul `!` convertește valoarea la o valoare booleană. Dacă valoarea este adevărată (truthy), valoarea returnată va fi `false`, iar dacă valoarea este falsă (falsy), valoarea returnată va fi `true`. În acest caz, valoarea returnată de `typeof randomValue` este valoarea adevărată (truthy) `"number"`, ceea ce înseamnă că valoarea lui `!typeof randomValue` este valoarea booleană `false`.
+
+`!typeof randomValue === "string"` întotdeauna returnează `false`, deoarece de fapt verificăm `false === "string"`. Deoarece condiția returnează `false`, blocul de cod al instrucțiunii `else` se execută, iar `Yay it's a string!` este înregistrat.
+
+
-Список доступных переводов:
-* [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)
+- [🇸🇦 العربية](../ar-AR/README_AR.md)
+- [🇪🇬 اللغة العامية](../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)
+- [🇮🇩 Indonesia](../id-ID/README.md)
+- [🇮🇹 Italiano](../it-IT/README.md)
+- [🇯🇵 日本語](../ja-JA/README-ja_JA.md)
+- [🇰🇷 한국어](../ko-KR/README-ko_KR.md)
+- [🇳🇱 Nederlands](../nl-NL/README.md)
+- [🇵🇱 Polski](../pl-PL/README.md)
+- [🇧🇷 Português Brasil](../pt-BR/README_pt_BR.md)
+- [🇷o Română](../ro-RO/README.ro.md)
+- [🇬🇧 English](../README.md)
+- [🇽🇰 Shqip](../sq-KS/README_sq_KS.md)
+- [🇹🇭 ไทย](../th-TH/README-th_TH.md)
+- [🇹🇷 Türkçe](../tr-TR/README-tr_TR.md)
+- [🇺🇦 Українська мова](../uk-UA/README.md)
+- [🇻🇳 Tiếng Việt](../vi-VI/README-vi.md)
+- [🇨🇳 简体中文](../zh-CN/README-zh_CN.md)
+- [🇹🇼 繁體中文](../zh-TW/README_zh-TW.md)
+정답
+답
정답
+답
정답
+답
@@ -440,12 +467,12 @@ console.log(sarah);
- A: true
- B: false
-정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
-그 후, `members`라는 변수를 선언해요. 배열의 첫 번째 요소에 `person` 변수의 값을 대입해요. 서로를 같게 설정하면 _참조_ 에 의해 상호작용해요. 어떤 변수에서 다른 변수로 참조를 할당하면, 그 참조의 _복사본_ 을 만들어요. (그들은 _같은_ 참조를 가지고 있지 않다는 것을 유의하세요!)
+그 후, `members`라는 변수를 선언해요. 배열의 첫 번째 요소에 `person` 변수의 값을 대입해요. 서로를 같게 설정하면 _참조_로 상호작용해요. 어떤 변수에서 다른 변수로 참조를 할당하면, 그 참조의 _복사본_ 을 만들어요. (그들은 _같은_ 참조를 가지고 있지 않다는 것을 유의하세요!)
@@ -1402,7 +1429,7 @@ console.log(members);
-배열의 첫 번째 요소는 객체에 대한 다른 (복사된) 참조를 가지고 있기 때문에, `person` 변수의 값만 변경하고, 배열의 첫 번째 요소는 변경할 수 없어요. `members`의 첫 번째 요소는 여전히 원본 객체에 대한 참조를 유지하고 있어요. `members` 배열을 출력할 때, 첫 번째 요소는 여전히 객체의 값을 유지하고 있어 로그가 출력돼요.
+`person` 변수의 값만 변경할 수 있고, 배열의 첫 번째 요소는 객체에 대한 다른 (복사된) 참조를 가지고 있기 때문에 변경할 수 없어요. `members`의 첫 번째 요소는 여전히 원본 객체에 대한 참조를 유지하고 있어요. `members` 배열을 출력할 때, 첫 번째 요소는 여전히 객체의 값을 갖고 있어 로그가 출력돼요.
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
-`a`는 이제 `1`이고, `b`는 이제 `2`예요. 질문에서 실제로 한 건 다음과 같아요:
+`a`의 값은 이제 `1`이고, `b`의 값은 이제 `2`예요. 사실 이 질문에서 한 건 다음과 같아요:
```javascript
[y] = [1, 2, 3, 4, 5];
@@ -1830,7 +1857,7 @@ console.log(y);
-이것은 `y`의 값은 숫자 `1`인 배열의 첫 번째 값과 같다는 것을 의미하죠. `y`를 출력하면 `1`이 리턴돼요.
+이것은 `y`의 값은 숫자 `1`인 배열의 첫 번째 값과 같다는 것을 의미해요. `y`를 출력하면 `1`이 반환돼요.
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
`world`
-정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
정답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+
+
+그리고서, 새로운 변수 `counterTwo`를 만들고, `counterOne`과 동일하게 설정해요. 객체는 참조로 상호작용 하므로, `counterOne`을 가리키는 같은 메모리 영역에 새로운 참조를 만들었어요. 메모리의 같은 장소에 존재 하므로, 참조를 가진 `counterTwo` 객체의 모든 변화는, `counterOne` 객체에도 적용돼요. 지금, `counterTwo.count`은 `2`예요.
+
+`count`를 `3`으로 만드는 `counterTwo.increment()`를 호출해요. 그리고서, `counterOne`의 count를 출력하고, `3`이 출력돼요.
+
+
+
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+답
+
+ JavaScript Vragen
+
+ ---
+
+ Ik plaats JavaScript meerkeuzevragen op mijn [Instagram](https://www.instagram.com/theavocoder) **stories**, welke ik ook hier zal plaatsen! Laatste update: 24 december
+
+ 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:
+
+ Voel je vrij om contact met mij op te nemen! 😊
+ Instagram || Twitter || LinkedIn || Blog
+ Zie alle 17 beschikbare vertalingen
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+
+
+Wanneer je één object veranderd, verander je ze allemaal.
+
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+
+
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+
+
+Dan wordt `foo` uitgevoerd en `"First"` wordt gelogd.
+
+
+
+`foo` wordt van de stack gegooid en `baz` wordt uitgevoerd. `"Third"` wordt gelogd.
+
+
+
+De WebAPI kan niet zomaar dingen toevoegen aan de stack. In plaats daarvan wordt de callback functie op de zogenaamde _queue_ gezet.
+
+
+
+Dit is waar de event loop zijn intrede doet. Een ***event loop* naar de stack en de task queue. Als de stack leeg is pakt het het eerste ding op van de queue en zet het op de stack.
+
+
+
+`bar` wordt uitgevoerd, `"Second"` wordt gelogd, en het verdwijnt van de stack.
+
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+
+
+Dan declareren we een variabele genaamd `members`. We vullen het eerste element van die array met de waarde van de variabele `person`. Objecten interacteren _by reference_. Wanneer je de ene referentie van een variabele toewijst aan een andere variabele, maak je een _kopie_ van die referentie (let op dat ze niet _dezelfde_ referentie hebben!).
+
+
+
+Dan zetten we de variabele `person` gelijk aan `null`.
+
+
+
+We passaen alleen de waarde aan van de `person` variabele en niet van het eerste element in de array, omdat dat element een andere referentie heeft (gekopieerd) naar dat object. Het eerste element behoudt nog steeds een referentie naar het eerste object. Wanneer we de array `members` loggen heeft het eerste element nog steeds de waarde van het object, wat dus gelogd wordt.
+
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+
+
+De waarde van `a` is nu `1` en de waarde van `b` is nu `2`. Wat we dus eigenlijk deden in de vraag is:
+
+```javascript
+[y] = [1, 2, 3, 4, 5];
+```
+
+
+
+Dat betekent dat de waarde van `y` gelijk is aan de eerste waarde van de array, het getal `1`. Wanneer we `y` loggen, geeft dit `1` terug.
+
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+
`world`
+- C: `Hello\nworld`
+- D: `Hello\n`
`world`
+
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+
+
+Dan maken we de variabele `counterTwo` aan en maken het gelijk aan `counterOne`. Omdat object interacteren _by reference_ creëeren we enkel een referentie naar dezelfde plek in het geheugen waarnaar `counterOne` verwijst. Omdat dit dezelfde plek in het geheugen is worden alle veranderingen op het object `counterTwo` ook doorgevoerd op `counterOne`. Op dat moment is `counterTwo.count` ook `2`.
+
+We roepen `counterTwo.increment()` aan, wat `count` gelijk maakt aan `3`. Als we de `count` op `counterOne` loggen is die `3`.
+
+
+
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+Antwoord
+
+ Pytania dotyczące JavaScript
+ Zobacz 20 dostępnych tłumaczeń 🇸🇦🇪🇬🇧🇦🇩🇪🇪🇸🇫🇷🇮🇩🇯🇵🇰🇷🇳🇱🇧🇷🇷🇺🇹🇭🇹🇷🇺🇦🇻🇳🇨🇳🇹🇼🇽🇰
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+
+
+Kiedy zmieniasz jeden obiekt, zmieniasz je wszystkie.
+
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+
+
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+
+
+Teraz, `foo` jest wywoływane, a `"First"` jest wyświetlane.
+
+
+
+`foo` jest zdejmowane ze stosu, a `baz` jest wywoływane. "Third" zostaje wyświetlony.
+
+
+
+WebAPI nie może dodawać rzeczy do stosu, gdy jest gotowy. Zamiast tego przesuwa funkcję zwrotną do czegoś zwanego _kolejką_.
+
+
+
+W tym miejscu zaczyna działać pętla zdarzeń. **Pętla zdarzeń** patrzy na stos i kolejkę zadań. Jeśli stos jest pusty, pobiera pierwszą rzecz z kolejki i przesuwa ją na stos.
+
+
+
+`bar` zostaje wywołany, `"Second"` zostaje wyświetlony i zdjęty ze stosu.
+
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+
+
+Następnie deklarujemy zmienną o nazwie `members`. Ustawiamy pierwszy element tej tablicy równy wartości zmiennej `person`. Obiekty oddziałują na siebie poprzez _referencję_, gdy ustawiamy je równe sobie. Kiedy przypisujesz referencję z jednej zmiennej do drugiej, tworzysz _kopię_ tej referencji. (Zauważ, że nie mają one _tej samej_ referencji!).
+
+
+
+Następnie ustawiamy zmienną `person` równą `null`.
+
+
+
+Modyfikujemy tylko wartość zmiennej `person`, a nie pierwszy element w tablicy, ponieważ ten element ma inną (skopiowaną) referencję do obiektu. Pierwszy element w `members` wciąż posiada referencję do oryginalnego obiektu. Kiedy wyświetlamy tablicę `members`, pierwszy element nadal przechowuje wartość obiektu, który jest wyświetlany.
+
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+
+
+Wartość `a` wynosi teraz `1`, a wartość `b` wynosi teraz `2`.To, co faktycznie zrobiliśmy w pytaniu, to:
+
+```javascript
+[y] = [1, 2, 3, 4, 5];
+```
+
+
+
+Oznacza to, że wartość `y` jest równa pierwszej wartości w tablicy, którą jest liczba `1`.Kiedy logujemy `y`, zwracana jest wartość `1`.
+
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+
`world`
+- C: `Hello\nworld`
+- D: `Hello\n`
`world`
+
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Odpowiedź
+Answer
+Resposta
Resposta
+Resposta
+Resposta
+
+
+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
+Resposta
+Resposta
+Resposta
+Resposta
+Resposta
+Resposta
+Resposta
+Resposta
+Resposta
+Resposta
+Resposta
+Resposta
+
+
+O valor de `a` agora é `1` e o valor de `b` agora é `2`. O que realmente fizemos na pergunta é:
+
+```javascript
+[y] = [1, 2, 3, 4, 5];
+```
+
+
+
+Isso significa que o valor de `y` é igual ao primeiro valor no array, que é o número `1`. Quando registramos no console `y`, `1` é retornado.
+
+Resposta
+Resposta
+Resposta
+Resposta
+Resposta
+Resposta
+Resposta
+Resposta
+Resposta
+Resposta
+Resposta
+Resposta
+
`world`
+- C: `Hello\nworld`
+- D: `Hello\n`
`world`
+
+Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+Answer
+
+ Întrebări JavaScript
+
+---
+
+Postez întrebări JavaScript cu opțiuni multiple pe [Instagram](https://www.instagram.com/theavocoder) **stories**, pe care le voi posta și aici! Ultima actualizare: 12 Iunie
+
+De la nivel de bază la avansat: testează cât de bine cunoști JavaScript, reîmprospătează-ți puțin cunoștințele sau pregătește-te pentru interviul tău de codare! :muscle: :rocket: Actualizez acest depozit în mod regulat cu întrebări noi. Am adăugat răspunsurile în **secțiunile restrânse** de sub întrebări, pur și simplu dă clic pe ele pentru a le extinde. Este doar pentru distracție, mult noroc! :heart:
+
+Nu ezita să mă contactezi! 😊
+Instagram || Twitter || LinkedIn || Blog
+
+ Vezi 20 de traduceri disponibile 🇸🇦🇪🇬🇧🇦🇩🇪🇪🇸🇫🇷🇮🇩🇯🇵🇰🇷🇳🇱🇧🇷🇷🇺🇹🇭🇹🇷🇺🇦🇻🇳🇨🇳🇹🇼🇽🇰
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+
+
+Când modifici un obiect, le modifici pe toate.
+
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+
+
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+
+
+Acum, `foo` este invocată, iar`"First"` este înregistrat.
+
+
+
+`foo` este scoasă din stivă, iar `baz` este invocată. Se înregistrează `"Third"`.
+
+
+
+WebAPI-ul nu poate adăuga pur și simplu lucruri în stivă atunci când este gata. În schimb, împinge funcția de callback într-o structură numită _coadă_.
+
+
+
+Aici începe să lucreze un event loop. Un **event loop** se uită la stivă și la coada de sarcini. Dacă stiva este goală, ia primul lucru din coadă și-l adaugă în stivă.
+
+
+
+`bar` este invocată, `"Second"` este înregistrat și este scos din stivă.
+
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+
+
+Apoi, declarăm o variabilă numită `members`. Setăm primul element al acestui array egal cu valoarea variabilei `person`. Obiectele interacționează prin _referință_ atunci când le setăm egale între ele. Atunci când atribuiți o referință de la o variabilă la alta, faceți o _copie_ a acelei referințe. (notați că acestea nu au _aceași_ referință!)
+
+
+
+Apoi, setăm variabila `person` egală cu `null`.
+
+
+
+Noi modificăm doar valoarea variabilei `person` nu și primul element din array, deoarece acel element are o referință diferită (copiată) la obiect. Primul element din `members` încă păstrează referința sa la obiectul original. Când înregistrăm în consolă array-ul `members` primul element păstrează valoarea obiectului, care este afișată în consolă.
+
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+
+
+Valoarea lui `a` este acum `1`, iar valoarea lui `b` este acum `2`. Ceea ce am făcut în întrebare este:
+
+```javascript
+[y] = [1, 2, 3, 4, 5];
+```
+
+
+
+Acest lucru înseamnă că valoarea lui `y` este egală cu prima valoare din array, care este numărul `1`. Când înregistrăm în consolă `y`, se returnează `1`.
+
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+
`world`
+- C: `Hello\nworld`
+- D: `Hello\n`
`world`
+
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+
+
+Apoi, creăm o nouă variabilă `counterTwo`, și o setăm egală cu `counterOne`. Deoarece obiectele interacționează prin referință, creăm doar o nouă referință către același loc în memorie la care indică `counterOne`. Deoarece au același loc în memorie, orice modificări făcute asupra obiectului la care `counterTwo` are o referință se aplică și la `counterOne`. În prezen, `counterTwo.count` este `2`.
+
+Apelăm `counterTwo.increment()`, ceea ce setează `count` la `3`. Apoi, afișăm valoarea lui `counterOne`, ceea ce va afișa `3`.
+
+
+
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+Răspuns
+
+ Вопросы по JavaScript
-Я ежедневно публикую вопросы по JavaScript с вариантами ответов в своем [Instagram](https://www.instagram.com/theavocoder), которые дублируются в этом репозитории.
+---
+
+Я (Lydia Hallie) ежедневно публикую вопросы по JavaScript с вариантами ответов в своем [Instagram](https://www.instagram.com/theavocoder) **сторис**, которые дублируются в этом репозитории! Последнее обновление: 12 июня.
-От базового до продвинутого: проверьте, насколько хорошо вы знаете JavaScript, немного освежите свои знания или подготовьтесь к собеседованию! :muscle: :rocket: Я обновляю репозиторий еженедельно новыми вопросами. Последнее обновление: 17 августа.
+От базового до продвинутого: проверьте, насколько хорошо вы знаете JavaScript, немного освежите свои знания или подготовьтесь к собеседованию! :muscle: :rocket: Я регулярно обновляю этот репозиторий новыми вопросами. Ответы находятся в **свернутой секции** под каждым вопросом. Просто нажми на "Ответ", чтобы развернуть. Удачи! :heart:
+
+Не стесняйтесь обращаться ко мне (Lydia Hallie)! 😊
+Instagram || Twitter || LinkedIn || Blog
+
-✨✉Подпишитесь на обновления✉✨
+---
+ Доступно в 20 переводах 🇸🇦🇪🇬🇧🇦🇩🇪🇪🇸🇫🇷🇮🇩🇯🇵🇰🇷🇳🇱🇧🇷🇷🇺🇹🇭🇹🇷🇺🇦🇻🇳🇨🇳🇹🇼🇽🇰
+
-Когда ты изменяешь один объект, то изменяются значения всех ссылок, указывающих на этот объект.
+Когда вы изменяете один объект, то изменяются значения всех ссылок, указывающих на этот объект.
@@ -828,12 +850,12 @@ for (let i = 1; i < 5; i++) { ```javascript String.prototype.giveLydiaPizza = () => { - return "Just give Lydia pizza already!"; + return 'Just give Lydia pizza already!'; }; -const name = "Lydia"; +const name = 'Lydia'; -name.giveLydiaPizza(); +console.log(name.giveLydiaPizza()) ``` - A: `"Just give Lydia pizza already!"` @@ -857,8 +879,8 @@ name.giveLydiaPizza(); ```javascript const a = {}; -const b = { key: "b" }; -const c = { key: "c" }; +const b = { key: 'b' }; +const c = { key: 'c' }; a[b] = 123; a[c] = 456; @@ -878,9 +900,9 @@ console.log(a[b]); Ключи объекта автоматически конвертируются в строки. Мы собираемся добавить объект в качестве ключа к объекту `a` со значением `123`. -Тем не менее, когда мы приводим объект к строке, он становится `"[object Object]"`. Таким образом, мы говорим, что `a["Object object"] = 123`. Потом мы делаем то же самое. `c` это другой объект, который мы неявно приводим к строке. Поэтому `a["Object object"] = 456`. +Тем не менее, когда мы приводим объект к строке, он становится `"[object Object]"`. Таким образом, мы говорим, что `a["object Object"] = 123`. Потом мы делаем то же самое. `c` это другой объект, который мы неявно приводим к строке. Поэтому `a["object Object"] = 456`. -Затем, когда мы выводим `a[b]`, мы имеем в виду `a["Object object"]`. Мы только что установили туда значение `456`, поэтому в результате получаем `456`. +Затем, когда мы выводим `a[b]`, мы имеем в виду `a["object Object"]`. Мы только что установили туда значение `456`, поэтому в результате получаем `456`.
@@ -2033,6 +2058,7 @@ multiply(value); Если вы не возвращаете значение из функции, она возвращает значение `undefined`. При следующем вызове аккумулятор равен `undefined`, а текущее значение равно 3. `undefined` и `3` будут зарегистрированы. При четвертом вызове мы снова не возвращаемся из функции обратного вызова. Аккумулятор снова равен `undefined`, а текущее значение равно `4`. `undefined` и` 4` будут зарегистрированы. +
#### Ответ: C -Функция генератора "приостанавливает" выполнение, когда видит ключевое слово yield. Во-первых, мы должны позволить функции выдать строку "Do you love JavaScript?", Что можно сделать, вызвав `game.next (). Value`. +Функция генератора "приостанавливает" выполнение, когда видит ключевое слово yield. Во-первых, мы должны позволить функции выдать строку "Do you love JavaScript?", что можно сделать, вызвав `game.next().value`. Каждая строка выполняется до тех пор, пока не найдет первое ключевое слово `yield`. В первой строке функции есть ключевое слово `yield` на первом месте: выполнение останавливается с первым выходом! _Это означает, что переменная `answer` еще не определена!_ @@ -2274,7 +2301,7 @@ console.log(String.raw`Hello\nworld`); ```javascript async function getData() { - return await Promise.resolve("I made it!"); + return await Promise.resolve('I made it!'); } const data = getData(); @@ -2311,7 +2338,7 @@ function addToList(item, list) { return list.push(item); } -const result = addToList("apple", ["banana"]); +const result = addToList('apple', ['banana']); console.log(result); ``` @@ -2371,9 +2398,9 @@ console.log(shape); ###### 76. Какой будет вывод? ```javascript -const { name: myName } = { name: "Lydia" }; +const { firstName: myName } = { firstName: 'Lydia' }; -console.log(name); +console.log(firstName); ``` - A: `"Lydia"` @@ -2386,11 +2413,45 @@ console.log(name); #### Ответ: D -Когда мы распаковываем свойство `name` из правого объекта, мы присваиваем его значение `"Lydia"` переменной с именем `myName`. +Используя [деструктурирующее присваивание](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment), мы можем распаковывать значения из массивов или свойства из объектов в отдельные переменные: + +```javascript +const { firstName } = { firstName: 'Lydia' }; +// Версия ES5: +// var firstName = { firstName: 'Lydia' }.firstName; + +console.log(firstName); // "Lydia" +``` + +Также свойство можно распаковать из объекта и присвоить переменной с именем, отличным от имени свойства объекта: + +```javascript +const { firstName: myName } = { firstName: 'Lydia' }; +// Версия ES5: +// var myName = { firstName: 'Lydia' }.firstName; + +console.log(myName); // "Lydia" +console.log(firstName); // Тут будет ошибка Uncaught ReferenceError: firstName is not defined +``` + +В этом случае `firstName` не существует как переменная, поэтому попытка доступа к ее значению вызовет `ReferenceError`. + +**Примечание.** Помните о свойствах глобальной области видимости: + +```javascript +const { name: myName } = { name: 'Lydia' }; + +console.log(myName); // "lydia" +console.log(name); // "" ----- Браузер, например, Chrome +console.log(name); // ReferenceError: name is not defined ----- NodeJS + +``` + +Всякий раз, когда Javascript не может найти переменную в _текущей области видимости_, то поднимается вверх по [цепочке областей видимости](https://developer.mozilla.org/ru/docs/Web/JavaScript/Closures#лексическая_область_видимости) и ищет ее на каждом уровне, и если достигает области верхнего уровня, также известной как **Глобальная область**, и все еще не находит нужной ссылки, то выдает `ReferenceError`. -С помощью `{name: myName}` мы сообщаем JavaScript, что хотим создать новую переменную с именем `myName` со значением свойства `name` в правой части. +- В **браузерах**, таких как _Chrome_, `name` является _устаревшим свойством глобальной области_. В этом примере код выполняется внутри _глобальной области_ и нет определяемой пользователем локальной переменной `name`, поэтому интерпретатор ищет предопределенные _переменные/свойства_ в глобальной области видимости, что в случае браузеров происходит через объект `window` и возвращается значение [window.name](https://developer.mozilla.org/en-US/docs/Web/API/Window/name), которое равно **пустой строке**. -Поскольку мы пытаемся зарегистрировать `name`, переменную, которая не определена, выдается ReferenceError. +- В **NodeJS** такого свойства в "глобальном" объекте нет, поэтому попытка доступа к несуществующей переменной вызовет [ReferenceError](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Errors/Not_defined).
@@ -2472,7 +2533,7 @@ console.log(addFunction(5 * 2));
###### 79. Какой будет вывод?
```javascript
-const myLifeSummedUp = ["☕", "💻", "🍷", "🍫"]
+const myLifeSummedUp = ['☕', '💻', '🍷', '🍫']
for (let item in myLifeSummedUp) {
console.log(item)
@@ -2542,9 +2603,9 @@ function sayHi(name) {
console.log(sayHi())
```
-- A: `Hello there, `
-- B: `Hello there, undefined`
-- C: `Hello there, null`
+- A: `Hi there, `
+- B: `Hi there, undefined`
+- C: `Hi there, null`
- D: `ReferenceError`
Ответ
@@ -2568,13 +2629,13 @@ console.log(sayHi())
###### 82. Какой будет вывод?
```javascript
-var status = "😎"
+var status = '😎'
setTimeout(() => {
- const status = "😍"
+ const status = '😍'
const data = {
- status: "🥑",
+ status: '🥑',
getStatus() {
return this.status
}
@@ -2599,7 +2660,6 @@ setTimeout(() => {
С помощью метода `call` мы можем изменить объект, на который ссылается ключевое слово `this`. В **функциях** ключевое слово `this` относится к _объекту, которому принадлежит функция_. Мы объявили функцию `setTimeout` для объекта _global_, поэтому в функции `setTimeout` ключевое слово `this` ссылается на объект _global_. В глобальном объекте есть переменная с именем _status_ со значением `"😎"`. При регистрации `this.status` выводится `"😎"`.
-
@@ -2734,7 +2794,7 @@ function getName(name) { ###### 87. Какой будет вывод? ```javascript -console.log("I want pizza"[0]) +console.log('I want pizza'[0]) ``` - A: `"""` @@ -2789,11 +2849,11 @@ sum(10) ```javascript // module.js -export default () => "Hello world" -export const name = "Lydia" +export default () => 'Hello world' +export const name = 'Lydia' // index.js -import * as data from "./module" +import * as data from './module' console.log(data) ``` @@ -2826,7 +2886,7 @@ class Person { } } -const member = new Person("John") +const member = new Person('John') console.log(typeof member) ``` @@ -2848,7 +2908,7 @@ function Person() { } ``` -Вызов конструктора функции с `new` приводит к созданию экземпляра `Person`, ключевое слово `typeof` возвращает `"object"` для экземпляра. `typeof member` возвращает `"объект"`. +Вызов конструктора функции с `new` приводит к созданию экземпляра `Person`, ключевое слово `typeof` возвращает `"object"` для экземпляра. `typeof member` возвращает `"object"`.
#### Ответ: 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]` +`[x, ...y] = [1, 2, 3, 4]` С помощью оставшихся параметров `... y` мы помещаем все "оставшиеся" аргументы в массив. Остальные аргументы - это `2`, `3` и `4` в этом случае. Значение `y` является массивом, содержащим все остальные параметры. В этом случае значение `x` равно `1`, поэтому, мы видим в логе `[x, y]`, `[1, [2, 3, 4]]`. -Функция `getUser` получает объект. В случае функций со стрелками мы не можем писать фигурные скобки, если мы просто возвращаем одно значение. Однако, если вы хотите вернуть _объект_ из стрелочной функции, вы должны написать его в скобках, в противном случае никакое значение не возвращается! Следующая функция вернула бы объект: +Функция `getUser` получает объект. В стрелочных функциях нам _не нужно_ писать фигурные скобки, если мы просто возвращаем одно значение. Однако, если вы хотите мгновенно вернуть _object_ из стрелочной функции, вы должны написать его между круглыми скобками, иначе все, что находится между двумя фигурными скобками, будет интерпретироваться как оператор блока. В этом случае код между фигурными скобками не является допустимым кодом JavaScript, поэтому выдается `SyntaxError`. -```const getUser = user => ({ name: user.name, age: user.age })``` +Следующая функция вернула бы объект: -Поскольку в этом случае значение не возвращается, функция возвращает значение `undefined`. +```const getUser = user => ({ name: user.name, age: user.age })```
@@ -3137,7 +3196,7 @@ The `getList` function receives an array as its argument. Between the parenthese ###### 99. Какой будет вывод? ```javascript -const name = "Lydia" +const name = 'Lydia' console.log(name()) ``` @@ -3196,7 +3255,7 @@ You should${'' && `n't`} see a therapist after so much JavaScript lol` ```javascript const one = (false || {} || null) -const two = (null || false || "") +const two = (null || false || '') const three = ([] || 0 || true) console.log(one, two, three) @@ -3216,9 +3275,1872 @@ console.log(one, two, three) `(false || {} || null)`: пустой объект `{}` является истинным значением. Это первое (и единственное) истинное значение, которое возвращается. `one` содержит `{}`. -`(null || false ||" ")`: все операнды являются ложными значениями. Это означает, что прошедший операнд `""` возвращается. `two` содержит `""`. +`(null || false || "")`: все операнды являются ложными значениями. Это означает, что прошедший операнд `""` возвращается. `two` содержит `""`. + +`([] || 0 || "")`: пустой массив `[]` является истинным значением. Это первое истинное значение, которое возвращается. `three` присвоено `[]`. + + + + +--- + +###### 102. Какое значение будет на выходе? + +```javascript +const myPromise = () => Promise.resolve('I have resolved!') + +function firstFunction() { + myPromise().then(res => console.log(res)) + console.log('second') +} + +async function secondFunction() { + console.log(await myPromise()) + console.log('second') +} + +firstFunction() +secondFunction() +``` + +- 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`, либо обещание, либо не обещание. Сам метод возвращает обещание с разрешенным значением (`
+ +#### Ответ: B + +Объекты передаются по ссылке. Когда мы проверяем объекты на строгое равенство (`===`), мы сравниваем их ссылки. + +Мы устанавливаем значение по умолчанию для `person2`, равное объекту `person`, и передаем объект `person` в качестве значения для `person1`. + +Это означает, что оба значения имеют ссылку на одно и то же место в памяти, поэтому они равны. + +Блок кода в операторе `else` запускается, и в лог выводится `They are the same!`. + +
++ +#### Ответ: D + +В JavaScript у нас есть два способа доступа к свойствам объекта: нотация в скобках или нотация в точках. В этом примере мы используем точечную нотацию (`colorConfig.colors`) вместо скобочной нотации (`colorConfig["colors"]`). + +В точечной нотации JavaScript пытается найти свойство объекта с таким точным именем. В этом примере JavaScript пытается найти свойство с именем `colors` в объекте `colorConfig`. Не существует свойства с именем `colors`, поэтому возвращается `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` возвращает аккумулированное значение. + +
++ +#### Ответ: 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`. В этом случае он бы записал `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`. +Пока есть ссылка, объект не будет собирать мусор. +Так как это интервал, установка `config` в `null` или `delete`-ing `config.alert` не приведет к сбору мусора для интервала, поэтому интервал все равно будет вызываться. +Его следует очистить с помощью `clearInterval(config.alert)`, чтобы удалить его из памяти. +Поскольку он не был очищен, функция обратного вызова `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}`. + +
++ +#### Ответ: 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` (которое нам не нужно, это значение по умолчанию), что означает, что будут объединены только массивы на первой глубине. `['🥑']` и `['✨', '✨', ['🍕', '🍕']]` в этом случае. Конкатенация этих двух массивов приводит к `['🥑', '✨', '✨', ['🍕', '🍕']]`. + +
+
+
+#### Ответ: D
+
+`counterOne` экземпляр класса `Counter`. Counter класс содержит метод `increment` и свойство `count` в конструкторе. Сперва, при помощи `counterOne.increment()`, мы дважды вызываем метод `increment`. `counterOne.count` становится `2`.
+
+
+
+Затем, мы создаем новую переменную `counterTwo`, и присваиваем ей `counterOne`. Поскольку объекты передаются по ссылке, мы просто создаем новую ссылку на то же место в памяти, на которое указывает `counterOne`. Поскольку переменные ссылаются на то же место в памяти, любые изменения, внесенные в объект, на который ссылается `counterTwo`, также применяются к` counterOne`. Теперь `counterTwo.count` равно `2`.
+
+Мы вызываем `counterTwo.increment()`, что устанавливает значение `count` равное `3`. Затем мы выводим в консоль значение переменной `counterOne`, которое равно `3`.
+
+
+
+
+ +#### Ответ: D + +Сначала мы вызываем `funcOne`. В первой строке `funcOne` мы вызываем _асинхронную_ функцию `setTimeout`, из которой обратный вызов отправляется в веб-API. (см. мою статью о цикле событий здесь.) + +Затем мы вызываем обещание `myPromise`, которое является _асинхронной_ операцией. + +И обещание, и тайм-аут являются асинхронными операциями, функция продолжает работать, пока она занята выполнением обещания и обработкой обратного вызова `setTimeout`. Это означает, что `Last line 1!` регистрируется первой, так как это не асинхронная операция. + +Поскольку стек вызовов еще не пуст, функция `setTimeout` и обещание в `funcOne` еще не могут быть добавлены в стек вызовов. + +В `funcTwo` переменная `res` получает `Promise`, потому что `Promise.resolve(Promise.resolve('Promise'))` эквивалентно `Promise.resolve('Promise')`, так как разрешение обещания просто разрешает его стоимость. `await` в этой строке останавливает выполнение функции до тех пор, пока она не получит разрешение промиса, а затем продолжает работать синхронно до завершения, поэтому `Promise 2!`, а затем `Last line 2!` регистрируются, а `setTimeout` отправляется в Web API. + +Тогда стек вызовов пуст. Промисы — это _микрозадачи_, поэтому они решаются первыми, когда стек вызовов пуст, поэтому `Promise 1!` регистрируется. + +Теперь, поскольку `funcTwo` выталкивается из стека вызовов, стек вызовов пуст. Обратные вызовы, ожидающие в очереди (`() => console.log("Timeout 1!")` из `funcOne`, и `() => console.log("Timeout 2!")` из `funcTwo`) добавляются в стек вызовов один за другим. Первый обратный вызов регистрирует `Timeout 1!` и удаляется из стека. Затем второй обратный вызов регистрирует `Timeout 2!` и удаляется из стека. + +
++ +#### Ответ: C + +Используя звездочку `*`, мы импортируем все экспортируемые значения из файла, включая именнованные экспорты и экспорты по умолчанию. Если бы у нас был следующий файл: + +```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); +``` + +В лог попадёт следующее: + +```javascript +{ + default: 'I love JavaScript', + name: 'Lydia', + age: 21 +} +``` + +Для примера `sum` это означает, что импортированное значение `sum` будет таким: + +```javascript +{ default: function sum(x) { return x + x } } +``` + +Следовательно, мы можем вызвать эту функцию используя `sum.default` + +
++ +#### Ответ: C + +C помощью Proxy мы можем добавить собственное поведению объекту, которое мы передаем вторым аргументом. В нашем случае мы передаем объект `handler` который содержит свойства: `set` и `get`. `set` вызывается каждый раз когда мы _устанавливаем_ значения свойств, `get` же вызывается всякий раз когда мы _получаем_ значения свойств. + +Первый аргумент — пустой объект `{}`, который является значением `person`. Для него будет добавлено собственное поведение, описанное в объекте `handler`. При добавлении значения для объекта `person` будет вызвано свойство `set`. При запросе к значению `person` вызовется свойство `get`. + +Сначала мы устанавливаем новое свойство `name` для объекта Proxy (`person.name = "Lydia"`). Вызывается `set` и в лог попадает `"Added a new property!"`. + +Затем мы обращаемся к значению Proxy-объекта. Вызывается свойство `get` объекта `handler`. `"Accessed a property!"` попадает в лог. + +
++ +#### Ответ: A + +С помощью `Object.seal` мы можем предотвращать как _добавление_ новых свойств, так и _удаление_ существующих. + +Однако, изменение существующих свойств остаётся доступным. + +
++ +#### Ответ: C + +С помощью метода `Object.freeze` мы можем _заморозить_ объект. Свойства не могут быть добавлены, изменены или удалены. + +Однако, это _неглубоко_ замораживает объект. Замораживаются только _непосредственные_ свойства объекта. Если свойством является другой объект(в нашем примере `address`), свойства этого объекта не замораживаются и могут быть изменены. + +
++ +#### Ответ: A + +Во-первых, мы вызваем `myFunc()` без передачи каких-либо аргументов. Поскольку мы не передаем аргументы, `num` и `value` получают свои значения по умолчанию: `num` равно `2`, а `value` возвращаемое значение функции `add`. В функцию `add` мы передаем в качестве аргумента `num` со значением `2`. `add` возвращает `4`, что является значением `value`. + +Затем мы вызваем `myFunc(3)` и передаем значение `3` в качестве значения аргумента `num`. Мы не передаем аргумент для `value`. Поскольку мы не передаем значение для аргумента `value`, он получаеи значение по умолчанию: возвращаемое значение функции `add`. В `add` мы передаем `num`, значение которого равно `3`. `add` возвращает `6`, что является значением `value`. + +
++ +#### Ответ: D + +В ES2020 мы можем добавлять приватные переменные в классы с помощью символа `#`. Мы не можем получить доступ к этим переменным вне класса. Когда мы пытаемся записать `counter.#number`, выдается `SyntaxError`: мы не можем получить доступ вне класса `Counter`! + +
++ +#### Ответ: B + +Чтобы выполнить итерацию по `members` в каждом элементе массива `teams`, нам нужно передать `teams[i].members` в функцию генератора `getMembers`. Функция генератора возвращает объект генератора. Чтобы перебрать каждый элемент в этом объекте-генераторе, нам нужно использовать `yield*`. + +Если бы мы написали `yield`, `return yield` или `return`, вся функция генератора была бы возвращена при первом вызове метода `next`. + +
++ +#### Ответ: C + +Функция `addHobby` получает два аргумента, `hobby` и `hobbies`, со значением по умолчанию массива `hobbies` в объекте `person`. + +Во-первых, мы вызываем функцию `addHobby` и передаем `"running"` в качестве значения для `hobby`, а пустой массив в качестве значения для `hobbies`. Так как мы передаем пустой массив в качестве значения для `hobbies`, `"running"` добавляется к этому пустому массиву. + +Затем мы вызываем функцию `addHobby` и передаем `dancing` в качестве значения для `hobby`. Мы не передавали значение для `hobbies`, поэтому оно получает значение по умолчанию, свойство `hobbies` объекта `person`. Мы помещаем хобби `dancing` в массив `person.hobbies`. + +Наконец, мы вызываем функцию `addHobby` и передаем `"baking"` в качестве значения для `hobby`, а массив `person.hobbies` в качестве значения для `hobbies`. Мы помещаем хобби `baking` в массив `person.hobbies`. + +После нажатия `танцы` и `выпечка`, значение `person.hobbies` равно `["coding", "dancing", "baking"]` + +
++ +#### Ответ: B + +Мы создаем переменную `pet`, которая является экземпляром класса `Flamingo`. Когда мы создаем этот экземпляр, вызывается `constructor` для `Flamingo`. Сначала регистрируется `"I'm pink. 🌸"`, после чего мы вызываем `super()`. `super()` вызывает конструктор родительского класса `Bird`. Конструктор в `Bird` вызывается и регистрирует `"I'm a bird. 🦢"`. + +
++ +#### Ответ: D + +Ключевое слово `const` просто означает, что мы не можем _повторно объявить_ значение этой переменной, оно доступно только для чтения. Однако само значение не является неизменным. Свойства массива `emojis` можно изменить, например, добавив новые значения, объединив их или установив длину массива на 0. + +
++ +#### Ответ: C + +По умолчанию объекты не являются итерируемыми. Итерируемым объект становится, если присутствует протокол итератора. Мы можем добавить это вручную, добавив символ итератора `[Symbol.iterator]`, который должен возвращать объект-генератор, например, сделав его функцией-генератором `*[Symbol.iterator]() {}`. Эта функция-генератор должна возвращать `Object.values` объекта `person`, если мы хотим, чтобы он возвращал массив `["Lydia Hallie", 21]`: `yield* Object.values(this)`. + +
++ +#### Ответ: C + +Условие `if` внутри цикла `forEach` проверяет, является ли значение `num` истинным или ложным. Поскольку первое число в массиве `nums` равно `0`, то есть ложное значение, блок оператора `if` не будет выполнен. `count` увеличивается только для остальных 3 чисел в массиве `nums`: `1`, `2` и `3`. Поскольку `count` увеличивается на 1 3 раза, значение `count` равно `3`. + +
++ +#### Ответ: D + +`?` позволяет нам дополнительно получить доступ к более глубоким вложенным свойствам внутри объектов. Мы пытаемся зарегистрировать элемент с индексом `1` в подмассиве с индексом `1` массива `fruits`. Если подмассив с индексом `1` в массиве `fruits` не существует, он просто вернет `undefined`. Если подмассив с индексом `1` в массиве `fruits` существует, но в этом подмассиве нет элемента с индексом `1`, он также вернет значение `undefined`. + +Во-первых, мы пытаемся зарегистрировать второй элемент в `['🍍']` подмассива `[['🍊', '🍌'], ['🍍']]`. Этот подмассив содержит только один элемент, что означает, что в индексе `1` нет элемента, и возвращает значение `undefined`. + +Затем мы вызываем функцию `getFruits` без передачи значения в качестве аргумента, что означает, что `fruits` по умолчанию имеет значение `undefined`. Поскольку мы условно связываем элемент с индексом `1` массива `fruits`, он возвращает значение `undefined`, поскольку этот элемент с индексом `1` не существует. + +Наконец, мы попытаемся зарегистрировать второй элемент в `['🍊', '🍌']` подмассива `['🍍'], ['🍊', '🍌']`. Элемент с индексом `1` в этом подмассиве — `🍌`, который регистрируется. + +
++ +#### Ответ: A + +Мы устанавливаем переменную `calc` равной новому экземпляру класса `Calc`. Затем мы создаем экземпляр нового экземпляра `Calc` и вызываем метод увеличения для этого экземпляра. Поскольку свойство `count` находится в конструкторе класса `Calc`, свойство `count` не используется в прототипе `Calc`. Это означает, что значение `count` не было обновлено для экземпляра, на который указывает `calc`, `count` по-прежнему равен `0`. + +
++ +#### Ответ: B + +Функция `updateUser` обновляет значения свойств `email` и `password` у пользователя, если их значения переданы в функцию, после чего функция возвращает объект `user`. Возвращаемое значение функции `updateUser` — это объект `user`, что означает, что значение `updatedUser` является ссылкой на тот же объект `user`, на который указывает `user`. `updatedUser === user` равно `true`. + +
++ +#### Ответ: C + +Во-первых, мы вызываем метод `slice` для массива фруктов. Метод `slice` не изменяет исходный массив, а возвращает значение, которое было вырезано из массива: банановый смайлик. +Затем мы вызываем метод `splice` для массива фруктов. Метод `splice` изменяет исходный массив, что означает, что массив фруктов теперь состоит из `['🍊', '🍎']`. +Наконец, мы вызываем метод `unshift` для массива `fruit`, который изменяет исходный массив, добавляя предоставленное значение, в данном случае `🍇`, в качестве первого элемента в массиве. Массив фруктов теперь состоит из `['🍇', '🍊', '🍎']`. + +
++ +#### Ответ: B + +Ключи объекта преобразуются в строки. + +Поскольку значение `dog` является объектом, `animals[dog]` на самом деле означает, что мы создаем новое свойство под названием `"object Object"`, равное новому объекту. `animals["object Object"]` теперь равно `{ emoji: "🐶", name: "Mara"}`. + +`cat` также является объектом, что означает, что `animals[cat]` на самом деле означает, что мы перезаписываем значение `animals["object Object"]` новыми свойствами кота. + +Регистрация `animals[dog]`, или фактически `animals["object Object"]`, поскольку преобразование объекта `dog` в строку приводит к `"object Object"`, возвращает `{ emoji: "🐈", name: " Сара"}`. + +
++ +#### Ответ: A + +Функция `updateEmail` представляет собой стрелочную функцию и не привязана к объекту пользователя. Это означает, что ключевое слово `this` не относится к объекту `user`, а в данном случае относится к глобальной области видимости. Значение `email` в объекте `user` не обновляется. При регистрации значения `user.email` возвращается исходное значение `my@email.com`. + +
++ +#### Ответ: D + +Метод `Promise.all` выполняет переданные промисы параллельно. Если одно обещание не выполняется, метод `Promise.all` _отколняется_ со значением отклоненного обещания. В этом случае `promise3` отклонен со значением `"Third"`. Мы перехватываем отклоненное значение в цепочке методов `catch` при вызове `runPromises`, чтобы перехватывать любые ошибки внутри функции `runPromises`. Только `"Third"` регистрируется, так как `promise3` отклонено с этим значением. + +
++ +#### Ответ: C + +Метод `fromEntries` превращает двумерный массив в объект. Первый элемент в каждом подмассиве будет ключом, а второй элемент в каждом подмассиве будет значением. В этом случае мы сопоставляем массив `keys`, который возвращает массив, первый элемент которого является элементом массива ключей текущего индекса, а второй элемент является элементом массива значений текущего индекса. + +Это создает массив подмассивов, содержащих правильные ключи и значения, что приводит к `{ name: "Lydia", age: 22 }` + +
++ +#### Ответ: C + +Значением по умолчанию для `address` является пустой объект `{}`. Когда мы устанавливаем переменную `member` равной объекту, возвращаемому функцией `createMember`, мы не передаем значение для адреса, что означает, что значение адреса является пустым объектом по умолчанию `{}`. Пустой объект является истинным значением, что означает, что условие `address ? address : null` условно возвращает `true`. Значением адреса является пустой объект `{}`. + +
++ +#### Ответ: B + +Условие в операторе `if` проверяет, равно ли значение `!typeof randomValue` "строке". Оператор `!` преобразует значение в логическое значение. Если значение истинно, возвращаемое значение будет "ложным", если значение ложным, возвращаемое значение будет "истинным". В этом случае возвращаемое значение `typeof randomValue` является истинным значением `"number"`, что означает, что значение `!typeof randomValue` является логическим значением `false`. -`([] || 0 ||" ")`: пустой массив `[]` является истинным значением. Это первое истинное значение, которое возвращается. `three` присвоено `[]`. +`!typeof randomValue === "string"` всегда возвращает `false`, поскольку на самом деле мы проверяем `false === "string"`. Поскольку условие вернуло `false`, запускается блок кода оператора `else`, и в журнал заносится сообщение `Yay it's a string!`.
+ +- [🇸🇦 العربية](../ar-AR/README_AR.md) +- [🇪🇬 اللغة العامية](../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) +- [🇮🇩 Indonesia](../id-ID/README.md) +- [🇮🇹 Italiano](../it-IT/README.md) +- [🇯🇵 日本語](../ja-JA/README-ja_JA.md) +- [🇰🇷 한국어](../ko-KR/README-ko_KR.md) +- [🇳🇱 Nederlands](../nl-NL/README.md) +- [🇵🇱 Polski](../pl-PL/README.md) +- [🇧🇷 Português Brasil](../pt-BR/README_pt_BR.md) +- [🇷o Română](../ro-RO/README.ro.md) +- [🇷🇺 Русский](../ru-RU/README.md) +- [🇽🇰 Shqip](./sq-KS/README_sq_KS.md) +- [🇹🇭 ไทย](../th-TH/README-th_TH.md) +- [🇹🇷 Türkçe](../tr-TR/README-tr_TR.md) +- [🇺🇦 Українська мова](../uk-UA/README.md) +- [🇻🇳 Tiếng Việt](../vi-VI/README-vi.md) +- [🇨🇳 简体中文](../zh-CN/README-zh_CN.md) +- [🇹🇼 繁體中文](../zh-TW/README_zh-TW.md) + +
++ +#### Përgjigja: D + +Brenda funksionit, fillimisht deklarojmë variablën `name` me fjalën kyçe `var`. Kjo do të thotë se variabla ngrihet - hoistohet (hapësira e memories caktohet gjatë fazës së krijimit) me vlerën e paracaktuar `undefined`, deri sa të arrijmë në rreshtin ku e definojmë variablën. Nuk kemi definuar ende variablën në rreshtin ku përpiqemi të shfaqim variablën `name`, kështu që ajo ende mban vlerën `undefined`. + +Variablat me fjalën kyçe `let` (dhe `const`) hoistohen, por ndryshe nga `var`, nuk inicializohen. Ato nuk janë të qasshme para rreshtit ku i deklarojmë (inicializojmë) ato. Kjo quhet "zona e vdekur temporale". Kur përpiqemi të iu qasemi variablave para se ato të jenë të deklaruara, JavaScript hedh një `ReferenceError`. + +
++ +#### Përgjigja: C + +Për shkak të ***event queque*** në JavaScript, funksioni callback `setTimeout` thirret pas ekzekutimit të unazës. Pasi që variabla `i` në iterimin e parë u deklarua duke përdorur fjalën kyçe `var`, kjo vlerë ishte globale. Gjatë unazës, ne rritëm vlerën e `i` me `1` çdo herë, duke përdorur operatorin unar `++`. Deri në kohën që funksioni callback `setTimeout` u thirr, `i` ishte e barabartë me `3` në unazën e parë. + +Në unazën e dytë, variabla `i` u deklarua duke përdorur fjalën kyçe `let`: variablat e deklaruara me fjalën kyçe `let` (dhe `const`) janë të qasshme në bllok (një bllok është çdo gjë mes `{ }`). Gjatë çdo iteracioni, `i` do të ketë një vlerë të re, dhe çdo vlerë është e qasshme brenda unazës. + +
++ +#### Përgjigja: B + +Vini re se vlera e `diameter` është një funksion i zakonshëm, ndërsa vlera e `perimeter` është një funksion shigjete (arrow function). + +Në funksionet shigjeta, fjala kyçe `this` referohet në qasjen në rrethinën aktuale përreth saj, ndryshe nga funksionet e zakonshme! Kjo do të thotë se kur ne e thërrasim `perimeter`, ajo nuk referohet tek objekti shape, por tek rrethina e saj (për shembull "window"). + +`radius` nuk ka ndonjë vlerë të caktuar në atë objekt, prandaj do të kemi si rezultat `NaN`. + +
++ +#### Përgjigja: A + +Operatori unar `+` provon të e konvertojë operandin në numër. `true` është `1`, dhe `false` është `0`. + +Vargu i karaktereve (stringu) `'Lydia'` konsiderohet si vlerë `true`. Çfarë ne realisht po pyesim është "a është kjo vlerë e vërtetë e pavërtetë?". Kjo do të kthejë vlerën `false`. + +
++ +#### Përgjigja: A + +Në JavaScript, të gjithë çelësat (keys) e objektit janë stringje (përveç nëse është Symbol). Edhe nëse nuk i _shkruajmë_ si stringje, ato gjithmonë konvertohen në stringje në prapavijë. + +JavaScript interpreton deklarimet. Kur përdorim notacionin e kllapave, ai shikon kllapën e parë hapëse `[` dhe vazhdon derisa të gjejë kllapën mbyllëse `]`. Vetëm atëherë do të vlerësohet deklarata (kthehet vlera e caktuar për atë deklarim). + +`mouse[bird.size]`: Fillimisht gjendet vlera e `bird.size`, e cila është `"small"`. `mouse["small"]` kthen `true` + +Megjithatë, me notacionin pikë, kjo nuk ndodh. `mouse` nuk ka një çelës të quajtur `bird`, që do të thotë se `mouse.bird` është `undefined`. Pastaj, ne kërkojmë "size" duke përdorur notacionin pikë: "mouse.bird.size". Meqenëse `mouse.bird` është `undefined`, ne në fakt po pyesim 'undefined.size'. Kjo nuk është valide dhe do të marrim një gabim të ngjashëm me `Cannot read property "size" of undefined`. + +
+
+
+#### Përgjigja: A
+
+Në JavaScript, të gjitha objektet ndërveprojnë me _referencë_ kur i vendosin me vlera të barabarta me njëri-tjetrin.
+
+Fillimisht, variabla `c` mbanë vlerën për një objekt. Më vonë, ne e caktojmë `d` me të njejtën reference të cilën `c` ka tek objekti.
+
+
+
+Kur e ndryshoni një objekt, i ndryshoni të gjitha objektet.
+
+
+ +#### Përgjigja: C + +`new Number()` është konstruktor i integruar (built-in function). Edhe pse duket si një numër, nuk është në të vërtetë një numër: ai ka një mori karakteristikash shtesë dhe si rrjedhojë është një objekt. + +Kur përdorim operatorin `==` (operatorin i barazimit), ai kontrollon vetëm nëse ka të njëjtën _vlerë_. Të dy kanë vlerën `3`, kështu që kthen `true`. + +Megjithatë, kur përdorim operatorin `===` (operatori i barazisë strikte), të dy vlerat dhe tipi i tyre duhet të jenë të njëjta. Nuk është: `new Number()` nuk është një numër, është një __objekt__. Të dy kthejnë `false`. + +
++ +#### Përgjigja: D + +Funksioni `colorChange` është statik. Metodat statike janë krijuar për të "jetuar" vetëm në konstruktorin në të cilin janë krijuar dhe nuk mund t'i kalohen asnjë fëmije ose të thirren në instancat e klasës. Meqenëse `freddie` është një instancë e klasës Chameleon, funksioni nuk mund të thirret. Në këtë rast do të kthehet `TypeError`. + +
++ +#### Përgjigja: A + +Do të printojë objekt, sepse ne sapo krijuam një objekt bosh në objektin global! Kur e shkruajtëm gabim `greeting` si `greetign`, interpretuesi i JS në fakt e pa këtë si: + +1. `global.greetign = {}` në Node.js +2. `window.greetign = {}`, `frames.greetign = {}` dhe `self.greetign` në shfletues (browser). +3. `self.greetign` në web workers. +4. `globalThis.greetign` në të gjitha mjediset. + +Për të shmangur këtë, ne mund të përdorim `"use strict"`. Kjo siguron që ju të keni deklaruar një variabël përpara se ta vendosni atë të barabartë (inicializoni ndonjë variabël tjetër me vlerën e saj) me ndonjë gjë. + +
++ +#### Përgjigja: A + +Kjo është e mundshme në JavaScript, spese funksionet janë objekte! (Gjithçka, përveç tipeve primitive janë objekte) + +Një funksion është një lloj i veçantë objekti. Kodi që shkruani vetë nuk është funksioni aktual. Funksioni është një objekt me veti. Kjo veti është e pavokueshme. + +
++ +#### Përgjigja: A + +Në JavaScript, funksionet janë objekte dhe për këtë arsye metoda `getFullName` i shtohet vetë objektit të funksionit të konstruktorit. Për këtë arsye, ne mund të thërrasim `Person.getFullName()`, por `member.getFullName` do të kthejë `TypeError`. + +Nëse dëshironi që një metodë të jetë e qasshme për të gjitha instancat e objektit, duhet ta shtoni atë në vetinë e quajtur "prototype": + +```js +Person.prototype.getFullName = function() { + return `${this.firstName} ${this.lastName}`; +}; +``` + +
++ +#### Përgjigja: A + +Për `sarah`, ne nuk përdorëm fjalën kyçe `new`. Kur përdorim `new`, `this` i referohet objektit të ri bosh që krijojmë. Megjithatë, nëse nuk shtoni `new`, `this` i referohet **objektit global**! + +E cekëm se `this.firstName` është `"Sarah"` dhe `this.lastName` është `"Smith"`. Çfarë bëmë realisht është se ne e definuam `global.firstName = 'Sarah'` dhe `global.lastName = 'Smith'`. `sarah` vetë mbetet `undefined`, pasi ne nuk kthejmë ndonjë vlerë nga funksioni `Person`. + +
+
+
+#### Përgjigja: D
+
+Gjatë fazës **capturing** (kapjes), eventi kalon nëpër elementet paraardhëse deri te elementi i synuar. Më pas arrin në elementin **target** (e synuar) dhe fillon **bubbling**.
+
+
+
+
+ +#### Përgjigja: B + +Të gjitha objektet kanë prototipe, me përjashtim të **objektit bazë**. Objekti bazë është objekti i krijuar nga përdoruesi, ose një objekt që krijohet duke përdorur fjalën kyçe "new". Objekti bazë ka qasje në disa metoda dhe veti, të tilla si `.toString`. Kjo është arsyeja pse ju mund të përdorni metoda të integruara të JavaScript! Të gjitha këto metoda janë të disponueshme në prototip. Megjithëse JavaScript nuk mund ta gjejë atë drejtpërdrejt në objektin tuaj, ai zbret në zinxhirin e prototipit dhe e gjen atje, gjë që e bën atë të qasshëm për ju. + +
++ +#### Përgjigja: C + +JavaScript është gjuhë e shkruar në mënyrë dinamike __dynamically typed language__: ne nuk specifikojmë se çfarë tipe janë variablat e caktuara. Vlerat mund të konvertohen automatikisht në një tip tjetër pa e ditur ju dhe ky proces quhet _implicit type coercion_ (shndërrimi i tipit në mënyrë të nënkuptuar). __Coercion__ është shndërrimi nga një tip në një tjetër. + +Në këtë shembull, JavaScript konverton numrin `1` në string, në mënyrë që për funksionin të ketë kuptim dhe të kthejë një vlerë. Përgjatë mbledhjes të një tipi number (`1`) dhe një tipi string (`'2'`), numri trajtohet si string. Ne mund ti bashkojmë stringjet si `"Hello" + "World"`, kështu që ajo që po ndodh këtu është `"1" + "2"` e cila kthen "12"`. + +
++ +#### Përgjigja: C + +**postfiks** operatori unar `++`: + +1. Kthen vlerën (kthen `0`) +2. Rrit vleren (numri tani është `1`) + +**prefiks** operatori unar `++`: + +1. Rrit vlerën (numri tani është `2`) +2. Kthen vlerën (kthen `2`) + +Prandaj rezultati që kthehet është `0 2 2`. + +
++ +#### Përgjigja: B + +Nëse përdorni literale të shabllonit (template literals) të etiketuar, vlera e argumentit të parë është gjithmonë një array vlerash stringu. Argumentet e mbetura marrin vlerat e shprehjeve të vendosura në variablat e dhëna! + +
++ +#### Përgjigja: C + +Kur testojmë barazinë, primitivet krahasohen me _vlerën_ e tyre, ndërsa objektet krahasohen me _referencën_ e tyre. JavaScript kontrollon nëse objektet kanë një referencë në të njëjtin vend në memorie. + +Dy objektet që po krahasojmë nuk e kanë këtë: objekti që kemi vendosur si parametër i referohet një vendndodhjeje të ndryshme në memorie nga objekti që kemi përdorur për të kontrolluar barazinë. + +Kjo tregon pse të dyja: `{ age: 18 } === { age: 18 }` dhe `{ age: 18 } == { age: 18 }` kthen `false`. + +
++ +#### Përgjigja: C + +Parametri "rest" (`...args`) na lejon të "mbledhim" të gjitha argumentet e mbetura në një array. Një array është një objekt, kështu që `typeof args` kthen `“objekt”` + +
++ +#### Përgjigja: C + +Me `"use strict"`, mund të siguroheni se nuk do të deklaroni variabla globale pa qëllim. Ne asnjëherë nuk e kemi deklaruar variablen `age`, dhe pasi ne e përdorim `"use strict"`, do të na kthehet një error reference. Në qoftesë nuk përdorim `"use strict"`, do të kishte funksionuar pasi vetia `age` do të ishte shtuar në objektin global. + +
++ +#### Përgjigja: A + +`eval` vlerëson kodet që i pasohen si string. Nëse është një shprehje, si në këtë rast, ajo vlerëson shprehjen. Shprehja është `10 * 10 + 5`. Kjo kthen numrin '105'. + +
++ +#### Përgjigja: B + +Të dhënat e ruajtura në `sessionStorage` largohen pasi të mbyllet _dritarja_. + +Nëse keni përdorur 'localStorage', të dhënat do të kishin mbetur aty përgjithmonë, përveç nëse për shembull thirret 'localStorage.clear()'. + +
++ +#### Përgjigja: B + +Me fjalën kyçe `var`, mund të deklaroni shumë variabla me të njëjtin emër. Më pas variabla do të mbajë vlerën e fundit të inicializuar në të. + +Ju nuk mund ta bëni këtë me 'let' ose 'const' pasi ato kanë qasje në bllok (block-scoped). + +
++ +#### Përgjigja: C + +Të gjitha çelësat e objektit (përjashto Simbolet) janë stringje në prapavijë, edhe nëse ju vetë nuk e shkruani atë si string. Kjo është arsyeja pse `obj.hasOwnProperty('1')` gjithashtu kthen vlerën true. + +Nuk funksionon në këtë mënyrë për një "set". Nuk ka asnjë `'1'` në set-in tonë: `set.has('1')` kthen `false`. Nëse ka tipin numër `1`, `set.has(1)` kthen `true`. + +
++ +#### Përgjigja: C + +Nëse keni dy çelësa me të njëjtin emër, çelësi do të zëvendësohet. Do të jetë ende në pozitën e parë, por me vlerën e fundit të specifikuar. + +
++ +#### Përgjigja: A + +Konteksti bazë i ekzekutimit është konteksti global i ekzekutimit: është ajo që është e qasshme kudo në kodin tuaj. + +
++ +#### Përgjigja: C + +Deklarata `continue` kalon një iterim nëse një kusht i caktuar kthen `true`. + +
++ +#### Përgjigja: A + +`String` është një konstruktor i integruar, të cilit mund t'i shtojmë veti. Sapo shtuam një metodë në prototipin e saj. Stringjet primitive konvertohen automatikisht në një objekt string, të gjeneruara nga funksioni i prototipit të stringut. Pra, të gjitha vargjet (objektet e stringut) kanë qasje në atë metodë! + +
++ +#### Përgjigja: B + +Çelësat e objekteve konvertohen automatikisht në stringje. Ne po provojmë të vendosim një objekt si çelës për objektin 'a', me vlerën '123'. + +Megjithatë, kur e përdorim "stringify" në një objekt, ai bëhet `"[object Object]"`. Pra, ajo që po themi këtu, është se `a["[object Object]"] = 123`. Pastaj, ne mund të provojmë të bëjmë të njëjtën gjë përsëri. `c` është një objekt tjetër që ne po e "stringify" në mënyrë implicite. Pra, atëherë, `a["[object Object]"] = 456`. + +Pastaj ne e printojmë `a[b]` e cila është `a["[object Object]"]`. We sapo e vendosëm `456` në të, prandaj edhe do të kthejë `456` + +
+
+
+#### Përgjigja: B
+
+Ne kemi një funksion "setTimeout" të cilin e thirrëm së pari. Megjithatë, ai u printua i fundit.
+
+Kjo është për shkak se në browser-a, ne nuk kemi vetëm "runtime" funksionalitet, ne gjithashtu kemi diçka që quhet `WebAPI`. `WebAPI` na jep funksionin `setTimeout` dhe poashtu për shembull DOM.
+
+Pasi _callback_ të vendoset në WebAPI, vetë funksioni "setTimeout" (por jo callback!) del nga pirgu (stack).
+
+
+
+Tani `foo` thirret dhe `"First"` do të printohet.
+
+
+
+`foo` del nga stack, dhe `baz` thirret. `"Third"` do të printohet.
+
+
+
+WebAPI nuk mund të shtojë gjëra në stack sa herë që është gati. Në vend të kësaj, ai vendos callback në diçka që quhet _queue_.
+
+
+
+Këtu fillon të funksionojë event loop. Një **event loop** shikon "stack" dhe "task queue". Nëse "stack" është bosh, ai merr gjënë e parë në radhë dhe e vendos atë në stack.
+
+
+
+`bar` thirret, `"Second"` do të printohet dhe do të largohet nga stack.
+
+
+ +#### Përgjigja: C + +Elementi më thellë i mbivendosur që shkaktoi ngjarjen është objektivi i ngjarjes. Ju mund të ndaloni bubbling me "event.stopPropagation". + +
++ Click here! +
++ +#### Përgjigja: A + +Nëse klikojmë `p`, shohim dy dalje: `p` dhe `div`. Gjatë "event propagation", ekzistojnë 3 faza: kapja, objektivi dhe flluska. Si parazgjedhje, mbajtësit e ngjarjeve (event handlers) ekzekutohen në fazën e flluskimit (përveç nëse e vendosni "useCapture" në "true"). Ai shkon nga elementi më i thellë i mbivendosur jashtë. + +
++ +#### Përgjigja: D + +Në të dy rastet, ne mund të e vendosim objektin si argument varësisht në cilin funksion dëshirojmë të referohemi me fjalën kyçe `this`. Megjithatë, `.call` gjithashtu ekzekutohet menjëherë! + +`.bind.` kthen një _kopje_ të funksionit, por me një kontekst të lidhur! Nuk ekzekutohet menjëherë. + +
++ +#### Përgjigja: B + +Funksioni `sayHi` kthen vlerën e kthyer të shprehjes së funksionit të thirrur menjëherë (IIFE). Ky funksion ktheu `0`, që është i tipit `“numër”`. + +FYI: `typeof` mund të kthejë listën e mëposhtme të vlerave: `undefined`, `boolean`, `number`, `bigint`, `string`, `symbol`, `function` dhe `object`. Vini re se `typeof null` kthen `“object”`. + +
++ +#### Përgjigja: A + +Ekzistojnë këto 8 vlera të cilat paraqesin false: + +- `undefined` +- `null` +- `NaN` +- `false` +- `''` (string i zbrazët) +- `0` +- `-0` +- `0n` (BigInt(0)) + +Konstruktorët e funksioneve, si `new Number` dhe `new Boolean` kthejnë vlerë të vërtetë (truthy). + +
++ +#### Përgjigja: B + +`typeof 1` kthen `"number"`. +`typeof "number"` kthen `"string"` + +
++ +#### Përgjigja: C + +Kur inicializoni një vlerë për një element të vargut (array) i cili e kalon gjatësinë e tij, Javascript-i krijon diçka që quhet "empty slots (vende të zbrazëta)". Këto realisht e kanë vlerën `undefined`, por ju do të shihni diçka si: + +`[1, 2, 3, empty x 7, 11]` + +varësisht ku e ekzekutoni kodin tuaj (dallon për çdo browser, node, etj.) + +
++ +#### Përgjigja: A + +Blloku `catch` merr argumentin `x`. Kjo nuk është e njëjta `x` si variabla kur ne japim argumente. Variabla `x` (në bllokun `catch`) ka shtrirje blloku (është block-scoped). + +Më vonë, ne e inicializojmë këtë variabël me shtrirje blloku të barabartë me `1` dhe inicializojmë vlerën e ndryshores `y`. Tani, ne printojmë ndryshoren me shtrirje blloku `x`, e cila është e barabartë me `1`. + +Jashtë bllokut `catch`, `x` është ende `undefined`, dhe `y` është `2`. Kur dëshirojmë të bëjmë `console.log(x)` jashtë bllokut `catch`, do të kthejë `undefined`, dhe `y` kthen `2`. + +
++ +#### Përgjigja: A + +JavaScript ka vetëm tipe primitive dhe objekte. + +Tipet primitive janë `boolean`, `null`, `undefined`, `bigint`, `number`, `string`, dhe `symbol`. + +Ajo që e dallon një tip primitiv nga një objekt është se primitivët nuk kanë asnjë veti ose metodë; megjithatë, do të vini re se `foo.toUpperCase()` vlerësohet në `'FOO'` dhe nuk rezulton në `TypeError`. Kjo ndodh sepse kur përpiqeni të qasni një veçori ose metodë në një primitive si një string, JavaScript do të mbështjellë në mënyrë implicite tipin primitiv duke përdorur një nga klasat e mbështjellësit, d.m.th. `String`, dhe më pas do ta heqë menjëherë mbështjellësin pasi të vlerësohet shprehja. Të gjithë primitivët përveç `null` dhe `undefined` e shfaqin këtë sjellje. + +
++ +#### Përgjigja: C + +`[1, 2]` është vlera jonë fillestare. Kjo është vlera me të cilën fillojmë, dhe vlera e parë e `acc`. Gjatë iterimit të parë, `acc` është `[1,2]`, dhe `cur` është `[0, 1]`. Ne i bashkojmë ato dhe kjo rezulton në `[1, 2, 0, 1]`. + +Pastaj, `[1, 2, 0, 1]` është `acc` dhe `[2, 3]` është `cur`. I bashkojmë ato dhe marrim `[1, 2, 0, 1, 2, 3]` + +
++ +#### Përgjigja: B + +`null` është false. `!null` kthen `true`. `!true` kthen `false`. + +`""` është false. `!""` kthen `true`. `!true` kthen `false`. + +`1` është e vërtetë (truthy). `!1` kthen `false`. `!false` kthen `true`. + +
++ +#### Përgjigja: A + +Kthen një id unike. Kjo id mund të përdoret për të pastruar intervalin me funksionin `clearInterval()`. + +
++ +#### Përgjigja: A + +Stringu është i iterueshëm. Operatori i përhapjes (spread operator) iteron çdo karakter të një elementi të iterueshëm në një element (në këtë rast array []). + +
++ +#### Përgjigja: C + +Funksionet e rregullta nuk mund të ndalen në mes të ekzekutimit pas thirrjes. Sidoqoftë, funksioni i gjeneratorit (generator function) mund të "ndalohet" në mes të rrugës dhe më vonë të vazhdojë nga vendi ku ndaloi. Sa herë që një funksion gjenerues ndeshet me fjalën kyçe `yield`, funksioni jep vlerën e specifikuar pas saj. Vini re se funksioni i gjeneratorit në atë rast nuk e _kthen_ (return) vlerën, por e _jep_ (yield) vlerën. + +Së pari, ne inicializojmë funksionin e gjeneratorit me `i` të barabartë me `10`. Ne thërrasim funksionin e gjeneratorit duke përdorur metodën `next()`. Herën e parë që thërrasim funksionin e gjeneratorit, `i` është i barabartë me `10`. Ai ndeshet me fjalën kyçe të parë `yield`: jep vlerën e `i`. Gjeneratori tani është `në pauzë` dhe `10` regjistrohet. + +Pastaj, ne e thirrim funksionin përsëri me metodën `next()`. Fillon dhe vazhdon aty ku ka ndaluar më parë, ende me `i` të barabartë me `10`. Tani, ai ndeshet me fjalën kyçe tjetër "yield" dhe jep `i * 2`. `i` është e barabartë me `10`, kështu që kthen `10 * 2`, që është `20`. Kjo rezulton në `10, 20`. + +
++ +#### Përgjigja: B + +Kur i kalojmë premtime (promises) të shumta metodës `Promise.race`, ajo zgjidh/refuzon premtimin _e parë_ që do të zgjidhet/refuzohet. Me metodën `setTimeout`, kalojmë një kohëmatës: 500 ms për premtimin e parë (`firstPromise`) dhe 100 ms për premtimin e dytë (`secondPromise`). Kjo do të thotë se `secondPromise`zgjidhet fillimisht me vlerën `'two'`. `res` tani mban vlerën e `'two'`, e cila printohet. + +
+
+
+#### Përgjigja: D
+
+Së pari, deklarojmë variablën `person` me vlerën e objektit i cili e ka vetinë `name`.
+
+
+
+Më pas, ne deklarojmë një variabël të quajtur `members`. E caktojmë elementin e parë të atij array të barabartë me vlerën e variablës `person`. Objektet ndërveprojnë me _referencë_ kur i vendosin të barabartë me njëri-tjetrin. Kur caktoni një referencë nga një ndryshore në tjetrën, ju bëni një _kopje_ të asaj reference. (vini re se ato nuk kanë të njëjtën referencë!)
+
+
+
+Pastaj e ri-inicializojmë variablën `person` të barabartë me `null`
+
+
+
+Ne po e modifikojmë vetëm vlerën e variblës `person`, dhe jo të elementit të parë ne array, meqenëse ai element ka një referencë të ndryshme (të kopjuar) për objektin. Elementi i parë në `members` ende mban referencën e tij ndaj objektit origjinal. Kur printojmë array `members`, elementi i parë ende mban vlerën e objektit, i cili printohet.
+
+
+ +#### Përgjigja: B + +Me unazën `for-in`, ne mund të iterojmë përgjatë çelësave të objektit, në këtë rast `name` dhe `age`. Në prapavijë, çelësat e objektit janë stringje (në qoftesë nuk janë Symbol). Në çdo unazë, ne vendosim vlerën e `item` të barabartë me çelësin aktual në të cilin po iterohet. Së pari, `item` është i barabartë me `name`, dhe printohet. Pastaj, `item` është e barabartë me `age` dhe printohet. + +
++ +#### Përgjigja: B + +Radha e veprimeve matematikore të operatorit është rendi në të cilin përpiluesi (kompajleri) vlerëson shprehjet, qoftë nga e majta në të djathtë ose nga e djathta në të majtë. Kjo ndodh vetëm nëse të gjithë operatorët kanë përparësinë _të njejtë_. Ne kemi vetëm një lloj operatori: `+`. Për më tepër, radha e veprimeve matematikore është nga e majta në të djathtë. + +`3 + 4` llogaritet së pari. Kjo rezulton në numrin `7`. + +`7 + '5'` rezulton në `"75"` për shkak të shndërrimit të tipit (coercion). JavaScript-i e konverton numrin `7` ne një string, shiko pyetjen 15. Ne mund të i bashkojmë dy stringje duke e përdorur operatorin `+`. `"7"` + `"5"` rezulton në `"75"` + +
++ +#### Përgjigja: C + +Kthehen vetëm numrat e parë në string. Bazuar në _radix (bazë)_ (argumenti i dytë për të specifikuar se në çfarë tipi duam ta parsojmë atë: bazën 10, heksadecimal, oktal, binar, etj.), `parseInt` kontrollon nëse karakteret në string janë të vlefshme. Pasi të ndeshet me një karakter që nuk është një numër i vlefshëm në bazë, ai ndalon parsimin dhe injoron karakteret e ardhshme. + +`*` nuk është numër valid. Parson vetëm `"7"` në decimal `7`. `num` tani mban vlerën `7`. + +
++ +#### Përgjigja: C + +Kur iterojmë (map-ojmë) një array, vlera e `num` është e barabartë me elementin që është duke u iteruar aktualisht. Në këtë rast, elementet janë numra, kështu që kushti i deklaratës if `typeof num === "number"` kthen `true`. Funksioni map krijon një grup të ri dhe fut vlerat e kthyera nga funksioni. + +Megjithatë, ne nuk kthejmë një vlerë. Kur nuk kthejmë një vlerë nga funksioni, funksioni kthen `undefined`. Për çdo element në array, blloku i funksionit thirret, kështu që për secilin element ne kthejmë `undefined`. + +
++ +#### Përgjigja: A + +Argumentet kalohen si _vlerë_, përveç nëse vlera e tyre është një objekt, atëherë ato kalohen si _referencë_. `birthYear` kalohet sipas vlerës, pasi është një string, jo një objekt. Kur kalojmë argumente sipas vlerës, krijohet një _kopje_ e asaj vlere (shih pyetjen 46). + +Variabla `birthYear` ka referencë në vlerën `“1997”`. Argumenti `year` gjithashtu ka referencë në vlerën `"1997"`, por nuk është e njëjta vlerë si `birthYear`. Kur përditësojmë vlerën e `year` duke vendosur `year` të barabartë me `"1998"`, ne po përditësojmë vetëm vlerën e `year`. `birthYear` është ende i barabartë me `"1997"`. + +Vlera e `person` është objekt. Argumenti `member` ka referencë (të kopjuar) për objektin e njejtë. Kur modifikojmë një veti të objektit që `member` ka një referencë, vlera e `person` gjithashtu do të modifikohet, pasi të dy kanë një referencë për të njëjtin objekt. Vetia `name` e `person` tani është e barabartë me vlerën `"Lydia"`. + +
++ +#### Përgjigja: D + +Me deklaratën `throw`, ne mund të krijojmë gabime (error) të personalizuara. Me këtë deklaratë, ju mund të bëni përjashtime. Një përjashtim mund të jetë një string, një numër, një boolean ose një objekt. Në këtë rast, përjashtimi ynë është stringy `'Hello world!'`. + +Me deklaratën `catch`, ne mund të specifikojmë se çfarë të bëjmë nëse një përjashtim hidhet në bllokun `try`. Bëhet një përjashtim: stringu `'Hello world!'`. `e` tani është e barabartë me atë string, të cilin e regjistrojmë. Kjo rezulton në `'Oh an error: Hello world!'`. + +
++ +#### Përgjigja: B + +Kur një konstruktor thirret me fjalën kyçe `new`, ai krijon një objekt dhe vendos fjalën kyçe `this` për t'iu referuar atij objekti. Si parazgjedhje, nëse konstruktori nuk kthen asgjë në mënyrë të qartë, ai do të kthejë objektin e krijuar së fundi. + +Në këtë rast, konstruktori `Car` kthen në mënyrë eksplicite një objekt të ri me `make` të vendosur në `"Maserati"`, i cili mbishkruan sjelljen e paracaktuar. Prandaj, kur thirret `New Car()`, objekti i kthyer i caktohet `myCar`, duke rezultuar në daljen `“Maserati”` kur qaset `myCar.make`. + +
++ +#### Përgjigja: A + +`let x = (y = 10);` është shkurtesë për: + +```javascript +y = 10; +let x = y; +``` + +Kur e vendosim `y` të barabartë me `10`, ne në të vërtetë e shtojmë vetinë `y` në objektin global (`window` në browser, `global` në Node). Në browser, `window.y` është tani e barabartë me `10`. + +Më pas, ne deklarojmë variablën `x` me vlerën `y`, e cila është `10`. Variablat e deklaruara me fjalën kyçe 'let' janë _block scoped_, ato përcaktohen vetëm brenda bllokut ku janë deklaruar; shprehja e funksionit të thirrur menjëherë (IIFE) në këtë rast. Kur përdorim operatorin `typeof`, operandi `x` nuk është i përcaktuar: ne po përpiqemi të qasim `x` jashtë bllokut ku ai është deklaruar. Kjo do të thotë se `x` nuk është përcaktuar. Vlerat e të cilave nuk u është caktuar një vlerë ose nuk janë deklaruar janë të tipit `"undefined"`. `console.log(typeof x)` kthen `"undefined"`. + +Megjithatë, ne krijuam një variabël globale `y` kur vendosëm `y` të barabartë me `10`. Kjo vlerë është e qasshme kudo në kodin tonë. `y` është përcaktuar dhe mban vlerën e tipit `"number"`. `console.log(typeof y)` kthen `"number"`. + +
++ +#### Përgjigja: A + +Ne mund të fshijmë veti nga objektet duke përdorur fjalën kyçe `delete`, gjithashtu në prototip. Duke fshirë një veti në prototip, ajo nuk është më e qasshme në zinxhirin e prototipit. Në këtë rast, funksioni `bark` nuk është më i qasshëm në prototip pas `delete Dog.prototype.bark`, por ne ende provojmë të i qasemi. + +Kur përpiqemi të thërrasim diçka që nuk është funksion, hidhet një 'TypeError'. Në këtë rast `TypeError: pet.bark is not a function`, pasi `pet.bark` është `undefined`. + +
++ +#### Përgjigja: D + +Objekti `Set` është një koleksion vlerash _unike_: një vlerë mund të paraqitet vetëm një herë në një grup (set). + +Vendosëm `[1, 1, 2, 3, 4]` me një vlerë dublikate `1`. Meqenëse nuk mund të kemi dy vlera të njëjta në një "set", njëra prej tyre largohet. Kjo rezulton në `{1, 2, 3, 4}`. + +
++ +#### Përgjigja: C + +Një modul i importuar mund vetëm të i lexohet vlera (_read-only_): nuk mund të modifikohet. Vetëm moduli i cili i importon ato mund të ndërrojë atë vlerë. + +Kur tentojmë të rrisim vlerën e `myCounter`, do të marrim një error: `myCounter` mundet vetëm të lexohet dhe nuk mund të modifikohet. + +
++ +#### Përgjigja: A + +Operatori "delete" kthen një vlerë booleane: `true` në fshirje të suksesshme, përndryshe do të kthejë `false`. Megjithatë, variablat e deklaruara me fjalën kyçe `var`, `const` ose `let` nuk mund të fshihen duke përdorur operatorin `delete`. + +Variabla `name` u deklarua me fjalën kyçe `const`, kështu që fshirja e saj nuk ishte e suksesshme: u kthye `false`. Kur vendosëm `age` të barabartë me `21`, ne në fakt shtuam një veti të quajtur `age` në objektin global. Ju mund të fshini me sukses vetitë nga objektet në këtë mënyrë, gjithashtu edhe objektin global, kështu që `delete age` kthen `true`. + +
+
+
+#### Përgjigja: C
+
+Ne mund të targetojmë vlerat nga vargjet ose vetitë nga objektet përmes destrukturimit. Për shembull:
+
+```javascript
+[a, b] = [1, 2];
+```
+
+
+
+Vlera `a` tani është `1`, dhe vlera `b` tani është `2`. Çfarë ne bëmë në të vërtetë në pyetje, është:
+
+```javascript
+[y] = [1, 2, 3, 4, 5];
+```
+
+
+
+Kjo do të thotë se vlera e `y` është e barabartë me vlerën e parë në array, që është numri `1`. Kur printojmë `y`, do të kthehet `1`.
+
+
+ +#### Përgjigja: B + +Është e mundur të kombinohen objektet duke përdorur operatorin e përhapjes (spread) `...`. Kjo ju lejon të krijoni kopje të çifteve çelës/vlerë të një objekti dhe t'i shtoni ato në një objekt tjetër. Në këtë rast, ne krijojmë kopje të objektit `user` dhe i shtojmë ato në objektin `admin`. Objekti `admin` tani përmban çiftet e kopjuara të çelësit/vlerës, që rezulton në `{ admin: true, emri: "Lydia", mosha: 21 }`. + +
++ +#### Përgjigja: B + +Me metodën `defineProperty`, ne mund të shtojmë veti të reja në një objekt, ose të modifikojmë ato ekzistuese. Kur shtojmë një veti në një objekt duke përdorur metodën `defineProperty`, ato janë si parazgjedhje _not enumerable_. Metoda `Object.keys` kthen të gjithë emrat e vetive _numerable_ nga një objekt, në këtë rast vetëm `"name"`. + +Vetitë e shtuara duke përdorur metodën `defineProperty` janë të pandryshueshme si parazgjedhje. Ju mund ta mbishkruani këtë sjellje duke përdorur veçoritë `writable`, `configurable` dhe `enumerable`. Në këtë mënyrë, metoda `defineProperty` ju jep shumë më tepër kontroll mbi vetitë që po i shtoni një objekti. + +
++ +#### Përgjigja: A + +Argumenti i dytë i "JSON.stringify" është _zëvendësuesi_. Zëvendësuesi mund të jetë ose një funksion ose një array, dhe ju lejon të kontrolloni se çfarë dhe si duhet të konvertohet një vlerë e JavaScript në JSON string. + +Nëse zëvendësuesi është një _array_, vetëm emrat e vetive të përfshira në array do të shtohen në stringun JSON. Në këtë rast, përfshihen vetëm vetitë me emrat `"level"` dhe `"health"`, përjashtohet `"username"`. `data` tani është e barabartë me `"{"level":19, "health":90}"`. + +Nëse zëvendësuesi është një _funksion_, ky funksion thirret në çdo veti në objektin që po e përdorni metodën 'stringify'. Vlera e kthyer nga ky funksion do të jetë vlera e vetive kur të shtohet në vargun JSON. Nëse vlera është `undefined`, kjo veti përjashtohet nga vargu JSON. + +
++ +#### Përgjigja: A + +Operatori unar `++` fillimisht kthen vlerën e operandit, pastaj e rrit vlerën e tij. Vlera e `num1` është `10`, meqenëse funksioni `increaseNumber` fillimisht kthen vlerën e `num`, e cila është `10`, dhe vetëm pastaj e rrit vlerën e `num`. + +`num2` është `10`, pasi ne e kaluam `num1` si argument tek `increasePassedNumber`. `number` është i barabartë me `10`(vlera e `num1`). Përsëri, operatori unar `++` _së pari kthen_ vlerën e operandit, dhe pastaj rrit vlerën e tij. Vlera e `number` është `10`, kështu që `num2` është e barabartë me `10`. + +
++ +#### Përgjigja: C + +Në ES6, ne mund të inicializojmë parametrat me një vlerë të paracaktuar (default). Vlera e parametrit do të jetë vlera e paracaktuar, nëse asnjë vlerë tjetër nuk i është kaluar funksionit, ose nëse vlera e parametrit është `"undefined"`. Në këtë rast, ne i shpërndajmë vetitë e objektit `value` në një objekt të ri, kështu që `x` ka vlerën e paracaktuar të `{ number: 10 }`. + +Argumenti i paracaktuar vlerësohet (llogaritet) në _kohën e thirrjes_! Sa herë që thërrasim funksionin, krijohet një objekt i ri. Ne e thërrasim funksionin `multiply` dy herët e para pa kaluar vlerën: `x` ka vlerën e paracaktuar të `{ number: 10 }`. Më pas printojmë vlerën e shumëzuar të atij numri, që është `20`. + +Herën e tretë që thërrasim funksionin `multiply`, kalojmë një argument: objektin e quajtur `value`. Operatori `*=` është në fakt shkurtesë për `x.number = x.number * 2`: ne e modifikojmë vlerën e `x.number` dhe printojmë vlerën e shumëzuar `20`. + +Herën e katërt, ne e kalojmë përsëri objektin `value`. `x.number` është modifikuar më parë në `20`, kështu që `x.number *= 2` printon `40`. + +
++ +#### Përgjigja: D + +Argumenti i parë që merr metoda `reduce` është _akumulatori_, në këtë rast `x`. Argumenti i dytë është _vlera aktuale_, `y`. Me metodën e reduktimit, ne ekzekutojmë një funksion të kthimit (callback) në çdo element në array, i cili përfundimisht mund të rezultojë në një vlerë të vetme. + +Në këtë shembull, ne nuk jemi duke kthyer ndonjë vlerë, jemi vetëm duke printuar vlerat e akumulatorit dhe vlerën aktuale. + +Vlera e akumulatorit është e barabartë me vlerën e kthyer më parë të funksionit të kthimit (callback). Nëse nuk e kaloni argumentin opsional `initialValue` në metodën `reduce`, akumuluesi është i barabartë me elementin e parë në thirrjen e parë. + +Në thirrjen e parë, akumuluesi (`x`) është `1`, dhe vlera aktuale (`y`) është `2`. Ne nuk kthehemi nga callback, ne printojmë akumuluesin dhe vlerën aktuale: `1` dhe `2` printohen. + +Nëse nuk ktheni një vlerë nga një funksion, ai kthen `undefined`. Në thirrjen tjetër, akumuluesi është `undefined` dhe vlera aktuale është `3`. `undefined` dhe `3` printohet. + +Në thirrjen e katërt, ne përsëri nuk kthehemi nga callback. Akumulatori është përsëri `undefined` dhe vlera aktuale është `4`. `undefined` dhe `4` printohen. + +
++ +#### Përgjigja: B + +Në një klasë të derivuar, ju nuk mund të përdorni fjalën kyçe `this` përpara se të e thirrni `super`. Nëse provoni ta bëni këtë, do të jap `ReferenceError`: 1 dhe 4 do të hedhin një gabim referimi. + +Me fjalën kyçe `super`, ne e thërrasim konstruktorin e asaj klase mëmë me argumentet e dhëna. Konstruktori i prindit merr argumentin `name`, kështu që ne duhet të kalojmë `name` në `super`. + +Klasa `Labrador` merr dy argumente, `name` meqenëse trashëgon klasën 'Dog', dhe `size` si një veti shtesë në klasën `Labrador`. Ata të dy duhet t'i kalojnë konstruktorit në `Labrador`, i cili implementohet saktë duke përdorur konstruktorin 2. + +
++ +#### Përgjigja: B + +Me fjalën kyçe `import`, të gjitha modulet e importuara parsohen fillimisht (_para-parsed_). Kjo do të thotë që modulet e importuara ekzekutohen _të parat_, kodi në file që importon modulin ekzekutohet _më pas_. + +Ky është një dallimi në mes `require()` në CommonJS dhe `import`! Me `require()`, mund të ngarkoni varësitë sipas kërkesës gjatë ekzekutimit të kodit. Nëse do të kishim përdorur `require` në vend të `import`, `running index.js`, `running sum.js`, `3` do të ishte printuar në tastierë. + +
++ +#### Përgjigja: A + +Çdo Symbol është tërësisht unik. Arsyeja e jepjes të argumentit në Symbol është të i jap përshkrim Symbol. Vlera e Symbol nuk është e varur nga argumenti i cili i ipet. Meqenëse po testojmë barazueshmërinë, ne jemi duke krijuar dy Symbol tërësisht të reja: `Symbol('foo')` i parë dhe `Symbol('foo)` i dytë. Të dy janë vlera unike dhe jo të barabarta me njëra tjetrën, `Symbol('foo') === Symbol('foo')` kthen `false`. + +
++ +#### Përgjigja: C + +Me metodën `padStart`, mund të shtojmë mbushje (padding) në fillim të një stringu. Vlera e kaluar në këtë metodë është gjatësia totale e stringut së bashku me mbushjen. Vargu "Lydia Hallie" ka një gjatësi prej `12` karakteresh. `name.padStart(13)` vendos 1 hapësirë në fillim të vargut, sepse 12 + 1 është 13. + +Nëse argumenti i kaluar në metodën `padStart` është më i vogël se gjatësia e array, nuk do të shtohet asnjë mbushje. + +
++ +#### Përgjigja: A + +Me operatorin `+`, ju mund të bashkoni vargjet. Në këtë rast, ne po bashkojmë stringun `"🥑"` me stringun `"💻"`, duke rezultuar në `"🥑💻"`. + +
++ +#### Përgjigja: C + +Një funksion gjenerues (generator function) "pauzon" ekzekutimin e tij kur sheh fjalën kyçe `yield`. Së pari, duhet ta lëmë funksionin të japë vargun "A ju pëlqen JavaScript?", i cili mund të bëhet duke thirrur `game.next().value`. + +Çdo rresht ekzekutohet derisa të gjejë fjalën kyçe të parë "yield". Ekziston një fjalë kyçe `yield` në rreshtin e parë brenda funksionit: ekzekutimi ndalon me yield-in e parë! _Kjo do të thotë se variabla `Përgjigja` nuk është përcaktuar ende!_ + +Kur e thërrasim `game.next("Po").value`, `yield` i mëparshëm zëvendësohet me vlerën e parametrave të kaluar në funksionin `next()`, `"Yes"` në këtë rast. Vlera e ndryshores `Përgjigja` tani është e barabartë me `"Yes"`. Kushti i deklaratës if kthehet `false`, dhe `JavaScript loves you back ❤️` printohet. + +
++ +#### Përgjigja: C + +`String.raw` kthen një varg ku karakteret speciale (`\n`, `\v`, `\t` etj.) injorohen! Vizat e pasme mund të jenë një problem pasi mund të përfundoni me diçka si: + +`const path = `C:\Documents\Projects\table.html`` + +E cila do të rezultonte në: + +`"C:DocumentsProjects able.html"` + +Me `String.raw`, vetëm do e injoronte karakterin special dhe do të printonte: + +`C:\Documents\Projects\table.html` + +Në këtë rast, `Hello\nworld` do të printohet. + +
++ +#### Përgjigja: C + +Një funksion asinkron gjithmonë kthen një "promise". `await` duhet të pres për funksionin "promise" te zgjidhjet: një "promise" në pritje do të kthehet kur e thirrim `getData()` në mënyrë që të vendosim `data` në të. + +Nëse do të dëshironim të kemi qasje në vlerën e zgjidhur `"I made it"` do të kishim përdorur metodën `.then()` në `data`: + +`data.then(res => console.log(res))` + +Kjo do të printonte `"I made it!"` + +
++ +#### Përgjigja: B + +Metoda `.push()` kthen _gjatësinë_ e vargut "array" të ri! Më parë, array përmbante një element (stringun `"banana"`) dhe kishte gjatësinë `1`. Pasi shtuam stringun `"apple"` në array, ai do të përmbajë dy elemente dhe do të ketë gjatësinë `2`. Kjo kthehet nga funksioni `addToList`. + +Metoda `push` modifikon array origjinal. Në qoftëse ju dëshironi të ktheni _array_ nga funksioni në vend të _gjatësisë së vargut_, ateherë ju duhet të ktheni `list` pasi e vendosni `item` në të. + +
++ +#### Përgjigja: B + +`Object.freeze` e bën të pamundur shtimin, largimin ose modifikimin e vetive në një objekt (përveç nëse vlera e një vetie është një objekt tjetër). + +Kur krijojmë ndryshoren `shape` dhe e vendosim të barabartë me objektin e ngrirë `box`, `shape` i referohet gjithashtu një objekti të ngrirë. Ju mund të kontrolloni nëse një objekt është i ngrirë duke përdorur `Object.isFrozen`. Në këtë rast, `Object.isFrozen(shape)` do të kthehej e vërtetë, pasi variabla `shape` ka një referencë për një objekt të ngrirë. + +Meqenëse `shape` është e ngrirë dhe meqenëse vlera e `x` nuk është një objekt, ne nuk mund të modifikojmë vetinë `x`. `x` është ende e barabartë me `10` dhe `{ x: 10, y: 20 }` do të printohet. + +
++ +#### Përgjigja: D + +Duke përdorur [sintaksen e funksioneve destruktuese](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) ne mund të targetojmë vlerat nga vargjet, ose vetitë nga objektet, në variabla të veçanta: + +```javascript +const { firstName } = { firstName: 'Lydia' }; +// versioni i ES5: +// var firstName = { firstName: 'Lydia' }.firstName; + +console.log(firstName); // "Lydia" +``` + +Gjithashtu, një veti mund të targetohet nga një objekt dhe t'i caktohet një variableje me një emër të ndryshëm nga vetia e objektit: + +```javascript +const { firstName: myName } = { firstName: 'Lydia' }; +// versioni i ES5: +// var myName = { firstName: 'Lydia' }.firstName; + +console.log(myName); // "Lydia" +console.log(firstName); // Uncaught ReferenceError: firstName is not defined +``` + +Prandaj, `firstName` nuk ekziston si variabël, kështu që tentimi për të qasur vlerën e saj do të ngrejë një `ReferenceError`. + +**Shënim:** Kujdes nga vetitë e `global scope`: + +```javascript +const { name: myName } = { name: 'Lydia' }; + +console.log(myName); // "lydia" +console.log(name); // "" ----- Browser psh. Chrome +console.log(name); // ReferenceError: name is not defined ----- NodeJS + +``` + +Kurdo që JavaScript nuk mundet të gjejë një varibël në _current scope_, ngrihet në [Scope chain](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/ch3.md) dhe kërkon për të dhe në qoftëse e arrin nivelin më të lartë të shtrirjes (the top-level scope), të quajtur __Global scope__, dhe ende nuk e gjen do të ngrejë `ReferenceError`. + +- Në __Browsers__ si _Chrome_, `name` është _vetia e shtrirjes globale e vjetëruar_. Në këtë shembull, kodi funksionon brenda _global scope_ dhe nuk ka asnjë variabël lokale të përcaktuar nga përdoruesi për `name`, prandaj ai kërkon _variables/properties_ të paracaktuara në shtrirjen globale, në këtë rast shfletuesve, ai kërkon përmes objektit `window`, dhe do të nxjerrë vlerën [window.name](https://developer.mozilla.org/en-US/docs/Web/API/Window/name) e cila është e barabartë me një varg __bosh__. +- Në __NodeJS__, nuk ka një veçori të tillë në objektin `global`, kështu që përpjekja për të iu qasur një variable joekzistente do të ngrejë një [ReferenceError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Not_defined). + +
++ +#### Përgjigja: A + +Një funksion është gjithmonë funksion i pastër nëse sa herë që i kalojmë argumente të njëjta gjithmonë kthen rezultatin e njëjtë. + +Funksioni `sum` _gjithmonë_ kthen të njëjtin rezultat. Nëse i kalojmë `1` dhe `2`, gjithmonë do të kthejë `3` pa ndonjë efekt anësorë. Nëse i kalojmë `5` dhe `10`, gjithmonë do të kthejë `15`, e kështu me radhë. Ky është definicioni i një funksioni të pastër. + +
++ +#### Përgjigja: C + +Funksioni `add` është një funksion _memoized_. Me memoizim, ne mund të ruajmë rezultatet e një funksioni në mënyrë që të përshpejtojmë ekzekutimin e tij. Në këtë rast, ne krijojmë një objekt `cache` që ruan vlerat e kthyera më parë. + +Nëse e thirrim sërish funksionin `addFunction` me të njëjtin argument, ai fillimisht kontrollon nëse e ka marrë tashmë atë vlerë në cache-in e tij. Nëse është kështu, vlera e caches do të kthehet, e cila kursen kohën e ekzekutimit. Përndryshe, nëse nuk është i ruajtur në memorie, ai do të llogarisë vlerën dhe do ta ruajë atë më pas. + +Ne e thirrim funksionin `addFunction` tre herë me të njëjtën vlerë: në thirrjen e parë, vlera e funksionit kur `num`" është e barabartë me `10` nuk është ruajtur ende në memorie. Kushtëzimi if `num in cache` kthen `false`, dhe blloku else ekzekutohet: `Calculated! 20` printohet dhe vlera e rezultatit i shtohet objektit të cache-it. `cache` tani duket si `{ 10: 20 }`. + +Herën e dytë, objekti `cache` përmban vlerën që kthehet për `10`. Kushtëzimi if `num in cache` kthen `true`, dhe `'From cache! 20'` printohet. + +Herën e tretë, ne kalojmë `5 * 2` te funksioni i cili llogaritet si `10`. Objekti `cache` përmban vlerën që kthehet për `10`. Kushtëzimi if `num in cache` kthen `true`, dhe `'From cache! 20' printohet. + +
++ +#### Përgjigja: A + +Me unazën _for-in_, ne mund të iterojmë në vetitë _e numërueshme_. Në një array, vetitë e numërueshmë janë "çelësat" e elementeve të array, të cilët janë në të vërtetë indekset e tij. Mund të shikoni array si: + +`{0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}` + +Ku çelësat janë vetitë e numërueshme. `0` `1` `2` `3` printohet. + +Me unazën _for-of_, ne mund të iterojmë mbi __iterables__. Një array është një "iterable". Kur iterojmë mbi array, variabla "item" është e barabartë me elementin mbi të cilin po iterojmë aktualisht, "☕"` `"💻"` `"🍷"` `"🍫"` printohet. + +
++ +#### Përgjigja: C + +Elementet e array mund të mbajnë çfarë vlere. Numra, stringje, objekte, array të tjerë, null, vlera boolean-e, undefined, dhe shprehje të tjera si data, funksione dhe kalkulime. + +Elementi do të jetë i barabartë me vlerën e kthyer. `1 + 2` kthen `3`, `1 * 2` kthen `2` dhe `1 / 2` kthen `0.5`. + +
++ +#### Përgjigja: B + +Paraprakisht, argumentet kane vlerën `undefined`, përveç në qoftëse ndonjë vlerë i kalohet në funksion. Në këtë rast, ne nuk e kaluam ndonjë vlerë për argumentin `name`. `name` është e barabartë me `undefined` e cila edhe printohet. + +Në ES6, ne mund të mbishkruajmë këtë vlerë paraprake `undefined` me parametër të definuar paraprakisht. Për shembull: + +`function sayHi(name = "Lydia") { ... }` + +Në këtë rast, nëse ne nuk kalojmë ndonjë vlerë ose e kalojmë `undefined`, `name` do të ishte gjithmonë i barabartë me stringun `Lydia`. + +
++ +#### Përgjigja: B + +Vlera e fjalës kyçe `this` varet nga vendi ku e përdorni. Në një __metodë__, si metoda `getStatus`, fjala kyçe `this` i referohet _objektit që i përket metoda_. Metoda i përket objektit `data`, kështu që `this` i referohet objektit `data`. Kur printojmë `this.status`, vetia `status` në objektin `data` printohet, që është `"🥑"`. + +Me metodën `call`, ne mund të ndryshojmë objektin të cilit i referohet fjala kyçe `this`. Në __funksione__, fjala kyçe `this` i referohet _objektit të cilit i përket funksioni_. Ne deklaruam funksionin `setTimeout` në objektin _global_, kështu që brenda funksionit `setTimeout`, fjala kyçe `this` i referohet objektit _global_. Në objektin global, ekziston një variabël e quajtur _status_ me vlerën `"😎"`. Kur printoni `this.status`, `"😎"` printohet. + +
++ +#### Përgjigja: A + +0Vendosëm variablën `city` të barabartë me vlerën e vetisë të quajtur `city` në objektin `person.`. Në objekt nuk ka ndonjë veti e cila quhet `city`, kështu që variabla `city` ka vlerën `undefined`. + +Vini re, ne _nuk_ jemi duke iu referuar objektit `person`! Ne vetëm e vendosëm variablën `city` të barabartë me vlerën aktuale të vetisë `city` në objektin `person`. + +Pastaj, ne vendosëm `city` të barabartë me stringun `"Amsterdam"`. Kjo nuk e ndryshon objektin person: nuk ka ndonjë referencë tek ai objekt. + +Kur printojmë objektin `person`. objekti i pamodifikuar kthehet. + +
++ +#### Përgjigja: C + +Variablat e deklaruara me fjalët kyçe `const` dhe `let` janë të qasshme vetëm në bllokun ku shtrihen (_block-scoped_). Një bllok quhet gjithçka që gjendet brenda kllapave gjarpërore (`{ }`). Në këtë rast, kllapat gjarpërore e deklarimeve if/else. Nuk mund të i referencohemi një variable jashtë bllokut ku është deklaruar, sepse do të ngrihet ReferenceError. + +
++ +#### Përgjigja: C + +Vlera e `res` në `.then` të dytë do të jetë e barabartë me vlerën e kthyer në `.then` paraprak. You mund të bëni `.then`-ë të tjerë si në shembull, ku vlera do të kalohet në trajtuesin tjetër. + +
++ +#### Përgjigja: A + +Me `!!name`, ne vendosim në qoftëse vlera e `name` është e vërtetë osë false. Nëse "name" është e vërtetë, për të cilën duam të testojmë, `!name` kthen `false`. `!false` (e cila është vlera të cilën `!!name` ka) kthen `true`. + +Kur vendosim `hasName` të barabartë me `name`, ju vendosni `hasName` të barabartë me çdo vlerë të cilën e kaloni si arguemnt tek funksioni `getName`, jo vlera boolean-e `true`. + +`new Boolean(true)` kthen një mbështjellës së objektit, jo vetë vlerën boolean-e. + +`name.length` kthen gjatësinë e argumentit të kaluar, jo në qoftëse është `true` ose jo. + +
++ +#### Përgjigja: B + +Në mënyrë që të marrim karakterin në një indeks specifik në string, mund të përdorimin notacionin e kllapave të mëdha "[]". Karakteri i parë në string ka indeksin 0, dhe kështu me rradhë. Në këtë rast, ne duam të marrim elementin me indeks 0, karakterin `"I"`, i cili printohet. + +Vini re se kjo metodë nuk suportohet në IE7 e më poshtë. Në këtë rast përdorni `.charAt()`. + +
++ +#### Përgjigja: B + +Ne mund të përcaktojmë një vlerë paraprakisht të barabartë me ndonjë parametër tjetër të funksionit, përderisa ato janë të deinuara përpara vlerës së paradefinuar. Ne e kalojmë vlerën `10` tek funksioni `sum`. Nëse funksioni `sum` pranon vetëm një argument, do të thotë se vlera për `num2` nuk është kaluar, dhe vlera e `num1` është e barabartë me vlerën `10` e cila ka kaluar si argument në këtë rast. Vlera e paradefinuar e `num2` është vlera e `num1`, e cila është `10`. `num1 + num2` kthen `20`. + +Në qoftëse provoni të vendosni një vlerë të paradefinuar të barabartë me një parametër i cili definohet _pastaj_ (në të djathë), vlera e parametrit nuk do të jetë e inicializuar ende, e cila do të kthejë një error. + +
++ +#### Përgjigja: A + +Me sintaksën `import * as name`, ne importojmë _të gjithë eksportet_ nga fajlli `module.js` në `index.js` si një objekt i ri i cili quhet `data` i cili krijohet. Në `module.js`, gjenden dy eksporta: eksporti i paracaktuar dhe një eksport i emërtuar. Eksporti i paracaktuar është funksion i cili kthen stringun `Hello World`, dhe esksporti i emëruar është variabla e quajtur `name` e cila ka vlerën e stringut `"Lydia"`. + +Objekti `data` ka një veti `default` për eksportin e paracaktuar, vetitë e tjera kanë emrat e eksporteve të emëruara dhe vlerat e tyre korrespoduese. + +
++ +#### Përgjigja: C + +Klasat janë si sintaksë që është krijuar për t'i bërë gjërat më të lehta për t'u lexuar ose për t'u shprehur për funksionet e konstruktorëve. Ekuivante e klasës `Person` si funksion kontruktorë do të ishte: + +```javascript +function Person(name) { + this.name = name; +} +``` + +Thirrja e një konstruktori me `new` rezulton në krijimin e një instance të `Person`, `typeof` do të kthejë `"object"` për një instancë. `typeof member` kthen `"object"`. + +
++ +#### Përgjigja: D + +Metoda `.push` kthen _gjatësinë e re_ të array, jo vetë array! Duke vendosur `newList` të barabartë me `[1, 2, 3].push(4)`, e vendosim `newList` të barabartë me gjatësinë e re të array: `4`. + +Pastaj, ne provojmë të përdorim metodën `.push` në `newList`. Meqenëse `newList` është vlera numerike e `4` ne nuk mund të përdorim metodën `.push`: do të ngrihet TypeError. + +
++ +#### Përgjigja: D + +Funskionet e rregullta, të tillë si funksioni `giveLydiaPizza`, kanë vetinë `prototype`, e cila është një objekt (veti e objektit) me veti `constructor`. Funksionet shigjetë (arrow functions) sidoqoftë, të tilla si funskioni `giveLydiaChocolate`, nuk e kanë këtë veti `prototype`. Kur tentojmë të i qasemi vetisë `prototype` duke pëdorur `giveLydiaChocolate.prototype` do të na kthehet `undefined`. + +
++ +#### Përgjigja: A + +`Object.entries(person)` kthen një array me array të ndërthurur, i cili përmban çelësat dhe objektet: + +`[ [ 'name', 'Lydia' ], [ 'age', 21 ] ]` + +Përdorimi i unazës `for-of`, na mundëson iterimin në secilin element në array, dhe nën array në këtë rast. Ne mund të destrukturojmë nën array menjëherë në unazën for-of, duke përdorur `const [x, y]`. `x` është e barabartë me elementin e parë në nën array, `y` është e barabartë me elementin e dytë në nën array. + +Nën array i parë është `["name", "Lydia"]`, me `x` të barabartë me `"name"`, dhe `y` të barabartë me `"Lydia"`, e cila printohet. Nën array i dytë është `["age", 21 ]`, me `x` të barabartë me `"age"`, dhe `y` të barabartë me `21`, e cila printohet. + +
++ +#### Përgjigja: D + +`...args` është "rest" parametër. Vlera e "rest" parametrit është një array i cili përmban të gjitha argumentet e mbetura, **dhe mund të jetë vetëm parametri i fundit**! Në këtë shembull, "rest" parametri ishte parametri i dytë. Kjo nuk është e mundur, dhe do të ngrisë gabim sintaksorë. + +```javascript +function getItems(fruitList, favoriteFruit, ...args) { + return [...fruitList, ...args, favoriteFruit]; +} + +getItems(['banana', 'apple'], 'pear', 'orange'); +``` + +Shembulli i mësipërm funskionon. Do të kthejë array `[ 'banana', 'apple', 'orange', 'pear' ]` + +
++ +#### Përgjigja: B + +Në JavaScript, nuk e duhet të e shkruajmë pikëpresjen `;` në mënyrë eksplicite, sidoqoftë makina e JavaScript prapë i vendos ato pas deklarimeve. Kjo quhet __Automatic Semicolon Insertion__ (vendosja e pikëpresjes automatikisht). Një deklaratë për shembull mund të jetë variabla, ose fjalët kyçe si `throw`, `return`, `break` etj. + +Në këtë rast, ne shkruajtëm deklaratën `return`, dhe vlerën tjetër `a + b` në rresht të ri. Sidoqoftë, meqenëse është rresht i ri, makina nuk e di se në të vërtetë ajo është vlera që ne po dëshirojmë të kthejmë. Në vend se të e llogarisë në atë mënyrë, në mënyrë automatike vendoset `return`. Kjo mund të shikohet edhe si kjo sintaksë: + +```javascript +return; +a + b; +``` + +Kjo do të thotë se `a + b` nuk arrihet asnjëherë, meqenëse funksioni ndalon ekzekutimin pas fjalës kyçe `return`. Nëse asnjë vlerë nuk kthehet si në këtë rast, funksioni kthen `undefined`. Vini re se nuk ka ndonjë përfshirje automatike pas deklarimit `if/else` + +
++ +#### Përgjigja: B + +Ne mund të iu shoqërojmë klasave konstruktorët e tjerë të klasave/funksioneve. Në këtë rast, ne vendosim `Person` të barabartë me `AnotherPerson`. Emri në këtë konstruktor është `Sarah`, kështu që vetia e emrit në instancën e re `Person`, `member` është `“Sarah”`. + +
++ +#### Përgjigja: D + +Një Symbol nuk është i _numërueshëm_. Metoda Object.keys kthen të gjithë çelësat e _numërueshëm në një objekt. Symbol nuk do të jetë i dukshëm, dhe një array i zbrazët do të kthehet. Kur e printojmë objektin në tërësi, të gjitha vetitë janë të dukshme, edhe ato të cilat nuk janë te numërueshme. + +Kjo është vetëm një nga shumë vetitë e symbol, përveç përfaqësimit të një vlere krejtësisht unike (e cila parandalon konflikt në emërtim të objekteve, për shembull kur punoni me 2 librari që duan të shtojnë vetitë në të njëjtin objekt), ju gjithashtu mund të "fshehni" vetitë e objekteve në këtë mënyrë (edhe pse jo plotësisht. Ju mund t'i qaseni simboleve duke përdorur metodën `Object.getOwnPropertySymbols()`). + +
++ +#### Përgjigja: A + +Funksioni `getList` merr një array si argument. Brenda kllapave të funksionit `getList`, ne e destrukturojmë ketë array në mënyrën e duhur. Kjo mund të shihet edhe si: + +`[x, ...y] = [1, 2, 3, 4]` + +Me "rest" parametrin `...y`, ne i vendosim argumentet "e mbetura" në një array. Argumentet e mbetura janë `2`, `3` dhe `4` në këtë rast. Vlera e `y` është një array, i cili i përmban të gjithë parametrat e mbetur. Vlera e `x` është e barabartë me `1` në këtë rast kur e printojmë `[x, y]`, printohet `[1, [2, 3, 4]]`. + +Funskioni `getUser` merr një objekt. Me funksionet shigjetë (arrow function), ne nuk kemi nevojë të shkruajmë kllapat gjarpërore nëse vetëm dëshirojmë të kthejmë një vlerë. Sidoqoftë, nëse dëshironi që në mënyrë instante të ktheni një objekt nga një arrow funksion, mund të e shkruani brenda kllapave të vogla "()", përndryshe çdo gjë mes dy kllapave do të interpretohet si një deklaratë blloku. Në këtë rast kodi në mes të kllapave nuk është kod valid i JavaScript, kështu që do të ngrihet `SyntaxError`. + +Funskioni i meposhtëm do të kthente një objekt: + +`const getUser = user => ({ name: user.name, age: user.age })` + +
++ +#### Përgjigja: C + +Variabla `name` mban vlerën e një stringu, i cili nuk është funksion, prandaj nuk mund të thirret si i tillë. + +TypeErrors do të ngrihen kur një vlerë nuk është e tipit që pritet. JavaScript pret që `name` të jetë një funksion meqenëse po provojmë të e thirrim atë. Sidoqoftë është një string, prandaj do të marrim TypeError: "name" nuk është një funksion. + +SyntaxErrors do të ngrihen kur ne shënojmë diçka e cila nuk është valide në JavaScript, për shembull kur e shënojmë fjalën `return` si `retrun`. +ReferenceErrors ngrihen kur Javascript-i nuk është në gjendje të gjejë referencë tek një vlerë të cilën ne provojmë të i qasemi. + +
++ +#### Përgjigja: B + +`[]` është vlerë "truthy". Me operatorin `&&`, vlera në anën e djathtë do të kthehet nëse vlera në anën e majtë është vlerë "truthy". Në këtë rast, vlera në anën e majtë `[]` është vlerë "truthy" prandaj `"Im"` do të kthehet. + +`""` është vlerë "falsy". Nësë ana e majtë është falsy, asgjë nuk kthehet. `n't` nuk do të kthehet. + +
++ +#### Përgjigja: C + +Me operatorin `||`, ne mund të kthejmë vlerën e parë "truthy" të operandit. Nëse të gjitha vlerat janë "falsy", operandi i fundit do të kthehet. + +`(false || {} || null)`: objekti i zbrazët `{}` është vlerë "truthy". Ky është i pari dhe i vetmi vlerë "truthy", i cili kthehet. `one` është i barabartë me `{}`. + +`(null || false || "")`: të gjithë operandët janë vlera "falsy". Kjo do të thotë se operandi i fundit, `""` do të kthehet. `two` është i barabartë me `""`. + +`([] || 0 || "")`: array i zbrazët `[]` është vlerë "truthy". Kjo është vlera e parë "truthy" e cila kthehet. `three` është e barabartë me `[]`. + +
++ +#### Përgjigja: D + +Me një premtim, në thelb themi _Dëshiroj ta ekzekutoj këtë funksion, por do të e lë mënjanë për momentin ndërsa është duke u ekzekutuar pasi kjo mund të marrë pak kohë. Vetëm kur një vlerë e caktuar zgjidhet (ose refuzohet) dhe kur "call stack" është bosh, unë dua ta përdor këtë vlerë._ + +Ne mund të marrim këtë rezultat me të dy: `.then` dhe fjalën kyçe `await` në `async` funksione. Edhe pse mund të marrim vlerën e 'promise' me të dy `.then` dhe `await` ato funksionojnë pak më ndryshe. + +Në funksionin e parë `firstFunction`, në një mënyrë e vendosim funksionin 'myPromise' mënjanë përgjatë ekzekutimit, por ne e vazhdojmë ekzekutimin e kodit tjetër, i cili në këtë rast është `console.log('second')`. Pastaj, funksioni zgjidhet me stringun `I have resolved`, i cili pastaj printohet pasi që e sheh se call stack është i zbrazët. + +Me fjalën kyçe `secondFunction`, në të vërtetë e pauzojmë ekzekutimin e funksionit async derisa vlera të zgjidhet përpara se të vazhdojmë tek rreshti tjetër. + +Kjo do të thotë se pret për `myPromise` të zgjidhet me vlerën `I have resolved`, dhe pasi ajo të ndodhë ne vazhdojmë ne rreshtin e ardhshëm: `second` do të printohet. + +
++ +#### Përgjigja: C + +Operatori `+` nuk përdoret vetëm vetëm për të mbledhur vlerat numberike, por mund të e përdorim për bashkimin e stringjeve. Sa herë që makina e JavaScript e vëren se një ose më shumë vlera nuk janë numra, e shndërron numrin në string. + +Ne fillim është `1` i cili është vlerë numerike. `1 + 2` kthen numrin 3. + +Megjithatë, vlera e dytë është string `"Lydia"`. `"Lydia"` është string dhe `2` është numër: `2` shndërrohet në string. `"Lydia"` dhe `"2"` bashkohen, dhe kjo rezulton në stringun `"Lydia2"`. + +`{ name: "Lydia"}` është objekt. Nuk është as numër as objekt është string, prandaj i konsideron si stringje të dyja. Sa herë që i konsiderojmë si stringje objektet e zakonshme, behet `"[object Object"]`.`"[object Object"]` bashkohet me `"2"` dhe bëhet `"[object Object]2"`. + +
++ +#### Përgjigja: C + +Ne mund të kalojmë qfarëdo vlere që duam te `Promise.resolve`, 'promise' ose 'jo-promise'. Metoda vetë kthen një 'promise' e cila zgjidhet me vlerën (`fulfilled`). Nëse i kaloni një funksion të zakonshëm, do të zgjidhet një promise me një vlerë të zakonshme. Nëse i kaloni një 'promise' si argument, do të zgjidhjet një promise me vlerën e zgjidhur me vlerën që i kalohet si promise. + +Në këtë rast, ne vetëm i kaluam si argument vlerën numerike `5`. Kthen promise të zgjidhur me vlerë `5`. + +
++ +#### Përgjigja: B + +Objektet vendosen si argumente në bazë të referencës së tyre. Kur i kontrollojmë objektet me operatorin për barazim strikt (`===`), ne po kontorllojmë referencën e tyre. + +Ne e paracaktuam vlerën e `person2` të barabartë me objektin `person`, dhe e kaluam objektin `person` si vlerë të `person1`. + +Kjo do të thotë që të dy vlerat kanë referencë të e njejta hapësirë memorike, dhe kështu ato janë të barabarta. + +Blloku i kodit në deklarimin `else` ekzekutohet dhe `They are the same!` printohet. + +
++ +#### Përgjigja: D + +Në JavaScript, kemi dy mënyra për të iu qasur vetive të një objekti: notacioni me kllapa të mëdha "[]" ose notacioni me pikë ".". Në këtë shembull ne po e perdorim notacionin (`colorConfig.colors`) në vend të notacionit me kllapë (`colorConfig["colors"]`). + +Me notacionin me pikë, JavaScript provon të gjejë veti në objekt me saktësisht të njejtin emër. Në këtë shembull, JavaScript provon të gjejë një veti e cila quhet `colors` në objektin `colorConfig`. Nuk ka ndonjë veti të quajtur `colors`, prandaj kjo do të kthejë `undefined`. Pastaj ne provojmë të i qasemi vlerës së elementit të parë ne array duke përdorur `[1]`. Nuk mund të e bëjmë këtë në vlerën e cila është `undefined`, prandaj do të ngrihet `TypeError`: `Cannot read property '1' of undefined`. + +JavaScript i interpreton deklarimet. Kur përdorim notacionin me kllapa të mëdha, e sheh kllapën hapëse `[` dhe vazhdon kërkon derisa të gjen kllapën mbyllëse `]`. Vetëm atëherë, e llogarit deklarimin. Nëse do të përdornim `colorConfig[colors[1]]`, do të kishte kthyer vlerën e vetisë `red` në objektin `colorConfig`. + +
++ +#### Përgjigja: A + +Në prapavijë, emoji-t janë kode të veçanta. Unikodet për emoji-t e zemrës janë `"U+2764 U+FE0F"`. Këto janë gjithmonë të njëjta për të njëjtat emoji, kështu që ne po krahasojmë dy stringje të barabarta me njëri-tjetrin, gjë që ktheh 'e vërtetë'. + +
++ +#### Përgjigja: D + +Me motodën `splice`, ne modifikojmë array origjinal duke fshirë, zëvendësuar ose shtuar elemente. Në këtë rast, ne larguam 2 gjëra duke filluar nga indeksi 1 ( larguam `'🥑'` dhe `'😍'`) dhe shtuam ✨ në vend të tyre. + +`map`, `filter` dhe `slide` kthen array të ri, `find` kthen një element dhe `reduce` kthen një vlerë të reduktuar. + +
++ +#### Përgjigja: A + +Ne vendosëm vlerën e vetisë `favoriteFood` në objektin `info` të barabartë me stringun me emoji-n e picës, `'🍕'`. Një string është një tip i të dhënave primitive. Në JavaScript, tipet primitive të të dhënave nuk ndërveprojnë me referencë. + +Në JavaScript, tipet primitive të të dhënave (gjithçka që nuk është objekt) ndërveprojnë me _vlerë_. Në këtë rast, ne vendosim vlerën e vetisë `favoriteFood` në objektin `info` të barabartë me vlerën e elementit të parë në array `food`, stringu me emoji-n e picës në këtë rast (`'🍕'`). Një string është një tip i të dhënave primitive dhe ndërvepron sipas vlerës (shikoni [blogpost](https://www.theavocoder.com/complete-javascript/2018/12/21/by-value-vs-by-reference) nëse jeni të interesuar të mësoni më shumë) + +Më pas, ne ndryshojmë vlerën e vetisë `favoriteFood` në objektin `info`. Vargu `food` nuk ka ndryshuar, pasi vlera e `favoriteFood` ishte thjesht një _kopje_ e vlerës së elementit të parë në grup dhe nuk ka një referencë për të njëjtin vend në memorie si elementi në `food[0]`. Kur printojmë 'food', është ende array origjinal, "['🍕", "🍫", "🥑", "🍔"]". + +
++ +#### Përgjigja: A + +Me metodën `JSON.parse()`, ne mund të parsojmë JSON stringun në një vlerë JavaScript-i. + +```javascript +// Stringifimi i një numri në një JSON valid, pastaj parsimi i nje4 stringu në vlerë të JavaScript: +const jsonNumber = JSON.stringify(4); // '4' +JSON.parse(jsonNumber); // 4 + +// Stringifimi i një array në JSON valid, pastaj parsimi i JSON stringut ne një vlerë të JavaScript: +const jsonArray = JSON.stringify([1, 2, 3]); // '[1, 2, 3]' +JSON.parse(jsonArray); // [1, 2, 3] + +// Stringifimi i një objekti në JSON valid, pastaj parsimi i JSON stringut në një vlerë të JavaScript: +const jsonArray = JSON.stringify({ name: 'Lydia' }); // '{"name":"Lydia"}' +JSON.parse(jsonArray); // { name: 'Lydia' } +``` + +
++ +#### Përgjigja: D + +Secili funksion ka _kontekstin e vetë të ekzekutimit_. Funksioni `getName` së pari shikon brenda kontekstit të tij në qoftëse përmban variablën `name` të cilën po provojmë të i qasemi. Në këtë rast, funksioni `getName` përmban variablën e tij `name`: e deklaruam variablën `name` me fjalën kyçe `let`m dhe i inicializuam vlerën `'Sarah'`. + +Variablat me fjalën kyçe `let` (dhe `const`) ngriten (hoistoh-en), por për dallim nga `var` nuk inicializohen. Ato nuk janë të qasshme më herët se rreshti në të cilin janë deklaruar (i kemi deklaruar). Kjo quhet "zona e vdekur e përkohshme" (temporal dead zone). Kur tentojmë të i qasemi variablave përpara se ato të deklarohen, JavaScript hedh `ReferenceError`. + +Nëse nuk do të kishim deklaruar `name` brenda funksionit `getName`, makina e JavaScript do të kishte shikuar poshtë _zingjirit të shtrirjes_. Fusha e jashtme ka variabël të quajtur `name` me vlerë `Lydia`. Në këtë rast, do të kishte printuat `Lydia`. + +```javascript +let name = 'Lydia'; + +function getName() { + console.log(name); +} + +getName(); // Lydia +``` + +
++ +#### Përgjigja: C + +Me fjalën kyçe `yield`, ne i japim vlerat në një funksion gjenerator. Me fjalën kyçe `yield*`, ne mund të nxjerrim vlera nga një funksion tjetër gjenerues, ose objekt i iterueshëm (për shembull një array). + +Në `generatorOne`, ne japim të gjithë array `['a', 'b', 'c']'` duke përdorur fjalën kyçe `yield`. Vlera e vetisë `value` në objektin e kthyer me metodën `next` në `one` (`one.next().value`) është e barabartë me të gjithë grupin `['a', 'b', 'c']`. + +```javascript +console.log(one.next().value); // ['a', 'b', 'c'] +console.log(one.next().value); // undefined +``` + +Në `generatorTwo`, ne përdorim fjalën kyçe `yield*`. Kjo do të thotë se vlera e parë e dhënë e `two`, është e barabartë me vlerën e dhënë në iterimin e parë. Iteratori është grupi `['a', 'b', 'c']`. Vlera e parë e dhënë është `a`, kështu që herën e parë që thërrasim `two.next().value`, kthehet `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 +``` + +
++ +#### Përgjigja: A + +Shprehjet brenda shablloneve literale vlerësohen së pari. Kjo do të thotë që stringu do të përmbajë vlerën e kthyer të shprehjes, funksionin e thirrur menjëherë `(x => x)('I love')` në këtë rast. Ne e kalojmë vlerën `'I love'` si argument në funksionin e shigjetës `x => x`. `x` është e barabartë me `'I love'`, e cila kthehet. Kjo rezulton në `I love to program`. + +
++ +#### Përgjigja: C + +Zakonisht kur i vendosim objektet të barabarta me `null`, ato objekte mirren nga _garbage collector_ pasi nuk ka më referencë për ato objekte. Megjithatë, meqenëse funksioni callback brenda `setInterval` është një funksion me shigjetë (pra i lidhur me objektin `config`), funksioni callback ende mban një referencë për objektin `config`. +Për sa kohë ka një referencë, objekti nuk do të merret nga 'garbage collector' (menaxhuesi i memories për të u larguar). +Meqenëse ky është një interval, vendosja e `config` në '`null` ose `delete` `config.alert` nuk do të mbledhet nga garbage-collector për intervalin, kështu që intervali do të vazhdojë të thirret. +Për ta hequr nga memoria duhet të e pastrojmë me `clearInterval(config.alert)`. +Meqenëse nuk u fshi, funksioni `setInterval` callback do të vazhdojë të thirret çdo 1000ms (1s). + +
++ +#### Përgjigja: B + +Kur shtoni një çift çelës/vlerë duke përdorur metodën `set`, çelësi do të jetë vlera e argumentit të parë që i kalohet funksionit `set`, dhe vlera do të jetë argumenti i dytë që i kalohet funksionit `set`. Çelësi është _functioni_ `() => 'greeting'` në këtë rast, dhe vlera `'Hello world'`. `myMap` tani është `{ () => 'greeting' => 'Hello world!' }`. + +1 është gabim, pasi çelësi nuk është `'greeting'` por `() => 'greeting'`. +3 është gabim, pasi ne po krijojmë një funksion të ri duke e kaluar atë si parametër në metodën `get`. Objekti ndërvepron me _referencë_. Funksionet janë objekte, prandaj dy funksione nuk janë kurrë rreptësisht të barabarta, edhe nëse janë identike: ato kanë një referencë në një vend të ndryshëm në memorie. + +
++ +#### Përgjigja: C + +Të dy funksionet `changeAge` dhe `changeAgeAndName` kanë një parametër të paracaktuar, përkatësisht një objekt të krijuar rishtazi `{...person}`. Ky objekt ka kopje të të gjithë çelësave/vlerave në objektin `person`. + +Së pari, e thirrim funksionin `changeAge` dhe e kalojmë objektin `person` si argument. Ky funksion rrit vlerën e vetisë `age` për 1. `person` tani është `{ name: "Lydia", age: 22 }`. + +Pastaj, e thirrim funksionin `changeAgeAndName`, sidoqoftë ne nuk e kalojmë një parametër. Në vend të kësaj, vlera e `x` është e barabartë me objektin e ri `{ ...person }`. Meqenëse është një objekt i ri, nuk do të afektojë vlerën e vetive në objektin `person`. `person` ende është e barabartë me `{ name: "Lydia", age: 22 }`. + +
++ +#### Përgjigja: C + +Me operatorin spread `...`, me mund të _përhapim_ iteruesit në elemente individuale. Funksioni `sumValues` merr tre argumente: `x`, `y` dhe `z`. `...[1, 2, 3]` do të rezultojë në `1, 2, 3`, të cilin ia kalojmë funksionit `sumValues`. + +
++ +#### Përgjigja: B + +Me operandin `+=`, ne po rrisim vlerën e `sum` për `1`. `num` kishte vlerën iniciale `1`, kështu `1 + 1` është `2`. Elementi në indeksin e dytë në `list` është 🥰, `console.log(list[2])` printon 🥰. + +
++ +#### Përgjigja: B + +Me operatorin opsional të zinxhirit `?.`, nuk duhet të kontrollojmë më në mënyrë eksplicite nëse vlerat më të thella të ndërthurura janë të vlefshme apo jo. Nëse po provojmë ti qasemi një vetie me një vlerë `undefined` ose `null` (_nullish_), shprehja lidhet me qark të shkurtër dhe kthen `undefined`. + +`person.pet?.name`: `person` ka një veti të quajtur `pet`: `person.pet` nuk është vlerë null. Ka një veti të quajtur `name`, dhe kthen `Mara`. +`person.pet?.family?.name`: `person` ka një veti të quajtur `pet`: `person.pet` nuk është vlerë null. `pet` nuk ka një veti të quajtur `family`, `person.pet.family` është vlerë null. Shprehja kthen `undefined`. +`person.getFullName?.()`: `person` ka një veti të quajtur `getFullName`: `person.getFullName()` nuk është vlerë null dhe mund të thirret, dhe do të kthejë `Lydia Hallie`. +`member.getLastName?.()`: variabla `member` nuk ekziston prandaj `ReferenceError` do të hedhet! + +
++ +#### Përgjigja: B + +Ne e kaluam kushtëzimin `groceries.indexOf("banana")` tek deklarimi if. `groceries.indexOf("banana")` kthen `0`, e cila është vlerë false. Përderisa deklarimi i kushtëzimit if është falsy, kodi në bllokun `else` ekzekutohet, dhe `We don't have to buy bananas!` do të printohet. + +
++ +#### Përgjigja: D + +Metoda `language` është metodë `setter` (vendosëse). Vendosësit nuk mbajë një vlerë aktuale, qêllimi i tyre është të _modifikojnë_ vetitë. Kur e thirrim metodën `setter`, do të kthehet `undefined`. + +
++ +#### Përgjigja: C + +`typeof name` kthen `"string"`. Stringu `"string"` është vlerë truthy, kështu që `!typeof name` kthen vlerën booleane `false`. `false === "object"` dhe `false === "string"` të dy kthejnë `false`. + +(Nëse do të dëshironim të shikojmë në qoftëse tipi ishtë (jo) i barabartë në një tip të caktuar, do të kishim shkruar `!==` në vend të `!typeof`) + +
++ +#### Përgjigja: A + +Funksioni `add` kthen një funksion shigjete, i cili kthen një funksion shigjete, i cili kthen një funksion shigjete. Funksioni i parë merr një argument `x` me vlerën `4`. Ne e thërrasim funksionin e dytë, i cili merr një argument `y` me vlerën `5`. Pastaj thërrasim funksionin e tretë, i cili merr një argument `z` me vlerën `6`. Kur po provojmë të qasemi në vlerën `x`, `y` dhe `z` brenda funksionit të fundit të shigjetës, makina JS shkon lart në zinxhirin e shtrirjes për të gjetur vlerat për `x` dhe `y` përkatësisht. Kjo kthen `4` `5` `6`. + +
++ +#### Përgjigja: C + +Funksioni gjenerator `range` kthen një objekt asinkron me premtimet për çdo elemnt në rangun që ne japim: `Promise{1}`, `Promise{2}`, `Promise{3}`. Ne vendosim variablën `gen` të jetë e barabartë me objektin asinkron, pas të cilit ne e iterojmë mbi të nëpërmjet unazës `for await ... of`. Ne vendosim variablën `item` të jetë e barabartë me vlerat e kthyera të Promise: së pari `Promise{1}`, pastaj `Promise{2}`, pastaj `Promise{3}`. Pasi që po _presim_ vlerën e `item`, premtimet e zgjidhura, vlerat e zgjidhura të premtimit kthehen: `1`, `2`, pastaj `3`. + +
++ +#### Përgjigja: D + +`myFunc` pret një objekt me vetitë `x`, `y` dhe `z` si argumente të tij. Pasi që po japim vetëm tre vlera numerike të ndara (1, 2, 3) në vend të një objekti me vetitë `x`, `y` dhe `z` ({x: 1, y: 2, z: 3}), `x`, `y` dhe `z` kanë vlerën e tyre të parazgjedhur si `undefined`. + +
++ +#### Përgjigja: B + +Me metoden `Intl.NumberFormat`, ne mund të formatojmë vlerat numerike në çdo vend. Ne formatojmë vlerën numerike `130` në vendin `en-US` si një `unit` në `mile-per-hour`, që rezulton në `130 mph`. Vlera numerike `300` në vendin `en-US` si një `currency` në `USD` rezulton në `$300.00`. + +
++ +#### Përgjigja: B + +Duke destrukturuar objektet, ne mund të targetojmë vlerat nga objekti i djathtë, dhe të caktojmë vlerën e targetuar në vlerën e emrit të njëjtë të vetisë në objektin në anën e majtë. Në këtë rast, ne po caktojmë vlerën "💀" në `spookyItems[3]`. Kjo do të thotë se ne po ndryshojmë vargun `spookyItems`, po i shtojmë "💀". Kur printojmë `spookyItems`, `["👻", "🎃", "🕸", "💀"]` printohet. + +
++ +#### Përgjigja: C + +Me metoden `Number.isNaN`, ju mund të kontrolloni nëse vlera që ju jepni është një _vlerë numerike_ dhe e barabartë me `NaN`. `name` nuk është një vlerë numerike, kështu që `Number.isNaN(name)` kthen `false`. `age` është një vlerë numerike, por nuk është e barabartë me `NaN`, kështu që `Number.isNaN(age)` kthen `false`. + +Me metoden `isNaN`, ju mund të kontrolloni nëse vlera që ju jepni nuk është numër. `name` nuk është numër, kështu që `isNaN(name)` kthen true. `age` është numër, kështu që `isNaN(age)` kthen `false`. + +
++ +#### Përgjigja: D + +Variablat e deklaruara me fjalën kyçe `const` nuk janë të referueshme para inicializimit të tyre: kjo quhet _zona e vdekjes së përkohshme_. Në funksionin `getInfo`, variabla `randomValue` është me shtrirje në fushën e funksionit `getInfo`. Në rreshtin ku ne duam të printojmë vlerën e `typeof randomValue`, variabla `randomValue` nuk është inicializuar ende: një `ReferenceError` hidhet! Makina e JS nuk shkoi poshtë në zinxhirin e fushës pasi ne deklaruam variablën `randomValue` në funksionin `getInfo`. + +
++ +#### Përgjigja: C + +Në bllokun `try`, ne jemi duke printuar vlerën e pritur të variablës `myPromise`: `"Woah some cool data"`. Pasi që nuk u hodhën gabime në bllokun `try`, kodi në bllokun `catch` nuk ekzekutohet. Kodi në bllokun `finally` _gjithmonë_ ekzekutohet, `"Oh finally!"` printohet. + +
++ +#### Përgjigja: B + +Me metodën flat, ne mund të krijojmë një varg të ri, të rrafshët. Thellësia e vargut të rrafshët varet nga vlera që ne japim. Në këtë rast, ne dhamë vlerën 1 (e cila nuk ishte e nevojshme, ajo është vlera e paracaktuar), që do të thotë se vetëm vargjet në thellësinë e parë do të bashkohen. ['🥑'] dhe ['✨', '✨', ['🍕', '🍕']] në këtë rast. Bashkimi i këtyre dy vargjeve rezulton në ['🥑', '✨', '✨', ['🍕', '🍕']]. + +
+
+
+#### Përgjigja: D
+
+`counterOne` është një instancë e klasës `Counter`. Klasa Counter përmban një veti `count` në konstruktorin e saj, dhe një metodë `increment`. Së pari, ne thirrëm metodën `increment` dy herë duke thirrur `counterOne.increment()`. Aktualisht, `counterOne.count` është `2`.
+
+
+
+Më pas, ne krijojmë një variabël të re `counterTwo`, dhe e vendosim të barabartë me `counterOne`. Pasi objektet ndërveprojnë me referencë, ne thjesht po krijojmë një referencë të re për të njëjtin vend në memorie ku `counterOne` tregon. Meqenëse po tregon në të njëjtin vend në memorie, çdo ndryshim i bërë në objektin që `counterTwo` ka një referencë, gjithashtu vlen edhe për `counterOne`. Aktualisht, `counterTwo.count` është `2`.
+
+Ne thërrasim `counterTwo.increment()`, i cili vendos `count` në `3`. Pastaj, printojmë numëruesin `counterOne`, i cili printon `3`.
+
+
+
+
+ +#### Përgjigja: C + +Së pari, ne thirrim `funcOne`. Në rreshtin e parë të `funcOne`, ne thirrim funksionin _asinkron_ `setTimeout`, nga i cili callback është dërguar tek API-ja e Web-it. (shih artikullin tim mbi ciklin e ngjarjeve këtu.) + +Pastaj e thirrim premtimin `myPromise`, e cila është një operacion _asinkron_. + +Edhe premtimi dhe koha e pritjes janë operacione asinkrone, funksioni vazhdon të ekzekutohet ndërsa është i zënë në plotësimin e premtimeve dhe trajtimin e callback-ut `setTimeout`. Kjo do të thotë se `Last line 1!` printohet së pari, pasi kjo nuk është një operacion asinkron. + +Meqenëse callstack nuk është bosh ende, funksioni `setTimeout` dhe premtimi në `funcOne` nuk mund të shtohen ende në callstack. + +Në `funcTwo`, variabla `res` merr `Promise` sepse `Promise.resolve(Promise.resolve('Promise'))` është ekuivalente me `Promise.resolve('Promise')` pasi plotësimi i një premtimi thjesht i plotëson vlerat e tij. `await` në këtë rresht ndalon ekzekutimin e funksionit derisa të marrë zgjidhjen e premtimit dhe pastaj vazhdon të ekzekutohet sinkronisht deri në përfundim, kështu që `Promise 2!` dhe pastaj `Last line 2!` janë regjistruar dhe `setTimeout` është dërguar tek API-ja e Web-it. + +Pastaj call stack është bosh. Premtimet janë _mikrodetyra_ (microtasks) prandaj ato zgjidhen së pari kur call stack është bosh, kështu që `Promise 1!` printohet. + +Tani, pasi që `funcTwo` është larguar nga call stack, call stack është bosh. Callback-et që po presin në radhë (`() => console.log("Timeout 1!")` nga `funcOne`, dhe `() => console.log("Timeout 2!")` nga `funcTwo`) shtohen në call stack një nga një. Callback-i i parë printon `Timeout 1!`, dhe largohet nga stack. Më pas, callback-i i dytë printon `Timeout 2!`, dhe largohet nga stack. + +
++ +#### Përgjigja: C + +Me yllin `*`, ne importojmë të gjitha vlerat e eksportuara nga ai fajll, si ato të paracaktuara dhe ato të emëruara. Nëse kemi fajllin e mëposhtëm: + +```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 +} +``` + +Për shembullin `sum`, do të thotë se vlera e importuar e `sum` do të dukej kështu: + +```javascript +{ default: function sum(x) { return x + x } } +``` + +Mund të e thërrasim këtë funksion, duke thirrur `sum.default` + +
++ +#### Përgjigja: C + +Me një objekt Proxy, ne mund të shtojmë sjellje të personalizuara për një objekt të cilit i kalohet si argumenti i dytë. Në këtë rast, ne i kalojmë objektin `handler` i cili përmban dy veti: `set` dhe `get`. `set` thirret çdo herë kur ne _caktojmë_ vlerat e vetisë, `get` thirret çdo herë kur ne _marrim_ (i qasemi) vlerave të vetisë. + +Argumenti i parë është një objekt i zbrazët `{}`, i cili është vlera e `person`. Tek ky objekt, shtohet sjellja e personalizuar e specifikuar në objektin `handler`. Nëse shtojmë një veti tek objekti `person`, `set` do të thirret. Nëse i qasemi një vetie në objektin `person`, `get` do të thirret. + +Së pari, ne shtuam një veti të re `name` tek objekti proxy (`person.name = "Lydia"`). `set` thirret, dhe printon `"Added a new property!"`. + +Pastaj, ne i qasemi një vlerë të vetisë në objektin proxy, vetia `get` në objektin handler thirret. `"Accessed a property!"` printohet. + +
++ +#### Përgjigja: A + +Me `Object.seal` ne mund të parandalojmë shtimin e vetive të reja, ose fshirjen e vetive ekzistuese. + +Megjithatë, ju ende mund të modifikoni vlerën e vetive ekzistuese. + +
++ +#### Përgjigja: C + +Metoda `Object.freeze` _ngrin_ një objekt. Asnjë veti nuk mund të shtohet, të modifikohet, ose të hiqet. + +Megjithatë, ajo vetëm _ngrin sipërfaqësisht_ objektin, që do të thotë se vetëm vetitë _e drejtpërdrejta_ në objekt janë të ngrira. Nëse vetia është një tjetër objekt, si `address` në këtë rast, vetitë në atë objekt nuk janë të ngrira, dhe mund të modifikohen. + +
++ +#### Përgjigja: A + +Së pari, ne thirrëm `myFunc()` pa kaluar asnjë argument. Pasi që nuk kaluam argumente, `num` dhe `value` morën vlerat e tyre të paracaktuara: num është `2`, dhe `value` është vlera e kthyer nga funksioni `add`. Tek funksioni `add`, ne i japim si argument `num`, i cili ka vlerën `2`. `Add` kthen `4`, e cila është vlera e `value`. + +Më pas, ne thirrëm `myFunc(3)` dhe kaluam vlerën `3` si vlerë për argumentin `num`. Nuk kaluam një argument për `value`. Pasi nuk kaluam një vlerë për argumentin `value`, ai mori vlerën e paracaktuar: vlerën e kthyer nga funksioni `add`. Tek `add`, ne i japim si argument `num`, i cili ka vlerën `3`. `Add` kthen `6`, e cila është vlera e `value`. + +
++ +#### Përgjigja: D + +Në ES2020, mund të shtojmë variabla private në klasa duke përdorur `#`. Nuk mund t'i qasemi këtyre variablave jashtë klasës. Kur provojmë të printojmë `counter.#number`, hidhet një SyntaxError: nuk mund t'i qaseni jashtë klasës `Counter`! + +
++ +#### Përgjigja: B + +Për të iteruar mbi `members` në çdo element në array `teams`, duhet të kaloni `teams[i].members` në funksionin gjenerator `getMembers`. Funksioni gjenerator kthen një objekt gjenerator. Për të iteruar mbi çdo element në këtë objekt gjenerator, duhet të përdorim `yield*`. + +Nëse do të shkruanim `yield`, `return yield`, ose `return`, gjithë funksioni gjenerator do të kthehej herën e parë që do e thirrim metodën `next`. + +
++ +#### Përgjigja: C + +Funksioni `addHobby` merr dy argumente, `hobby` dhe `hobbies` me vlerën e paracaktuar të array `hobbies` në objektin `person`. + +Së pari, ne thirrim funksionin `addHobby`, dhe japim `"running"` si vlerë për `hobby` dhe një array bosh si vlerë për `hobbies`. Pasi japim një varg bosh si vlerë për `hobbies`, `"running"` shtohet në këtë varg bosh. + +Pastaj, ne thirrim funksionin `addHobby`, dhe japim `"dancing"` si vlerë për `hobby`. Nuk kemi dhënë vlerë për `hobbies`, kështu që ajo merr vlerën e paracaktuar, vetinë `hobbies` në objektin `person`. Ne shtojmë hobi `dancing` në array `person.hobbies`. + +Në fund, ne thirrim funksionin `addHobby`, dhe japim `"baking"` si vlerë për `hobby`, dhe array `person.hobbies` si vlerë për `hobbies`. Ne shtojmë hobi `baking` në array `person.hobbies`. + +Pas shtimit të `dancing` dhe `baking`, vlera e `person.hobbies` është `["coding", "dancing", "baking"]` + +
++ +#### Përgjigja: B + +Krijojmë variablën `pet` që është një instancë e klasës `Flamingo`. Kur ne e instantojmë këtë instancë, thirret `constructor` në `Flamingo`. Së pari, `"I'm pink. 🌸"` printohet, pas të cilit thirrim `super()`. `super()` thirr constructorin e klasës prind, `Bird`. Thirret constructori në `Bird`, dhe printon `"I'm a bird. 🦢"`. + +
++ +#### Përgjigja: D + +Fjala kyçe `const` thjesht do të thotë se nuk mund të _ri-deklarojmë_ vlerën e asaj ndryshore, është _vetëm për lexim_. Megjithatë, vlera e elementeve të array nuk është e pandryshueshme. Vetitë në vargun `emojis` mund të modifikohen, për shembull duke shtuar vlera të reja, duke i shpërndarë ato, ose duke caktuar gjatësinë e vargut në 0. + +
++ +#### Përgjigja: C + +Objektet nuk janë të paraprakisht të iterueshme. Një objekt është i iterueshëm nëse protokolli i iteratorëve është prezent. Ne mund ta shtojmë këtë manualisht duke shtuar simbolin e iteratorit `[Symbol.iterator]`, i cili duhet të kthejë një objekt gjenerator, për shembull duke e bërë atë një funksion gjenerator `*[Symbol.iterator]() {}`. Ky funksion gjenerator duhet të prodhojë `Object.values` e objektit `person` nëse dëshirojmë që të kthejë array `["Lydia Hallie", 21]`: `yield* Object.values(this)`. + +
++ +#### Përgjigja: C + +Kushti `if` brenda ciklit `forEach` kontrollon nëse vlera e `num` është e vërtetë apo false. Meqenëse numri i parë në array `nums` është `0`, një vlerë false, blloku i kodit të deklaratës `if` nuk do të ekzekutohet. `count` rritet vetëm për 3 numrat e tjerë në array `nums`, `1`, `2` dhe `3`. Meqenëse `count` rritet për `1` 3 herë, vlera e `count` është `3`. + +
++ +#### Përgjigja: D + +Simboli ? na lejon të i qasemi opsionalisht vetive më të thella brenda objekteve. Ne po provojmë të shfaqim elementin në indeksin 1 brenda në nën-array që është në indeksin 1 të array fruits. Nëse nën-array në indeksin 1 në array fruits nuk ekziston, thjesht do të kthejë undefined. Nëse nën-array në indeksin 1 në vargun fruits ekziston, por ky nën-array nuk ka një artikull në indeksin e tij 1, gjithashtu do të kthejë undefined. + +Së pari, ne po përpiqemi të printojmë artikullin e dytë në nën-array `['🍍']` të `[['🍊', '🍌'], ['🍍']]`. Ky nën-array përmban vetëm një element, që do të thotë se nuk ka element në indeksin `1`, dhe kthen `undefined`. + +Më pas, ne po thërrasim funksionin `getFruits` pa kaluar një vlerë si argument, që do të thotë se `fruits` ka vlerë `undefined` të paracaktuar. Pasi që po lidhim në mënyrë kushtëzuese elementin në indeksin `1` të `fruits`, kthen `undefined` pasi ky element në indeksin `1` nuk ekziston. + +Së fundmi, po përpiqemi të shfaqim artikullin e dytë në nën-array `['🍊', '🍌']` të `['🍍'], ['🍊', '🍌']`. Elementi në indeksin `1` brenda këtij nën-array është `🍌` që printohet. + +
++ +#### Përgjigja: A + +Ne i caktojmë variablës `calc` të jetë e barabartë me një instancë të re të klasës `Calc`. Më pas, ne krijojmë një instancë të re të `Calc`, dhe thërrasim metodën `increase` në këtë instancë. Pasi që vetia 'count' është brenda konstruktorit të klasës `Calc`, vetia 'calc' nuk është e përbashkët në prototipin e `Calc`. Kjo do të thotë se vlera 'calc' nuk është përditësuar për instancën që tregon calc, numërimi është ende `0`. + +
++ +#### Përgjigja: B + +Funksioni `updateUser` përditëson vlerat e vetive `email` dhe `password` në user, nëse vlerat e tyre i janë kaluar funksionit, pas së cilës funksioni kthen objektin `user`. Vlera e kthyer e funksionit `updateUser` është objekti `user`, që do të thotë se vlera e updatedUser është një referencë për të njëjtin objekt `user` që tregon `user`. `updatedUser === user` është e barabartë me `true`. + +
++ +#### Përgjigja: C + +Së pari, ne thirrim metodën `slice` në array e frutave. Metoda slice nuk modifikon array origjinal, por kthen vlerën që e ka 'prerë (slice)' nga array: emoji e bananes. +Më pas, ne thirrim metodën `splice` në array e frutave. Metoda splice modifikon array origjinal, që do të thotë se array i frutave tani përbëhet nga `['🍊', '🍎']`. +Në fund, ne thirrim metodën `unshift` në array e frutave, e cila modifikon array origjinal duke shtuar vlerën e dhënë, në këtë rast ‘🍇’, si elementin e parë në varg. Array i frutave tani përbëhet nga `['🍇', '🍊', '🍎']`. + +
++ +#### Përgjigja: B + +Çelësat e objektit konvertohen në stringje. + +Pasi që vlera e `dog` është një objekt, `animals[dog]` në fakt do të thotë që ne po krijojmë një veti të re të quajtur `"object Object"` të barabartë me objektin e ri. Tani `animals["object Object"]` është i barabartë me `{ emoji: "🐶", name: "Mara"}`. + +`cat` është gjithashtu një objekt, që do të thotë që `animals[cat]` në fakt do të thotë se ne po mbishkruajmë vlerën e `animals["object Object"]` me vetitë e reja të macës. + +Duke printuar `animals[dog]`, ose në fakt `animals["object Object"]` pasi që konvertimi i objektit `dog` në string rezulton në `"object Object"`, kthen `{ emoji: "🐈", name: "Sara" }`. + +
++ +#### Përgjigja: A + +Funksioni `updateEmail` është një funksion shigjetë dhe nuk është i lidhur me objektin `user`. Kjo do të thotë se fjalë kyçe `this` nuk i referohet objektit `user`, por i referohet shtrirjes globale në këtë rast. Vlera e `email` brenda objektit `user` nuk përditësohet. Kur printohet vlera e `user.email`, kthehet vlera origjinale e `my@email.com`. + +
++ +#### Përgjigja: D + +Metoda `Promise.all` ekzekuton premtimet e dhëna si argumente paralelisht. Nëse një premtim dështon, metoda 'Promise.all' _refuzon_ me vlerën e premtimit të refuzuar. Në këtë rast, `promise3` u refuzua me vlerën `"Third"`. Ne po kapim vlerën e refuzuar në metodën `catch` në thirrjen `runPromises` për të kapur çdo gabim brenda funksionit `runPromises`. Vetëm `"Third"` printohet, pasi `promise3` u refuzua me këtë vlerë. + +
++ +#### Përgjigja: C + +Metoda `fromEntries` transformon një array 2d në një objekt. Elementi i parë në çdo nën-array do të jetë çelësi, dhe elementi i dytë në çdo nën-array do të jetë vlera. Në këtë rast, ne jemi duke mapuar mbi array `keys`, i cili kthen një array ku elementi i parë është elementi në array të çelësave në indeksin aktual, dhe elementi i dytë është elementi i vlerave të array në indeksin aktual. + +Kjo krijon një array të nën-arrays që përmbajnë çelësat dhe vlerat e duhura, të cilat rezultojnë në `{ name: "Lydia", age: 22 }` + +
++ +#### Përgjigja: C + +Vlera e paracaktuar e `address` është një objekt i zbrazët `{}`. Kur vendosëm variablën `member` të barabartë me objektin që kthehet nga funksioni `createMember`, ne nuk kaluam një vlerë për adresën, që do të thotë se vlera e adresës është objekti i zbrazët parazgjedhur `{}`. Një objekt i zbrazët është një vlerë e vërtetë, që do të thotë se gjendja e `address ? address : null` kushtëzuese kthehet `true`. Vlera e adresës është objekti i zbrazët `{}`. + +
++ +#### Përgjigja: B + +Kushti brenda deklaratës `if` kontrollon nëse vlera e `!typeof randomValue` është e barabartë me `"string"`. Operatori `!` e shndërron vlerën në një vlerë booleane. Nëse vlera është e vërtetë, vlera e kthyer do të jetë `false`, nëse vlera është e pavërtetë, vlera e kthyer do të jetë `true`. Në këtë rast, vlera e kthyer e `typeof randomValue` është vlera e vërtetë `"number"`, që do të thotë se vlera e `!typeof randomValue` është vlera booleane `false`. + +`!typeof randomValue === "string"` gjithmonë kthen false, pasi në fakt po kontrollojmë `false === "string"`. Pasi që kushtëzimi ktheu `false`, blloku i kodit të deklaratës `else` ekzekutohet, dhe `Yay it's a string!` printohet. + +
+-#### Answer: D +#### คำตอบ: 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`. +ในฟังก์ชันดังกล่าวได้ทำการประกาศตัวแปร `name` ด้วย `var` คีย์เวิร์ด หมายความว่าตัวแปรได้รับการ Hoisted (คือส่วนของหน่วยความจำจะถูกจองไว้ในขั้นตอน creation phase) ด้วยค่าเริ่มต้น `undefined` จนกว่าจะถึงบรรทัดที่กำหนดค่าให้กับตัวแปร เนื่องจากเราไม่ได้กำหนดค่าให้กับตัวแปรในบรรทัดที่เราแสดงผล ดังนั้นค่าของตัวแปร `name` จึงเป็น `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`. +ตัวแปรที่ประกาศโดยใช้คีย์เวิร์ด `let` (และ `const`) ถูก Hoisted เช่นกัน แต่มันจะไม่ถูกตั้งค่าเริ่มต้น (initialize) เหมือนกับคีย์เวิร์ด `var` พวกมันไม่สามารถเข้าถึงได้หากยังไม่ถึงบรรทัดที่ถูกประกาศ (initialize) เรียกว่า "temporal dead zone" ดังนั้นเมื่อเราพยายามเข้าถึงตัวแปรก่อนที่จะมีการประกาศ JavaScript จะส่งข้อความ `ReferenceError`
-#### Answer: C +#### คำตอบ: 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. +เพราะว่าลำดับเหตุการที่เกิดขึ้นใน Javascript ฟังก์ชัน `setTimeout` ที่เป็น callback ถูกเรียก _หลังจาก_ loop รันเสร็จ เนื่องจากตัวแปร `i` ใน loop แรกถูกประกาศด้วยคีย์เวิร์ด `var` จึงทำให้มันเป็น global scope ระหว่างการวนรอบ loop เป็นการเพิ่มค่า `i` ที่ละ `1` ในแต่ละครั้งด้วย unary operator `++`. ในเวลาที่ `setTimeout` callback ถูกเรียก แต่ว่าค่า `i` มีค่าเท่ากับ `3` แล้วดังตัวอย่างแรก -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. +ใน loop ที่สอง ตัวแปร `i` ถูกประกาศโดยใช้คีย์เวิร์ด `let` : ตัวแปรที่ประกาศด้วยคีย์เวิร์ด `let` (และ `const`) เป็น block-scope (block คืออะไรก็ตามที่อยู่ภายใน `{ }`) ค่า `i` แต่ละค่าจะถูกกำหนดขอบเขตภายใน loop ในเวลาที่ `setTimeout` callback ถูกเรียก ค่า `i` แต่ละค่าจะเป็นค่าเฉพาะของแต่ละ callback `1 2 และ 3` ตามละดับ
-#### Answer: B +#### คำตอบ: B -Note that the value of `diameter` is a regular function, whereas the value of `perimeter` is an arrow function. +Note ค่าของ `diameter` เป็น regular function แต่ว่าค่าของ `perimeter` เป็น 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). +ด้วย arrow functions คีย์เวิร์ด `this` อ้างอิงไปที่ขอบเขตโดยรอบ (Statis scope หรือ Lexical scope) มันจะไม่เหมือนกับ regular functions! นั้นหมายถึงว่าเมื่อเราเรียก `perimeter` คำว่า `this` มันไม่ได้อ้างอิงไปที่ตัว shape object แต่มันอ้างอิงไปที่ขอบเขตโดยรอบ(ในตัวอย่าง `this` จะอ้างอิงไปที่ window object). -There is no value `radius` on that object, which returns `undefined`. +ไม่มีค่าของ `radius` ที่ window object ดังนั้น `this.radius` จึงมีค่าเป็น `undefined`
-#### Answer: A +#### คำตอบ: A -The unary plus tries to convert an operand to a number. `true` is `1`, and `false` is `0`. +เครื่องหมายบวกจะพยายามแปลงตัวถูกดำเนินการเป็นตัวเลข `true` เป็น `1`, และ `false` เป็น `0` -The string `'Lydia'` is a truthy value. What we're actually asking, is "is this truthy value falsy?". This returns `false`. +String `'Lydia'` เป็นค่าความจริง สิ่งที่เราถามคือ "ค่าความจริงนี้เป็นเท็จหรือไม่?" (ซึ่งคำตอบก็คือ "ไม่") ค่าจึงเป็น `false`
-#### Answer: A +#### คำตอบ: 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, ทุกๆ object keys เป็น strings (unless it's a Symbol). แม้ว่าเราไม่ได้กำหนด _type_ ของมันให้เป็น strings, object keys มันจะถูกแปลงเป็น strings หลังบ้านขอภาษา Javscript. -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 interprets (or unboxes) statements. เมื่อเราใช้ bracket notation, มันจะมองไปที่ opening bracket `[` และมองไปจนถึง closing bracket `]`. หลังจากนั้นมันจะประเมินค่า statement. -`mouse[bird.size]`: First it evaluates `bird.size`, which is `"small"`. `mouse["small"]` returns `true` +`mouse[bird.size]`: การประเมิณลำดับแรก `bird.size`, มีค่าเท่ากับ `"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`. +อย่างไรก็ตามด้วย dot notation, สิ่งนี้ไม่มีทางเกิดขึ้น. `mouse` ไม่มี key `bird`, ซึ่งหมายความว่า `mouse.bird` มีค่าเป็น `undefined`. เมื่อเราเรียกหา `size` โดยใช้ dot notation: `mouse.bird.size`. เนื่องจาก `mouse.bird` มีค่าเป็น `undefined`, มันเลยเป็นการเรียก `undefined.size`. ซึ่งไม่ valid (isn't valid), และจะมี error แจ้งขึ้นมา `Cannot read property "size" of undefined`.
-#### Answer: A
+#### คำตอบ: A
-In JavaScript, all objects interact by _reference_ when setting them equal to each other.
+ในภาษา Javascript, ทุก Object จะ interact โดย _reference_ เมื่อมีการตั้งค่าให้เท่ากัน.
-First, variable `c` holds a value to an object. Later, we assign `d` with the same reference that `c` has to the object.
+จากคำถามลำดับแรก `c` เก็บค่าที่เป็น object. หลังจากนั้นทำการกำหนดค่า `d` ไปที่ Reference ที่ค่า `c` เนื่องจากค่า `c` เป็น object การกำหนดค่าจึงเป็นการ Reference
-When you change one object, you change all of them.
+เมื่อมีการเปลี่ยนแปลงค่า object ตัวใดตัวหนึ่งค่าตัวอื่นจึงเปลี่ยนตามไปด้วย
-#### Answer: C +#### คำตอบ: 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()` เป็น built-in function constructor. แม้ว่ามันจะคล้ายกับ number, แต่มันไม่ได้เป็น number จริงๆ: มันมีคุณสมบัติพิเศษมากมายเนื่องจากมันเป็น 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`. +เมื่อใช้เครื่องหมาย `==` , มันเป็นแค่การตรวจสอบว่าข้อมูลสองค่ามีค่าเท่ากันหรือไม่ _value_. ซึ่งค่าทั้งสองมีค่าเท่ากับ `3`, จึง 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.` +อย่างไรก็ตามเมื่อใช้เครื่องหมาย `===` , ทั้งค่าของมัน _และ_ type ของมันควรเหมือนกันจึงจะ return `true`. เนื่องจาก `new Number()` ไม่ใช่ number, มันเป็น **object**. `a === b` _และ_ `b === c` จึง return `false.`
-#### Answer: D
+#### คำตอบ: 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.
@@ -293,7 +307,7 @@ The `colorChange` function is static. Static methods are designed to live only o
---
-###### 9. What's the output?
+###### 9. ผลลัพธ์ที่ได้คืออะไร?
```javascript
let greeting;
@@ -305,10 +319,10 @@ console.log(greetign);
- B: `ReferenceError: greetign is not defined`
- C: `undefined`
-
-#### Answer: A
+#### คำตอบ: 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).
@@ -319,7 +333,7 @@ In order to avoid this, we can use `"use strict"`. This makes sure that you have
---
-###### 10. What happens when we do this?
+###### 10. จะเกิดอะไรขึ้นหากเราทำเช่นนี้?
```javascript
function bark() {
@@ -334,10 +348,10 @@ bark.animal = "dog";
- C: `"Woof"` gets logged.
- D: `ReferenceError`
-
-#### Answer: A
+#### คำตอบ: A
This is possible in JavaScript, because functions are objects! (Everything besides primitive types are objects)
@@ -348,7 +362,7 @@ A function is a special type of object. The code you write yourself isn't the ac
---
-###### 11. What's the output?
+###### 11. ผลลัพธ์ที่ได้คืออะไร?
```javascript
function Person(firstName, lastName) {
@@ -369,10 +383,10 @@ console.log(member.getFullName());
- C: `Lydia Hallie`
- D: `undefined` `undefined`
-
-#### Answer: A
+#### คำตอบ: 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,
@@ -389,7 +403,7 @@ would have made `member.getFullName()` work. Why is this beneficial? Say that we
---
-###### 12. What's the output?
+###### 12. ผลลัพธ์ที่ได้คืออะไร?
```javascript
function Person(firstName, lastName) {
@@ -404,36 +418,36 @@ console.log(lydia);
console.log(sarah);
```
-- A: `Person {firstName: "Lydia", lastName: "Hallie"}` and `undefined`
-- B: `Person {firstName: "Lydia", lastName: "Hallie"}` and `Person {firstName: "Sarah", lastName: "Smith"}`
-- C: `Person {firstName: "Lydia", lastName: "Hallie"}` and `{}`
-- D:`Person {firstName: "Lydia", lastName: "Hallie"}` and `ReferenceError`
+- A: `Person {firstName: "Lydia", lastName: "Hallie"}` และ `undefined`
+- B: `Person {firstName: "Lydia", lastName: "Hallie"}` และ `Person {firstName: "Sarah", lastName: "Smith"}`
+- C: `Person {firstName: "Lydia", lastName: "Hallie"}` และ `{}`
+- D:`Person {firstName: "Lydia", lastName: "Hallie"}` และ `ReferenceError`
-
-#### Answer: A
+#### คำตอบ: 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.
+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.
-#### Answer: D
+#### คำตอบ: 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.
@@ -444,15 +458,15 @@ During the **capturing** phase, the event goes through the ancestor elements dow
---
-###### 14. All object have prototypes.
+###### 14. ทุกๆ object มี prototypes.
- A: true
- B: false
-
-#### Answer: B
+#### คำตอบ: 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.
@@ -461,7 +475,7 @@ All objects have prototypes, except for the **base object**. The base object is
---
-###### 15. What's the output?
+###### 15. ผลลัพธ์ที่ได้คืออะไร?
```javascript
function sum(a, b) {
@@ -476,10 +490,10 @@ sum(1, "2");
- C: `"12"`
- D: `3`
-
-#### Answer: C
+#### คำตอบ: 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.
@@ -490,7 +504,7 @@ In this example, JavaScript converts the number `1` into a string, in order for
---
-###### 16. What's the output?
+###### 16. ผลลัพธ์ที่ได้คืออะไร?
```javascript
let number = 0;
@@ -504,10 +518,10 @@ console.log(number);
- C: `0` `2` `2`
- D: `0` `1` `2`
-
-#### Answer: C
+#### คำตอบ: C
The **postfix** unary operator `++`:
@@ -526,7 +540,7 @@ This returns `0 2 2`.
---
-###### 17. What's the output?
+###### 17. ผลลัพธ์ที่ได้คืออะไร?
```javascript
function getPersonInfo(one, two, three) {
@@ -545,10 +559,10 @@ getPersonInfo`${person} is ${age} years old`;
- B: `["", " is ", " years old"]` `"Lydia"` `21`
- C: `"Lydia"` `["", " is ", " years old"]` `21`
-
-#### Answer: B
+#### คำตอบ: 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!
@@ -557,7 +571,7 @@ If you use tagged template literals, the value of the first argument is always a
---
-###### 18. What's the output?
+###### 18. ผลลัพธ์ที่ได้คืออะไร?
```javascript
function checkAge(data) {
@@ -577,23 +591,23 @@ checkAge({ age: 18 });
- B: `You are still an adult.`
- C: `Hmm.. You don't have an age I guess`
-
-#### Answer: C
+#### คำตอบ: 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 }` และ `{ age: 18 } == { age: 18 }` return `false`.
-#### Answer: C
+#### คำตอบ: C
The rest parameter (`...args`.) lets us "collect" all remaining arguments into an array. An array is an object, so `typeof args` returns `"object"`
@@ -620,7 +634,7 @@ The rest parameter (`...args`.) lets us "collect" all remaining arguments into a
---
-###### 20. What's the output?
+###### 20. ผลลัพธ์ที่ได้คืออะไร?
```javascript
function getAge() {
@@ -637,10 +651,10 @@ getAge();
- C: `ReferenceError`
- D: `TypeError`
-
-#### Answer: C
+#### คำตอบ: 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.
@@ -649,7 +663,7 @@ With `"use strict"`, you can make sure that you don't accidentally declare globa
---
-###### 21. What's value of `sum`?
+###### 21. จากโจทย์ `sum` มีค่าเท่ากับเท่าไหร่?
```javascript
const sum = eval("10*10+5");
@@ -660,10 +674,10 @@ const sum = eval("10*10+5");
- C: `TypeError`
- D: `"10*10+5"`
-
-#### Answer: A
+#### คำตอบ: 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`.
@@ -672,7 +686,7 @@ const sum = eval("10*10+5");
---
-###### 22. How long is cool_secret accessible?
+###### 22. cool_secret จะถูก accessible ได้นานเท่าไหร่?
```javascript
sessionStorage.setItem("cool_secret", 123);
@@ -683,10 +697,10 @@ sessionStorage.setItem("cool_secret", 123);
- C: When the user closes the entire browser, not only the tab.
- D: When the user shuts off their computer.
-
-#### Answer: B
+#### คำตอบ: B
The data stored in `sessionStorage` is removed after closing the _tab_.
@@ -697,7 +711,7 @@ If you used `localStorage`, the data would've been there forever, unless for exa
---
-###### 23. What's the output?
+###### 23. ผลลัพธ์ที่ได้คืออะไร?
```javascript
var num = 8;
@@ -711,10 +725,10 @@ console.log(num);
- C: `SyntaxError`
- D: `ReferenceError`
-
-#### Answer: B
+#### คำตอบ: B
With the `var` keyword, you can declare multiple variables with the same name. The variable will then hold the latest value.
@@ -725,7 +739,7 @@ You cannot do this with `let` or `const` since they're block-scoped.
---
-###### 24. What's the output?
+###### 24. ผลลัพธ์ที่ได้คืออะไร?
```javascript
const obj = { 1: "a", 2: "b", 3: "c" };
@@ -742,10 +756,10 @@ set.has(1);
- C: `true` `true` `false` `true`
- D: `true` `true` `true` `true`
-
-#### Answer: C
+#### คำตอบ: 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.
@@ -756,7 +770,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. ผลลัพธ์ที่ได้คืออะไร?
```javascript
const obj = { a: "one", b: "two", a: "three" };
@@ -768,10 +782,10 @@ console.log(obj);
- C: `{ a: "three", b: "two" }`
- D: `SyntaxError`
-
-#### Answer: C
+#### คำตอบ: 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.
@@ -780,16 +794,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. Global execution context ใน JavaScript สร้าง 2 สิ่งคือ: global object และคีย์เวิร์ด "this"
- A: true
- B: false
- C: it depends
-
-#### Answer: A
+#### คำตอบ: A
The base execution context is the global execution context: it's what's accessible everywhere in your code.
@@ -798,7 +812,7 @@ The base execution context is the global execution context: it's what's accessib
---
-###### 27. What's the output?
+###### 27. ผลลัพธ์ที่ได้คืออะไร?
```javascript
for (let i = 1; i < 5; i++) {
@@ -812,10 +826,10 @@ for (let i = 1; i < 5; i++) {
- C: `1` `2` `4`
- D: `1` `3` `4`
-
-#### Answer: C
+#### คำตอบ: C
The `continue` statement skips an iteration if a certain condition returns `true`.
@@ -824,7 +838,7 @@ The `continue` statement skips an iteration if a certain condition returns `true
---
-###### 28. What's the output?
+###### 28. ผลลัพธ์ที่ได้คืออะไร?
```javascript
String.prototype.giveLydiaPizza = () => {
@@ -833,7 +847,7 @@ String.prototype.giveLydiaPizza = () => {
const name = "Lydia";
-name.giveLydiaPizza();
+console.log(name.giveLydiaPizza())
```
- A: `"Just give Lydia pizza already!"`
@@ -841,10 +855,10 @@ name.giveLydiaPizza();
- C: `SyntaxError`
- D: `undefined`
-
-#### Answer: A
+#### คำตอบ: 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!
@@ -853,7 +867,7 @@ name.giveLydiaPizza();
---
-###### 29. What's the output?
+###### 29. ผลลัพธ์ที่ได้คืออะไร?
```javascript
const a = {};
@@ -871,23 +885,23 @@ console.log(a[b]);
- C: `undefined`
- D: `ReferenceError`
-
-#### Answer: B
+#### คำตอบ: 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`.
+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`.
+Then, we log `a[b]`, which is actually `a["object Object"]`. We just set that to `456`, so it returns `456`.
-#### Answer: B
+#### คำตอบ: B
We have a `setTimeout` function and invoked it first. Yet, it was logged last.
@@ -940,7 +954,7 @@ This is where an event loop starts to work. An **event loop** looks at the stack
---
-###### 31. What is the event.target when clicking the button?
+###### 31. event.target คืออะไรเมื่อคลิก button?
```html
-#### Answer: C
+#### คำตอบ: C
The deepest nested element that caused the event is the target of the event. You can stop bubbling by `event.stopPropagation`
@@ -969,7 +983,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. เมื่อคุณคลิกที่ paragraph, ผลลัพธ์ที่ได้ใน console log คืออะไร?
```html
-#### Answer: A
+#### คำตอบ: 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` และ `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
+#### คำตอบ: D
With both, we can pass the object to which we want the `this` keyword to refer to. However, `.call` is also _executed immediately_!
@@ -1028,7 +1042,7 @@ With both, we can pass the object to which we want the `this` keyword to refer t
---
-###### 34. What's the output?
+###### 34. ผลลัพธ์ที่ได้คืออะไร?
```javascript
function sayHi() {
@@ -1043,20 +1057,20 @@ console.log(typeof sayHi());
- C: `"function"`
- D: `"undefined"`
-
-#### Answer: B
+#### คำตอบ: 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`, `symbol`, และ `bigint`. `"function"` is not a type, since functions are objects, it's of type `"object"`.
-#### Answer: A
+#### คำตอบ: A
There are only six falsy values:
@@ -1086,14 +1100,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` และ `new Boolean` are truthy.
-#### Answer: B
+#### คำตอบ: B
`typeof 1` returns `"number"`.
`typeof "number"` returns `"string"`
@@ -1117,7 +1131,7 @@ console.log(typeof typeof 1);
---
-###### 37. What's the output?
+###### 37. ผลลัพธ์ที่ได้คืออะไร?
```javascript
const numbers = [1, 2, 3];
@@ -1130,10 +1144,10 @@ console.log(numbers);
- C: `[1, 2, 3, 7 x empty, 11]`
- D: `SyntaxError`
-
-#### Answer: C
+#### คำตอบ: 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:
@@ -1146,7 +1160,7 @@ depending on where you run it (it's different for every browser, node, etc.)
---
-###### 38. What's the output?
+###### 38. ผลลัพธ์ที่ได้คืออะไร?
```javascript
(() => {
@@ -1167,46 +1181,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
+#### คำตอบ: 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`.
+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`.
-#### Answer: A
+#### คำตอบ: A
JavaScript only has primitive types and objects.
-Primitive types are `boolean`, `null`, `undefined`, `bigint`, `number`, `string`, and `symbol`.
+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` 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'` 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.
-#### Answer: C
+#### คำตอบ: 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, 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` and `[2, 3]` is `cur`. We concatenate them, and get `[1, 2, 0, 1, 2, 3]`
+Then, `[1, 2, 0, 1]` is `acc` และ `[2, 3]` is `cur`. We concatenate them, and get `[1, 2, 0, 1, 2, 3]`
-#### Answer: B
+#### คำตอบ: B
`null` is falsy. `!null` returns `true`. `!true` returns `false`.
@@ -1265,7 +1279,7 @@ 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. `setInterval` method ส่งค่าอะไรให้เบราว์เซอร์?
```javascript
setInterval(() => console.log("Hi"), 1000);
@@ -1276,10 +1290,10 @@ setInterval(() => console.log("Hi"), 1000);
- C: the passed function
- D: `undefined`
-
-#### Answer: A
+#### คำตอบ: A
It returns a unique id. This id can be used to clear that interval with the `clearInterval()` function.
@@ -1288,7 +1302,7 @@ It returns a unique id. This id can be used to clear that interval with the `cle
---
-###### 43. What does this return?
+###### 43. ผลลัพธ์ทีได้คืออะไร?
```javascript
[..."Lydia"];
@@ -1299,10 +1313,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
+#### คำตอบ: A
A string is an iterable. The spread operator maps every character of an iterable to one element.
@@ -1311,7 +1325,7 @@ A string is an iterable. The spread operator maps every character of an iterable
---
-###### 44. What's the output?
+###### 44. ผลลัพธ์ที่ได้คืออะไร?
```javascript
function* generator(i) {
@@ -1330,10 +1344,10 @@ console.log(gen.next().value);
- C: `10, 20`
- D: `0, 10 and 10, 20`
-
-#### Answer: C
+#### คำตอบ: 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.
@@ -1346,7 +1360,7 @@ Then, we invoke the function again with the `next()` method. It starts to contin
---
-###### 45. What does this return?
+###### 45. ผลลัพธ์ทีได้คืออะไร?
```javascript
const firstPromise = new Promise((res, rej) => {
@@ -1365,10 +1379,10 @@ Promise.race([firstPromise, secondPromise]).then(res => console.log(res));
- C: `"two" "one"`
- D: `"one" "two"`
-
-#### Answer: B
+#### คำตอบ: 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.
@@ -1377,7 +1391,7 @@ When we pass multiple promises to the `Promise.race` method, it resolves/rejects
---
-###### 46. What's the output?
+###### 46. ผลลัพธ์ที่ได้คืออะไร?
```javascript
let person = { name: "Lydia" };
@@ -1392,10 +1406,10 @@ console.log(members);
- C: `[{}]`
- D: `[{ name: "Lydia" }]`
-
-#### Answer: D
+#### คำตอบ: D
First, we declare a variable `person` with the value of an object that has a `name` property.
@@ -1416,7 +1430,7 @@ We are only modifying the value of the `person` variable, and not the first elem
---
-###### 47. What's the output?
+###### 47. ผลลัพธ์ที่ได้คืออะไร?
```javascript
const person = {
@@ -1434,19 +1448,19 @@ for (const item in person) {
- C: `"Lydia", 21`
- D: `["name", "Lydia"], ["age", 21]`
-
-#### Answer: B
+#### คำตอบ: 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` และ `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
+#### คำตอบ: 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.
@@ -1473,7 +1487,7 @@ Operator associativity is the order in which the compiler evaluates the expressi
---
-###### 49. What's the value of `num`?
+###### 49. `num` เท่ากับเท่าไหร่?
```javascript
const num = parseInt("7*6", 10);
@@ -1484,10 +1498,10 @@ const num = parseInt("7*6", 10);
- C: `7`
- D: `NaN`
-
-#### Answer: C
+#### คำตอบ: 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.
@@ -1498,7 +1512,7 @@ Only the first numbers in the string is returned. Based on the _radix_ (the seco
---
-###### 50. What's the output`?
+###### 50. ผลลัพธ์ที่ได้คืออะไร?
```javascript
[1, 2, 3].map(num => {
@@ -1512,10 +1526,10 @@ 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
+#### คำตอบ: 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.
@@ -1526,7 +1540,7 @@ However, we don’t return a value. When we don’t return a value from the func
---
-###### 51. What's the output?
+###### 51. ผลลัพธ์ที่ได้คืออะไร?
```javascript
function getInfo(member, year) {
@@ -1547,10 +1561,10 @@ console.log(person, birthYear);
- C: `{ name: "Lydia" }, "1998"`
- D: `{ name: "Sarah" }, "1997"`
-
-#### Answer: A
+#### คำตอบ: 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).
@@ -1563,7 +1577,7 @@ The value of `person` is an object. The argument `member` has a (copied) referen
---
-###### 52. What's the output?
+###### 52. ผลลัพธ์ที่ได้คืออะไร?
```javascript
function greeting() {
@@ -1587,10 +1601,10 @@ sayHi();
- C: `SyntaxError: can only throw Error objects`
- D: `Oh no an error: Hello world!`
-
-#### Answer: D
+#### คำตอบ: 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'`.
@@ -1601,7 +1615,7 @@ With the `catch` statement, we can specify what to do if an exception is thrown
---
-###### 53. What's the output?
+###### 53. ผลลัพธ์ที่ได้คืออะไร?
```javascript
function Car() {
@@ -1618,10 +1632,10 @@ console.log(myCar.make);
- C: `ReferenceError`
- D: `TypeError`
-
-#### Answer: B
+#### คำตอบ: 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"`.
@@ -1630,7 +1644,7 @@ When you return a property, the value of the property is equal to the _returned_
---
-###### 54. What's the output?
+###### 54. ผลลัพธ์ที่ได้คืออะไร?
```javascript
(() => {
@@ -1646,10 +1660,10 @@ console.log(typeof y);
- C: `"object", "number"`
- D: `"number", "undefined"`
-
-#### Answer: A
+#### คำตอบ: A
`let x = y = 10;` is actually shorthand for:
@@ -1669,7 +1683,7 @@ However, we created a global variable `y` when setting `y` equal to `10`. This v
---
-###### 55. What's the output?
+###### 55. ผลลัพธ์ที่ได้คืออะไร?
```javascript
class Dog {
@@ -1696,10 +1710,10 @@ pet.bark();
- C: `"Woof I am Mara"`, `undefined`
- D: `TypeError`, `TypeError`
-
-#### Answer: A
+#### คำตอบ: 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.
@@ -1710,7 +1724,7 @@ When we try to invoke something that is not a function, a `TypeError` is thrown.
---
-###### 56. What's the output?
+###### 56. ผลลัพธ์ที่ได้คืออะไร?
```javascript
const set = new Set([1, 1, 2, 3, 4]);
@@ -1723,10 +1737,10 @@ console.log(set);
- C: `{1, 1, 2, 3, 4}`
- D: `{1, 2, 3, 4}`
-
-#### Answer: D
+#### คำตอบ: D
The `Set` object is a collection of _unique_ values: a value can only occur once in a set.
@@ -1737,7 +1751,7 @@ We passed the iterable `[1, 1, 2, 3, 4]` with a duplicate value `1`. Since we ca
---
-###### 57. What's the output?
+###### 57. ผลลัพธ์ที่ได้คืออะไร?
```javascript
// counter.js
@@ -1759,10 +1773,10 @@ console.log(myCounter);
- C: `Error`
- D: `NaN`
-
-#### Answer: C
+#### คำตอบ: C
An imported module is _read-only_: you cannot modify the imported module. Only the module that exports them can change its value.
@@ -1773,7 +1787,7 @@ When we try to increment the value of `myCounter`, it throws an error: `myCounte
---
-###### 58. What's the output?
+###### 58. ผลลัพธ์ที่ได้คืออะไร?
```javascript
const name = "Lydia";
@@ -1788,10 +1802,10 @@ console.log(delete age);
- C: `true`, `true`
- D: `undefined`, `undefined`
-
-#### Answer: A
+#### คำตอบ: 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.
@@ -1802,7 +1816,7 @@ The `name` variable was declared with a `const` keyword, so its deletion is not
---
-###### 59. What's the output?
+###### 59. ผลลัพธ์ที่ได้คืออะไร?
```javascript
const numbers = [1, 2, 3, 4, 5];
@@ -1816,10 +1830,10 @@ console.log(y);
- C: `1`
- D: `[1]`
-
-#### Answer: C
+#### คำตอบ: C
We can unpack values from arrays or properties from objects through destructuring. For example:
@@ -1844,7 +1858,7 @@ This means that the value of `y` is equal to the first value in the array, which
---
-###### 60. What's the output?
+###### 60. ผลลัพธ์ที่ได้คืออะไร?
```javascript
const user = { name: "Lydia", age: 21 };
@@ -1858,10 +1872,10 @@ console.log(admin);
- C: `{ admin: true, user: ["Lydia", 21] }`
- D: `{ admin: true }`
-
-#### Answer: B
+#### คำตอบ: 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 }`.
@@ -1870,7 +1884,7 @@ It's possible to combine objects using the spread operator `...`. It lets you cr
---
-###### 61. What's the output?
+###### 61. ผลลัพธ์ที่ได้คืออะไร?
```javascript
const person = { name: "Lydia" };
@@ -1886,21 +1900,21 @@ console.log(Object.keys(person));
- C: `{ name: "Lydia"}`, `["name", "age"]`
- D: `{ name: "Lydia"}`, `["age"]`
-
-#### Answer: B
+#### คำตอบ: 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` และ `enumerable` properties. This way, the `defineProperty` method gives you a lot more control over the properties you're adding to an object.
-#### Answer: A
+#### คำตอบ: 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 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.
@@ -1934,7 +1948,7 @@ If the replacer is a _function_, this function gets called on every property in
---
-###### 63. What's the output?
+###### 63. ผลลัพธ์ที่ได้คืออะไร?
```javascript
let num = 10;
@@ -1954,10 +1968,10 @@ console.log(num2);
- C: `11`, `11`
- D: `11`, `12`
-
-#### Answer: A
+#### คำตอบ: 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.
@@ -1968,7 +1982,7 @@ The unary operator `++` _first returns_ the value of the operand, _then incremen
---
-###### 64. What's the output?
+###### 64. ผลลัพธ์ที่ได้คืออะไร?
```javascript
const value = { number: 10 };
@@ -1988,10 +2002,10 @@ multiply(value);
- C: `20`, `20`, `20`, `40`
- D: `NaN`, `NaN`, `20`, `40`
-
-#### Answer: C
+#### คำตอบ: 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 }`.
@@ -2006,21 +2020,21 @@ The fourth time, we pass the `value` object again. `x.number` was previously mod
---
-###### 65. What's the output?
+###### 65. ผลลัพธ์ที่ได้คืออะไร?
```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` และ `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`
-
-#### Answer: D
+#### คำตอบ: 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.
@@ -2028,17 +2042,17 @@ In this example, we are not returning any values, we are simply logging the valu
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`, 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` 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`, 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` and `4` 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.
-#### Answer: B
+#### คำตอบ: 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.
+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.
-#### Answer: B
+#### คำตอบ: 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_.
@@ -2123,7 +2137,7 @@ This is a difference between `require()` in CommonJS and `import`! With `require
---
-###### 68. What's the output?
+###### 68. ผลลัพธ์ที่ได้คืออะไร?
```javascript
console.log(Number(2) === Number(2))
@@ -2136,10 +2150,10 @@ console.log(Symbol('foo') === Symbol('foo'))
- C: `true`, `false`, `true`
- D: `true`, `true`, `true`
-
-#### Answer: A
+#### คำตอบ: 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`.
@@ -2148,7 +2162,7 @@ Every Symbol is entirely unique. The purpose of the argument passed to the Symbo
---
-###### 69. What's the output?
+###### 69. ผลลัพธ์ที่ได้คืออะไร?
```javascript
const name = "Lydia Hallie"
@@ -2161,10 +2175,10 @@ console.log(name.padStart(2))
- C: `" Lydia Hallie"`, `"Lydia Hallie"` (`"[1x whitespace]Lydia Hallie"`, `"Lydia Hallie"`)
- D: `"Lydia Hallie"`, `"Lyd"`,
-
-#### Answer: C
+#### คำตอบ: 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.
@@ -2175,7 +2189,7 @@ If the argument passed to the `padStart` method is smaller than the length of th
---
-###### 70. What's the output?
+###### 70. ผลลัพธ์ที่ได้คืออะไร?
```javascript
console.log("🥑" + "💻");
@@ -2186,10 +2200,10 @@ console.log("🥑" + "💻");
- C: A string containing their code points
- D: Error
-
-#### Answer: A
+#### คำตอบ: A
With the `+` operator, you can concatenate strings. In this case, we are concatenating the string `"🥑"` with the string `"💻"`, resulting in `"🥑💻"`.
@@ -2198,7 +2212,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. ค่าที่แสดงใน log หลังจากที่เรา commented out ใน console.log จะเป็นอย่างไร?
```javascript
function* startGame() {
@@ -2214,28 +2228,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` และ `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: C
+#### คำตอบ: 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`, และ `JavaScript loves you back ❤️` gets logged.
-#### Answer: C
+#### คำตอบ: 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:
@@ -2270,7 +2284,7 @@ In this case, the string is `Hello\nworld`, which gets logged.
---
-###### 73. What's the output?
+###### 73. ผลลัพธ์ที่ได้คืออะไร?
```javascript
async function getData() {
@@ -2286,10 +2300,10 @@ console.log(data);
- C: `Promise {
-#### Answer: C
+#### คำตอบ: 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.
@@ -2304,7 +2318,7 @@ This would've logged `"I made it!"`
---
-###### 74. What's the output?
+###### 74. ผลลัพธ์ที่ได้คืออะไร?
```javascript
function addToList(item, list) {
@@ -2320,10 +2334,10 @@ console.log(result);
- C: `true`
- D: `undefined`
-
-#### Answer: B
+#### คำตอบ: 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.
@@ -2334,7 +2348,7 @@ The `push` method modifies the original array. If you wanted to return the _arra
---
-###### 75. What's the output?
+###### 75. ผลลัพธ์ที่ได้คืออะไร?
```javascript
const box = { x: 10, y: 20 };
@@ -2352,23 +2366,23 @@ console.log(shape);
- C: `{ x: 100 }`
- D: `ReferenceError`
-
-#### Answer: B
+#### คำตอบ: 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.
+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.
-#### Answer: D
+#### คำตอบ: 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`.
@@ -2397,7 +2411,7 @@ Since we try to log `name`, a variable that is not defined, a ReferenceError get
---
-###### 77. Is this a pure function?
+###### 77. นี่เป็น pure function หรือไม่?
```javascript
function sum(a, b) {
@@ -2408,21 +2422,21 @@ function sum(a, b) {
- A: Yes
- B: No
-
-#### Answer: A
+#### คำตอบ: 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.
+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.
-#### Answer: C
+#### คำตอบ: 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.
@@ -2460,16 +2474,16 @@ If we call the `addFunction` function again with the same argument, it first che
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 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`, 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`, และ `'From cache! 20'` gets logged.
-#### Answer: A
+#### คำตอบ: 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:
@@ -2506,7 +2520,7 @@ With a _for-of_ loop, we can iterate over **iterables**. An array is an iterable
---
-###### 80. What is the output?
+###### 80. ผลลัพธ์ที่ได้คืออะไร?
```javascript
const list = [1 + 2, 1 * 2, 1 / 2]
@@ -2518,21 +2532,21 @@ console.log(list)
- C: `[3, 2, 0.5]`
- D: `[1, 1, 1]`
-
-#### Answer: C
+#### คำตอบ: 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`.
+The element will be equal to the returned value. `1 + 2` returns `3`, `1 * 2` returns `2`, และ `1 / 2` returns `0.5`.
-#### Answer: B
+#### คำตอบ: 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.
@@ -2565,7 +2579,7 @@ In this case, if we didn't pass a value or if we passed `undefined`, `name` woul
---
-###### 82. What is the output?
+###### 82. ผลลัพธ์ที่ได้คืออะไร?
```javascript
var status = "😎"
@@ -2585,15 +2599,15 @@ setTimeout(() => {
}, 0)
```
-- A: `"🥑"` and `"😍"`
-- B: `"🥑"` and `"😎"`
-- C: `"😍"` and `"😎"`
-- D: `"😎"` and `"😎"`
+- A: `"🥑"` และ `"😍"`
+- B: `"🥑"` และ `"😎"`
+- C: `"😍"` และ `"😎"`
+- D: `"😎"` และ `"😎"`
-
-#### Answer: B
+#### คำตอบ: 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 `"🥑"`.
@@ -2605,7 +2619,7 @@ With the `call` method, we can change the object to which the `this` keyword ref
---
-###### 83. What is the output?
+###### 83. ผลลัพธ์ที่ได้คืออะไร?
```javascript
const person = {
@@ -2624,10 +2638,10 @@ console.log(person)
- C: `{ name: "Lydia", age: 21, city: undefined }`
- D: `"Amsterdam"`
-
-#### Answer: A
+#### คำตอบ: 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`.
@@ -2642,7 +2656,7 @@ When logging the `person` object, the unmodified object gets returned.
---
-###### 84. What is the output?
+###### 84. ผลลัพธ์ที่ได้คืออะไร?
```javascript
function checkAge(age) {
@@ -2663,19 +2677,19 @@ console.log(checkAge(21))
- C: `ReferenceError`
- D: `undefined`
-
-#### Answer: C
+#### คำตอบ: 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.
+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.
-#### Answer: C
+#### คำตอบ: 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.
@@ -2700,7 +2714,7 @@ The value of `res` in the second `.then` is equal to the returned value of the p
---
-###### 86. Which option is a way to set `hasName` equal to `true`, provided you cannot pass `true` as an argument?
+###### 86. ข้อไหนคือวิธีที่เราสามารถเซ็ตให้ `hasName` มีค่าเป็น `true` กรณีที่คุณไม่สามารถส่งค่า `true` ใน argument ได้?
```javascript
function getName(name) {
@@ -2713,10 +2727,10 @@ function getName(name) {
- C: `new Boolean(name)`
- D: `name.length`
-
-#### Answer: A
+#### คำตอบ: 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`.
@@ -2731,7 +2745,7 @@ By setting `hasName` equal to `name`, you set `hasName` equal to whatever value
---
-###### 87. What's the output?
+###### 87. ผลลัพธ์ที่ได้คืออะไร?
```javascript
console.log("I want pizza"[0])
@@ -2742,10 +2756,10 @@ console.log("I want pizza"[0])
- C: `SyntaxError`
- D: `undefined`
-
-#### Answer: B
+#### คำตอบ: 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.
@@ -2756,7 +2770,7 @@ Note that this method is not supported in IE7 and below. In that case, use `.cha
---
-###### 88. What's the output?
+###### 88. ผลลัพธ์ที่ได้คืออะไร?
```javascript
function sum(num1, num2 = num1) {
@@ -2771,12 +2785,12 @@ sum(10)
- C: `ReferenceError`
- D: `undefined`
-
-#### Answer: B
+#### คำตอบ: 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, amd 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`.
+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.
@@ -2785,7 +2799,7 @@ If you're trying to set a default parameter's value equal to a parameter which i
---
-###### 89. What's the output?
+###### 89. ผลลัพธ์ที่ได้คืออะไร?
```javascript
// module.js
@@ -2803,10 +2817,10 @@ console.log(data)
- C: `{ default: "Hello world", name: "Lydia" }`
- D: Global object of `module.js`
-
-#### Answer: A
+#### คำตอบ: 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"`.
@@ -2817,7 +2831,7 @@ The `data` object has a `default` property for the default export, other propert
---
-###### 90. What's the output?
+###### 90. ผลลัพธ์ที่ได้คืออะไร?
```javascript
class Person {
@@ -2835,10 +2849,10 @@ console.log(typeof member)
- C: `"object"`
- D: `"string"`
-Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
`world`
-Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ
Answer
+คำตอบ