diff --git "a/sep/sep-3rd/yunji/[sep-3rd]\354\234\244\354\247\200\355\225\231\354\212\265\354\240\225\353\246\254.md" "b/sep/sep-3rd/yunji/[sep-3rd]\354\234\244\354\247\200\355\225\231\354\212\265\354\240\225\353\246\254.md" new file mode 100644 index 0000000..30e2124 --- /dev/null +++ "b/sep/sep-3rd/yunji/[sep-3rd]\354\234\244\354\247\200\355\225\231\354\212\265\354\240\225\353\246\254.md" @@ -0,0 +1,280 @@ +# ๐Ÿ“ 16์žฅ ~ 17์žฅ ์š”์•ฝ ์ •๋ฆฌ + +## 1. ๊ฐ์ฒด = ๋ฐ์ดํ„ฐ + ์ˆจ๊ฒจ์ง„ ์ •๋ณด + +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ **๊ฐ์ฒด**๋Š” ๋‹จ์ˆœํžˆ `{}`์— ๊ฐ’๋งŒ ๋‹ด๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ, +์—”์ง„์ด ๋ชฐ๋ž˜ ๊ด€๋ฆฌํ•˜๋Š” **์ˆจ๊ฒจ์ง„ ์Šฌ๋กฏ([[Prototype]], [[Call]] ๋“ฑ)** ๊ณผ +**์ž๋™์œผ๋กœ ์‹คํ–‰๋˜๋Š” ๋ฉ”์„œ๋“œ( [[Get]], [[Set]])** ๊นŒ์ง€ ํฌํ•จ๋œ๋‹ค. + +``` +๊ฐ์ฒด = { ํ”„๋กœํผํ‹ฐ๋“ค } + [[์Šฌ๋กฏ]] + [[๋ฉ”์„œ๋“œ]] +``` + +
+ +## 2. ํ•จ์ˆ˜ ๊ฐ์ฒด = ํŠน๋ณ„ํ•œ ๊ฐ์ฒด + +ํ•จ์ˆ˜๋„ **๊ฐ์ฒด**์ด๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ํ•จ์ˆ˜๋ผ์„œ ํŠน๋ณ„ํžˆ ๋‘ ๊ฐ€์ง€ ์Šฌ๋กฏ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค. + +1. **[[Call]]** โ†’ ํ•จ์ˆ˜์ฒ˜๋Ÿผ ์‹คํ–‰ ๊ฐ€๋Šฅ (`f()`) +2. **[[Construct]]** โ†’ new ์—ฐ์‚ฐ์ž๋กœ ์‹คํ–‰ ๊ฐ€๋Šฅ (`new f()`) + +๐Ÿ‘‰ **๋ชจ๋“  ํ•จ์ˆ˜๋Š” ๊ฐ์ฒด์ง€๋งŒ, ๋ชจ๋“  ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑ์ž(new) ๊ฐ€๋Šฅํ•œ ๊ฑด ์•„๋‹˜**. + +
+ +## 3. ํ•จ์ˆ˜์˜ ์ข…๋ฅ˜ + +### (1) callable ํ•จ์ˆ˜ (ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•œ ํ•จ์ˆ˜) + +- `[[Call]]` ์Šฌ๋กฏ์„ ๊ฐ€์ง„ ํ•จ์ˆ˜ +- ๊ทธ๋ƒฅ `f()` ํ˜•ํƒœ๋กœ ์‹คํ–‰ ๊ฐ€๋Šฅ + +```javascript +function sayHi() { + console.log("hi"); +} +sayHi(); // ์‹คํ–‰๋จ +``` + +### (2) constructor ํ•จ์ˆ˜ (์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๊ฐ€๋Šฅ) + +- `[[Call]]` + `[[Construct]]` ๋‘˜ ๋‹ค ์žˆ๋Š” ํ•จ์ˆ˜ +- ์ฆ‰, `f()`๋„ ๋˜๊ณ , `new f()`๋„ ๋˜๋Š” ํ•จ์ˆ˜ + + #### โ†’ function ์„ ์–ธ๋ฌธ, function ํ‘œํ˜„์‹, class + + #### โ†’ ์ฆ‰, ๋ณดํ†ต function ํ‚ค์›Œ๋“œ๋กœ ๋งŒ๋“  ํ•จ์ˆ˜๋Š” ๋‹ค constructor + +```js +function Foo() {} // โœ… constructor +const Bar = function () {}; // โœ… constructor +class Baz {} // โœ… constructor +``` + +### (3) non-constructor ํ•จ์ˆ˜ (์ƒ์„ฑ์ž ๋ถˆ๊ฐ€) + +- `[[Call]]`๋งŒ ์žˆ๊ณ  `[[Construct]]` ์—†๋‹ค +- ์ฆ‰, ๊ทธ๋ƒฅ `f()`๋งŒ ๋˜๊ณ , new๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๋‹ค + #### โ†’ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜, ๋ฉ”์„œ๋“œ ์ถ•์•ฝ ํ‘œํ˜„ + +```javascript +const arrow = () => {}; // โŒ non-constructor +const obj = { + hi() {}, // โŒ ๋ฉ”์„œ๋“œ ์ถ•์•ฝํ˜• โ†’ non-constructor +}; +``` + +
+ +## 4. this ๋ฐ”์ธ๋”ฉ ์›๋ฆฌ + +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ `this๋Š” "๋ˆ„๊ฐ€ ํ˜ธ์ถœํ–ˆ๋ƒ"์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง„๋‹ค.` + +1. ๊ทธ๋ƒฅ ํ•จ์ˆ˜ ํ˜ธ์ถœ โ†’ ์ „์—ญ ๊ฐ์ฒด(window/undefined) +2. ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋กœ ํ˜ธ์ถœ โ†’ ๊ทธ ๊ฐ์ฒด๊ฐ€ this +3. new๋กœ ์ƒ์„ฑ์ž ํ˜ธ์ถœ โ†’ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ง„ ๊ฐ์ฒด๊ฐ€ this +4. `bind`, `call`, `apply` ์‚ฌ์šฉ โ†’ ์ง€์ •ํ•œ ๊ฐ’์ด this + +
+ +์˜ˆ์‹œ: + +### 1. ๊ทธ๋ƒฅ ํ•จ์ˆ˜ ํ˜ธ์ถœ + +```js +function sayHi() { + console.log(this); +} + +sayHi(); +``` + +- ์—„๊ฒฉ ๋ชจ๋“œ(strict mode) โ†’ undefined + +- ๋น„์—„๊ฒฉ ๋ชจ๋“œ โ†’ window (๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ ์ „์—ญ ๊ฐ์ฒด) + +#### ๐Ÿ‘‰ ์•„๋ฌด๋„ ์ฃผ์ธ์ด ์—†์œผ๋‹ˆ๊นŒ, ๊ธฐ๋ณธ์ ์œผ๋กœ ์ „์—ญ ๊ฐ์ฒด๊ฐ€ this๊ฐ€ ๋จ. + +
+ +### 2. ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋กœ ํ˜ธ์ถœ + +```js +let user = { + name: "์ฒ ์ˆ˜", + greet: function () { + console.log(this.name); + }, +}; + +user.greet(); // "์ฒ ์ˆ˜" +``` + +- `user.greet()`๋ผ๊ณ  ๊ฐ์ฒด๊ฐ€ ์•ž์— ๋ถ™์–ด์„œ ํ˜ธ์ถœ๋˜๋ฉด โ†’ ๊ทธ ๊ฐ์ฒด(`user`)๊ฐ€ `this` + +#### ๐Ÿ‘‰ "๋ˆ„๊ฐ€ ๋ถˆ๋ €๋ƒ? โ†’ user๊ฐ€ ๋ถˆ๋ €๋„ค โ†’ this = user" + +
+ +### 3. new๋กœ ์ƒ์„ฑ์ž ํ˜ธ์ถœ + +```js +function Person(name) { + this.name = name; +} + +let p1 = new Person("์˜ํฌ"); +console.log(p1.name); // "์˜ํฌ" +``` + +- `new` ํ‚ค์›Œ๋“œ๋กœ ๋ถ€๋ฅด๋ฉด โ†’ **์ƒˆ๋กœ์šด ๊ฐ์ฒด๊ฐ€ ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด์ง€๊ณ ** ๊ทธ ๊ฐ์ฒด๊ฐ€ this + +- `this.name = name` ์€ ๊ฒฐ๊ตญ `์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ง„ ๊ฐ์ฒด์— name์„ ๋ถ™์ด๋Š” ๊ฒƒ.` + +#### ๐Ÿ‘‰ "new๋Š” ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์„œ this๋กœ ์คŒ" + +
+ +### 4. bind, call, apply ์‚ฌ์šฉ + +```js +function sayHello() { + console.log(this.name); +} + +let user1 = { name: "๋ฏผ์ˆ˜" }; +let user2 = { name: "์ง€์ˆ˜" }; + +sayHello.call(user1); // "๋ฏผ์ˆ˜" +sayHello.apply(user2); // "์ง€์ˆ˜" + +let bound = sayHello.bind(user1); +bound(); // "๋ฏผ์ˆ˜" +``` + +- call, apply, bind๋Š” this๋ฅผ ๊ฐ•์ œ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ• + +- `.call(user1)` ํ•˜๋ฉด โ†’ `this = user1` + +- `.apply(user2)` ํ•˜๋ฉด โ†’ `this = user2` + +- `.bind(user1)` ํ•˜๋ฉด โ†’ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๊ฐ€ ๋งŒ๋“ค์–ด์ง€๊ณ  ๊ทธ ์•ˆ์—์„œ ํ•ญ์ƒ `this = user1` + +#### ๐Ÿ‘‰ "this๋ฅผ ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๊ฐ์ฒด๋กœ ๊ฐ•์ œ ๊ณ ์ •์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค + +
+ +## 5. new ์—ฐ์‚ฐ์ž์˜ ๋™์ž‘ + +`new Foo()`๊ฐ€ ์‹คํ–‰๋  ๋•Œ ์‹ค์ œ๋กœ ์ผ์–ด๋‚˜๋Š” ์ผ: + +1. **์ƒˆ ๊ฐ์ฒด ์ƒ์„ฑ** `{}` +2. ๊ทธ ๊ฐ์ฒด์˜ `[[Prototype]]`์„ `Foo.prototype`์œผ๋กœ ์„ค์ • +3. `Foo` ํ•จ์ˆ˜ ์‹คํ–‰ (this = ์ƒˆ ๊ฐ์ฒด) +4. `Foo` ์•ˆ์—์„œ ๊ฐ์ฒด๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ returnํ•˜๋ฉด ๊ทธ ๊ฐ์ฒด ๋ฐ˜ํ™˜, ์•„๋‹ˆ๋ฉด ์ƒˆ ๊ฐ์ฒด ๋ฐ˜ํ™˜ + +```js +function Foo() { + this.value = 10; +} +const obj = new Foo(); + +console.log(obj); // Foo { value: 10 } +console.log(obj.__proto__ === Foo.prototype); // true +``` + +
+
+
+ +# + ์ถ”๊ฐ€๋กœ + +## this ๋ฐ”์ธ๋”ฉ ๊ทœ์น™ (์šฐ์„ ์ˆœ์œ„ ์ค‘์‹ฌ) + +this๋Š” ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋ฌธ๋งฅ(ํ˜ธ์ถœ ๋ฐฉ์‹)์— ๋”ฐ๋ผ ๊ฒฐ์ •๋œ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์šฐ์„ ์ˆœ์œ„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค: + +### 1. new ๋ฐ”์ธ๋”ฉ(์ƒ์„ฑ์ž ํ˜ธ์ถœ) + +- `new F()` โ†’ this๋Š” ์ƒˆ๋กœ ์ƒ์„ฑ๋œ ๊ฐ์ฒด(ํ•ญ์ƒ ๊ฐ์ฒด). (๊ฐ€์žฅ ๋†’์€ ์šฐ์„ ์ˆœ์œ„) + +### 2. ๋ช…์‹œ์  ๋ฐ”์ธ๋”ฉ (explicit binding) + +- `f.call(obj, ...), f.apply(obj, ...)` โ†’ this๋Š” obj๋กœ ๊ณ ์ •. + +- `f.bind(obj)`๋กœ ๋งŒ๋“  ๋ฐ”์šด๋“œ ํ•จ์ˆ˜๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ [[BoundThis]]๋ฅผ ๊ฐ€์ง„๋‹ค. + +### 3. ์•”์‹œ์ (๊ฐ์ฒด) ๋ฐ”์ธ๋”ฉ (implicit / method call) + +- `obj.m()` โ†’ this๋Š” ํ˜ธ์ถœ ์‹œ์ ์˜ ๋ฒ ์ด์Šค ๊ฐ์ฒด(obj). + +- ์ฃผ์˜: `const fn = obj.m; fn();` ์ฒ˜๋Ÿผ ์ถ”์ถœํ•˜๋ฉด ์•”์‹œ์  ๋ฐ”์ธ๋”ฉ ์ƒ์‹ค. + +### 4. ๊ธฐ๋ณธ ๋ฐ”์ธ๋”ฉ(default) + +- ์œ„ ๊ทœ์น™์— ํ•ด๋‹นํ•˜์ง€ ์•Š์œผ๋ฉด: + + - ์—„๊ฒฉ ๋ชจ๋“œ(strict): this === undefined + + - ๋น„์—„๊ฒฉ(sloppy): this === globalThis (๋ธŒ๋ผ์šฐ์ €์—์„  window, ๋ชจ๋˜ ํ™˜๊ฒฝ์—์„  globalThis) + +๊ทธ๋ฆฌ๊ณ  ํŠน์ˆ˜ ๊ทœ์น™: + +- ํ™”์‚ดํ‘œ ํ•จ์ˆ˜(arrow): this๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜์ง€ ์•Š์Œ. ์„ ์–ธ ์‹œ์ (๋ ‰์‹œ์ปฌ)์˜ this๋ฅผ ์บก์ฒ˜(= lexical this). ๋”ฐ๋ผ์„œ call/apply/bind๋กœ ๋ฐ”๊พธ์ง€ ๋ชปํ•จ. + +- ๋ฐ”์šด๋“œ ํ•จ์ˆ˜: bind๋กœ ๋งŒ๋“  ํ•จ์ˆ˜๋Š” ๋‚ด๋ถ€ ์Šฌ๋กฏ์— [[BoundThis]]๋ฅผ ๊ฐ–๊ณ  ์ผ๋ฐ˜ ํ˜ธ์ถœ์—์„œ ๊ทธ ๊ฐ’์ด ์‚ฌ์šฉ๋จ. ๋‹ค๋งŒ new๋กœ ํ˜ธ์ถœํ•˜๋ฉด(๋Œ€์ƒ ์ƒ์„ฑ์ž์ด๋ฉด) new ์šฐ์„ ๊ถŒ ๋•Œ๋ฌธ์— ๋ฐ”์šด๋“œ๋œ this๋Š” ๋ฌด์‹œ๋  ์ˆ˜ ์žˆ์Œ(์•„๋ž˜ ์˜ˆ์‹œ ์ฐธ์กฐ). + +์˜ˆ์‹œ + +```js +function show() { + console.log(this); +} + +const obj = { a: 1, show }; + +obj.show(); // implicit โ†’ this === obj +const f = obj.show; +f(); // default โ†’ this === undefined (strict) or globalThis (non-strict) + +show.call({ x: 1 }); // explicit โ†’ this === {x:1} + +const arrow = () => console.log(this); +arrow(); // lexical this (์„ ์–ธ๋œ ํ™˜๊ฒฝ์˜ this) +``` + +์šฐ์„ ์ˆœ์œ„ ์˜ˆ์‹œ (bind vs new): + +```js +function Person(name) { + this.name = name; +} +const Bound = Person.bind({ name: "BOUND" }); + +Bound("A"); // ์ผ๋ฐ˜ ํ˜ธ์ถœ: ๋ฐ”์šด๋“œ๋œ this({name:'BOUND'})์— ์ ์šฉ +new Bound("B"); // new ํ˜ธ์ถœ: new๊ฐ€ ์šฐ์„  โ†’ this๋Š” ์ƒˆ ๊ฐ์ฒด, name === 'B' +``` + +์š”์ : new๋กœ ์ƒ์„ฑํ•˜๋ฉด ์ƒˆ ๊ฐ์ฒด๊ฐ€ this๊ฐ€ ๋˜๊ณ , ๋ฐ”์šด๋“œ๋œ this๋Š” ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค(๋‹จ, ๋‚ด๋ถ€ ๋™์ž‘์€ spec ์ฒ˜๋ฆฌ๊ฐ€ ์•ฝ๊ฐ„ ๋ณต์žกํ•˜์ง€๋งŒ ์‚ฌ์šฉ์ž ์ž…์žฅ์—์„  ์ด๋ ‡๊ฒŒ ์ดํ•ดํ•˜๋ฉด ๋œ๋‹ค). + +
+ +## prototype๊ณผ constructor ๊ด€๊ณ„ + +(์‹ค๋ฌด์—์„œ ์ž์ฃผ ํ—ท๊ฐˆ๋ฆฌ๋Š” ๋ถ€๋ถ„) + +- ํ•จ์ˆ˜ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ(์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜) ์ž๋™์œผ๋กœ ๊ทธ ํ•จ์ˆ˜์˜ prototype ํ”„๋กœํผํ‹ฐ(๊ฐ์ฒด)๊ฐ€ ๋งŒ๋“ค์–ด์ง„๋‹ค. ์ด prototype ๊ฐ์ฒด์—๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ constructor ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ๊ณ , ๊ทธ ๊ฐ’์€ ๋‹ค์‹œ ์›๋ž˜ ํ•จ์ˆ˜(์ž๊ธฐ ์ž์‹ )๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค. + +```js +function Foo() {} +Foo.prototype.constructor === Foo; // true +``` + +- `new Foo()`๋กœ ๋งŒ๋“  ์ธ์Šคํ„ด์Šค์˜ ๋‚ด๋ถ€ `[[Prototype]](a.k.a. __proto__)`๋Š” Foo.prototype์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค. + +์ฃผ์˜: ํ”„๋กœํ† ํƒ€์ž…์„ ๋ฎ์–ด์“ฐ๋ฉด(constructor ์—ฐ๊ฒฐ์ด ๊นจ์งˆ ์ˆ˜ ์žˆ์Œ) constructor๊ฐ€ ์ž๋™ ๋ณต๊ตฌ๋˜์ง€ ์•Š์œผ๋‹ˆ ํ•„์š”ํ•˜๋ฉด ์ˆ˜๋™์œผ๋กœ ์„ค์ •ํ•ด์•ผ ํ•จ. + +```js +Foo.prototype = { hello: function () {} }; // ์ด์ œ Foo.prototype.constructor !== Foo +Foo.prototype.constructor = Foo; // ๋ณต๊ตฌ +```