From 4e13f8dbef600f25689f79452bbb10b6555c66ab Mon Sep 17 00:00:00 2001 From: NterChoi Date: Sat, 16 May 2026 12:12:32 +0900 Subject: [PATCH 1/8] =?UTF-8?q?[=EC=B6=A9=EB=8F=8C=ED=95=B4=EA=B2=B0]=20Pa?= =?UTF-8?q?rt1=209.3=20class=20extends=20Object=20=EA=B3=BC=EC=A0=9C=20?= =?UTF-8?q?=ED=95=B4=EC=84=A4=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../3-class-extend-object/solution.md | 25 ++++--------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md index 7b5ee6ca2..83305a5c9 100644 --- a/1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md +++ b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md @@ -1,6 +1,6 @@ 먼저, 해당 코드가 왜 작동하지 않는지 살펴봐야 합니다. -코드를 실행하면 이유를 찾을 수 있습니다. 상속 받는 클래스의 생성자는 `super()`를 반드시 호출해야 합니다. 그렇지 않으면 `"this"`가 '정의'되지 않습니다. +코드를 실행하면 이유를 찾을 수 있습니다. 상속받는 클래스의 생성자는 `super()`를 반드시 호출해야 합니다. 그렇지 않으면 `"this"`가 '정의'되지 않습니다. 수정한 코드는 다음과 같습니다. @@ -21,22 +21,14 @@ alert( rabbit.hasOwnProperty('name') ); // true 그런데 이게 끝이 아닙니다. -<<<<<<< HEAD -위와 같이 수정 해도, 여전히 `"class Rabbit extends Object"`와 `class Rabbit`는 다른점이 있습니다. -======= -Even after the fix, there's still an important difference between `"class Rabbit extends Object"` and `class Rabbit`. ->>>>>>> upstream/master +위와 같이 수정해도, 여전히 `"class Rabbit extends Object"`와 `class Rabbit` 사이에는 중요한 차이가 있습니다. 아시다시피 'extends' 문법은 두 개의 프로토타입을 설정합니다. 1. 생성자 함수의 `"prototype"` 사이(일반 메서드용) 2. 생성자 함수 자체 사이(정적 메서드용) -<<<<<<< HEAD -예시의 `class Rabbit extends Object`는 다음과 같은 관계를 만들죠. -======= -In the case of `class Rabbit extends Object` it means: ->>>>>>> upstream/master +예시의 `class Rabbit extends Object`는 다음과 같은 관계를 만듭니다. ```js run class Rabbit extends Object {} @@ -45,11 +37,7 @@ alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true alert( Rabbit.__proto__ === Object ); // (2) true ``` -<<<<<<< HEAD 따라서 `Rabbit`은 아래와 같이 `Rabbit`을 통해 `Object`의 정적 메서드에 접근할 수 있습니다. -======= -So `Rabbit` now provides access to the static methods of `Object` via `Rabbit`, like this: ->>>>>>> upstream/master ```js run class Rabbit extends Object {} @@ -79,11 +67,8 @@ alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // Error 이런 이유 때문에 `Rabbit`에서 `Object`의 정적 메서드를 사용할 수 없습니다. -<<<<<<< HEAD -한편, `Function.prototype`은 `call`, `bind` 등의 '일반' 함수 메서드를 가집니다. 내장 객체, `Object`의 생성자는 `Object.__proto__ === Function.prototype` 관계를 갖기 때문에 `Function.prototype`에 정의된 일반 함수 메서드는 두 경우 모두에 사용할 수 있습니다. -======= -By the way, `Function.prototype` also has "generic" function methods, like `call`, `bind` etc. They are ultimately available in both cases, because for the built-in `Object` constructor, `Object.__proto__ === Function.prototype`. ->>>>>>> upstream/master +한편, `Function.prototype`은 `call`, `bind` 등의 '일반' 함수 메서드를 가집니다. 내장 객체 `Object`의 생성자는 `Object.__proto__ === Function.prototype` 관계를 갖기 때문에 `Function.prototype`에 정의된 일반 함수 메서드는 두 경우 모두에 사용할 수 있습니다. + 이해를 돕기 위한 그림: From 599786699f32cebd29b63294351a29548527734d Mon Sep 17 00:00:00 2001 From: NterChoi Date: Sat, 16 May 2026 13:14:08 +0900 Subject: [PATCH 2/8] =?UTF-8?q?[=EB=B2=88=EC=97=AD]=20Part1=209.3=20?= =?UTF-8?q?=EC=A0=95=EC=A0=81=20=EB=A9=94=EC=84=9C=EB=93=9C=EC=99=80=20?= =?UTF-8?q?=EC=A0=95=EC=A0=81=20=ED=94=84=EB=A1=9C=ED=8D=BC=ED=8B=B0=20?= =?UTF-8?q?=EC=B6=A9=EB=8F=8C=20=ED=95=B4=EA=B2=B0=20=EB=B0=8F=20=EB=AF=B8?= =?UTF-8?q?=EB=B2=88=EC=97=AD=EB=B6=84=20=EB=B2=88=EC=97=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../03-static-properties-methods/article.md | 59 ++++--------------- 1 file changed, 10 insertions(+), 49 deletions(-) diff --git a/1-js/09-classes/03-static-properties-methods/article.md b/1-js/09-classes/03-static-properties-methods/article.md index a5e9916e7..f1d9ffac4 100644 --- a/1-js/09-classes/03-static-properties-methods/article.md +++ b/1-js/09-classes/03-static-properties-methods/article.md @@ -1,15 +1,9 @@ # 정적 메서드와 정적 프로퍼티 -<<<<<<< HEAD `"prototype"`이 아닌 클래스 함수 자체에 메서드를 설정할 수도 있습니다. 이런 메서드를 *정적(static)* 메서드라고 부릅니다. 정적 메서드는 아래와 같이 클래스 안에서 `static` 키워드를 붙여 만들 수 있습니다. -======= -We can also assign a method to the class as a whole. Such methods are called *static*. - -In a class declaration, they are prepended by `static` keyword, like this: ->>>>>>> upstream/master ```js run class User { @@ -37,17 +31,9 @@ User.staticMethod(); // true `User.staticMethod()`가 호출될 때 `this`의 값은 클래스 생성자인 `User` 자체가 됩니다(점 앞 객체). -<<<<<<< HEAD -정적 메서드는 어떤 특정한 객체가 아닌 클래스에 속한 함수를 구현하고자 할 때 주로 사용됩니다. - -객체 `Article`이 여러 개 있고 이들을 비교해줄 함수가 필요하다고 가정해 봅시다. 가장 먼저 아래와 같이 `Article.compare`를 추가하는 방법이 떠오를 겁니다. -======= -Usually, static methods are used to implement functions that belong to the class as a whole, but not to any particular object of it. - -For instance, we have `Article` objects and need a function to compare them. +정적 메서드는 어떤 특정한 객체가 아닌 클래스 전체에 속한 함수를 구현하고자 할 때 주로 사용됩니다. -A natural solution would be to add `Article.compare` static method: ->>>>>>> upstream/master +객체 `Article`이 여러 개 있고 이들을 비교해줄 함수가 필요하다고 가정해 봅시다. 가장 먼저 아래와 같이 `Article.compare` 정적 메서드를 추가하는 방법이 떠오를 겁니다. ```js run class Article { @@ -77,17 +63,11 @@ articles.sort(Article.compare); alert( articles[0].title ); // CSS ``` -<<<<<<< HEAD -여기서 `Article.compare`는 article(글)을 비교해주는 수단으로, 글 전체를 '위에서' 바라보며 비교를 수행합니다. `Article.compare`이 글 하나의 메서드가 아닌 클래스의 메서드여야 하는 이유가 여기에 있습니다. +여기서 `Article.compare`는 article(글)을 비교해주는 수단으로, article 하나에 속한 메서드가 아니라 클래스 전체에 속한 메서드입니다. -이번에 살펴볼 예시는 '팩토리' 메서드를 구현한 코드입니다. 다양한 방법을 사용해 조건에 맞는 article 인스턴스를 만들어야 한다고 가정해 봅시다. -======= -Here `Article.compare` method stands "above" articles, as a means to compare them. It's not a method of an article, but rather of the whole class. +이번에 살펴볼 예시는 소위 '팩토리(factory)' 메서드를 구현한 코드입니다. -Another example would be a so-called "factory" method. - -Let's say, we need multiple ways to create an article: ->>>>>>> upstream/master +다양한 방법을 사용해 조건에 맞는 article 인스턴스를 만들어야 한다고 가정해 봅시다. 1. 매개변수(`title`, `date` 등)를 이용해 관련 정보가 담긴 article 생성 2. 오늘 날짜를 기반으로 비어있는 article 생성 @@ -95,11 +75,7 @@ Let's say, we need multiple ways to create an article: 첫 번째 방법은 생성자를 사용해 구현할 수 있습니다. 두 번째 방법은 클래스에 정적 메서드를 만들어 구현할 수 있습니다. -<<<<<<< HEAD 아래 `Article.createTodays()`같이 말이죠. -======= -Such as `Article.createTodays()` here: ->>>>>>> upstream/master ```js run class Article { @@ -126,23 +102,13 @@ alert( article.title ); // Today's digest 정적 메서드는 아래 예시와 같이 항목 검색, 저장, 삭제 등을 수행해주는 데이터베이스 관련 클래스에도 사용됩니다. ```js -<<<<<<< HEAD // Article은 article을 관리해주는 특별 클래스라고 가정합시다. // article 삭제에 쓰이는 정적 메서드 Article.remove({id: 12345}); ``` +````warn header="정적 메서드는 클래스에서 호출할 수 있으며, 개별 객체에서는 호출할 수 없습니다." -## 정적 프로퍼티 -======= -// assuming Article is a special class for managing articles -// static method to remove the article by id: -Article.remove({id: 12345}); -``` - -````warn header="Static methods aren't available for individual objects" -Static methods are callable on classes, not on individual objects. - -E.g. such code won't work: +예를 들어 아래 코드는 동작하지 않습니다. ```js // ... @@ -150,8 +116,7 @@ article.createTodays(); /// Error: article.createTodays is not a function ``` ```` -## Static properties ->>>>>>> upstream/master +## 정적 프로퍼티 [recent browser=Chrome] @@ -171,11 +136,7 @@ alert( Article.publisher ); // Ilya Kantor Article.publisher = "Ilya Kantor"; ``` -<<<<<<< HEAD -## 정적 프로퍼티와 메서드 상속 -======= -## Inheritance of static properties and methods [#statics-and-inheritance] ->>>>>>> upstream/master +## 정적 프로퍼티와 메서드 상속 [#statics-and-inheritance] 정적 프로퍼티와 메서드는 상속됩니다. @@ -224,7 +185,7 @@ rabbits[0].run(); // 검은 토끼가 속도 5로 달립니다. alert(Rabbit.planet); // 지구 ``` -이제 `Rabbit.compare`을 호출하면 `Animal.compare`가 호출됩니다. +이제 `Rabbit.compare`를 호출하면 `Animal.compare`가 호출됩니다. 이게 가능한 이유는 프로토타입 때문입니다. 이미 예상하셨겠지만, `extends` 키워드는 `Rabbit`의 `[[Prototype]]`이 `Animal`을 참조하도록 해줍니다. From f44cc4bfbb9b8fb8ac402a9273d3ebf90e0925b6 Mon Sep 17 00:00:00 2001 From: NterChoi Date: Sat, 16 May 2026 14:36:18 +0900 Subject: [PATCH 3/8] =?UTF-8?q?[=EB=B2=88=EC=97=AD]=20Part1=209.4=20privat?= =?UTF-8?q?e,=20protected=20=ED=94=84=EB=A1=9C=ED=8D=BC=ED=8B=B0=EC=99=80?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=A9=EB=8F=8C=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0=20=EB=B0=8F=20=EB=AF=B8=EB=B2=88=EC=97=AD=EB=B6=84=20?= =?UTF-8?q?=EB=B2=88=EC=97=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../article.md | 57 ++++--------------- 1 file changed, 11 insertions(+), 46 deletions(-) diff --git a/1-js/09-classes/04-private-protected-properties-methods/article.md b/1-js/09-classes/04-private-protected-properties-methods/article.md index 3a1f58082..9fbb00801 100644 --- a/1-js/09-classes/04-private-protected-properties-methods/article.md +++ b/1-js/09-classes/04-private-protected-properties-methods/article.md @@ -7,7 +7,7 @@ 잠시 개발을 벗어나 현실 세계로 눈을 돌려, 내부 인터페이스와 외부 인터페이스 구분이 무엇을 의미하는지 알아봅시다. -일상생활에서 접하게 되는 기계들은 꽤 복잡한 구조로 되어 있습니다. 하지만 내부인터페이스와 외부 인터페이스가 구분되어있기 때문에 문제없이 기계를 사용할 수 있습니다. +일상생활에서 접하게 되는 기계들은 꽤 복잡한 구조로 되어 있습니다. 하지만 내부 인터페이스와 외부 인터페이스가 구분되어 있기 때문에 문제없이 기계를 사용할 수 있습니다. ## 실생활 예제 @@ -19,7 +19,7 @@ ![](coffee-inside.jpg) -뭔가 디테일한 것들이 아주 많네요. 하지만 이 모든 것을 알지 못해도 커피 머신을 사용하는 데 지장이 없습니다. +뭔가 디테일한 것들이 아주 많네요. 하지만, 이 모든 것을 알지 못해도 커피 머신을 사용하는 데 지장이 없습니다. 커피 머신은 꽤 믿음직한 기계입니다. 수년 간 사용할 수 있고, 중간에 고장이 나도 수리를 받으면 됩니다. @@ -42,7 +42,7 @@ 내부 인터페이스의 세부사항들은 서로의 정보를 이용하여 객체를 동작시킵니다. 발열 장치에 부착된 관을 통해 뜨거운 물이 이동하는 것처럼 말이죠. -그런데 커피 머신은 보호 커버에 둘러싸여 있기 때문에 보호 커버를 벗기지 않고는 커피머신 외부에서 내부로 접근할 수 없습니다. 밖에선 세부 요소를 알 수 없고, 접근도 불가능합니다. 내부 인터페이스의 기능은 외부 인터페이스를 통해야만 사용할 수 있습니다. +그런데 커피 머신은 보호 커버에 둘러싸여 있기 때문에 보호 커버를 벗기지 않고는 커피 머신 외부에서 내부로 접근할 수 없습니다. 밖에선 세부 요소를 알 수 없고, 접근도 불가능합니다. 내부 인터페이스의 기능은 외부 인터페이스를 통해야만 사용할 수 있습니다. 이런 특징 때문에 외부 인터페이스만 알아도 객체를 가지고 무언가를 할 수 있습니다. 객체 안이 어떻게 동작하는지 알지 못해도 괜찮다는 점은 큰 장점으로 작용합니다. @@ -96,13 +96,9 @@ class CoffeeMachine { _waterAmount = 0; set waterAmount(value) { -<<<<<<< HEAD - if (value < 0) throw new Error("물의 양은 음수가 될 수 없습니다."); -======= if (value < 0) { value = 0; } ->>>>>>> upstream/master this._waterAmount = value; } @@ -119,19 +115,11 @@ class CoffeeMachine { // 커피 머신 생성 let coffeeMachine = new CoffeeMachine(100); -<<<<<<< HEAD // 물 추가 -coffeeMachine.waterAmount = -10; // Error: 물의 양은 음수가 될 수 없습니다. +coffeeMachine.waterAmount = -10; // _waterAmount는 -10이 아닌 0이 됩니다. ``` -이제 물의 양을 0 미만으로 설정하면 실패합니다. -======= -// add water -coffeeMachine.waterAmount = -10; // _waterAmount will become 0, not -10 -``` - -Now the access is under control, so setting the water amount below zero becomes impossible. ->>>>>>> upstream/master +이제 접근을 통제할 수 있기 때문에 물의 양을 0 미만으로 설정하는 것은 불가능합니다. ## 읽기 전용 프로퍼티 @@ -173,11 +161,7 @@ class CoffeeMachine { _waterAmount = 0; *!*setWaterAmount(value)*/!* { -<<<<<<< HEAD - if (value < 0) throw new Error("물의 양은 음수가 될 수 없습니다."); -======= if (value < 0) value = 0; ->>>>>>> upstream/master this._waterAmount = value; } @@ -191,7 +175,7 @@ new CoffeeMachine().setWaterAmount(100); 다소 길어보이긴 하지만, 이렇게 함수를 선언하면 다수의 인자를 받을 수 있기 때문에 좀 더 유연합니다(위 예시에선 인자가 하나뿐이긴 하지만요). -반면 get, set 문법을 사용하면 코드가 짧아진다는 장점이 있습니다. 어떤걸 사용해야 한다는 규칙은 없으므로 원하는 방식을 선택해서 사용하세요. +반면 get, set 문법을 사용하면 코드가 짧아진다는 장점이 있습니다. 어떤 걸 사용해야 한다는 규칙은 없으므로 원하는 방식을 선택해서 사용하세요. ```` ```smart header="protected 필드는 상속됩니다." @@ -208,11 +192,7 @@ private 프로퍼티와 메서드는 제안(proposal) 목록에 등재된 문법 private 프로퍼티와 메서드는 `#`으로 시작합니다. `#`이 붙으면 클래스 안에서만 접근할 수 있습니다. -<<<<<<< HEAD -물 용량 한도를 나타내는 private 프로퍼티 `#waterLimit`과 남아있는 물의 양을 확인해주는 private 메서드 `#checkWater`를 구현해봅시다. -======= -For instance, here's a private `#waterLimit` property and the water-checking private method `#fixWaterAmount`: ->>>>>>> upstream/master +예를 들어, 물 용량 한도를 나타내는 private 프로퍼티 `#waterLimit`과 물의 양을 보정해주는 private 메서드 `#fixWaterAmount`가 있습니다. ```js run class CoffeeMachine { @@ -221,15 +201,9 @@ class CoffeeMachine { */!* *!* -<<<<<<< HEAD - #checkWater(value) { - if (value < 0) throw new Error("물의 양은 음수가 될 수 없습니다."); - if (value > this.#waterLimit) throw new Error("물이 용량을 초과합니다."); -======= #fixWaterAmount(value) { if (value < 0) return 0; if (value > this.#waterLimit) return this.#waterLimit; ->>>>>>> upstream/master } */!* @@ -242,13 +216,8 @@ class CoffeeMachine { let coffeeMachine = new CoffeeMachine(); *!* -<<<<<<< HEAD -// 클래스 외부에서 private에 접근할 수 없음 -coffeeMachine.#checkWater(); // Error -======= -// can't access privates from outside of the class +// 클래스 외부에서 private에 접근할 수 없습니다. coffeeMachine.#fixWaterAmount(123); // Error ->>>>>>> upstream/master coffeeMachine.#waterLimit = 1000; // Error */!* ``` @@ -269,11 +238,7 @@ class CoffeeMachine { } set waterAmount(value) { -<<<<<<< HEAD - if (value < 0) throw new Error("물의 양은 음수가 될 수 없습니다."); -======= if (value < 0) value = 0; ->>>>>>> upstream/master this.#waterAmount = value; } } @@ -322,12 +287,12 @@ class User { 객체 지향 프로그래밍에선 내부 인터페이스와 외부 인터페이스를 구분하는 것을 [캡슐화(encapsulation)]라는 용어를 사용해 설명합니다. -캡슐화는 이점은 다음과 같습니다. +캡슐화의 이점은 다음과 같습니다. 사용자가 자신의 발등을 찍지 않도록 보호 -: 커피 머신를 함께 사용하는 개발팀이 있다고 상상해봅시다. "Best CoffeeMachine"이라는 회사에서 만든 이 커피 머신은 현재 잘 작동하고 있지만, 보호 커버가 없어서 내부 인터페이스가 노출되어있는 상황입니다. +: 커피 머신을 함께 사용하는 개발팀이 있다고 상상해봅시다. "Best CoffeeMachine"이라는 회사에서 만든 이 커피 머신은 현재 잘 작동하고 있지만, 보호 커버가 없어서 내부 인터페이스가 노출되어 있는 상황입니다. - 교양있는 팀원들은 모두 설계 의도에 맞게 커피 머신을 사용합니다. 그런데 어느 날 John이라는 개발자가 자신의 능력을 과신하며 커피 머신 내부를 살짝 만지게 됩니다. 이틀 후, 커피 머신은 고장이 나버렸죠. + 교양 있는 팀원들은 모두 설계 의도에 맞게 커피 머신을 사용합니다. 그런데 어느 날 John이라는 개발자가 자신의 능력을 과신하며 커피 머신 내부를 살짝 만지게 됩니다. 이틀 후, 커피 머신은 고장이 나버렸죠. 커피 머신이 고장 난 건 John의 잘못이라기보다는, 보호 커버를 없애고 John이 마음대로 조작하도록 내버려 둔 사람의 잘못입니다. From 0c5f51b7433df00889ffbeea5860cbffdec929db Mon Sep 17 00:00:00 2001 From: NterChoi Date: Sat, 16 May 2026 15:51:12 +0900 Subject: [PATCH 4/8] =?UTF-8?q?[=EB=B2=88=EC=97=AD]=20Part1=209.6=20instan?= =?UTF-8?q?ceof=20=EC=B6=A9=EB=8F=8C=20=ED=95=B4=EA=B2=B0=20=EB=B0=8F=20?= =?UTF-8?q?=EB=AF=B8=EB=B2=88=EC=97=AD=EB=B6=84=20=EB=B2=88=EC=97=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1-js/09-classes/06-instanceof/article.md | 29 +++++++----------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/1-js/09-classes/06-instanceof/article.md b/1-js/09-classes/06-instanceof/article.md index b011ca1ff..ccc8b66a5 100644 --- a/1-js/09-classes/06-instanceof/article.md +++ b/1-js/09-classes/06-instanceof/article.md @@ -2,11 +2,7 @@ `instanceof` 연산자를 사용하면 객체가 특정 클래스에 속하는지 아닌지를 확인할 수 있습니다. `instanceof`는 상속 관계도 확인해줍니다. -<<<<<<< HEAD -확인 기능은 다양한 곳에서 쓰이는데, 이번 챕터에선 `instanceof`를 사용해 인수의 타입에 따라 이를 다르게 처리하는 *다형적인(polymorphic)* 함수를 만드는데 사용해보겠습니다. -======= -Such a check may be necessary in many cases. For example, it can be used for building a *polymorphic* function, the one that treats arguments differently depending on their type. ->>>>>>> upstream/master +확인 기능은 다양한 곳에서 쓰이는데, 예를 들어 `instanceof`를 사용하면 인수의 타입에 따라 이를 다르게 처리하는 *다형적인(polymorphic)* 함수를 만들 수 있습니다. ## instanceof 연산자 [#ref-instanceof] @@ -59,13 +55,8 @@ alert( arr instanceof Object ); // true 예시: ```js run -<<<<<<< HEAD - // canEat 프로퍼티가 있으면 animal이라고 판단할 수 있도록 - // instanceOf의 로직을 직접 설정합니다. -======= - // set up instanceof check that assumes that - // anything with canEat property is an animal ->>>>>>> upstream/master + // canEat 프로퍼티가 있으면 animal이라고 판단하도록 + // instanceof 로직을 직접 설정합니다. class Animal { static [Symbol.hasInstance](obj) { if (obj.canEat) return true; @@ -77,13 +68,9 @@ alert( arr instanceof Object ); // true alert(obj instanceof Animal); // true, Animal[Symbol.hasInstance](obj)가 호출됨 ``` -<<<<<<< HEAD -2. 그런데, 대부분의 클래스엔 `Symbol.hasInstance`가 구현되어있지 않습니다. 이럴 땐 일반적인 로직이 사용됩니다. `obj instanceOf Class`는 `Class.prototype`이 `obj` 프로토타입 체인 상의 프로토타입 중 하나와 일치하는지 확인합니다. -======= -2. Most classes do not have `Symbol.hasInstance`. In that case, the standard logic is used: `obj instanceof Class` checks whether `Class.prototype` is equal to one of the prototypes in the `obj` prototype chain. ->>>>>>> upstream/master +2. 그런데 대부분의 클래스에는 `Symbol.hasInstance`가 구현되어 있지 않습니다. 이 경우 일반적인 로직이 사용됩니다. `obj instanceof Class`는 `Class.prototype`이 `obj` 프로토타입 체인 상의 프로토타입 중 하나와 일치하는지 확인합니다. - 비교는 차례 차례 진행됩니다. + 비교는 차례차례 진행됩니다. ```js obj.__proto__ === Class.prototype? obj.__proto__.__proto__ === Class.prototype? @@ -148,7 +135,7 @@ alert(obj); // [object Object] alert(obj.toString()); // 같은 결과가 출력됨 ``` -이렇게 `[object Object]`가 되는 이유는 `toString`의 구현방식 때문입니다. 그런데 `toString`엔 `toString`을 더 강력하게 만들어주는 기능이 숨겨져 있습니다. `toString`의 숨겨진 기능을 사용하면 확장 `typeof`, `instanceof`의 대안을 만들 수 있습니다. +이렇게 `[object Object]`가 되는 이유는 `toString`의 구현 방식 때문입니다. 그런데 `toString`엔 `toString`을 더 강력하게 만들어주는 기능이 숨겨져 있습니다. `toString`의 숨겨진 기능을 사용하면 확장 `typeof`, `instanceof`의 대안을 만들 수 있습니다. 아직 감이 안 잡히시겠지만, 구체적으로 설명하겠습니다. @@ -159,7 +146,7 @@ alert(obj.toString()); // 같은 결과가 출력됨 - `null` -- `[object Null]` - `undefined` -- `[object Undefined]` - 배열 -- `[object Array]` -- 그외 -- 커스터마이징 가능 +- 그 외 -- 커스터마이징 가능 예시: @@ -210,7 +197,7 @@ alert( {}.toString.call(window) ); // [object Window] alert( {}.toString.call(new XMLHttpRequest()) ); // [object XMLHttpRequest] ``` -실행 결과에서 보듯이 호스트 환경 고유 객체의 `Symbol.toStringTag` 값은 `[object ...]`로 쌓여진 값과 동일합니다. +실행 결과에서 보듯이 호스트 환경 고유 객체의 `Symbol.toStringTag` 값은 `[object ...]`로 쌓인 값과 동일합니다. 이처럼 'typeof' 연산자의 강력한 변형들(`toString`과 `toStringTag` - 옮긴이)은 원시 자료형뿐만 아니라 내장 객체에도 사용할 수 있습니다. 그리고 커스터마이징까지 가능합니다. From 2221c8487a37ccbcb1a3016b38f8708bb2723795 Mon Sep 17 00:00:00 2001 From: NterChoi Date: Sat, 16 May 2026 17:17:57 +0900 Subject: [PATCH 5/8] =?UTF-8?q?[=EB=B2=88=EC=97=AD]=20Part1=209.7=20?= =?UTF-8?q?=EB=AF=B9=EC=8A=A4=EC=9D=B8=20=EC=B6=A9=EB=8F=8C=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0=20=EB=B0=8F=20=EB=AF=B8=EB=B2=88=EC=97=AD=EB=B6=84=20?= =?UTF-8?q?=EB=B2=88=EC=97=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1-js/09-classes/07-mixins/article.md | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/1-js/09-classes/07-mixins/article.md b/1-js/09-classes/07-mixins/article.md index 785d10b68..4d615c4d0 100644 --- a/1-js/09-classes/07-mixins/article.md +++ b/1-js/09-classes/07-mixins/article.md @@ -69,11 +69,7 @@ let sayMixin = { }; let sayHiMixin = { -<<<<<<< HEAD - __proto__: sayMixin, // (Object.create를 사용해 프로토타입을 설정할 수도 있습니다.) -======= - __proto__: sayMixin, // (or we could use Object.setPrototypeOf to set the prototype here) ->>>>>>> upstream/master + __proto__: sayMixin, // (Object.setPrototypeOf를 사용해 여기서 프로토타입을 설정할 수도 있습니다.) sayHi() { *!* @@ -107,17 +103,13 @@ new User("Dude").sayHi(); // Hello Dude! 이는 `sayHi`와 `sayBye`가 생성된 곳이 `sayHiMixin`이기 때문입니다. 따라서 메서드를 복사했더라도, 이 메서드들의 내부 프로퍼티인 `[[HomeObject]]`는 위 그림처럼 `sayHiMixin`을 참조합니다. -<<<<<<< HEAD -메서드의 `super`가 `[[HomeObject]].[[Prototype]]`내에서 부모 메서드를 찾기 때문에, 메서드는 `User.[[Prototype]]`이 아닌 `sayHiMixin.[[Prototype]]`을 검색합니다. -======= -As `super` looks for parent methods in `[[HomeObject]].[[Prototype]]`, that means it searches `sayHiMixin.[[Prototype]]`. ->>>>>>> upstream/master +메서드의 `super`가 `[[HomeObject]].[[Prototype]]` 내에서 부모 메서드를 찾기 때문에, 메서드는 `User.[[Prototype]]`이 아닌 `sayHiMixin.[[Prototype]]`을 검색합니다. ## 이벤트 믹스인 실제로 사용할 수 있는 믹스인을 만들어봅시다. -상당수 브라우저 객체는 이벤트를 생성이라는 중요한 기능을 가지고 있습니다. 이벤트는 정보를 필요로 하는 곳에 '정보를 널리 알리는(broadcast)' 훌륭한 수단입니다. 아래 예시에선 클래스나 객체에 이벤트 관련 함수를 쉽게 추가할 수 있도록 해주는 믹스인을 만들어 보겠습니다. +상당수 브라우저 객체는 이벤트를 생성하는 중요한 기능을 가지고 있습니다. 이벤트는 정보를 필요로 하는 곳에 '정보를 널리 알리는(broadcast)' 훌륭한 수단입니다. 아래 예시에선 클래스나 객체에 이벤트 관련 함수를 쉽게 추가할 수 있도록 해주는 믹스인을 만들어 보겠습니다. - 믹스인은 뭔가 중요한 일이 발생했을 때 '이벤트를 생성하는' 메서드, `.trigger(name, [...data])`를 제공합니다. 인수 `name`은 이벤트 이름이고, 뒤따르는 선택 인수는 이벤트 데이터 정보를 담습니다. - 메서드 `.on(name, handler)`은 `name`에 해당하는 이벤트에 리스너로 `handler` 함수를 추가합니다. `.on()`은 이벤트(`name`)가 트리거 될 때 호출되고, `.trigger` 호출에서 인수를 얻습니다. @@ -203,7 +195,7 @@ menu.choose("123"); 이제 `menu.on(...)`을 사용해 메뉴 선택이라는 정보를 들을 수 있게 되었고, 이에 반응하는 코드를 추가할 수 있게 되었습니다. -그리고 믹스인 `eventMixin`을 사용하면 이런 동작을 상속 체이닝에 끼어들지 않고도 원하는 클래스에 모두에 추가할 수 있습니다. +그리고 믹스인 `eventMixin`을 사용하면 이런 동작을 상속 체이닝에 끼어들지 않고도 원하는 클래스 모두에 추가할 수 있습니다. ## 요약 @@ -213,4 +205,4 @@ menu.choose("123"); 이벤트 믹스인 예시에서 본 것처럼, 믹스인은 이벤트 핸들링 등의 행동을 추가하여 클래스를 확장하는 용도로 사용할 수 있습니다. -mixin이 실수로 기존 클래스 메서드를 덮어쓰면 충돌이 발생할 수 있습니다. 따라서 mixin을 만들 땐 충돌이 발생하지 않도록 메서드 이름을 신중하게 정하셔야 합니다. +믹스인이 실수로 기존 클래스 메서드를 덮어쓰면 충돌이 발생할 수 있습니다. 따라서 믹스인을 만들 땐 충돌이 발생하지 않도록 메서드 이름을 신중하게 정하셔야 합니다. From c70f725279be5f356b5f97887d5e9e706e6efddb Mon Sep 17 00:00:00 2001 From: NterChoi Date: Sun, 17 May 2026 10:19:57 +0900 Subject: [PATCH 6/8] =?UTF-8?q?[=EC=A0=95=EC=A0=81=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=EC=99=80=20=EC=A0=95=EC=A0=81=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=8D=BC=ED=8B=B0]=20=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1-js/09-classes/03-static-properties-methods/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/09-classes/03-static-properties-methods/article.md b/1-js/09-classes/03-static-properties-methods/article.md index f1d9ffac4..7ec406ecb 100644 --- a/1-js/09-classes/03-static-properties-methods/article.md +++ b/1-js/09-classes/03-static-properties-methods/article.md @@ -63,7 +63,7 @@ articles.sort(Article.compare); alert( articles[0].title ); // CSS ``` -여기서 `Article.compare`는 article(글)을 비교해주는 수단으로, article 하나에 속한 메서드가 아니라 클래스 전체에 속한 메서드입니다. +여기서 `Article.compare`는 article(글)을 비교해주는 수단으로, 글 전체를 '위에서' 바라보며 비교를 수행합니다. `Article.compare`가 글 하나의 메서드가 아닌 클래스의 메서드여야 하는 이유가 여기에 있습니다. 이번에 살펴볼 예시는 소위 '팩토리(factory)' 메서드를 구현한 코드입니다. From 7fd7941855483e23741e682c9ecb974ecc9b8492 Mon Sep 17 00:00:00 2001 From: NterChoi Date: Sun, 17 May 2026 10:25:34 +0900 Subject: [PATCH 7/8] =?UTF-8?q?[=EC=A0=95=EC=A0=81=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=EC=99=80=20=EC=A0=95=EC=A0=81=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=8D=BC=ED=8B=B0]=20=EB=88=84=EB=9D=BD=20=EB=B6=80=EB=B6=84?= =?UTF-8?q?=20=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1-js/09-classes/03-static-properties-methods/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/09-classes/03-static-properties-methods/article.md b/1-js/09-classes/03-static-properties-methods/article.md index 7ec406ecb..fdfbb54e0 100644 --- a/1-js/09-classes/03-static-properties-methods/article.md +++ b/1-js/09-classes/03-static-properties-methods/article.md @@ -107,7 +107,7 @@ alert( article.title ); // Today's digest Article.remove({id: 12345}); ``` ````warn header="정적 메서드는 클래스에서 호출할 수 있으며, 개별 객체에서는 호출할 수 없습니다." - +정적 메서드는 개별 객체가 아닌 클래스 자체에서 호출할 수 있습니다. 즉, 객체 하나에 속한 메서드가 아니라 클래스 자체에 속한 메서드입니다. 예를 들어 아래 코드는 동작하지 않습니다. ```js From 8718d92cbce5c9e385847700f910ead5ae0325cc Mon Sep 17 00:00:00 2001 From: NterChoi Date: Sun, 17 May 2026 13:56:14 +0900 Subject: [PATCH 8/8] =?UTF-8?q?[=EC=A0=95=EC=A0=81=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=EC=99=80=20=EC=A0=95=EC=A0=81=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=8D=BC=ED=8B=B0]=20=EC=A4=84=EB=B0=94=EA=BF=88=20=20?= =?UTF-8?q?=EB=B6=80=EB=B6=84=20=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1-js/09-classes/03-static-properties-methods/article.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/1-js/09-classes/03-static-properties-methods/article.md b/1-js/09-classes/03-static-properties-methods/article.md index fdfbb54e0..5226bc227 100644 --- a/1-js/09-classes/03-static-properties-methods/article.md +++ b/1-js/09-classes/03-static-properties-methods/article.md @@ -33,7 +33,8 @@ User.staticMethod(); // true 정적 메서드는 어떤 특정한 객체가 아닌 클래스 전체에 속한 함수를 구현하고자 할 때 주로 사용됩니다. -객체 `Article`이 여러 개 있고 이들을 비교해줄 함수가 필요하다고 가정해 봅시다. 가장 먼저 아래와 같이 `Article.compare` 정적 메서드를 추가하는 방법이 떠오를 겁니다. +객체 `Article`이 여러 개 있고 이들을 비교해줄 함수가 필요하다고 가정해 봅시다. +가장 먼저 아래와 같이 `Article.compare` 정적 메서드를 추가하는 방법이 떠오를 겁니다. ```js run class Article {