JavaScript 질문

--- JavaScript에 관한 객관식 질문을 [Instagram](https://www.instagram.com/theavocoder) **스토리**에 올리고 있어요, 물론 여기에도 게시할 거예요! 마지막 업데이트: 6월 12일 기초부터 심화까지: JavaScript를 얼마나 잘 알고 있는지 테스트하거나, 지식을 조금 더 새롭게 하거나, 코딩 면접을 준비하세요! :muscle: :rocket: 이 저장소를 새로운 질문과 함께 주기적으로 업데이트해요. 질문 아래 **접힌 부분**에 답을 추가했어요, 답을 클릭하면 간단하게 펼쳐져요. 그냥 재미로 하는 거예요, 행운을 빌어요! :heart: 내게 편하게 연락하세요! 😊
Instagram || Twitter || LinkedIn || Blog
| 프로젝트에 자유롭게 사용하세요! 😃 이 저장소를 참고해 준다면 _정말_ 감사할 거예요, 저는 질문과 해설을 만들고(네 슬퍼요 하하), 커뮤니티는 제가 레포를 유지하고 개선하는 데 많은 도움을 줘요! 💪🏼 고맙고 좋은 시간 보내요! | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---
사용 가능한 번역 20개 🇸🇦🇪🇬🇧🇦🇬🇧🇩🇪🇪🇸🇫🇷🇮🇩🇯🇵🇳🇱🇧🇷🇷🇺🇹🇭🇹🇷🇺🇦🇻🇳🇨🇳🇹🇼🇽🇰

- [🇸🇦 العربية](../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)

--- ###### 1. 무엇이 출력 될까요? ```javascript function sayHi() { console.log(name); console.log(age); var name = 'Lydia'; let age = 21; } sayHi(); ``` - A: `Lydia` 그리고 `undefined` - B: `Lydia` 그리고 `ReferenceError` - C: `ReferenceError` 그리고 `21` - D: `undefined` 그리고 `ReferenceError`

#### 답: D 함수 안에서, 우선 `var` 키워드를 사용해 `name` 변수를 선언해요. 이것은 변수를 정의한 줄에 실제로 도달할 때까지, 기본값 `undefined`으로 호이스팅 되는 것(생성단계에 메모리 공간이 설정)을 의미해요. `name` 변수를 출력하려는 줄에서 아직 변수를 정의하지 않았기 때문에, `undefined` 값을 유지해요. `var`와는 다르게 `let` 키워드(그리고 `const`)를 가진 변수는 호이스팅 되지만, 초기화 되지 않아요. 변수를 선언(초기화)하는 줄 전에는 접근할 수 없어요. 이건 "일시적 사각지대"라고 불려요. 변수가 선언되기 전 변수에 접근하려고 하면, JavaScript는 `ReferenceError`를 던져요.

--- ###### 2. 무엇이 출력 될까요? ```javascript for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 1); } for (let i = 0; i < 3; i++) { setTimeout(() => console.log(i), 1); } ``` - A: `0 1 2` 그리고 `0 1 2` - B: `0 1 2` 그리고 `3 3 3` - C: `3 3 3` 그리고 `0 1 2`

#### 답: C JavaScript의 이벤트 큐 때문에, `setTimeout`의 콜백 함수는 루프가 실행된 _후에_ 호출돼요. 첫 번째의 루프의 변수 `i`는 `var` 키워드를 사용해 선언되어 전역 값이 돼요. 루프 동안, 단항 연산자 `++`를 사용해 매번 `i`의 값을 `1`씩 증가시켰어요. `setTimeout`콜백 함수가 호출되기까지, 첫 번째 예시에서의 `i`는 `3`이에요. 두 번째 루프에서, 변수 `i`는 `let` 키워드를 사용해 선언되었어요: `let`(그리고 `const`) 키워드로 선언된 변수는 블록-스코프예요(블록은 `{ }` 사이의 모든 것). 각각을 반복하는 동안, `i`는 새로운 값을 갖게 되고, 각각의 값은 루프 스코프 안에 있어요.

--- ###### 3. 무엇이 출력 될까요? ```javascript const shape = { radius: 10, diameter() { return this.radius * 2; }, perimeter: () => 2 * Math.PI * this.radius, }; console.log(shape.diameter()); console.log(shape.perimeter()); ``` - A: `20` 그리고 `62.83185307179586` - B: `20` 그리고 `NaN` - C: `20` 그리고 `63` - D: `NaN` 그리고 `63`

#### 답: B `diameter`의 값은 일반 함수지만, `perimeter`의 값은 화살표 함수라는 점을 유의하세요. 화살표 함수에서 `this` 키워드는 일반 함수와는 다르게 현재 주변 스코프를 참조해요! 이것은 `perimeter`를 부를 때 shape 객체가 아닌 그것을 둘러싼 스코프(예를 들면 window)를 참조하는 것을 의미해요. 그 객체에는 `radius`라는 값은 없기 때문에 `undefined`를 반환해요.

--- ###### 4. 무엇이 출력 될까요? ```javascript +true; !'Lydia'; ``` - A: `1` 그리고 `false` - B: `false` 그리고 `NaN` - C: `false` 그리고 `false`

#### 답: A 단항 더하기는 피연산자를 숫자로 변환하려 해요. `true`는 `1`이고, `false`는 `0`이에요. 문자열 `'Lydia'`는 참 같은 값이에요. 사실 우리가 물어본 건 "참 같은 이 값은 거짓인가?"예요. 이건 `false`를 반환해요.

--- ###### 5. 답은 어느 것일까요? ```javascript const bird = { size: 'small', }; const mouse = { name: 'Mickey', small: true, }; ``` - A: `mouse.bird.size` 는 유효하지 않아요 - B: `mouse[bird.size]` 는 유효하지 않아요 - C: `mouse[bird['size']]` 는 유효하지 않아요 - D: 이 모든 것은 유효해요.

#### 답: A JavaScript에서 모든 객체의 키는 문자열이에요(심볼이 아닌 한). 객체의 키를 문자열 _형_ 으로 입력하지 않더라도, 항상 내부적으로 문자열로 변환돼요. JavaScript는 문장을 해석(또는 분)해요. 대괄호 표기를 사용하면 첫 번째 열린 대괄호 `[`를 보고 닫힌 대괄호 `]`를 찾을 때까지 진행해요. 다 찾은 후에만 문장을 평가할 거예요. `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`와 비슷한 오류를 던질 거예요.

--- ###### 6. 무엇이 출력 될까요? ```javascript let c = { greeting: 'Hey!' }; let d; d = c; c.greeting = 'Hello'; console.log(d.greeting); ``` - A: `Hello` - B: `Hey!` - C: `undefined` - D: `ReferenceError` - E: `TypeError`

#### 답: A JavaScript에서 모든 객체는 서로를 동일하게 설정하면 _참조_로 상호작용해요. 우선, 변수 `c`는 객체에 대한 값을 갖고 있어요. 그 후 `c`가 객체에 가지고 있는 것과 동일한 참조를 `d`에 할당해요. 하나의 객체를 변경하면, 모든 객체가 변해요.

--- ###### 7. 무엇이 출력 될까요? ```javascript let a = 3; let b = new Number(3); let c = 3; console.log(a == b); console.log(a === b); console.log(b === c); ``` - A: `true` `false` `true` - B: `false` `false` `true` - C: `true` `false` `false` - D: `false` `true` `true`

#### 답: C `new Number()`는, 내장 함수 생성자예요. 숫자처럼 보이지만, 사실 숫자가 아니에요: 많은 추가 특성이 있고 그것은 객체예요. `==`연산자를 사용할 때는, 같은 _값_ 을 가졌는지 여부만 확인해요. 모두`3`의 값을 가지고 있음으로 `true`를 반환해요. 그러나, `===`연산자를 사용할 때는, 값 _그리고_ 형 둘 다 같아야 해요. 이건 아니에요: `new Number()`는 숫자가 아니에요. **객체**에요. 그래서 둘 다 `false`를 반환해요.

--- ###### 8. 무엇이 출력 될까요? ```javascript class Chameleon { static colorChange(newColor) { this.newColor = newColor; return this.newColor; } constructor({ newColor = 'green' } = {}) { this.newColor = newColor; } } const freddie = new Chameleon({ newColor: 'purple' }); console.log(freddie.colorChange('orange')); ``` - A: `orange` - B: `purple` - C: `green` - D: `TypeError`

#### 답: D `colorChange`함수는 정적이에요. 정적 메소드는 그것이 만들어지는 생성자에서만 살아있도록 설계되어, 어떤 자식들도 상속받을 수 없어요. `freddie`는 자식이기 때문에, 이 함수는 상속되지 않아 `freddie`인스턴스에서는 이용할 수 없어요: `TypeError`가 던져져요.

--- ###### 9. 무엇이 출력 될까요? ```javascript let greeting; greetign = {}; // Typo! console.log(greetign); ``` - A: `{}` - B: `ReferenceError: greetign is not defined` - C: `undefined`

#### 답: A 방금 전역 객체에 빈 객체를 만들었기 때문에, 객체는 출력돼요. `greeting`을 `greettign`으로 잘못 입력했을 때, JS 인터프리터는 `global.greettign = {}` (또는 브라우저의 `window.greetign = {}`)라고 간주해요. 이것을 피하려면, `"use strict"`를 사용해요. 이렇게 하면 변수를 어떤 것과 동일하게 설정하기 전에 변수를 선언했는지 확인할 수 있어요.

--- ###### 10. 이렇게 하면 무슨 일이 생길까요? ```javascript function bark() { console.log('Woof!'); } bark.animal = 'dog'; ``` - A: 별일 없어요, 이건 완전히 괜찮아요! - B: `SyntaxError` 이 방법으로 함수에 속성을 추가할 수 없어요. - C: `"Woof"`이 출력돼요. - D: `ReferenceError`

#### 답: A JavaScript에서는 가능한데, 함수는 객체이기 때문이에요! (원시형 이외는 모두 객체) 함수는 특별한 종류의 객체예요. 당신이 쓴 코드는 실제 함수가 아니에요. 함수는 속성을 가진 객체예요. 이 속성은 호출이 가능해요.

--- ###### 11. 무엇이 출력 될까요? ```javascript function Person(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } const member = new Person('Lydia', 'Hallie'); Person.getFullName = function () { return `${this.firstName} ${this.lastName}`; }; console.log(member.getFullName()); ``` - A: `TypeError` - B: `SyntaxError` - C: `Lydia Hallie` - D: `undefined` `undefined`

#### 답: A JavaScript에서, 함수는 객체이고 그렇기 때문에 메소드 `getFullName`은 생성자 함수 객체 자체에 추가돼요. 이런 이유로, 우리는 `Person.getFullName()`을 부를 수 있지만 `member.getFullName()`은 `TypeError`를 던져요. 모든 객체 인스턴스에서 메소드를 사용할 수 있게 하려면, 메소드를 프로토타입 속성에 추가하세요. ```js Person.prototype.getFullName = function () { return `${this.firstName} ${this.lastName}`; }; ```

--- ###### 12. 무엇이 출력 될까요? ```javascript function Person(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } const lydia = new Person('Lydia', 'Hallie'); const sarah = Person('Sarah', 'Smith'); console.log(lydia); console.log(sarah); ``` - 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`

#### 답: A `sarah`에게 `new` 키워드를 사용하지 않았어요. `new`를 사용한 경우, `this`는 우리가 만든 새로운 빈 객체를 참조해요. 그러나, `new`를 추가하지 않으면 **전역 변수**를 참조해요! `this.firstName`은 `"Sarah"`이고, `this.lastName`은 `"Smith"`라고 말했었어요. (그렇지만)실제로는, `global.firstName = 'Sarah'` 그리고 `global.lastName = 'Smith'`를 정의한 거예요. `sarah` 자체는 `undefined`로 남아있어요, 그렇기 때문에 `Person`함수의 값을 반환하지 않아요.

--- ###### 13. 이벤트 전달의 3단계는 무엇일까요? - A: Target > Capturing > Bubbling - B: Bubbling > Target > Capturing - C: Target > Bubbling > Capturing - D: Capturing > Target > Bubbling

#### 답: D **capturing** 단계 동안에, 이벤트는 조상 요소를 거쳐 target 요소까지 내려가요. 그런 다음 **target** 요소에 도달하고, **bubbling**이 시작돼요.

--- ###### 14. 모든 객체는 프로토 타입을 가져요. - A: true - B: false

#### 답: B **기본 객체**를 제외한, 모든 객체는 프로토타입을 가져요. 기본 객체는 사용자가 만든 객체이거나 `new` 키워드를 사용해 만들어진 객체예요. 기본 객체는 `.toString`과 같은 몇 개의 메소드와 속성에 접근할 수 있어요. 이것이 내장 JavaScript 메소드를 사용할 수 있는 이유죠! 이러한 모든 메소드는 프로토타입에서 사용할 수 있어요. JavaScript가 당신의 객체를 바로 찾을 수 없더라도, 당신이 접근할 수 있도록 프로토타입 체인으로 내려가 찾을 거예요.

--- ###### 15. 무엇이 출력 될까요? ```javascript function sum(a, b) { return a + b; } sum(1, '2'); ``` - A: `NaN` - B: `TypeError` - C: `'12'` - D: `3`

#### 답: C JavaScript는 **동적으로 유형화된 언어**에요: 특정 변수가 어떤 유형인지 명시하지 않아요. 변수는 당신이 모르는 사이에 자동으로 다른 유형으로 변환될 수 있는데, 이걸 _암묵적 형 변환_ 이라고 불러요. **Coercion**은 하나의 유형을 다른 유형으로 변환해요. 이 예제에서, JavaScript는 함수가 이해하고 값을 반환하도록 숫자 `1`을 문자열로 변환해요. 숫자 유형 (`1`)과 문자열 유형 (`'2'`)을 추가하는 동안, 숫자는 문자열로 취급돼요. `"Hello" + "World"`처럼 문자열을 연결해요, 따라서 여기서 일어나는 일은 `"1" + "2"`는 `"12"`에요.

--- ###### 16. 무엇이 출력 될까요? ```javascript let number = 0; console.log(number++); console.log(++number); console.log(number); ``` - A: `1` `1` `2` - B: `1` `2` `2` - C: `0` `2` `2` - D: `0` `1` `2`

#### 답: C **접미사** 단항 연산자 `++`: 1. 값 반환 (`0`을 반환해요) 2. 값 증가 (지금 number는 `1`이에요) **접두사** 단항 연산자 `++`: 1. 값 증가 (지금 number는 `2`이에요) 2. 값 반환 (`2`를 반환해요) `0 2 2`를 반환해요.

--- ###### 17. 무엇이 출력 될까요? ```javascript function getPersonInfo(one, two, three) { console.log(one); console.log(two); console.log(three); } const person = 'Lydia'; const age = 21; getPersonInfo`${person} is ${age} years old`; ``` - A: `"Lydia"` `21` `["", " is ", " years old"]` - B: `["", " is ", " years old"]` `"Lydia"` `21` - C: `"Lydia"` `["", " is ", " years old"]` `21`

#### 답: B 태그가 지정된 템플릿 리터럴을 사용한다면, 첫 번째 인수의 값은 항상 문자열 값의 배열이에요. 나머지 인수는 표현식을 통과한 값을 가져요.

--- ###### 18. 무엇이 출력 될까요? ```javascript function checkAge(data) { if (data === { age: 18 }) { console.log('You are an adult!'); } else if (data == { age: 18 }) { console.log('You are still an adult.'); } else { console.log(`Hmm.. You don't have an age I guess`); } } checkAge({ age: 18 }); ``` - A: `You are an adult!` - B: `You are still an adult.` - C: `Hmm.. You don't have an age I guess`

#### 답: C 동등성을 테스트할 때, 원시형은 _값_ 으로 비교되고, 객체는 _참조_ 로 비교돼요. JavaScript는 객체가 메모리 내의 같은 장소를 참조하고 있는지를 확인해요. 비교하고 있는 두 개의 객체는 그것이 없어요: 파라미터로 전달된 객체와 동등성을 확인하기 위해 사용한 객체는 메모리 내의 다른 장소를 참조해요. `{ age: 18 } === { age: 18 }` 그리고 `{ age: 18 } == { age: 18 }` 두 개 다 `false`를 반환하는 이유예요.

--- ###### 19. 무엇이 출력 될까요? ```javascript function getAge(...args) { console.log(typeof args); } getAge(21); ``` - A: `"number"` - B: `"array"` - C: `"object"` - D: `"NaN"`

#### 답: C rest 파라미터 (`...args`)는 남아있는 모든 인수을 하나의 배열로 "집합" 해요. 배열은 객체이니까 `typeof args`는 `"object"`를 반환해요.

--- ###### 20. 무엇이 출력 될까요? ```javascript function getAge() { 'use strict'; age = 21; console.log(age); } getAge(); ``` - A: `21` - B: `undefined` - C: `ReferenceError` - D: `TypeError`

#### 답: C `"use strict"`을 사용하면, 실수로 전역 변수를 선언하지 않게 해줘요. `age`라는 변수를 선언한 적이 전혀 없고, `"use strict"`을 사용하고 있으니, reference error를 던지게 될 거예요. 만약 `"use strict"`을 사용하지 않았다면 동작할 거예요, `age` 속성이 전역 객체에 추가된 것이기 때문이죠.

--- ###### 21. `sum`의 값은 무엇일까요? ```javascript const sum = eval('10*10+5'); ``` - A: `105` - B: `"105"` - C: `TypeError` - D: `"10*10+5"`

#### 답: A `eval` 문자열로 통과된 코드를 평가해요. 만약 그것이 이 경우처럼 표현 식이라면, 표현 식을 평가해요. 표현식은 `10 * 10 + 5`이에요. 이것은 숫자 `105`를 반환해요.

--- ###### 22. cool_secret에 몇 시간이나 접근이 가능할까요? ```javascript sessionStorage.setItem('cool_secret', 123); ``` - A: 영원히, 데이터는 사라지지 않아요. - B: 사용자가 탭을 닫을 때. - C: 사용자가 탭뿐만 아니라, 브라우저 전체를 닫을 때. - D: 사용자가 자신의 컴퓨터를 종료시켰을 때.

#### 답: B `sessionStorage`에 저장된 데이터는 _탭_ 을 닫은 후에 삭제돼요. 만약 `localStorage`를 사용했다면, 예를 들어 `localStorage.clear()`를 호출하지 않는 한, 데이터는 영원할 거예요.

--- ###### 23. 무엇이 출력 될까요? ```javascript var num = 8; var num = 10; console.log(num); ``` - A: `8` - B: `10` - C: `SyntaxError` - D: `ReferenceError`

#### 답: B `var` 키워드를 사용하면, 같은 이름으로 복수의 변수를 선언할 수 있어요. 변수는 최신의 값을 가져요. 블록 스코프의 `let` 또는 `const`에서는 할 수 없어요.

--- ###### 24. 무엇이 출력 될까요? ```javascript const obj = { 1: 'a', 2: 'b', 3: 'c' }; const set = new Set([1, 2, 3, 4, 5]); obj.hasOwnProperty('1'); obj.hasOwnProperty(1); set.has('1'); set.has(1); ``` - A: `false` `true` `false` `true` - B: `false` `true` `true` `true` - C: `true` `true` `false` `true` - D: `true` `true` `true` `true`

#### 답: C 모든 객체의 키는(심볼 제외) 문자열로 직접 입력하지 않았다고 해도 내부적으로는 문자열이에요. 이것이 `obj.hasOwnProperty('1')`도 true를 반환하는 이유예요. set에서는 동작하지 않아요. set에는 `'1'`이 없어요: `set.has('1')`은 `false`를 반환해요. 숫자 유형인 `1`을 가지고 있어, `set.has(1)`는 `true`를 반환해요.

--- ###### 25. 무엇이 출력 될까요? ```javascript const obj = { a: 'one', b: 'two', a: 'three' }; console.log(obj); ``` - A: `{ a: "one", b: "two" }` - B: `{ b: "two", a: "three" }` - C: `{ a: "three", b: "two" }` - D: `SyntaxError`

#### 답: C 같은 이름의 키를 두 개 갖고 있다면, 키는 대체 될 거예요. 여전히 첫 번째 위치에 있지만, 마지막으로 지정된 값을 가져요.

--- ###### 26. JavaScript의 전역 실행 컨텍스트는 두가지를 만들어요: 전역객체와 "this" 키워드에요. - A: true - B: false - C: 경우에 따라 달라요

#### 답: A 기본적인 실행 콘텍스트는 전역 실행 문장이에요: 당신의 코드 모든 곳에서 접근할 수 있어요.

--- ###### 27. 무엇이 출력 될까요? ```javascript for (let i = 1; i < 5; i++) { if (i === 3) continue; console.log(i); } ``` - A: `1` `2` - B: `1` `2` `3` - C: `1` `2` `4` - D: `1` `3` `4`

#### 답: C `continue` 표현 식은 특정 조건이 `true`를 반환하면 반복 처리를 건너뛰어요.

--- ###### 28. 무엇이 출력 될까요? ```javascript String.prototype.giveLydiaPizza = () => { return 'Just give Lydia pizza already!'; }; const name = 'Lydia'; console.log(name.giveLydiaPizza()) ``` - A: `"Just give Lydia pizza already!"` - B: `TypeError: not a function` - C: `SyntaxError` - D: `undefined`

#### 답: A `String`은 내장 생성자로 속성을 추가할 수 있어요. 그냥 문자열 프로토타입에 메소드를 추가한거예요. 원시형 문자열은 문자열 프로토타입 함수가 생성한 문자열 객체로 자동 변환돼요. 그래서, 모든 문자열(문자열 객체)은 그 메소드에 접근할 수 있어요!

--- ###### 29. 무엇이 출력 될까요? ```javascript const a = {}; const b = { key: 'b' }; const c = { key: 'c' }; a[b] = 123; a[c] = 456; console.log(a[b]); ``` - A: `123` - B: `456` - C: `undefined` - D: `ReferenceError`

#### 답: B 객체 키는 자동으로 문자열로 변환돼요. 객체 `a`에 키는 객체(b), 값은 `123`으로 설정하려고 해요. 그러나, 객체를 문자열화 하면 `"[object Object]"`가 돼요. 그래서 여기서 말하고자 하는 건 `a["object Object"] = 123`이라는 거예요. 그 후, 같은 일을 다시 시도해요. `c`는 암묵적으로 문자열화 한 다른 객체에요. 그래서 `a["object Object"] = 456`이 돼요. 그 후, `a[b]`를 출력하면 실제로는 `a["object Object"]`예요. 그냥 `456`을 설정했기 때문에, `456`을 반환해요.

--- ###### 30. 무엇이 출력 될까요? ```javascript const foo = () => console.log('First'); const bar = () => setTimeout(() => console.log('Second')); const baz = () => console.log('Third'); bar(); foo(); baz(); ``` - A: `First` `Second` `Third` - B: `First` `Third` `Second` - C: `Second` `First` `Third` - D: `Second` `Third` `First`

#### 답: B 처음에 `setTimeout`함수를 호출했어요. 그러나 그것은 마지막에 출력돼요. 브라우저에는 런타임 엔진뿐만 아니라 `WebAPI`라고 불리는 것도 존재해요. `WebAPI`는 `setTimeout`함수를 최초에 부여하는데, DOM을 예로 들 수 있어요. _callback_ 이 WebAPI에 푸시된 후, `setTimeout`함수 자체(callback이 아니에요!)는 stack에 사라졌어요. 지금, `foo` 는 호출되었고, `"First"`는 출력되었어요. `foo`는 stack에 사라지고, `baz`가 호출되었어요. `"Third"`가 출력되었어요. WebAPI는 준비가 될 때마다 stack에 항목을 추가할 수 없어요. 대신에, _queue_ 라고 불리는 것에 callback 함수를 푸시해요. 여기서 event loop가 작동하기 시작해요. **event loop**는 stack과 task queue를 봐요. stack이 비어있다면, queue에 첫 번째의 것을 가져다가 stack 위로 푸시해요. `bar`가 호출되었고, `"Second"`가 출력되었으며, stack에서 사라졌어요.

--- ###### 31. 버튼을 클릭했을때 event.target은 무엇일까요? ```html
``` - A: 외부의 `div` - B: 내부의 `div` - C: `button` - D: 중첩된 모든 요소의 배열

#### 답: C 가장 깊이 중첩된 요소가 이벤트를 발생시킬 이벤트 대상이예요. `event.stopPropagation`을 통해서 버블링을 중단할 수 있어요.

--- ###### 32. p태그를 클릭하면 출력된 로그는 무엇일까요? ```html

Click here!

``` - A: `p` `div` - B: `div` `p` - C: `p` - D: `div`

#### 답: A `p`를 클릭하면, 2개의 로그를 볼 수 있어요: `p` 그리고 `div`. 이벤트의 전파 중에는 3단계가 있어요: 캡처링, 타겟, 버블링. 기본적으로, 이벤트 핸들러는 버블링 단계에서 시작돼요. (`useCapture`를 `true`로 설정하지 않는 한). 가장 깊게 중첩된 요소에서 바깥쪽으로 가요.

--- ###### 33. 무엇이 출력 될까요? ```javascript const person = { name: 'Lydia' }; function sayHi(age) { console.log(`${this.name} is ${age}`); } sayHi.call(person, 21); sayHi.bind(person, 21); ``` - A: `undefined is 21` `Lydia is 21` - B: `function` `function` - C: `Lydia is 21` `Lydia is 21` - D: `Lydia is 21` `function`

#### 답: D 두 개 모두, `this` 키워드를 참조하고자 하는 객체로 보낼 수 있어요. 그렇지만, `.call`은 _즉시 실행돼요_! `.bind.`는 함수의 _복사본_ 을 반환하지만, 바인딩된 콘텍스트죠! 즉시 실행되지 않아요.

--- ###### 34. 무엇이 출력 될까요? ```javascript function sayHi() { return (() => 0)(); } console.log(typeof sayHi()); ``` - A: `"object"` - B: `"number"` - C: `"function"` - D: `"undefined"`

#### 답: B `sayHi`함수는 즉시 호출 함수 표현식(IIFE)으로서 반환된 값을 반환해요. 이 함수는 `0`을 반환하고, 형은 `"number"`이에요. 참고: 내장된 형은 7개만 있어요: `null`, `undefined`, `boolean`, `number`, `string`, `object` 그리고 `symbol`. 함수는 객체이기 때문에 `"function"`은 형이 아니라 `"object"`형이에요.

--- ###### 35. 이 값 중 어느 것이 거짓 같은 값일까요? ```javascript 0; new Number(0); (''); (' '); new Boolean(false); undefined; ``` - A: `0`, `''`, `undefined` - B: `0`, `new Number(0)`, `''`, `new Boolean(false)`, `undefined` - C: `0`, `''`, `new Boolean(false)`, `undefined` - D: 모든 값은 거짓

#### 답: A 8개의 거짓 같은 값이 있어요: - `undefined` - `null` - `NaN` - `false` - `''` (빈 문자열) - `0` - `-0` - `-0n` (BigInt(0)) `new Number` 그리고 `new Boolean`과 같은 생성자 함수는 참 같은 값이에요.

--- ###### 36. 무엇이 출력 될까요? ```javascript console.log(typeof typeof 1); ``` - A: `"number"` - B: `"string"` - C: `"object"` - D: `"undefined"`

#### 답: B `typeof 1` 은 `"number"`를 반환해요. `typeof "number"`은 `"string"`을 반환해요.

--- ###### 37. 무엇이 출력 될까요? ```javascript const numbers = [1, 2, 3]; numbers[10] = 11; console.log(numbers); ``` - A: `[1, 2, 3, 7 x null, 11]` - B: `[1, 2, 3, 11]` - C: `[1, 2, 3, 7 x empty, 11]` - D: `SyntaxError`

#### 답: C 배열의 길이를 초과한 값을 배열의 요소로 설정하고자 할 때, JavaScript는 "empty slots"라고 불리는 것을 생성해요. 이것은 사실 `undefined`의 값을 가지고 있지만, 다음과 같은 것을 보게 될 거예요: `[1, 2, 3, 7 x empty, 11]` 실행 위치에 따라 달라요 (브라우저, node 등마다 달라요.)

--- ###### 38. 무엇이 출력 될까요? ```javascript (() => { let x, y; try { throw new Error(); } catch (x) { (x = 1), (y = 2); console.log(x); } console.log(x); console.log(y); })(); ``` - A: `1` `undefined` `2` - B: `undefined` `undefined` `undefined` - C: `1` `1` `2` - D: `1` `undefined` `undefined`

#### 답: A `catch`블록은 인수`x`를 받아요. 이것은 인수를 전달할 때 변수로서의 `x`와는 달라요. 이 `x` 변수는 블록-스코프예요. 후에, 블록-스코프 변수는 `1`로 설정하고, 변수 `y`의 값을 설정해요. 여기서, 블록-스코프의 변수 `x`를 출력하는데, 이것은 `1`이에요. `catch` 블록 밖에서, `x`는 여전히 `undefined`이고 `y`는 `2`이에요. `catch` 블록 밖에서 `console.log(x)`를 출력하면, `undefined`를 반환하고. 그리고 `y`는 `2`를 반환해요.

--- ###### 39. JavaScript의 모든 것은... - A: primitive 또는 object - B: function 또는 object - C: 함정 문제! objects만 - D: number 또는 object

#### 답: A JavaScript는 원시형과 객체만 가지고 있어요. 원시형은 `boolean`, `null`, `undefined`, `bigint`, `number`, `string` 그리고 `symbol`이 있어요. 원시형과 객체를 구별하는 법은 원시형에는 속성이나 메소드가 없어요. 그렇지만 `'foo'.toUpperCase()`는 `'FOO'`로 평가되어, 결과적으로 `TypeError`가 되지 않아요. 문자열과 같은 원시형이 속성 또는 메소드에 접근하려고 할 때, JavaScript는 래퍼 클래스 중 하나인 `String`을 사용하여 암묵적으로 감싸고, 표현 식이 평가된 후 즉시 래퍼를 폐기하기 때문이에요. `null` 그리고 `undefined`를 제외한 모든 원시형은 이러한 행동을 합니다.

--- ###### 40. 무엇이 출력 될까요? ```javascript [ [0, 1], [2, 3], ].reduce( (acc, cur) => { return acc.concat(cur); }, [1, 2] ); ``` - A: `[0, 1, 2, 3, 1, 2]` - B: `[6, 1, 2]` - C: `[1, 2, 0, 1, 2, 3]` - D: `[1, 2, 6]`

#### 답: C `[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]`을 얻게 돼요.

--- ###### 41. 무엇이 출력 될까요? ```javascript !!null; !!''; !!1; ``` - A: `false` `true` `false` - B: `false` `false` `true` - C: `false` `true` `true` - D: `true` `true` `false`

#### 답: B `null`은 거짓 같은 값이에요. `!null`은 `true`를 반환해요. `!true`는 `false`를 반환해요. `""` 은 거짓 같은 값이에요. `!""`은 `true`를 반환해요. `!true`는 `false`를 반환해요. `1`은 참 같은 값이에요. `!1`은 `false`를 반환해요. `!false`는 `true`를 반환해요.

--- ###### 42. `setInterval` 메소드는 브라우저에게 무엇을 반환 할까요? ```javascript setInterval(() => console.log('Hi'), 1000); ``` - A: 유니크한 id - B: 지정된 밀리초 - C: 통과된 함수 - D: `undefined`

#### 답: A 이것은 유니크한 id를 반환해요. 이 id는 `clearInterval()` 함수의 간격을 없애기 위해 사용될 수 있어요.

--- ###### 43. 이것은 무엇을 반환할까요? ```javascript [...'Lydia']; ``` - A: `["L", "y", "d", "i", "a"]` - B: `["Lydia"]` - C: `[[], "Lydia"]` - D: `[["L", "y", "d", "i", "a"]]`

#### 답: A 문자열은 반복 가능한 객체예요. spread 연산자는 반복 가능한 객체의 모든 문자를 하나의 요소로 매핑해요.

--- ###### 44. 무엇이 출력 될까요? ```javascript function* generator(i) { yield i; yield i * 2; } const gen = generator(10); console.log(gen.next().value); console.log(gen.next().value); ``` - A: `[0, 10], [10, 20]` - B: `20, 20` - C: `10, 20` - D: `0, 10` 그리고 `10, 20`

#### 답: C 일반 함수는 호출 한 뒤 중간에 멈출 수 없어요. 하지만, 제너레이터 함수는 중간에 "멈췄다가", 나중에 중단된 부분부터 계속할 수 있어요. 제너레이터 함수는 `yield` 키워드를 만날 때마다, yield 뒤에 명시된 값을 넘겨줘요. 제너레이터 함수에서는 값을 _반환_ 하지 않고, 값을 _넘겨진다_ 는 것을 유의하세요. 우선, 제너레이터 함수에서 `i`를 `10`으로 초기화해요. `next()` 메소드를 사용해 제너레이터 함수를 호출해요. 처음에 제너레이터 함수를 호출하면, `i`은 `10`이에요. 첫 번째 `yield` 키워드를 만났어요: 그것은 `i`의 값을 넘겨줘요. 이제 제너레이터는 "멈추고", `10`을 출력해요. 그 후, `next()` 메소드를 사용해 함수를 다시 호출해요. 이전에 멈춘 부분에서부터 다시 시작하고, `i`는 여전히 `10`이에요. 이제, 다음 `yield` 키워드를 만나 `i * 2`를 넘겨줘요. `i`는 `10`이므로, `10 * 2`, 즉 `20`을 반환해요. 결과는 `10, 20`이에요.

--- ###### 45. 이것은 무엇을 반환할까요? ```javascript const firstPromise = new Promise((res, rej) => { setTimeout(res, 500, 'one'); }); const secondPromise = new Promise((res, rej) => { setTimeout(res, 100, 'two'); }); Promise.race([firstPromise, secondPromise]).then((res) => console.log(res)); ``` - A: `"one"` - B: `"two"` - C: `"two" "one"` - D: `"one" "two"`

#### 답: B 복수의 프로미스를 `Promise.race` 메소드에 넘겨주면, _최초_ 의 프로미스를 해결/거부해요. `setTimeout` 메소드에 타이머를 전달해요: 첫 번째 프로미스(`firstPromise`)에는 500ms, 두 번째 프로미스(`secondPromise`)에는 100ms. 이것은 `'two'`의 값을 가진 `secondPromise`를 최초로 해결한다는 것을 의미해요. 이제 `res`는 `'two'`의 값을 갖고 출력돼요.

--- ###### 46. 무엇이 출력 될까요? ```javascript let person = { name: 'Lydia' }; const members = [person]; person = null; console.log(members); ``` - A: `null` - B: `[null]` - C: `[{}]` - D: `[{ name: "Lydia" }]`

#### 답: D 우선, 변수 `person`의 값을 `name` 속성을 가진 객체로 선언해요. 그 후, `members`라는 변수를 선언해요. 배열의 첫 번째 요소에 `person` 변수의 값을 대입해요. 서로를 같게 설정하면 _참조_로 상호작용해요. 어떤 변수에서 다른 변수로 참조를 할당하면, 그 참조의 _복사본_ 을 만들어요. (그들은 _같은_ 참조를 가지고 있지 않다는 것을 유의하세요!) 그리고, 변수 `person`을 `null`로 설정해요. `person` 변수의 값만 변경할 수 있고, 배열의 첫 번째 요소는 객체에 대한 다른 (복사된) 참조를 가지고 있기 때문에 변경할 수 없어요. `members`의 첫 번째 요소는 여전히 원본 객체에 대한 참조를 유지하고 있어요. `members` 배열을 출력할 때, 첫 번째 요소는 여전히 객체의 값을 갖고 있어 로그가 출력돼요.

--- ###### 47. 무엇이 출력 될까요? ```javascript const person = { name: 'Lydia', age: 21, }; for (const item in person) { console.log(item); } ``` - A: `{ name: "Lydia" }, { age: 21 }` - B: `"name", "age"` - C: `"Lydia", 21` - D: `["name", "Lydia"], ["age", 21]`

#### 답: B `for-in` 루프를 사용하면, 객체의 키를 통해서 반복할 수 있는데, 이 경우에서는 `name` 그리고 `age`에요. 내부적으로, 객체의 키는 문자열이에요 (심볼이 아니라면 말이죠). 모든 루프에서, `item`의 값은 반복 중인 현재의 키 값으로 동일하게 설정해요. 우선, `item`은 `name`으로 출력돼요. 그 후, `item`은 `age`로 출력돼요.

--- ###### 48. 무엇이 출력 될까요? ```javascript console.log(3 + 4 + '5'); ``` - A: `"345"` - B: `"75"` - C: `12` - D: `"12"`

#### 답: B 연산자 결합성은 왼쪽에서 오른쪽 또는 오른쪽에서 왼쪽으로 컴파일러가 표현 식을 평가하는 순서가 돼요. 이것은 연산자가 _같은_ 우선순위를 가진 경우에만 해당돼요. 한 유형의 연산자만 있어요: `+`. 게다가, 결합성은 왼쪽에서 오른쪽이에요. 처음으로 `3 + 4`가 평가돼요. 결과는 숫자 `7`이에요. `7 + '5'`의 결과는 강제성 때문에 `"75"`가 돼요. JavaScript는 숫자 `7`을 문자열로 변환하고, (관련된 자세한 설명은) 질문 15를 보세요. `+` 연산자를 사용해서 두 개의 문자열을 연결할 수 있어요. `"7" + "5"`의 결과는 `"75"`이에요.

--- ###### 49. `num`의 값은 무엇일까요? ```javascript const num = parseInt('7*6', 10); ``` - A: `42` - B: `"42"` - C: `7` - D: `NaN`

#### 답: C 문자열의 첫 번째 숫자만 반환돼요. _진법_ 에 근거해(파싱하고자 하는 숫자의 기준을 명시하기 위한 두 번째 인수: 기본 10진수, 6진수, 8진수, 2진수 등), `parseInt`는 문자열 내의 문자가 타당한지 여부를 확인해요. 진수에 유효한 숫자가 아닌 문자를 만나면, 파싱을 멈추고, 다음 문자를 무시해요. `*`은 유효한 숫자가 아니에요. `"7"`만 십진수의 `7`로 파싱 돼요. 이제 `num`은 `7`의 값을 가져요.

--- ###### 50. 무엇이 출력 될까요? ```javascript [1, 2, 3].map((num) => { if (typeof num === 'number') return; return num * 2; }); ``` - A: `[]` - B: `[null, null, null]` - C: `[undefined, undefined, undefined]` - D: `[ 3 x empty ]`

#### 답: C 배열을 매핑할 때, `num`의 값은 헌재 순환하고 있는 요소예요. 이 경우 요소는 숫자이기 때문에, if 문의 조건 `typeof num === "number"`는 `true`를 반환해요. map 함수는 새로운 배열을 만들고 함수에서 반환된 값을 삽입해요. 그러나, 우리는 값을 반환하지 않아요. 함수는 값을 반환하지 않을 때 `undefined`를 반환해요. 배열에서의 모든 요소에 대해 함수 블록이 호출되므로, 각 요소에 대해 `undefined`를 반환해요.

--- ###### 51. 무엇이 출력 될까요? ```javascript function getInfo(member, year) { member.name = 'Lydia'; year = '1998'; } const person = { name: 'Sarah' }; const birthYear = '1997'; getInfo(person, birthYear); console.log(person, birthYear); ``` - A: `{ name: "Lydia" }, "1997"` - B: `{ name: "Sarah" }, "1998"` - C: `{ name: "Lydia" }, "1998"` - D: `{ name: "Sarah" }, "1997"`

#### 답: A 인수는 값이 객체가 아니면 _값_ 으로 전달되고, 그렇지 않으면(값이 객체면) _참조_ 로 전달돼요. `birthYear`는 객체가 아니라 문자열이기 때문에 값으로 전달돼요. 값으로 전달하면 값의 _복사본_ 이 만들어져요(질문 46을 보세요). 변수 `birthYear`는 `"1997"`값에 대한 참조를 가져요. 인수 `year` 또한 `"1997"`에 대한 참조를 가지지만, `birthYear`가 가진 참조 값과는 달라요. `year`에 `"1998"`을 대입하여 `year`의 값을 업데이트할 때, `year`의 값만 업데이트해요. `birthYear`는 여전히 `"1997"`이에요. `person`의 값은 객체예요. 인수 `member`는 _같은_ 객체의 (복사된) 참조를 가져요. 참조를 가진 `member`객체의 속성을 변경하면, 두 개 모두 같은 객체의 참조를 가지고 있기 때문에, `person`도 변경돼요. 이제 `person`'의 `name` 속성의 값은 `"Lydia"`예요.

--- ###### 52. 무엇이 출력 될까요? ```javascript function greeting() { throw 'Hello world!'; } function sayHi() { try { const data = greeting(); console.log('It worked!', data); } catch (e) { console.log('Oh no an error:', e); } } sayHi(); ``` - A: `"It worked! Hello world!"` - B: `"Oh no an error: undefined"` - C: `SyntaxError: can only throw Error objects` - D: `"Oh no an error: Hello world!"`

#### 답: D `throw`문을 사용해, 사용자 지정 오류를 만들 수 있어요. 이 표현 식을 사용해, 예외를 던질 수 있어요. 예외는 문자열, 숫자, 불린 또는 객체가 될 수 있어요. 이 경우, 예외는 `'Hello world'` 문자열이에요. `catch` 문을 사용해, `try` 블록에서 예외를 던진 경우 무엇을 할지 명시할 수 있어요. 예외가 던져졌어요: 문자열 `'Hello world'`. 이제 `e`는 문자열이고, 그것을 출력해요. 결과는 `'Oh an error: Hello world'`예요.

--- ###### 53. 무엇이 출력 될까요? ```javascript function Car() { this.make = 'Lamborghini'; return { make: 'Maserati' }; } const myCar = new Car(); console.log(myCar.make); ``` - A: `"Lamborghini"` - B: `"Maserati"` - C: `ReferenceError` - D: `TypeError`

#### 답: B 속성을 반환할 때, 속성값은 생성자에 설정한 값이 아닌, _반환된_ 값과 같아요. `"Maserati"` 문자열을 반환하기 때문에, `myCar.make`는 `"Maserati"`예요.

--- ###### 54. 무엇이 출력 될까요? ```javascript (() => { let x = (y = 10); })(); console.log(typeof x); console.log(typeof y); ``` - A: `"undefined", "number"` - B: `"number", "number"` - C: `"object", "number"` - D: `"number", "undefined"`

#### 답: A `let x = y = 10;`은 다음의 단축형이에요: ```javascript y = 10; let x = y; ``` `y`에 `10`을 대입하면, 전역 객체에 속성 `y`를 추가해요(브라우저에서는 `window`, Node에서는 `global`). 브라우저에서, `window.y`는 이제 `10`이에요. 그 후, 변수 `x`를 `10`인 `y`를 값으로 선언해요. `let`키워드로 선언된 변수는 _블록 스코프_ 로, 선언된 블록 내에서만 정의돼요: 이 경우에선 즉시 호출 함수예요(IIFE). `typeof`연산자를 사용할 때, 피연산자 `x`는 정의되지 않았어요: 우리는 선언된 블록 밖에서 접근하려 했어요. 이것은 `x`가 정의되지 않았음을 의미해요. 값을 할당하지 않거나 선언하지 않은 변수는 `"undefined"` 형이에요. `console.log(typeof x)`는 `"undefined"`를 반환해요. 그러나, `y`를 `10`으로 설정할 때 전역 변수 `y`를 만들었어요. 이 값은 코드 내 어디에서나 접근할 수 있어요. `y`는 정의되어있고, `"number"`형의 값을 유지해요. `console.log(typeof y)`는 `"number"`을 반환해요.

--- ###### 55. 무엇이 출력 될까요? ```javascript class Dog { constructor(name) { this.name = name; } } Dog.prototype.bark = function () { console.log(`Woof I am ${this.name}`); }; const pet = new Dog('Mara'); pet.bark(); delete Dog.prototype.bark; pet.bark(); ``` - A: `"Woof I am Mara"`, `TypeError` - B: `"Woof I am Mara"`, `"Woof I am Mara"` - C: `"Woof I am Mara"`, `undefined` - D: `TypeError`, `TypeError`

#### 답: A 프로토타입에서도 `delete`키워드를 사용해 객체의 속성을 삭제할 수 있어요. 프로토타입에서 속성을 삭제하면, 프로토타입 체인에서 더는 사용할 수 없어요. 이 경우, `bark` 함수는 `delete Dog.prototype.bark` 후에는 프로토타입에서 더는 사용할 수 없게 되었어요, 그러나 우리는 여전히 그것에 접근하려고 해요. 함수가 아닌 것을 호출하려고 할 때, `TypeError`가 던져져요. 이 경우 `pet.bark`는 `undefined`이기 때문에, `TypeError: pet.bark is not a function`예요.

--- ###### 56. 무엇이 출력 될까요? ```javascript const set = new Set([1, 1, 2, 3, 4]); console.log(set); ``` - A: `[1, 1, 2, 3, 4]` - B: `[1, 2, 3, 4]` - C: `{1, 1, 2, 3, 4}` - D: `{1, 2, 3, 4}`

#### 답: D `Set`은 _unique_ 값의 집합 객체예요: 값은 set 내에서 단 한 번만 발생해요. 중복 값 `1`을 가진 반복 가능한 `[1, 1, 2, 3, 4]`을 전달하기 때문에, 그 중 하나는 삭제돼요. 이것은 결과적으로 `{1, 2, 3, 4}`돼요.

--- ###### 57. 무엇이 출력 될까요? ```javascript // counter.js let counter = 10; export default counter; ``` ```javascript // index.js import myCounter from './counter'; myCounter += 1; console.log(myCounter); ``` - A: `10` - B: `11` - C: `Error` - D: `NaN`

#### 답: C import 된 모듈은 _read-only_ 예요 : import 된 모듈은 수정할 수 없어요. export 한 모듈에서만 값을 변경할 수 있어요. `myCounter`의 값을 증가시키려고 할 때, 오류를 던져요: `myCounter`는 read-only이고 수정할 수 없어요.

--- ###### 58. 무엇이 출력 될까요? ```javascript const name = "Lydia"; age = 21; console.log(delete name); console.log(delete age); ``` - A: `false`, `true` - B: `"Lydia"`, `21` - C: `true`, `true` - D: `undefined`, `undefined`

#### 답: A `delete`연산자는 불린 값을 반환해요: 성공적으로 삭제를 한 경우 `true`를, 그렇지 않다면 `false`를 반환해요. 그러나, `var`, `const` 또는 `let` 키워드로 선언된 변수은 `delete`연산자를 사용해서 삭제될 수 없어요. `name` 변수는 `const`키워드로 선언되었기 때문에, 삭제에 실패해요: `false`가 반환돼요. `age`를 `21`로 설정할 때, 사실은 `age`라는 속성을 전역 객체에 추가한 거죠. 이 방법으로 객체, 전역 객체의 속성을 성공적으로 삭제할 수 있어요, 그래서 `delete age`는 `true`를 반환해요.

--- ###### 59. 무엇이 출력 될까요? ```javascript const numbers = [1, 2, 3, 4, 5]; const [y] = numbers; console.log(y); ``` - A: `[[1, 2, 3, 4, 5]]` - B: `[1, 2, 3, 4, 5]` - C: `1` - D: `[1]`

#### 답: C 구조 분해 할당을 통해 객체의 배열 또는 속성으로부터 변수를 해체할 수 있어요. 예를 들어: ```javascript [a, b] = [1, 2]; ``` `a`의 값은 이제 `1`이고, `b`의 값은 이제 `2`예요. 사실 이 질문에서 한 건 다음과 같아요: ```javascript [y] = [1, 2, 3, 4, 5]; ``` 이것은 `y`의 값은 숫자 `1`인 배열의 첫 번째 값과 같다는 것을 의미해요. `y`를 출력하면 `1`이 반환돼요.

--- ###### 60. 무엇이 출력 될까요? ```javascript const user = { name: 'Lydia', age: 21 }; const admin = { admin: true, ...user }; console.log(admin); ``` - A: `{ admin: true, user: { name: "Lydia", age: 21 } }` - B: `{ admin: true, name: "Lydia", age: 21 }` - C: `{ admin: true, user: ["Lydia", 21] }` - D: `{ admin: true }`

#### 답: B spread 연산자 `...` 를 사용해 객체를 결합할 수 있어요. 이것은 한 객체의 키/값 쌍을 복사본으로 만들어, 다른 객체에 추가해요. 이 경우, `user` 객체의 복사본을 만들어, `admin` 객체에 추가해요. `admin` 객체는 이제 복사된 키/값 쌍이 들어있고, 결과는 `{ admin: true, name: "Lydia", age: 21 }` 예요.

--- ###### 61. 무엇이 출력 될까요? ```javascript const person = { name: 'Lydia' }; Object.defineProperty(person, 'age', { value: 21 }); console.log(person); console.log(Object.keys(person)); ``` - A: `{ name: "Lydia", age: 21 }`, `["name", "age"]` - B: `{ name: "Lydia", age: 21 }`, `["name"]` - C: `{ name: "Lydia"}`, `["name", "age"]` - D: `{ name: "Lydia"}`, `["age"]`

#### 답: B `defineProperty`메소드를 사용해, 객체에 새로운 속성을 추가하거나 기존 속성을 수정할 수 있어요. `defineProperty` 메소드를 사용해 객체의 속성을 추가할 때, 객체의 속성은 기본적으로 _비 열거자_ 예요. `Object.keys`메소드는 모든 _열거자_ 객체의 속성 이름을 반환하는데, 이 경우는 `"name"` 뿐이에요. `defineProperty`를 사용해 추가된 속성은 기본적으로 변경할 수 없어요. `writable`, `configurable` 그리고 `enumerable` 속성을 사용해 덮어쓸 수 있어요. `defineProperty`메소드를 사용하는 방법은 객체에 추가하는 속성을 훨씬 더 많이 제어할 수 있어요.

--- ###### 62. 무엇이 출력 될까요? ```javascript const settings = { username: 'lydiahallie', level: 19, health: 90, }; const data = JSON.stringify(settings, ['level', 'health']); console.log(data); ``` - A: `"{"level":19, "health":90}"` - B: `"{"username": "lydiahallie"}"` - C: `"["level", "health"]"` - D: `"{"username": "lydiahallie", "level":19, "health":90}"`

#### 답: A `JSON.stringify` 두 번째 인수는 _replacer_ 예요. replacer는 함수 또는 배열일 수 있고, 문자열로 변환 할 대상과 방법을 제어할 수 있게 해줘요. replacer가 _배열_ 이라면, 배열에 포함된 속성의 이름만 JSON 문자열에 추가될 거에요. 이 경우, 이름을 가진 `"level"` 그리고 `"health"`속성만 포함되고, `"username"`은 제외 돼요. `data` 은 이제 `"{"level":19, "health":90}"`에요. replacer가 _함수_ 라면, 문자열로 변환 할 객체의 모든 속성에 호출돼요. 이 함수로부터 반환된 값은 JSON 문자열에 추가될 때 속성의 값이 될 거예요. 만약 값이 `undefined`라면, 이 속성은 JSON 문자열에서 제외돼요.

--- ###### 63. 무엇이 출력 될까요? ```javascript let num = 10; const increaseNumber = () => num++; const increasePassedNumber = number => number++; const num1 = increaseNumber(); const num2 = increasePassedNumber(num1); console.log(num1); console.log(num2); ``` - A: `10`, `10` - B: `10`, `11` - C: `11`, `11` - D: `11`, `12`

#### 답: A 단항 연산자 `++`는 _우선_ 피연산자의 값을 _반환하고_, _그 후_ 피연산자의 값을 _증가시켜요_. `increaseNumber` 함수가 처음으로 반환 한 `num`의 값은 `10` 이기 때문에, `num1`의 값은 `10`이고, 그 후엔 `num`의 값만 증가해요. `num1`을 `increasePassedNumber`로 전달했기 때문에, `num2`는 `10`이에요. `number`는 `10`이에요(`num1`의 값. 다시, 단항 연산자가 `++`는 _우선_ 피연산자의 값을 _반환하고_, _그 후_ 피연산자의 값을 _증가해요_. `number`의 값은 `10`이에요 즉, `num2`는 `10`이죠.

--- ###### 64. 무엇이 출력 될까요? ```javascript const value = { number: 10 }; const multiply = (x = { ...value }) => { console.log((x.number *= 2)); }; multiply(); multiply(); multiply(value); multiply(value); ``` - A: `20`, `40`, `80`, `160` - B: `20`, `40`, `20`, `40` - C: `20`, `20`, `20`, `40` - D: `NaN`, `NaN`, `20`, `40`

#### 답: C ES6에서, 기본값으로 파라미터를 초기화할 수 있어요. 함수에 값이 없이 전달되거나, 파라미터의 값이 `"undefined"`라면, 파라미터의 값은 기본값이 될 거예요. 이 경우, `value` 객체의 속성을 새로운 객체 안에 전개했어요. 따라서 `x`는 `{ number: 10 }`을 기본값으로 가져요. 기본 인수는 _호출 시점_ 에 평가돼요! 함수를 부를 때마다, _새로운_ 객체를 만들어요. 처음 두 번은 값을 전달하지 않고, `multiply` 함수를 호출해요: `x`는 `{ number: 10 }`의 기본값을 가져요. 그다음 해당 숫자를 곱한 값인 `20`을 출력해요. 세 번째로 곱셈을 호출할 때, 인수를 전달해요: 그 객체는 `value`라고 불려요. `*=` 연산자는 사실 `x.number = x.number * 2`의 줄임말이에요: `x.number`의 값을 변경하고, 곱셈한 값 `20`을 출력해요 네 번째엔, `value` 객체를 다시 한번 전달해요. `x.number`는 이전에 `20`으로 바뀌었기 때문에, `x.number *= 2`는 `40`을 출력해요.

--- ###### 65. 무엇이 출력 될까요? ```javascript [1, 2, 3, 4].reduce((x, y) => console.log(x, y)); ``` - 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`

#### 답: D `reduce` 메소드가 받은 첫 번째 인수는 _누산기_ 예요, 이 경우엔 `x`죠. 두 번째 인수 `y`는 _현재 값_ 이에요. reduce 메소드에서, 배열에 있는 모든 요소에 콜백 함수를 실행하므로 궁극적으로는 하나의 값을 얻어요. 이 예제에서는, 값을 반환하지 않고, 단지 누적된 값과 현재 값을 출력해요. 누산기의 값은 콜백 함수가 이전에 반환한 값이에요. 만약 추가적인 `초기값` 인수를 `reduce` 메소드에 전달하지 않았다면, 누산기는 첫번째 부른 첫 번째 요소와 동일해요. 첫 번째로 부를 땐, 누산기 (`x`)는 `1` 이에요, 그리고 현재 값인 (`y`)는 `2`예요. 콜백 함수로부터 반환되지 않았고, 누산기와 현재 값을 출력해요: `1` 그리고 `2`가 출력돼요. 함수에서 값을 반환하지 않았다면, `undefined`를 반환해요. 다음번에 부를 때, 누산기는 `undefined`고, 그리고 현재 값은 `3`이에요. `undefined` 그리고 `3`이 출력돼요. 네 번째 부를 땐, 또 콜백 함수에서 반환받지 않았어요. 누산기는 다시 `undefined`고, 현재 값은 `4`예요. `undefined` 그리고 `4`가 출력돼요.

--- ###### 66. `Dog` 클래스를 성공적으로 확장할 수 있는 생성자는 어느 것일까요? ```javascript class Dog { constructor(name) { this.name = name; } }; class Labrador extends Dog { // 1 constructor(name, size) { this.size = size; } // 2 constructor(name, size) { super(name); this.size = size; } // 3 constructor(size) { super(name); this.size = size; } // 4 constructor(name, size) { this.name = name; this.size = size; } }; ``` - A: 1 - B: 2 - C: 3 - D: 4

#### 답: B 파생 클래스에서, `super`를 부르기 전에는 `this` 키워드에 접근할 수 없어요. 그렇게 하려고 한다면, ReferenceError를 던질 거에요: 1과 4는 reference error를 던져요 `super` 키워드를 가지고, 부모 클래스 생성자에 주어진 인수를 부를 수 있어요. 부모 생성자는 `name` 인수를 받아요, 그래서 `name`을 `super`로 전달해야 해요. `Labrador` 클래스는 2개의 인수를 받는데, `Dog`로 부터 확장된 `name`과 `Labrador` 클래스의 추가 속성인 `size`예요. 그 두 개는 `Labrador` 생성자 함수에 전달되어야 하는데, 올바르게 사용된 건 2번째 생성자예요.

--- ###### 67. 무엇이 출력 될까요? ```javascript // index.js console.log('running index.js'); import { sum } from './sum.js'; console.log(sum(1, 2)); // sum.js console.log('running sum.js'); export const sum = (a, b) => a + b; ``` - A: `running index.js`, `running sum.js`, `3` - B: `running sum.js`, `running index.js`, `3` - C: `running sum.js`, `3`, `running index.js` - D: `running index.js`, `undefined`, `running sum.js`

#### 답: B `import` 키워드를 사용하면, 모든 import된 modules은 _우선-파싱_ 되어요. import된 모듈은 _처음에_ 실행되는 것을 의미하고, import한 파일 안에 있는 코드는 _나중에_ 실행돼요. 이것은 CommonJSd의 `require()`와 `import`의 차이예요! `require()`을 사용하면, 런타임 중 코드에서 필요한 시점에 의존성 모듈을 로드 할 수 있어요. 만약 `import` 대신에 `require`을 사용하면, `running index.js`, `running sum.js`, `3`으로 콘솔에 출력될 거에요.

--- ###### 68. 무엇이 출력 될까요? ```javascript console.log(Number(2) === Number(2)); console.log(Boolean(false) === Boolean(false)); console.log(Symbol('foo') === Symbol('foo')); ``` - A: `true`, `true`, `false` - B: `false`, `true`, `false` - C: `true`, `false`, `true` - D: `true`, `true`, `true`

#### 답: A 모든 심볼은 완전히 유니크해요. 심볼에 전달된 인수의 목적은 심볼에 설명을 제공하는 거에요. 심볼의 값은 전달된 인수에 따라 달라지지 않아요. 동등성을 테스트할 때, 완전히 새로운 두 개의 심볼을 만들어요: 첫번째 `Symbol('foo')`와 두번째 `Symbol('foo')`. 이 두개의 값은 유니크하고, 서로 같지 않아요, `Symbol('foo') === Symbol('foo')`는 `false`를 반환해요.

--- ###### 69. 무엇이 출력 될까요? ```javascript const name = 'Lydia Hallie'; console.log(name.padStart(13)); console.log(name.padStart(2)); ``` - A: `"Lydia Hallie"`, `"Lydia Hallie"` - B: `" Lydia Hallie"`, `" Lydia Hallie"` (`"[13x whitespace]Lydia Hallie"`, `"[2x whitespace]Lydia Hallie"`) - C: `" Lydia Hallie"`, `"Lydia Hallie"` (`"[1x whitespace]Lydia Hallie"`, `"Lydia Hallie"`) - D: `"Lydia Hallie"`, `"Lyd"`,

#### 답: C `padStart` 메소드를 사용해, 문자열의 시작 부분에 패딩을 추가해 줄 수 있어요. 이 메소드에 전달된 값은 패딩을 포함한 문자열의 _전체_ 길이예요. 문자열 `"Lydia Hallie"`의 길이는 `12`예요. `name.padStart(13)`은 문자열의 시작점에 1 스페이스를 삽입해요, 따라서 12 + 1 은 13이죠. `padStart` 메소드에 전달된 인수가 배열의 길이보다 작다면, 패딩은 추가되지 않을 거예요.

--- ###### 70. 무엇이 출력 될까요? ```javascript console.log('🥑' + '💻'); ``` - A: `"🥑💻"` - B: `257548` - C: 해당 코드 주소를 포함하는 문자열 - D: 오류

#### 답: A `+` 연산자를 사용해, 문자열을 연결 시킬 수 있어요. 이 경우에는, 문자열 `"🥑"`과 문자열 `"💻"`을 연결해, 결과 `"🥑💻"`를 얻었어요.

--- ###### 71. console.log 표현식 뒤에 언급된 값을 어떻게 출력할 수 있을까요? ```javascript function* startGame() { const answer = yield 'Do you love JavaScript?'; if (answer !== 'Yes') { return "Oh wow... Guess we're gone here"; } return 'JavaScript loves you back ❤️'; } const game = startGame(); console.log(/* 1 */); // Do you love JavaScript? console.log(/* 2 */); // JavaScript loves you back ❤️ ``` - 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")`

#### 답: C 제너레이터 함수는 `yield` 키워드를 보면 실행을 "멈춰"요. 첫 번째로, `game.next().value`를 불러, 함수가 "Do you love JavaScript?" 문자열을 넘겨주도록 할 수 있어요. `yield` 키워드를 처음으로 찾기 전까지, 모든 줄이 실행되요. 함수 안 첫 번째 줄에 `yield` 키워드가 있어요: 첫 번째 yield으로 실행을 멈춰요! _이것은 `answer` 변수가 아직 정의되지 않았는 뜻이에요!_ `game.next("Yes").value`을 부를 때, 이전 `yield`는 `next()` 함수가 전달한 파라미터의 값으로 대체 되는데, 이 경우에는 `"Yes"`로 대체 돼요. `answer` 변수의 값은 이제 `"Yes"`예요. if문의 조건은 `false`를 반환해, `JavaScript loves you back ❤️`이 출력돼요.

--- ###### 72. 무엇이 출력 될까요? ```javascript console.log(String.raw`Hello\nworld`); ``` - A: `Hello world!` - B: `Hello`
     `world` - C: `Hello\nworld` - D: `Hello\n`
     `world`

#### 답: C `String.raw`는 escapes(`\n`, `\v`, `\t` 등.)가 무시되는 문자열을 반환해요! 백슬래시는 다음과 같이 끝나면 문제가 될 수 있어요: `` const path = `C:\Documents\Projects\table.html` `` 이렇게 될 거예요: `"C:DocumentsProjects able.html"` `String.raw`을 사용하면, 간단하게 escape를 무시하고 출력해요: `C:\Documents\Projects\table.html` 이 경우, 문자열 `Hello\nworld`이 출력되요.

--- ###### 73. 무엇이 출력 될까요? ```javascript async function getData() { return await Promise.resolve('I made it!'); } const data = getData(); console.log(data); ``` - A: `"I made it!"` - B: `Promise {: "I made it!"}` - C: `Promise {}` - D: `undefined`

#### 답: C async 함수는 항상 promise를 반환해요. `await`는 promise가 resolve 할 때까지 기다려야 해요: pending promise는 `data`를 설정하기 위해 부른 `getData()`가 반환한 것을 가져요. resolve된 값 `"I made it"`에 접근하고 싶다면, `data`에 `.then()` 메소드를 사용해야해요. `data.then(res => console.log(res))` 이건 `"I made it!"`을 출력할 거예요.

--- ###### 74. 무엇이 출력 될까요? ```javascript function addToList(item, list) { return list.push(item); } const result = addToList('apple', ['banana']); console.log(result); ``` - A: `['banana', 'apple']` - B: `2` - C: `true` - D: `undefined`

#### 답: B `.push()`메소드는 새로운 배열의 _길이_ 를 반환해요! 이전에, 배열은 한 개의 요소(문자열 `"banana"`)를 포함하고 길이는 `1`예요. 배열에 문자열 `"apple"`을 추가한 후, 배열은 두 개 요소를 포함하고, 길이 `2`를 가져요. `addToList` 함수로부터 반환 받은거예요. `push` 메소드는 원본 배열을 수정해요. 만약 함수로부터 _배열의 길이_ 대신에 _배열_ 을 반환하고 싶다면, `item`을 푸시한 후 `list`를 반환해야해요.

--- ###### 75. 무엇이 출력 될까요? ```javascript const box = { x: 10, y: 20 }; Object.freeze(box); const shape = box; shape.x = 100; console.log(shape); ``` - A: `{ x: 100, y: 20 }` - B: `{ x: 10, y: 20 }` - C: `{ x: 100 }` - D: `ReferenceError`

#### 답: B `Object.freeze`는 객체의 속성을 추가, 삭제 혹은 수정하지 못하게 만들어요(다른 객체 속성의 값이 아닌 한). 변수 `shape`을 생성할 때, 동결 객체 `box`와 동일하게 설정했고, `shape` 역시 동결 객체를 참조해요. `Object.isFrozen`을 사용해 객체의 동결 여부를 확인할 수 있어요. 이 경우, `Object.isFrozen(shape)`은 true를 반환하고, 따라서 변수 `shape`는 동결 객체 참조를 가져요. `shape`가 동결 상태이므로, `x`의 값은 객체가 아니며, `x`의 속성을 수정할 수 없어요. `x`는 여전히 `10`이고, `{ x: 10, y: 20 }`가 출력돼요.

--- ###### 76. 무엇이 출력 될까요? ```javascript const { name: myName } = { name: 'Lydia' }; console.log(name); ``` - A: `"Lydia"` - B: `"myName"` - C: `undefined` - D: `ReferenceError`

#### 답: D 오른쪽에 있는 객체로부터 속성 `name`을 분해할 때, `myName`라는 이름을 가진 변수에 값 `"Lydia"`을 할당해요. `{ name: myName }`은, JavaScript에게 오른쪽에 있는 `name`속성의 값을 가진 `myName`이라고 불리는 새로운 변수를 만든다고 말하는 거예요. `name`을 출력하려고 하면, 변수는 정의되지 않아 ReferenceError를 던질거예요.

--- ###### 77. 이것은 순수 함수일까요? ```javascript function sum(a, b) { return a + b; } ``` - A: Yes - B: No

#### 답: A 순수 함수는 _항상_ 같은 결과를 반환하는 함수예요, 만약 같은 인수가 전달 된다면 말이죠. `sum` 함수는 항상 같은 결과를 반환해요. 만약 `1`과 `2`를 전달하면, 부작용 없이 _항상_ `3`을 반환할 거예요. `5`와 `10`을 전달하면, _항상_ `15`를 반환할 거예요. 이게 순수 함수의 정의예요.

--- ###### 78. 무엇이 출력 될까요? ```javascript const add = () => { const cache = {}; return (num) => { if (num in cache) { return `From cache! ${cache[num]}`; } else { const result = num + 10; cache[num] = result; return `Calculated! ${result}`; } }; }; const addFunction = add(); console.log(addFunction(10)); console.log(addFunction(10)); console.log(addFunction(5 * 2)); ``` - A: `Calculated! 20` `Calculated! 20` `Calculated! 20` - B: `Calculated! 20` `From cache! 20` `Calculated! 20` - C: `Calculated! 20` `From cache! 20` `From cache! 20` - D: `Calculated! 20` `From cache! 20` `Error`

#### 답: 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'`이 출력돼요.

--- ###### 79. 무엇이 출력 될까요? ```javascript const myLifeSummedUp = ['☕', '💻', '🍷', '🍫']; for (let item in myLifeSummedUp) { console.log(item); } for (let item of myLifeSummedUp) { console.log(item); } ``` - A: `0` `1` `2` `3` 그리고 `"☕"` ` "💻"` `"🍷"` `"🍫"` - B: `"☕"` ` "💻"` `"🍷"` `"🍫"` 그리고 `"☕"` ` "💻"` `"🍷"` `"🍫"` - C: `"☕"` ` "💻"` `"🍷"` `"🍫"` 그리고 `0` `1` `2` `3` - D: `0` `1` `2` `3` 그리고 `{0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}`

#### 답: A _for-in_ 루프에서는, **열거 가능한** 속성에 대해 반복 할 수 있어요. 배열에서, 열거 가능한 속성은 배열 요소의 "키"이고, 사실 그들의 인덱스예요. 배열은 다음과 같이 볼 수 있어요: `{0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}` 여기서 키는 열거 가능한 속성이에요. `0` `1` `2` `3`이 출력되요. _for-of_ 루프에서는, **반복 가능한** 속성을 가진 요소에 대해 반복 할 수 있어요. 배열은 반복 가능해요. 배열을 반복할 때, "item" 변수는 현재 반복중인 요소와 같고, `"☕"` ` "💻"` `"🍷"` `"🍫"`이 출력돼요.

--- ###### 80. 무엇이 출력 될까요? ```javascript const list = [1 + 2, 1 * 2, 1 / 2]; console.log(list); ``` - A: `["1 + 2", "1 * 2", "1 / 2"]` - B: `["12", 2, 0.5]` - C: `[3, 2, 0.5]` - D: `[1, 1, 1]`

#### 답: C 배열 요소은 모든 값을 가질 수 있어요. 숫자, 문자, 객체, 다른 배열, null, 불리언 값, undefined, 그리고 날짜, 함수, 연산자와 같은 표현식 요소는 반환된 값과 같아질 거예요. `1 + 2`는 `3`을 반환하고, `1 * 2`는 `2`를 반환하고, `1 / 2` 는 `0.5`을 반환해요.

--- ###### 81. 무엇이 출력 될까요? ```javascript function sayHi(name) { return `Hi there, ${name}`; } console.log(sayHi()); ``` - A: `Hi there,` - B: `Hi there, undefined` - C: `Hi there, null` - D: `ReferenceError`

#### 답: B 기본적으로, 인수는 함수에 값이 전달되지 않으면 `undefined` 값을 가져요. 이 경우, `name` 인수를 위한 값을 전달하지 않았어요. `name`은 `undefined`로 출력돼요. ES6에서, 기본값 `undefined` 값을 기본값 매개변수로 덮어쓸 수 있어요. 예를 들면: `function sayHi(name = "Lydia") { ... }` 이 경우, 값을 전달하지 않거나 `undefined`를 전달하면, `name`은 항상 문자열 `Lydia`가 될 거예요.

--- ###### 82. 무엇이 출력 될까요? ```javascript var status = '😎'; setTimeout(() => { const status = '😍'; const data = { status: '🥑', getStatus() { return this.status; }, }; console.log(data.getStatus()); console.log(data.getStatus.call(this)); }, 0); ``` - A: `"🥑"` 그리고 `"😍"` - B: `"🥑"` 그리고 `"😎"` - C: `"😍"` 그리고 `"😎"` - D: `"😎"` 그리고 `"😎"`

#### 답: B `this`키워드의 값은 사용하는 곳에 따라 달라요. `getStatus`메소드 같은 **메소드**에서 `this`키워드는 _메소드가 속한 객체_ 를 참조해요. 이 메소드는 `data` 객체에 속해 있어, `this`는 `data`객체를 참조해요. `this.status`를 출력할 때, `data`객체의 `status` 속성 `"🥑"`이 출력돼요. `call` 메소드를 사용해, `this` 키워드가 참조하는 객체를 바꿀 수 있어요. **함수**에서, `this` 키워드는 _함수가 속한 객체_ 를 참조해요. `setTimeout` 함수를 _전역 객체_ 에 선언했어요, 따라서 `setTimeout` 함수 안에서 `this`키워드는 _전역 객체_ 를 참조해요. 전역 객체에는 `"😎"`값을 가진 _status_ 라는 변수가 있어요. `this.status`를 출력하면, `"😎"`이 출력돼요.

--- ###### 83. 무엇이 출력 될까요? ```javascript const person = { name: 'Lydia', age: 21, }; let city = person.city; city = 'Amsterdam'; console.log(person); ``` - A: `{ name: "Lydia", age: 21 }` - B: `{ name: "Lydia", age: 21, city: "Amsterdam" }` - C: `{ name: "Lydia", age: 21, city: undefined }` - D: `"Amsterdam"`

#### 답: A `city` 변수를 `person` 객체의 `city`라고 불리는 속성 값으로 설정 했어요. 이 객체에서는 `city`라고 불리는 속성이 없기 때문에, 변수 `city`는 값 `undefined`를 가져요. `person`객체 자체를 참조 _하지않는다_ 는 걸 참고해요! 변수 `city`는 `person` 객체의 `city` 속성의 현재 값으로 설정 했을 뿐이에요. 그 뒤, 우리는 `city`를 문자열 `"Amsterdam"`로 설정 했어요. 이건 person 객체를 바꾸지 않아요: 여기서 객체를 참조하는 건 없어요. `person`객체를 출력할 때, 수정되지 않은 객체를 반환 받아요.

--- ###### 84. 무엇이 출력 될까요? ```javascript function checkAge(age) { if (age < 18) { const message = "Sorry, you're too young."; } else { const message = "Yay! You're old enough!"; } return message; } console.log(checkAge(21)); ``` - A: `"Sorry, you're too young."` - B: `"Yay! You're old enough!"` - C: `ReferenceError` - D: `undefined`

#### 답: C `const`와 `let` 키워드를 사용한 변수는 _블록-스코프_ 예요. 블록은 중괄호 (`{ }`) 사이에 있는 모든 것이에요. 이 경우, if/else 표현식의 중괄호를 의미해요. 변수가 선언된 블록 외부에서 참조할 수 없어요, ReferenceError를 던져요.

--- ###### 85. 어떤 종류의 정보가 출력될까요? ```javascript fetch('https://www.website.com/api/user/1') .then((res) => res.json()) .then((res) => console.log(res)); ``` - A: `fetch` 메소드의 결과 - B: `fetch` 메소드의 두번째 호출 결과 - C: 이전 `.then()`에서 callback된 결과 - D: 항상 undefined

#### 답: C 두번째 `.then`에서의 `res`의 값은 이전`.then`에서 반환된 값이에요. 이것 처럼 `.then`을 계속해서 연결할 수 있고, 값은 계속해서 다음 핸들러로 전달 돼요.

--- ###### 86. `true`를 인수로 전달 할 수 없도록 주어졌을 때, `hasName`을 `true`로 설정할 수 있는 방법은 어느 것일까요? ```javascript function getName(name) { const hasName = // } ``` - A: `!!name` - B: `name` - C: `new Boolean(name)` - D: `name.length`

#### 답: A `!!name`에서, 우리는 `name`의 값이 참 같은지 거짓 같은지 여부를 결정해요. 만약 시험 하려는 name이 참 같다면, `!name`은 `false`를 반환해요. `!false`(실제로는 `!!name`)는 `true`를 반환해요. `hasName`을 `name`으로 설정하면, `hasName`은 불린 값 `true`가 아니라, `getName` 함수에 전달된 값으로 설정해요. `new Boolean(true)`은 불린 값 자체가 아닌, 감싼 객체를 반환해요. `name.length`은 그것의 `true`의 여부가 아닌, 전달된 인수의 길이를 반환해요.

--- ###### 87. 무엇이 출력 될까요? ```javascript console.log('I want pizza'[0]); ``` - A: `"""` - B: `"I"` - C: `SyntaxError` - D: `undefined`

#### 답: B 문자열의 특정 인덱스의 문자를 얻으려면, 대괄호 표기법을 사용하면 돼요. 문자열의 첫 번째 문자는 인덱스 0과 기타등등을 가지고 있어요. 이 경우엔 인덱스가 0이고 문자 `"I'`가 출력되는 요소를 갖길 원해요. 이 방법은 IE7 이하에서는 지원되지 않는다는 것을 유의하세요. 이 경우, `.charAt()`를 사용하세요.

--- ###### 88. 무엇이 출력 될까요? ```javascript function sum(num1, num2 = num1) { console.log(num1 + num2); } sum(10); ``` - A: `NaN` - B: `20` - C: `ReferenceError` - D: `undefined`

#### 답: B 기본값 매개변수를 이전에 정의한 함수의 다른 매개변수로 설정 할 수 있어요. 우리는 `sum` 함수에 값 `10`을 전달했어요. 만약 `sum` 함수에 인수의 값을 하나만 받았다면, `num2`의 값은 전달되지 않았고, `num1`은 전달된 값 `10`과 같다는 의미에요. `num2`의 기본값은 `num1`의 값인 `10`과 같아요. `num1 + num2`는 `20`을 반환해요. 만약 기본갑 매개변수가 정의된 _후_ (오른쪽에) 기본 파라미터의 값을 설정하려고 시도한다면, 파라미터의 값은 아직 초기화되지 않아, 오류를 던질 거에요.

--- ###### 89. 무엇이 출력 될까요? ```javascript // module.js export default () => 'Hello world'; export const name = 'Lydia'; // index.js import * as data from './module'; console.log(data); ``` - A: `{ default: [Function (anonymous)], name: "Lydia" }` - B: `{ default: [Function (anonymous)] }` - C: `{ default: "Hello world", name: "Lydia" }` - D: Global object of `module.js`

#### 답: 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의 이름과 그에 해당하는 값을 가져요.

--- ###### 90. 무엇이 출력 될까요? ```javascript class Person { constructor(name) { this.name = name; } } const member = new Person('John'); console.log(typeof member); ``` - A: `"class"` - B: `"function"` - C: `"object"` - D: `"string"`

#### 답: C Class는 함수 생성자를 위한 문법적 설탕이에요. 함수 생성자로서 `Person` 클래스와 동등한 것은 다음과 같아요: ```javascript function Person() { this.name = name; } ``` `new`와 함께 불려진 함수 생성자는 `Person`의 인스턴스를 생성하고, `typeof` 키워드는 인스턴스의 `"object"`를 반환해요. `typeof member`는 `"object"`을 반환해요.

--- ###### 91. 무엇이 출력 될까요? ```javascript let newList = [1, 2, 3].push(4); console.log(newList.push(5)); ``` - A: `[1, 2, 3, 4, 5]` - B: `[1, 2, 3, 5]` - C: `[1, 2, 3, 4]` - D: `Error`

#### 답: D `.push` 메소드는 배열 자체가 아니라, 배열의 _새로운 길이_ 를 반환해요! `newList`를 `[1, 2, 3].push(4)`과 동일하게 설정함으로써, `newList`를 배열의 새로운 길이와 동일하게 설정했어요: `4`. 그리고서, `.push` 메소드를 `newList`에 사용하려고 했어요. `newList`는 숫자 값 `4` 이기 때문에, `.push` 메소드를 사용할 수 없어요: TypeError가 던져져요.

--- ###### 92. 무엇이 출력 될까요? ```javascript function giveLydiaPizza() { return 'Here is pizza!'; } const giveLydiaChocolate = () => "Here's chocolate... now go hit the gym already."; console.log(giveLydiaPizza.prototype); console.log(giveLydiaChocolate.prototype); ``` - A: `{ constructor: ...}` `{ constructor: ...}` - B: `{}` `{ constructor: ...}` - C: `{ constructor: ...}` `{}` - D: `{ constructor: ...}` `undefined`

#### 답: D `giveLydiaPizza`와 같은 일반 함수는, `생성자` 속성을 가진 객체(프로토타입 객체)이고, `프로토타입` 속성을 갖고 있어요. 그러나 `giveLydiaChocolate` 함수와 같은 화살표 함수에서는, `prototype` 속성을 가지고 있지 않아요. `giveLydiaChocolate.prototype`을 사용해 `prototype` 속성에 접근하려고 할 때, `undefined`이 반환될 거에요.

--- ###### 93. 무엇이 출력 될까요? ```javascript const person = { name: 'Lydia', age: 21, }; for (const [x, y] of Object.entries(person)) { console.log(x, y); } ``` - A: `name` `Lydia` 그리고 `age` `21` - B: `["name", "Lydia"]` 그리고 `["age", 21]` - C: `["name", "age"]` 그리고 `undefined` - D: `Error`

#### 답: 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`을 출력해요.

--- ###### 94. 무엇이 출력 될까요? ```javascript function getItems(fruitList, ...args, favoriteFruit) { return [...fruitList, ...args, favoriteFruit] } getItems(["banana", "apple"], "pear", "orange") ``` - A: `["banana", "apple", "pear", "orange"]` - B: `[["banana", "apple"], "pear", "orange"]` - C: `["banana", "apple", ["pear"], "orange"]` - D: `SyntaxError`

#### 답: 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' ]`을 반환해요.

--- ###### 95. 무엇이 출력 될까요? ```javascript function nums(a, b) { if (a > b) console.log('a is bigger'); else console.log('b is bigger'); return; a + b; } console.log(nums(4, 2)); console.log(nums(1, 2)); ``` - A: `a is bigger`, `6` 그리고 `b is bigger`, `3` - B: `a is bigger`, `undefined` 그리고 `b is bigger`, `undefined` - C: `undefined` 그리고 `undefined` - D: `SyntaxError`

#### 답: B JavaScript에서, 세미콜론을 (`;`)을 명시적으로 _포함하여_ 쓰지 않더라도, JavaScript 엔진은 여전히 문 뒤에 그들을 추가해요. 이것은 **자동 세미콜론 삽입**이라고 불려요. 예를 들어 문은 변수, 또는 `throw`, `return`, `break` 등과 같은 키워드가 될 수도 있어요. 여기, `return`문을 썼고, 다른 값 `a + b`은 _새로운 줄_ 에 쓰였어요. 그러나, 새로운 줄이기 때문에, 엔진은 실제로 그 값이 반환되길 바라는지 알 수 없어요. 대신에, 자동적으로 `return` 뒤에 세미콜론을 더해요. 이것을 볼 수 있을거에요: ```javascript return; a + b; ``` `return` 키워드 뒤에 함수가 실행되는 것이 중단되기 때문에, `a + b`의 의미는 도달되지 않아요. 여기서처럼, 만약 아무 값도 반환되지 않는다면 함수는 `undefined`를 반환해요. `if/else`문 뒤에는 아무것도 자동으로 삽입되지 않는다는 걸 유의해요!

--- ###### 96. 무엇이 출력 될까요? ```javascript class Person { constructor() { this.name = 'Lydia'; } } Person = class AnotherPerson { constructor() { this.name = 'Sarah'; } }; const member = new Person(); console.log(member.name); ``` - A: `"Lydia"` - B: `"Sarah"` - C: `Error: cannot redeclare Person` - D: `SyntaxError`

#### 답: B 클래스를 다른 클래스/함수 생성자로 설정할 수 있어요. 이 경우, `Person`을 `AnotherPerson`로 설정했어요. 이 생성자의 name은 `Sarah`예요, 따라서 새로운 `Person`의 인스턴스 `member`의 name 속성은 `"Sarah"`예요.

--- ###### 97. 무엇이 출력 될까요? ```javascript const info = { [Symbol('a')]: 'b', }; console.log(info); console.log(Object.keys(info)); ``` - A: `{Symbol('a'): 'b'}` 그리고 `["{Symbol('a')"]` - B: `{}` 그리고 `[]` - C: `{ a: "b" }` 그리고 `["a"]` - D: `{Symbol('a'): 'b'}` 그리고 `[]`

#### 답: D 심볼은 _열거 불가능_ 해요. Object.keys 메소드는 객체의 모든 _열거 가능_ 한 키 속성을 반환해요. 심볼은 보이지 않고, 빈 객체가 반환돼요. 객체 전체를 출력하면, 심지어 열거 불가능한 것이라도 모든 속성을 볼 수 있어요. 이것은 심볼의 많은 특성 중 하나에요: 완전히 고유한 값(예를 들어 작업중인 2개의 라이브러리를 같은 객체의 속성으로 추가하고 싶을 때, 객체의 우연한 이름 충돌을 방지해요)을 나타내는 것 외에, 이 방법으로 객체의 속성을 "숨길" 수 있어요(비록 완전히는 아닐지라도. 여전히 `Object.getOwnPropertySymbols()` 메소드를 사용해 심볼에 접근 할 수 있어요).

--- ###### 98. 무엇이 출력 될까요? ```javascript const getList = ([x, ...y]) => [x, y] const getUser = user => { name: user.name, age: user.age } const list = [1, 2, 3, 4] const user = { name: "Lydia", age: 21 } console.log(getList(list)) console.log(getUser(user)) ``` - A: `[1, [2, 3, 4]]` 그리고 `undefined` - B: `[1, [2, 3, 4]]` 그리고 `{ name: "Lydia", age: 21 }` - C: `[1, 2, 3, 4]` 그리고 `{ name: "Lydia", age: 21 }` - D: `Error` 그리고 `{ name: "Lydia", age: 21 }`

#### 답: A `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`을 반환해요.

--- ###### 99. 무엇이 출력 될까요? ```javascript const name = 'Lydia'; console.log(name()); ``` - A: `SyntaxError` - B: `ReferenceError` - C: `TypeError` - D: `undefined`

#### 답: C 변수 `name`은 문자열을 값으로 가지고 있고, 함수가 아니에요, 따라서 호출할 수 없어요. TypeErrors는 값이 예상된 유형이 아닐 경우 던져져요. JavaScript는 `name`을 호출하려고 했기 때문에 함수일거라 예상했어요. 그러나 문자열이였기 때문에, TypeError가 던져져요: name은 함수가 아니에요! SyntaxErrors는 어떤 것을 썼을때 JavaScript에서 유효하지 않을 때 던져져요, 예를들어 `return`을 `retrun`로 썼을때 말이죠. ReferenceErrors는 JavaScript가 접근하려고 하는 값의 참조를 찾을 수 없을 때 던져져요.

--- ###### 100. output의 값은 무엇일까요? ```javascript // 🎉✨ 이번이 내 100번째 질문이에요! ✨🎉 const output = `${[] && 'Im'}possible! You should${'' && `n't`} see a therapist after so much JavaScript lol`; ``` - A: `possible! You should see a therapist after so much JavaScript lol` - B: `Impossible! You should see a therapist after so much JavaScript lol` - C: `possible! You shouldn't see a therapist after so much JavaScript lol` - D: `Impossible! You shouldn't see a therapist after so much JavaScript lol`

#### 답: B `[]`은 참 같은 값이에요. `&&` 연산자를 사용할 때, 왼쪽에 있는 값이 참 같은 값이라면 오른쪽 값은 반환될 거에요. 이 경우, 왼쪽의 값 `[]`은 참 같은 값이에요, 따라서 `'Im'`은 반환될 거예요. `""`은 거짓 같은 값이에요. 만약 왼쪽 값이 거짓 같은 값이라면, 반환되는 것은 없어요. `n't`은 반환되지 않아요.

--- ###### 101. 무엇이 출력 될까요? ```javascript const one = false || {} || null; const two = null || false || ''; const three = [] || 0 || true; console.log(one, two, three); ``` - A: `false` `null` `[]` - B: `null` `""` `true` - C: `{}` `""` `[]` - D: `null` `null` `true`

#### 답: C `||` 연산자를 사용하면, 첫번째로 참 같은 피연산자를 반환해요. 만약 모든 값이 거짓 같다면, 마지막 피연산자를 반환해요. `(false || {} || null)`: 빈 객체 `{}`는 진짜 같은 값이에요. 이것은 최초로(그리고 유일하게) 진짜 같은 값이라 반환돼요. `one`은 `{}`이에요. `(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` 그리고 `I have resolved!`, `second` - B: `second`, `I have resolved!` 그리고 `second`, `I have resolved!` - C: `I have resolved!`, `second` 그리고 `second`, `I have resolved!` - D: `second`, `I have resolved!` 그리고 `I have resolved!`, `second`

#### 답: 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`이 출력돼요.

--- ###### 103. 무엇이 출력 될까요? ```javascript const set = new Set(); set.add(1); set.add('Lydia'); set.add({ name: 'Lydia' }); for (let item of set) { console.log(item + 2); } ``` - A: `3`, `NaN`, `NaN` - B: `3`, `7`, `NaN` - C: `3`, `Lydia2`, `[object Object]2` - D: `"12"`, `Lydia2`, `[object Object]2`

#### 답: C `+` 연산자는 숫자로 나타난 값을 더하는데 사용될 뿐만 아니라, 문자열을 연결하는데 사용해요. JavaScript 엔진은 하나 이상의 값이 숫자가 아닌 것을 발견 했을 때, 숫자를 문자열로 강제로 변환해요. 첫번째 `1`은, 숫자로된 값이에요. `1 + 2`는 숫자 3을 반환해요. 그러나, 두번째는 문자열 `"Lydia"`이에요. `"Lydia"`은 문자열이고, `2`는 숫자에요: `2`는 문자열로 강제 변환되어요. `"Lydia"`그리고 `"2"`이 연결되어, 문자열 `"Lydia2"`이 반환되요. `{ name: "Lydia" }`은 객체에요. 객체가 아닌 숫자나 객체는 문자열이 아니므로, 둘다 문자화되어요. 일반 객체를 문자화 할때, `"[object Object]"`가 돼요. `"[object Object]"`는 `"2"`와 연결되어 `"[object Object]2"`가 돼요.

--- ###### 104. 값은 무엇일까요? ```javascript Promise.resolve(5); ``` - A: `5` - B: `Promise {: 5}` - C: `Promise {: 5}` - D: `Error`

#### 답: C promise 또는 non-promise가 아니더라도, 어떤 유형의 값이라도 `Promise.resolve`으로 전달 할 수 있어요. 메소드 그 자체는 resolved 값을 가진 promise를 반환해요 (``). 일반 함수를 전달한다면, 일반 값을 가진 resolved promise를 얻게 될거에요. 만약 promise를 전달한다면, 전달된 promise의 resolved 값과 resolved promise를 얻게 될거에요. 이 경우, 숫자 값 `5`를 전달했어요. 이것은 값 `5`를 가진 resolved promise를 반환해요.

--- ###### 105. 값은 무엇일까요? ```javascript function compareMembers(person1, person2 = person) { if (person1 !== person2) { console.log('Not the same!'); } else { console.log('They are the same!'); } } const person = { name: 'Lydia' }; compareMembers(person); ``` - A: `Not the same!` - B: `They are the same!` - C: `ReferenceError` - D: `SyntaxError`

#### 답: B 객체는 참조로 전달되었어요. 엄격한 동등 비교 (`===`)로 객체를 검사한다면, 그들의 참조를 비교할거에요. `person2`의 기본 값을 `person` 객체로 설정 하고, `person` 객체를 `person1`의 값으로 전달 했어요. 이것은 두개의 값은 메모리의 같은 장소의 참조를 가지고 있다는 걸 의미해요, 그렇기 때문에 그들은 같아요. `else`구문 안에 코드블럭이 실행되면, `They are the same!`을 출력해요.

--- ###### 106. 값은 무엇일까요? ```javascript const colorConfig = { red: true, blue: false, green: true, black: true, yellow: false, }; const colors = ['pink', 'red', 'blue']; console.log(colorConfig.colors[1]); ``` - A: `true` - B: `false` - C: `undefined` - D: `TypeError`

#### 답: 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` 의 값이 반환될 거에요.

--- ###### 107. 값은 무엇일까요? ```javascript console.log('❤️' === '❤️'); ``` - A: `true` - B: `false`

#### 답: A 엔진에서, 이모티콘은 유니코드에요. 하트 이모티콘의 유니코드는 `"U+2764 U+FE0F"`에요. 같은 이모티콘의 유니코드는 항상 같아요, 따라서 각각 다른 두개의 같은 문자열을 비교하는 것이므로 true를 반환해요.

--- ###### 108. 다음 중 원본 배열을 수정하는 method는 무엇일까요? ```javascript const emojis = ['✨', '🥑', '😍']; emojis.map((x) => x + '✨'); emojis.filter((x) => x !== '🥑'); emojis.find((x) => x !== '🥑'); emojis.reduce((acc, cur) => acc + '✨'); emojis.slice(1, 2, '✨'); emojis.splice(1, 2, '✨'); ``` - A: `All of them` - B: `map` `reduce` `slice` `splice` - C: `map` `slice` `splice` - D: `splice`

#### 답: D `splice` method를 사용하면, 요소를 삭제, 대체하거나 추가함으로써 원본 배열을 수정해요. 이 경우에서, 인덱스 1에서 부터 2개의 아이템을 제거했어요. (`'🥑'` 와 `'😍'`를 삭제했어요) 그리고 ✨ 이모티콘을 대신 추가했어요. `map`, `filter` 그리고 `slice` 는 새로운 배열을 반환하고, `find` 는 요소를 반환하며, `reduce` 는 감소된 값을 반환해요.

--- ###### 109. 무엇이 출력 될까요? ```javascript const food = ['🍕', '🍫', '🥑', '🍔']; const info = { favoriteFood: food[0] }; info.favoriteFood = '🍝'; console.log(food); ``` - A: `['🍕', '🍫', '🥑', '🍔']` - B: `['🍝', '🍫', '🥑', '🍔']` - C: `['🍝', '🍕', '🍫', '🥑', '🍔']` - D: `ReferenceError`

#### 답: 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를 출력하면, 여전히 원본 배열 `['🍕', '🍫', '🥑', '🍔']` 이에요.

--- ###### 110. 이 메소드는 무엇을 할까요? ```javascript JSON.parse(); ``` - A: JSON을 JavaScript 값으로 Parses - B: JavaScript 객체를 JSON으로 Parses - C: 모든 JavaScript 값을 JSON으로 Parses - D: JSON을 JavaScript 객체로만 Parses

#### 답: 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' } ```

--- ###### 111. 무엇이 출력 될까요? ```javascript let name = 'Lydia'; function getName() { console.log(name); let name = 'Sarah'; } getName(); ``` - A: Lydia - B: Sarah - C: `undefined` - D: `ReferenceError`

#### 답: 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 ```

--- ###### 112. 무엇이 출력 될까요? ```javascript function* generatorOne() { yield ['a', 'b', 'c']; } function* generatorTwo() { yield* ['a', 'b', 'c']; } const one = generatorOne(); const two = generatorTwo(); console.log(one.next().value); console.log(two.next().value); ``` - A: `a` 그리고 `a` - B: `a` 그리고 `undefined` - C: `['a', 'b', 'c']` 그리고 `a` - D: `a` 그리고 `['a', 'b', 'c']`

#### 답: 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 ```

--- ###### 113. 무엇이 출력 될까요? ```javascript console.log(`${((x) => x)('I love')} to program`); ``` - A: `I love to program` - B: `undefined to program` - C: `${(x => x)('I love') to program` - D: `TypeError`

#### 답: A 템플릿 리터러를 사용한 표현식은 첫번째로 평가돼요. 문자열은 표현식의 반환된 값을 포함하게 된다는 것을 의미하고, 이 경우 함수 `(x => x)('I love')`는 즉시 호출 돼요. 화살표 함수 `x => x`의 인수 값으로 `I love`를 전달 했어요. `x`는 `'I love'`이고 반환 될 거에요. 이 결과는 `I love to program` 이에요.

--- ###### 114. 무슨일이 발생할까요? ```javascript let config = { alert: setInterval(() => { console.log('Alert!'); }, 1000), }; config = null; ``` - A: `setInterval` 콜백은 호출되지 않을거에요 - B: `setInterval` 콜백은 한 번만 호출돼요 - C: `setInterval` 콜백은 여전히 매 초마다 호출돼요 - D: 결코 `config.alert()`를 호출 하지 않고, config 는 `null`이에요

#### 답: C 일반적으로 객체를 `null`로 설정했을 때, 객체는 더 이상 참조할 객체가 없어 _쓰레기 수집_ 되어요. 그러나, `setInterval`을 가진 콜백 함수는 화살표 함수 (`config` 객체로 감싸진) 이기 때문에, 콜백 함수는 여전히 `config` 객체를 참조 하고 있어요 참조가 존재하는 한, 객체는 쓰레기 수집 되지 않아요. 이것은 interval이므로, `config`를 `null` 또는 `delete`-ing `config.alert`로 설정하면 interval이 쓰레기 수집되지 않아, interval은 계속 호출됩니다 메모리에서 제거하기 위해서 `clearInterval(config.alert)`로 지워야 합니다. 지워지지 않았기 때문에, `setInterval` 콜백 함수는 매 1000ms (1s)마다 계속 호출 될 거에요.

--- ###### 115. 어느 method가 값 `'Hello world!'`를 반환 할까요? ```javascript const myMap = new Map(); const myFunc = () => 'greeting'; myMap.set(myFunc, 'Hello world!'); //1 myMap.get('greeting'); //2 myMap.get(myFunc); //3 myMap.get(() => 'greeting'); ``` - A: 1 - B: 2 - C: 2 그리고 3 - D: 모두

#### 답: B 키/값을 쌍으로 추가할 때 `set` 메소드를 사용하면, 키는 `set` 함수로 전달 된 첫 번째 인수의 값이 되고, 값은 `set` 함수로 전달된 두 번째 인수의 값이 될 거에요. 이 경우에 키는 _함수_ `() => 'greeting'`이고, 값은 `'Hello world'`예요. `myMap`은 이제 `{ () => 'greeting' => 'Hello world!' }` 예요. 1은 틀렸어요, 키는 `'greeting'`가 아니라 `() => 'greeting'`이기 때문이에요. 3은 틀렸어요, `get`메소드에 새로 생성한 함수를 파라미터로 전달 했기 때문이에요. 객체는 _참조_ 로 상호작용해요. 함수는 객체이기 때문에, 두 함수가 같다고 하더라도 절대로 동일하지 않아요: 메모리 안에 다른 장소의 참조를 가지고 있어요.

--- ###### 116. 무엇이 출력 될까요? ```javascript const person = { name: 'Lydia', age: 21, }; const changeAge = (x = { ...person }) => (x.age += 1); const changeAgeAndName = (x = { ...person }) => { x.age += 1; x.name = 'Sarah'; }; changeAge(person); changeAgeAndName(); console.log(person); ``` - A: `{name: "Sarah", age: 22}` - B: `{name: "Sarah", age: 23}` - C: `{name: "Lydia", age: 22}` - D: `{name: "Lydia", age: 23}`

#### 답: C `changeAge`와 `changeAgeAndName`함수 모두 _새롭게_ 만들어진 객체 `{ ...person }`를 기본값 매개변수로 가지고 있어요. 이 객체는 `person` 객체의 모든 키/값의 복사본을 가지고 있어요. 첫번째로, `changeAge`함수를 호출 했고, 그것의 인수로 `person` 객체를 전달 했어요. 이 함수는 `age`속성의 값을 1 증가 시켜요. `person`은 이제 `{ name: "Lydia", age: 22 }`예요. 그리고서, `changeAgeAndName` 함수를 호출 했지만, 파라미터를 전달하지 않았어요. 대신에, `x`의 값은 _새로운_ 객체와 같아요: `{ ...person }`. 새로운 객체이기 때문에, `person`객체의 속성의 값에 영향을 주지 않아요. `person`은 여전히 `{ name: "Lydia", age: 22 }`와 같아요.

--- ###### 117. 다음 선택지 중 어느 것이 `6`을 반환 할까요? ```javascript function sumValues(x, y, z) { return x + y + z; } ``` - A: `sumValues([...1, 2, 3])` - B: `sumValues([...[1, 2, 3]])` - C: `sumValues(...[1, 2, 3])` - D: `sumValues([1, 2, 3])`

#### 답: C 연산자 `...`를 사용하면, 반복 가능한 객체를 개별요소로 _spread_ 펼칠 수 있어요. `sumValues` 함수는 인수 3개를 받았어요: `x`, `y` 그리고 `z`. `...[1, 2, 3]`를 `sumValues` 함수에 전달하면 `1, 2, 3` 가 될 거예요.

--- ###### 118. 무엇이 출력 될까요? ```javascript let num = 1; const list = ['🥳', '🤠', '🥰', '🤪']; console.log(list[(num += 1)]); ``` - A: `🤠` - B: `🥰` - C: `SyntaxError` - D: `ReferenceError`

#### 답: B `+=` 연산자를 사용하면, `num`의 값을 `1` 씩 증가시켜요. `num`은 초기값 `1`을 가지고 있어요, 그래서 `1 + 1` 은 `2`예요.`list` 배열의 2번째 인덱스 아이템은 🥰 예요, `console.log(list[2])` 는 🥰 을 출력해요.

--- ###### 119. 무엇이 출력 될까요? ```javascript const person = { firstName: 'Lydia', lastName: 'Hallie', pet: { name: 'Mara', breed: 'Dutch Tulip Hound', }, getFullName() { return `${this.firstName} ${this.lastName}`; }, }; console.log(person.pet?.name); console.log(person.pet?.family?.name); console.log(person.getFullName?.()); console.log(member.getLastName?.()); ``` - A: `undefined` `undefined` `undefined` `undefined` - B: `Mara` `undefined` `Lydia Hallie` `ReferenceError` - C: `Mara` `null` `Lydia Hallie` `null` - D: `null` `ReferenceError` `null` `ReferenceError`

#### 답: 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`을 반환해요.

--- ###### 120. 무엇이 출력 될까요? ```javascript const groceries = ['banana', 'apple', 'peanuts']; if (groceries.indexOf('banana')) { console.log('We have to buy bananas!'); } else { console.log(`We don't have to buy bananas!`); } ``` - A: We have to buy bananas! - B: We don't have to buy bananas - C: `undefined` - D: `1`

#### 답: B if문에 조건 `groceries.indexOf("banana")`을 전달했어요. `groceries.indexOf("banana")`은 `0`을 반환하고, 이건 거짓 같은 값이에요. if문의 조건이 거짓 같은 값이기 때문에, 코드는 `else` 블록을 실행하고, `We don't have to buy bananas!`이 출력돼요.

--- ###### 121. 무엇이 출력 될까요? ```javascript const config = { languages: [], set language(lang) { return this.languages.push(lang); }, }; console.log(config.language); ``` - A: `function language(lang) { this.languages.push(lang }` - B: `0` - C: `[]` - D: `undefined`

#### 답: D `language` 메소드는 `setter`예요. Setters는 실제 값을 유지하지 않아요, 그들의 목적은 속성을 _수정_ 하는 거예요. `setter` 메소드를 부르면, `undefined`가 반환돼요.

--- ###### 122. 무엇이 출력 될까요? ```javascript const name = 'Lydia Hallie'; console.log(!typeof name === 'object'); console.log(!typeof name === 'string'); ``` - A: `false` `true` - B: `true` `false` - C: `false` `false` - D: `true` `true`

#### 답: C `typeof name`은 `"string"`을 반환해요. 문자열 `"string"`은 진짜 같은 값이고, `!typeof name`은 불리언 값 `false`을 반환해요. `false === "object"` 그리고 `false === "string"` 둘다 `false`을 반환해요. (특정한 형과 같은지(다른지) 알고 싶다면, `!typeof` 대신 `!==`을 사용 해야 해요.)

--- ###### 123. 무엇이 출력 될까요? ```javascript const add = (x) => (y) => (z) => { console.log(x, y, z); return x + y + z; }; add(4)(5)(6); ``` - A: `4` `5` `6` - B: `6` `5` `4` - C: `4` `function` `function` - D: `undefined` `undefined` `6`

#### 답: A `add`함수는 화살표 함수를 반환하는 함수를 반환하고, 반환한 함수는 화살표 함수를 반환하고, 반환한 함수는 화살표 함수를 반환해요(아직 나와 함께인가요?). 첫 번째 함수는 값이 `4`인 인수 `x`를 받아요. 값이 `5`인 인수 `y`를 받은 두 번째 함수를 호출해요. 그리고 우리는 값이 `6`인 인수 `z`를 받은 세 번째 함수를 호출해요. 값 `x`, `y` 그리고 `z`를 가진 마지막 화살표 함수에 접근하려고 할 때, JS 엔진은 그에 따른 값 `x` 그리고 `y`를 찾기 위해 스코프 체인을 올라가요. 이건 `4` `5` `6`을 반환해요.

--- ###### 124. 무엇이 출력 될까요? ```javascript async function* range(start, end) { for (let i = start; i <= end; i++) { yield Promise.resolve(i); } } (async () => { const gen = range(1, 3); for await (const item of gen) { console.log(item); } })(); ``` - A: `Promise {1}` `Promise {2}` `Promise {3}` - B: `Promise {}` `Promise {}` `Promise {}` - C: `1` `2` `3` - D: `undefined` `undefined` `undefined`

#### 답: 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`.

--- ###### 125. 무엇이 출력 될까요? ```javascript const myFunc = ({ x, y, z }) => { console.log(x, y, z); }; myFunc(1, 2, 3); ``` - A: `1` `2` `3` - B: `{1: 1}` `{2: 2}` `{3: 3}` - C: `{ 1: undefined }` `undefined` `undefined` - D: `undefined` `undefined` `undefined`

#### 답: D `myFunc`는 속성 `x`, `y` 그리고 `z`를 속성으로 가진 객체가 인수라고 예상해요. `x`, `y` 그리고 `z`의 속성을 가진 하나의 객체({x: 1, y: 2, z: 3}) 대신, 분리된 숫자 값 (1, 2, 3)을 전달했기 때문에 `x`, `y` 그리고 `z`는 기본값 `undefined`을 가져요.

--- ###### 126. 무엇이 출력 될까요? ```javascript function getFine(speed, amount) { const formattedSpeed = new Intl.NumberFormat('en-US', { style: 'unit', unit: 'mile-per-hour', }).format(speed); const formattedAmount = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', }).format(amount); return `The driver drove ${formattedSpeed} and has to pay ${formattedAmount}`; } console.log(getFine(130, 300)); ``` - A: The driver drove 130 and has to pay 300 - B: The driver drove 130 mph and has to pay \$300.00 - C: The driver drove undefined and has to pay undefined - D: The driver drove 130.00 and has to pay 300.00

#### 답: B `Intl.NumberFormat` 메소드를 사용하면, 숫자 값을 원하는 로케일로 만들 수 있어요. 숫자 값 `130`을 `unit`이 `mile-per-hour`인 로케일 `en-US`로 만들면, `130 mph`가 돼요. 숫자 값 `300`을 `currency`가 `USD`인 로케일 `en-US`로 만들면 `$300.00`가 돼요.

--- ###### 127. 무엇이 출력 될까요? ```javascript const spookyItems = ['👻', '🎃', '🕸']; ({ item: spookyItems[3] } = { item: '💀' }); console.log(spookyItems); ``` - A: `["👻", "🎃", "🕸"]` - B: `["👻", "🎃", "🕸", "💀"]` - C: `["👻", "🎃", "🕸", { item: "💀" }]` - D: `["👻", "🎃", "🕸", "[object Object]"]`

#### 답: B 객체를 분해함으로써, 오른쪽 객체의 값을 꺼내고, 꺼낸 값은 왼쪽 객체에 같은 속성 이름의 값으로 할당 할 수 있어요. 이 경우, 값 "💀"을 `spookyItems[3]`에 할당했어요. 이건 `spookyItems`을 수정, 즉 배열에 "💀"을 추가한다는 의미예요. `spookyItems`을 출력하면, `["👻", "🎃", "🕸", "💀"]`이 출력ㅗ대요.

--- ###### 128. 무엇이 출력 될까요? ```javascript const name = 'Lydia Hallie'; const age = 21; console.log(Number.isNaN(name)); console.log(Number.isNaN(age)); console.log(isNaN(name)); console.log(isNaN(age)); ``` - A: `true` `false` `true` `false` - B: `true` `false` `false` `false` - C: `false` `false` `true` `false` - D: `false` `true` `false` `true`

#### 답: C `Number.isNaN` 메소드를 사용하면, 전달한 값이 _숫자 값_ 그리고 `NaN`인지 확인 할 수 있어요. `name`은 숫자 값이 아니에요, 따라서 `Number.isNaN(name)` 은 `false`을 반환해요. `age`는 숫자 값이지만, `NaN`은 아니에요, 따라서 `Number.isNaN(age)`은 `false`을 반환해요. `isNaN` 메소드를 사용하면, 전달한 값이 숫자가 아닌지 확인할 수 있어요. `name`은 숫자가 아니에요, 따라서 `isNaN(name)`은 true를 반환해요. `age`은 숫자이고, 따라서 `isNaN(age)`은 `false`을 반환해요.

--- ###### 129. 무엇이 출력 될까요? ```javascript const randomValue = 21; function getInfo() { console.log(typeof randomValue); const randomValue = 'Lydia Hallie'; } getInfo(); ``` - A: `"number"` - B: `"string"` - C: `undefined` - D: `ReferenceError`

#### 답: D `const` 키워드를 사용해 선언된 변수는 초기화 되기 전에 참조 할 수 없어요: 이건 _일시적 사각지대_ 라고 불려요. `getInfo`힘수에서, 변수 `randomValue`는 함수 `getInfo`의 스코프 안에 있어요. `typeof randomValue`의 값을 출력하고 싶은 줄에서, 변수 `randomValue`는 아직 초기화 되지 않았어요: `ReferenceError`가 던져져요! 변수 `randomValue`를 함수 `getInfo`안에 선언했기 때문에 엔진은 스코프 체인 아래로 내려가지 않아요.

--- ###### 130. 무엇이 출력 될까요? ```javascript const myPromise = Promise.resolve('Woah some cool data'); (async () => { try { console.log(await myPromise); } catch { throw new Error(`Oops didn't work`); } finally { console.log('Oh finally!'); } })(); ``` - A: `Woah some cool data` - B: `Oh finally!` - C: `Woah some cool data` `Oh finally!` - D: `Oops didn't work` `Oh finally!`

#### 답: C `try` 블록에서, `myPromise`의 awaited 값을 출력하고 있어요: `"Woah some cool data"`. `try` 블록에서 오류가 없기 때문에, `catch` 블록 안의 코드는 실행되지 않아요. `finally` 블록 안의 코드는 _항상_ 실행되고, `"Oh finally!"`가 출력돼요.

--- ###### 131. 무엇이 출력 될까요? ```javascript const emojis = ['🥑', ['✨', '✨', ['🍕', '🍕']]]; console.log(emojis.flat(1)); ``` - A: `['🥑', ['✨', '✨', ['🍕', '🍕']]]` - B: `['🥑', '✨', '✨', ['🍕', '🍕']]` - C: `['🥑', ['✨', '✨', '🍕', '🍕']]` - D: `['🥑', '✨', '✨', '🍕', '🍕']`

#### 답: B `flat`를 사용하면, 새로운 평평한 배열을 만들어요. 평평한 배열의 깊이는 전달한 값에 달려있어요. 이 경우, 값 `1`(기본 값)을 전달했고,, 1번째 깊이에 있는 배열만 연결된다는 뜻이에요. 이 경우에선 `['🥑']` 그리고 `['✨', '✨', ['🍕', '🍕']]`. 두 배열을 연결하면 `['🥑', '✨', '✨', ['🍕', '🍕']]`가 돼요.

--- ###### 132. 무엇이 출력 될까요? ```javascript class Counter { constructor() { this.count = 0; } increment() { this.count++; } } const counterOne = new Counter(); counterOne.increment(); counterOne.increment(); const counterTwo = counterOne; counterTwo.increment(); console.log(counterOne.count); ``` - A: `0` - B: `1` - C: `2` - D: `3`

#### 답: D `counterOne`는 클래스 `Counter`의 인스턴스예요. counter 클래스는 생성자 안에 속성 `count`와 `increment` 메소드를 포함해요. 우선, `counterOne.increment()`를 사용해 `increment` 메소드를 두 번 호출해요. 현재, `counterOne.count`는 `2`예요. 그리고서, 새로운 변수 `counterTwo`를 만들고, `counterOne`과 동일하게 설정해요. 객체는 참조로 상호작용 하므로, `counterOne`을 가리키는 같은 메모리 영역에 새로운 참조를 만들었어요. 메모리의 같은 장소에 존재 하므로, 참조를 가진 `counterTwo` 객체의 모든 변화는, `counterOne` 객체에도 적용돼요. 지금, `counterTwo.count`은 `2`예요. `count`를 `3`으로 만드는 `counterTwo.increment()`를 호출해요. 그리고서, `counterOne`의 count를 출력하고, `3`이 출력돼요.

--- ###### 133. 무엇이 출력 될까요? ```javascript const myPromise = Promise.resolve(Promise.resolve('Promise!')); function funcOne() { myPromise.then((res) => res).then((res) => console.log(res)); setTimeout(() => console.log('Timeout!'), 0); console.log('Last line!'); } async function funcTwo() { const res = await myPromise; console.log(await res); setTimeout(() => console.log('Timeout!'), 0); console.log('Last line!'); } funcOne(); funcTwo(); ``` - A: `Promise! Last line! Promise! Last line! Last line! Promise!` - B: `Last line! Timeout! Promise! Last line! Timeout! Promise!` - C: `Promise! Last line! Last line! Promise! Timeout! Timeout!` - D: `Last line! Promise! Promise! Last line! Timeout! Timeout!`

#### 답: 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!`을 출력해요.

--- ###### 134. `index.js`에서 `sum.js` 안에 있는 `sum`을 호출 하려면 어떻게 해야하나요? ```javascript // sum.js export default function sum(x) { return x + x; } // index.js import * as sum from './sum'; ``` - A: `sum(4)` - B: `sum.sum(4)` - C: `sum.default(4)` - D: Default aren't imported with `*`, only named exports

#### 답: 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`을 불러 함수를 호출 할 수 있어요.

--- ###### 135. 무엇이 출력 될까요? ```javascript const handler = { set: () => console.log('Added a new property!'), get: () => console.log('Accessed a property!'), }; const person = new Proxy({}, handler); person.name = 'Lydia'; person.name; ``` - A: `Added a new property!` - B: `Accessed a property!` - C: `Added a new property!` `Accessed a property!` - D: Nothing gets logged

#### 답: 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!"`을 출력 해요.

--- ###### 136. 다음 중 어느 것이 `person` 객체를 수정 할 수 있을까요? ```javascript const person = { name: 'Lydia Hallie' }; Object.seal(person); ``` - A: `person.name = "Evan Bacon"` - B: `person.age = 21` - C: `delete person.name` - D: `Object.assign(person, { age: 21 })`

#### 답: A `Object.seal`을 사용하면, 새로운 속성이 _추가_ 되거나, 혹은 존재하는 속성이 _제거_ 되는 것을 막을 수 있어요. 그러나, 여전히 존재하는 속성의 값을 수정 할 수 있어요.

--- ###### 137. 다음 중 어느 것이 `person` 객체를 수정 할 수 있을까요? ```javascript const person = { name: 'Lydia Hallie', address: { street: '100 Main St', }, }; Object.freeze(person); ``` - A: `person.name = "Evan Bacon"` - B: `delete person.address` - C: `person.address.street = "101 Main St"` - D: `person.pet = { name: "Mara" }`

#### 답: C `Object.freeze` 메소드는 객체를 _얼려요_ . 속성을 추가, 수정, 제거 할 수 없어요. 하지만, 객체를 _얕은_ 수준으로만 얼리고, 이건 객체의 _직접적인_ 속성만 얼려진다는 의미예요. 속성이 `address` 와 같은 객체인 경우, 객체의 속성은 얼려지지 않고, 수정될 수 있어요.

--- ###### 138. 무엇이 출력 될까요? ```javascript const add = (x) => x + x; function myFunc(num = 2, value = add(num)) { console.log(num, value); } myFunc(); myFunc(3); ``` - A: `2` `4` and `3` `6` - B: `2` `NaN` and `3` `NaN` - C: `2` `Error` and `3` `6` - D: `2` `4` and `3` `Error`

#### 답: 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`을 반환해요.

--- ###### 139. 무엇이 출력 될까요? ```javascript class Counter { #number = 10; increment() { this.#number++; } getNum() { return this.#number; } } const counter = new Counter(); counter.increment(); console.log(counter.#number); ``` - A: `10` - B: `11` - C: `undefined` - D: `SyntaxError`

#### 답: D ES2020에서, `#`을 사용한 private 변수를 추가 할 수 있어요. 클래스 외부에서 private 변수에 접근 할 수 없어요. `counter.#number`을 출력하려고 할 때, SyntaxError가 던져져요: `Counter` 클래스 외부에서 private 변수에 접근 할 수 없어요!

--- ###### 140. 무엇이 빠졌을까요? ```javascript const teams = [ { name: 'Team 1', members: ['Paul', 'Lisa'] }, { name: 'Team 2', members: ['Laura', 'Tim'] }, ]; function* getMembers(members) { for (let i = 0; i < members.length; i++) { yield members[i]; } } function* getTeams(teams) { for (let i = 0; i < teams.length; i++) { // ✨ SOMETHING IS MISSING HERE ✨ } } const obj = getTeams(teams); obj.next(); // { value: "Paul", done: false } obj.next(); // { value: "Lisa", done: false } ``` - A: `yield getMembers(teams[i].members)` - B: `yield* getMembers(teams[i].members)` - C: `return getMembers(teams[i].members)` - D: `return yield getMembers(teams[i].members)`

#### 답: B `teams` 배열의 `members`의 각 요소를 계속해서 반복하기 위해선, `teams[i].members`를 제너레이터 함수 `getMembers`에 전달해야해요. 제너레이터 함수는 제너리에터 객체를 리턴해요. 제너레이터 객체의 각 요소를 계속해서 반복 하기 위해선, `yield*`를 사용해야 해요. `yield`, `return yield` 또는 `return`를 쓰면, 모든 제너레이터 함수는 첫번째로 호출한 `next` 메소드가 반환한 값을 가져요.

--- ###### 141. 무엇이 출력 될까요? ```javascript const person = { name: 'Lydia Hallie', hobbies: ['coding'], }; function addHobby(hobby, hobbies = person.hobbies) { hobbies.push(hobby); return hobbies; } addHobby('running', []); addHobby('dancing'); addHobby('baking', person.hobbies); console.log(person.hobbies); ``` - A: `["coding"]` - B: `["coding", "dancing"]` - C: `["coding", "dancing", "baking"]` - D: `["coding", "running", "dancing", "baking"]`

#### 답: 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"]`예요.

--- ###### 142. 무엇이 출력 될까요? ```javascript class Bird { constructor() { console.log("I'm a bird. 🦢"); } } class Flamingo extends Bird { constructor() { console.log("I'm pink. 🌸"); super(); } } const pet = new Flamingo(); ``` - A: `I'm pink. 🌸` - B: `I'm pink. 🌸` `I'm a bird. 🦢` - C: `I'm a bird. 🦢` `I'm pink. 🌸` - D: Nothing, we didn't call any method

#### 답: B `Flamingo` 클래스의 인스턴스인 변수 `pet` 생성했어요. 인스턴스를 인스턴스화 할 때, `Flamingo`의 `constructor`를 불러요. 우선, `"I'm pink. 🌸"`가 출력되고, 그 후에 `super()`를 불러요. `super()`는 부모 클래스 `Bird`의 constructor를 불러요. `Bird`의 constructor 를 불러, `"I'm a bird. 🦢"`가 출력돼요.

--- ###### 143. 다음 중 어느 것의 결과가 오류일까요? ```javascript const emojis = ['🎄', '🎅🏼', '🎁', '⭐']; /* 1 */ emojis.push('🦌'); /* 2 */ emojis.splice(0, 2); /* 3 */ emojis = [...emojis, '🥂']; /* 4 */ emojis.length = 0; ``` - A: 1 - B: 1 and 2 - C: 3 and 4 - D: 3

#### 답: D `const` 키워드는 단순히 변수의 값을 _재선언_ 할 수 없고, _읽기만_ 가능하다는 의미예요. 하지만, 값 자체가 불변하는 건 아니에요. 배열 `emojis`의 속성을 수정할 수 있는데, 예를 들자면 새로운 값을 추가하거나, 원본 배열 자체를 수정(splice)하거나, 배열의 길이를 0으로 설정 할 수 있어요.

--- ###### 144. `person`에 무엇을 추가해야 `[...person]`의 결과로 `["Lydia Hallie", 21]`를 얻을 수 있을까요? ```javascript const person = { name: "Lydia Hallie", age: 21 } [...person] // ["Lydia Hallie", 21] ``` - A: 객체는 기본적으로 반복 가능 하므로, 아무것도 하지 않아요. - B: `*[Symbol.iterator]() { for (let x in this) yield* this[x] }` - C: `*[Symbol.iterator]() { yield* Object.values(this) }` - D: `*[Symbol.iterator]() { for (let x in this) yield this }`

#### 답: C 객체는 기본적으로 반복 불가능해요. 반복 가능한 객체는 iterator protocol이 제공되면 반복 가능해요. 제너레이터 함수 `*[Symbol.iterator]() {}`을 만드는 제너레이터 객체를 반환하는 iterator symbol `[Symbol.iterator]`을 수동으로 추가 할 수 있어요. 배열 `["Lydia Hallie", 21]`을 반환 하려면 제너레이터 함수는 `person` 객체의 `Object.values`를 yield 해야해요: `yield* Object.values(this)`.

--- ###### 145. 무엇이 출력 될까요? ```javascript let count = 0; const nums = [0, 1, 2, 3]; nums.forEach((num) => { if (num) count += 1; }); console.log(count); ``` - A: 1 - B: 2 - C: 3 - D: 4

#### 답: C `forEach` 순환에 포함 된 `if` 조건문은 `num`의 값이 진짜 같은 값인지 또는 가짜 같은 값인지 확인해요. `nums`배열의 첫 번째 값은 거짓 같은 값 `0`이고, `if` 조건문의 코드 블럭은 실행되지 않아요. `count` 는 오직 `nums` 배열의 다른 숫자 3개에 대해서만 증가해요. `1`, `2` 그리고 `3`. `count`는 3번 동안 `1` 씩 증가하고, `count`의 값은 `3`이에요.

--- ###### 146. 무엇이 출력 될까요? ```javascript function getFruit(fruits) { console.log(fruits?.[1]?.[1]); } getFruit([['🍊', '🍌'], ['🍍']]); getFruit(); getFruit([['🍍'], ['🍊', '🍌']]); ``` - A: `null`, `undefined`, 🍌 - B: `[]`, `null`, 🍌 - C: `[]`, `[]`, 🍌 - D: `undefined`, `undefined`, 🍌

#### 답: D `?`는 객체 내에서 더 깊이 중첩된 속성에 접근하는 것을 선택적으로 허용해요. `fruits`배열의 인덱스 `1`에 있는 하위 배열의 인덱스 `1`의 아이템을 출력하려해요. `fruits`배열의 인덱스 `1`에 하위 배열이 존재하지 않는다면, 간단히 `undefined`를 반환할 거예요. `fruits` 배열의 인덱스 `1`에 하위배열이 있지만, 하위 배열에 인덱스 `1` 의 아이템이 없다면, 그것 역시 `undefined`를 반환해요. 우선, `[['🍊', '🍌'], ['🍍']]`의 하위 배열의 두 번째 아이템 `['🍍']`을 출력해요 . 하위 배열은 아이템 하나만 가지고 있고, 이건 인덱스 `1`에 대한 아이템을 갖고 있지 않다는 의미로 `undefined`를 반환해요. 그리고서, 인수에 어떤 값도 전달하지 않은 `getFruits` 함수를 호출 하고, `fruits`은 기본값으로 값 `undefined`을 가져요. `fruits`의 인덱스 `1`의 아이템을 선택적으로 연결(conditionally chaining)하기 때문에, 인덱스 `1`에 아이템이 존재하지 않아 `undefined`를 반환해요. 마지막으로, `['🍍'], ['🍊', '🍌']`의 하위 배열 `['🍊', '🍌']`의 두번째 아이템을 출력하려고 해요. 하위 배열의 인덱스 `1`의 아이템인 `🍌`이 출력돼요.

--- ###### 147. 무엇이 출력 될까요? ```javascript class Calc { constructor() { this.count = 0 } increase() { this.count++ } } const calc = new Calc() new Calc().increase() console.log(calc.count) ``` - A: `0` - B: `1` - C: `undefined` - D: `ReferenceError`

#### 답: A 변수 `calc`를 `Calc` 클래스의 새로운 인스턴스로 설정 했어요. 그리고서, 새로운 인스턴스 `Calc`를 인스턴스화 하고, 이 인스턴스의 `increase` 메소드를 호출 했어요. 속성 count은 `Calc` 클래스의 생성자 안에 있기 때문에 , 속성 count은 `Calc`의 프로토타입에 공유될 수 없어요. 인스턴스 calc이 가리키는 count의 값은 업데이트 되지 않고, count는 여전히 `0`예요.

--- ###### 148. 무엇이 출력 될까요? ```javascript const user = { email: "e@mail.com", password: "12345" } const updateUser = ({ email, password }) => { if (email) { Object.assign(user, { email }) } if (password) { user.password = password } return user } const updatedUser = updateUser({ email: "new@email.com" }) console.log(updatedUser === user) ``` - A: `false` - B: `true` - C: `TypeError` - D: `ReferenceError`

#### 답: B `updateUser` 함수는 값이 전달 되면 user의 속성 `email` 과 `password`의 값을 업데이트 하고, `user`객체를 반환해요. `updateUser` 함수의 반환된 값은 객체 `user` 이고, updateUser의 값은 `user`가 가리키는 `user` 객체의 참조와 같다는 의미예요. `updatedUser === user`는 `true`예요.

--- ###### 149. 무엇이 출력 될까요? ```javascript const fruit = ['🍌', '🍊', '🍎'] fruit.slice(0, 1) fruit.splice(0, 1) fruit.unshift('🍇') console.log(fruit) ``` - A: `['🍌', '🍊', '🍎']` - B: `['🍊', '🍎']` - C: `['🍇', '🍊', '🍎']` - D: `['🍇', '🍌', '🍊', '🍎']`

#### 답: C 우선, fruit 배열에 `slice` 메소드를 호출해요. slice 메소드는 원본 배열을 수정하지 않지만, 배열에서 잘라낸(slice) 값을 반환해요: 바나나 이모지. 그리고서, fruit 배열에 `splice` 메소드를 호출해요. splice 메소드는 원본 배열을 수정하고, 이제 fruit 배열은 `['🍊', '🍎']`로 구성돼요. 마지막엔, `fruit` 배열에 `unshift` 메소드를 호출하고, 이 경우엔 제공된 값 ‘🍇’을 배열의 첫 번째 요소로 추가해 원본 배열을 수정해요. 이제 fruit 배열은 `['🍇', '🍊', '🍎']`로 구성돼요.

--- ###### 150. 무엇이 출력 될까요? ```javascript const animals = {}; let dog = { emoji: '🐶' } let cat = { emoji: '🐈' } animals[dog] = { ...dog, name: "Mara" } animals[cat] = { ...cat, name: "Sara" } console.log(animals[dog]) ``` - A: `{ emoji: "🐶", name: "Mara" }` - B: `{ emoji: "🐈", name: "Sara" }` - C: `undefined` - D: `ReferenceError`

#### 답: 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" }`를 반환해요.

--- ###### 151. 무엇이 출력 될까요? ```javascript const user = { email: "my@email.com", updateEmail: email => { this.email = email } } user.updateEmail("new@email.com") console.log(user.email) ``` - A: `my@email.com` - B: `new@email.com` - C: `undefined` - D: `ReferenceError`

#### 답: A `updateEmail`함수는 화살표 함수로, `user`객체에 바인딩 되지 않았어요. `this`키워드는 `user`객체를 참조하지 않지만, 이 경우엔 전역 범위를 참조하고 있다는 의미예요. `user` 객체의 `email` 는 업데이트 되지 않아요. `user.email`을 출력할 때, `my@email.com`의 원래의 값이 반환되어요.

--- ###### 152. 무엇이 출력 될까요? ```javascript const promise1 = Promise.resolve('First') const promise2 = Promise.resolve('Second') const promise3 = Promise.reject('Third') const promise4 = Promise.resolve('Fourth') const runPromises = async () => { const res1 = await Promise.all([promise1, promise2]) const res2 = await Promise.all([promise3, promise4]) return [res1, res2] } runPromises() .then(res => console.log(res)) .catch(err => console.log(err)) ``` - A: `[['First', 'Second'], ['Fourth']]` - B: `[['First', 'Second'], ['Third', 'Fourth']]` - C: `[['First', 'Second']]` - D: `'Third'`

#### 답: D `Promise.all` 메소드는 프로미스를 병렬로 실행해요. 만약 하나의 프로미스가 실패하면, `Promise.all` 메소드는 rejected 프로미스의 값을 가지고 _rejects_ 되어요. 이 경우, `promise3`는 값 `"Third"`과 함께 rejected 되었어요. `runPromises` 호출에 연결되어 있고 `runPromises` 함수 안에서 모든 에러를 잡은 `catch` 메소드에서 rejected 값을 잡아요. `promise3`가 이 값과 함께 rejected 되어 `"Third"`만 출력돼요.

--- ###### 153. 무엇이 `method`의 값이어야 `{ name: "Lydia", age: 22 }`를 출력할까요? ```javascript const keys = ["name", "age"] const values = ["Lydia", 22] const method = /* ?? */ Object[method](keys.map((_, i) => { return [keys[i], values[i]] })) // { name: "Lydia", age: 22 } ``` - A: `entries` - B: `values` - C: `fromEntries` - D: `forEach`

#### 답: C `fromEntries` 메소드는 2차원 배열을 객체로 변환해요. 각 하위 배열의 첫번 째 요소는 키가 될거고, 각 하위 배열의 요소의 두번째 요소는 값이 될거에요. 이 경우엔, keys배열에서 현재 인덱스의 아이템을 첫 번재 요소로, values의 배열에서 현재 인덱스의 아이템을 두번째 요소로 반환하는 `keys` 배열을 매핑해요. 키와 값의 집합을 포함하고 있는 하위 배열을 만들었고, `{ name: "Lydia", age: 22 }`가 되어.

--- ###### 154. 무엇이 출력 될까요? ```javascript const createMember = ({ email, address = {}}) => { const validEmail = /.+\@.+\..+/.test(email) if (!validEmail) throw new Error("Valid email pls") return { email, address: address ? address : null } } const member = createMember({ email: "my@email.com" }) console.log(member) ``` - A: `{ email: "my@email.com", address: null }` - B: `{ email: "my@email.com" }` - C: `{ email: "my@email.com", address: {} }` - D: `{ email: "my@email.com", address: undefined }`

#### 답: C `address`의 기본 값은 빈 객체 `{}`예요. 변수 `member`의 값을 `createMember` 함수에서 반환한 값으로 설정하고, address의 값을 전달하지 않았어요, address의 값은 빈 객체 `{}`가 기본 값이예요. 빈객체는 진짜 같은 값으로, 조건 `address ? address : null`에서 `true`를 반환한다는 의미예요. address의 값은 빈 객체 `{}`예요.

--- ###### 155. 무엇이 출력 될까요? ```javascript let randomValue = { name: "Lydia" } randomValue = 23 if (!typeof randomValue === "string") { console.log("It's not a string!") } else { console.log("Yay it's a string!") } ``` - A: `It's not a string!` - B: `Yay it's a string!` - C: `TypeError` - D: `undefined`

#### 답: B `if`문 안에 조건은 `!typeof randomValue`값이 `"string"`와 같은지 여부를 확인해요. `!` 연산자는 값을 불리언 값으로 변환해요. 값이 진짜 같은 값이라면 반환될 값은 `false`가 될 거고, 만약 값이 가짜 같은 값이라면 반환될 값은 `true`가 될 거예요. 이 경우에서, `typeof randomValue`의 반환된 값은 진짜 같은 값인 `"number"`이고, `!typeof randomValue`의 값은 불리언 값 `false`라는 의미예요. `!typeof randomValue === "string"`은 실제로 `false === "string"`을 확인하기 때문에 항상 false를 반환해요. 조건은 `false`을 반환 하므로, `else`문의 코드 블록이 실행되어 `Yay it's a string!`가 출력돼요.