Skip to content

Commit

Permalink
πŸ“ 백광인 2024-03-05
Browse files Browse the repository at this point in the history
  • Loading branch information
RookieAND committed Mar 5, 2024
1 parent 0ba5d65 commit 5805e3d
Showing 1 changed file with 258 additions and 0 deletions.
258 changes: 258 additions & 0 deletions docs/RookieAND/dil/2024-03-05.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
# βœ’οΈ ν•¨μˆ˜

### ✏️ ν•¨μˆ˜μ˜ μ •μ˜

- ν•¨μˆ˜λž€ μž‘μ—…μ„ μˆ˜ν–‰ν•˜κ±°λ‚˜ 값을 κ³„μ‚°ν•˜λŠ” 과정을 ν‘œν˜„ν•˜κ³ , 이λ₯Ό ν•˜λ‚˜μ˜ "블둝" 으둜 감싸 μ‹€ν–‰ λ‹¨μœ„λ‘œ λ§Œλ“  것이닀.

### ✏️ ν•¨μˆ˜μ˜ μ •μ˜ 방식

1. ν•¨μˆ˜ μ„ μ–Έλ¬Έ : `function` ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ ν•¨μˆ˜λ₯Ό μ •μ˜ν•œλ‹€.
2. ν•¨μˆ˜ ν‘œν˜„μ‹ : `function` ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μ •μ˜ν•œ ν•¨μˆ˜λ₯Ό μ‹λ³„μžμ— ν• λ‹Ήν•œλ‹€.

```js
// ν•¨μˆ˜ μ„ μ–Έλ¬Έ
function add(a, b) {
return a + b;
}

// ν•¨μˆ˜ ν‘œν˜„μ‹
const add = function (a, b) {
return a + b;
};
```

- 두 ν‘œν˜„ λͺ¨λ‘ ν•¨μˆ˜λ₯Ό μ •μ˜ν•˜λŠ”λ° μ“°μ΄μ§€λ§Œ, κ°€μž₯ 큰 μ°¨μ΄λŠ” hoisting 의 여뢀이닀.
- ν•¨μˆ˜ μ„ μ–Έλ¬Έμ˜ 경우 μ½”λ“œ μ‹€ν–‰ 전에 ν•΄λ‹Ή ν•¨μˆ˜μ˜ 정보가 사전에 λ©”λͺ¨λ¦¬μ— λ“±λ‘λ˜κΈ° λ•Œλ¬Έμ— λ™μΌν•œ 레벨의 μ»¨ν…μŠ€νŠΈ λ‚΄λΆ€μ—μ„œλŠ” μ–΄λ””μ„œλ“  μ‚¬μš©μ΄ κ°€λŠ₯ν•˜λ‹€.
- ν•˜μ§€λ§Œ ν•¨μˆ˜ ν‘œν˜„μ‹μ€ μƒμ„±λœ ν•¨μˆ˜λ₯Ό λ³€μˆ˜μ— ν• λ‹Ήν•˜μ˜€κ³ , λ³€μˆ˜μ˜ 경우 값이 ν• λ‹Ήλ˜κΈ° 이전에 μ‚¬μš©λ  경우 var λŠ” `undefined` λ₯Ό, const 와 let 은 `ReferenceError` λ₯Ό μœ λ°œμ‹œν‚¨λ‹€.

3. Function μƒμ„±μž : `new Function()` μƒμ„±μžλ₯Ό 기반으둜 ν•¨μˆ˜λ₯Ό μƒμ„±ν•˜λŠ” 방식
4. Arrow Function : `=>` ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•œ 읡λͺ… ν•¨μˆ˜λ₯Ό μƒμ„±ν•˜κ³  이λ₯Ό λ³€μˆ˜μ— ν• λ‹Ήν•˜λŠ” 방식.

```js
// Function μƒμ„±μž
const add = new Function("a", "b", "return a + b");

const subFuncBody = "return a - b";
const sub = new Function("a", "b", subFuncBody); // λŸ°νƒ€μž„ ν™˜κ²½μ—μ„œ Body λ₯Ό ν• λ‹Ήλ°›μ•„ 싀행이 κ°€λŠ₯ν•˜λ‹€.

// Arrow Function
const add = (a, b) => a + b;
```

- Function μƒμ„±μžμ˜ 경우 κ°€μž₯ λ§ˆμ§€λ§‰ 인자둜 μ‹€ν–‰ν•  ν•¨μˆ˜ 본문을 λ°›κ³ , 이전 μΈμžλ“€μ€ λͺ¨λ‘ λ§€κ°œλ³€μˆ˜λ‘œ λ°›λŠ”λ‹€.
- Function μƒμ„±μžμ˜ κ°€μž₯ 큰 νŠΉμ΄μ μ€ λŸ°νƒ€μž„ ν™˜κ²½μ—μ„œ 인계 받은 λ¬Έμžμ—΄μ„ μ‚¬μš©ν•˜μ—¬ ν•¨μˆ˜λ₯Ό λ§Œλ“€ 수 μžˆλ‹€λŠ” 점이닀. (μ½”λ“œ μ‹€ν–‰ 전이 μ•„λ‹ˆλΌ, λŸ°νƒ€μž„ ν™˜κ²½μ΄λΌλŠ” 게 μ€‘μš”ν•˜λ‹€)
- Arrow Function 의 경우 ν•¨μˆ˜ ν‘œν˜„μ‹κ³Ό μ„ μ–Έλ¬Έ λ°©μ‹μœΌλ‘œ μƒμ„±λœ ν•¨μˆ˜μ™€λŠ” 달리 `arguments` κ°€ μ—†μœΌλ©° μƒμ„±μž 기반으둜 μ œμž‘μ΄ λΆˆκ°€λŠ₯ν•˜λ‹€.
- λ˜ν•œ this 바인딩이 νŠΉμ΄ν•œλ°, ν™”μ‚΄ν‘œ ν•¨μˆ˜λŠ” ν•¨μˆ˜ 자체의 바인딩을 가지지 μ•ŠκΈ° λ•Œλ¬Έμ— μžμ‹ μ„ ν˜ΈμΆœν•œ μŠ€μ½”ν”„λ₯Ό κΈ°μ€€μœΌλ‘œ μƒμœ„ μŠ€μ½”ν”„λ₯Ό 가리킨닀.

### ✏️ κ·Έ μ™Έ 자주 μ“°μ΄λŠ” ν•¨μˆ˜ μ‚¬μš© νŒ¨ν„΄

1. IIFE (μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜) : ν•¨μˆ˜λ₯Ό μ •μ˜ν•˜λŠ” μˆœκ°„ μ‹€ν–‰λ˜λŠ” ν•¨μˆ˜
2. HOC (κ³ μ°¨ ν•¨μˆ˜) : ν•¨μˆ˜λ₯Ό 인자둜 λ°›κ±°λ‚˜ μƒˆλ‘œμš΄ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜

```js
// IIFE
async (() => {
const slackClient = await slackApp.bootstrap();
slackClient.init();
})

// HOC
const Component = () => (<div> {...} </div>)
const intlComponent = withIntl(Component);
```

- IIFE 의 경우 ν•¨μˆ˜κ°€ μ •μ˜λ˜λŠ” μ¦‰μ‹œ μ‹€ν–‰λ˜κΈ°μ— 1νšŒμ„±μœΌλ‘œ λ™μž‘ν•œλ‹€. λ”°λΌμ„œ μž¬μ‚¬μš©μ΄ λΆˆκ°€λŠ₯ν•˜λ‹€.
- HOC 의 경우 ν•¨μˆ˜ν˜• μ»΄ν¬λ„ŒνŠΈ λ˜ν•œ ν•¨μˆ˜μ΄κΈ° λ•Œλ¬Έμ— νŠΉμ • μ»΄ν¬λ„ŒνŠΈλ₯Ό 인자둜 λ°›μ•„ λ‘œμ§μ„ λΆ€μ°©μ‹œμΌœ λ°˜ν™˜ν•˜λŠ” μš©λ„λ‘œ 많이 쓰인닀.


### ✏️ ν•¨μˆ˜ μ œμž‘ μ‹œ 주의 사항

1. ν•¨μˆ˜μ˜ λΆ€μˆ˜ 효과λ₯Ό μ΅œλŒ€ν•œ μ–΅μ œν•˜λΌ

- ν•¨μˆ˜μ˜ λΆ€μˆ˜νš¨κ³Όλž€ ν•¨μˆ˜ λ‚΄λΆ€μ˜ μž‘λ™μœΌλ‘œ ν•¨μˆ˜ 외뢀에 영ν–₯을 λΌμΉ˜λŠ” ν˜„μƒμ„ μ˜λ―Έν•œλ‹€.
- ν•¨μˆ˜λŠ” 기본적으둜 λ™μΌν•œ 인자λ₯Ό λ°›μœΌλ©΄ 항상 λ™μΌν•œ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•΄μ•Ό ν•˜λ©°, ν•¨μˆ˜μ˜ 싀행이 외뢀에 영ν–₯을 λ―Έμ³μ„œλŠ” μ•ˆλœλ‹€.
- λ¬Όλ‘  λΆ€μˆ˜ νš¨κ³Όκ°€ μ•„μ˜ˆ μ—†λŠ” 상황은 μ—†μœΌλ‚˜ μ½”λ“œλ₯Ό 더 μ‰½κ²Œ μ΄ν•΄ν•˜λ„λ‘ ν•˜λ©° 디버깅을 μš©μ΄ν•˜κ²Œ ν•˜λŠ” 순수 ν•¨μˆ˜λ₯Ό μ±„μš©ν•˜λ € λ…Έλ ₯ν•΄μ•Ό ν•œλ‹€.


2. ν•¨μˆ˜λ₯Ό μž‘κ²Œ λ§Œλ“€μ–΄λΌ.

- ν•˜λ‚˜μ˜ ν•¨μˆ˜μ— μ—¬λŸ¬ λ™μž‘μ„ 넣지 말고 μ΅œλŒ€ν•œ 단일 κΈ°λŠ₯을 ν•˜λ„λ‘ ν•¨μˆ˜λ₯Ό μ„€κ³„ν•˜μž.
- ν•¨μˆ˜μ— μ—¬λŸ¬ κΈ°λŠ₯이 μΆ”κ°€λ˜λ©΄ 각 κΈ°λŠ₯듀이 λ™μž‘ν•˜λŠ” κ³Όμ •μ—μ„œ μ˜ˆμƒμΉ˜ λͺ»ν•œ μ—λŸ¬λ₯Ό λ§žμ΄ν•  ν™•λ₯ μ΄ μ˜¬λΌκ°„λ‹€.

3. ν•¨μˆ˜ λͺ…을 λͺ…λ£Œν•˜κ²Œ μ§“μž.


# βœ’οΈ 클래슀

### ✏️ ν΄λž˜μŠ€λž€?

- 주둜 νŠΉμ •ν•œ λͺ©μ μ„ 가진 객체λ₯Ό 반볡적으둜 μƒμ„±ν•˜κΈ° μœ„ν•΄ μ‚¬μš©λœλ‹€.
- ES6 μŠ€νŽ™μ—μ„œ μΆ”κ°€λœ 문법이며, 이전 λ²„μ „μ˜ 경우 주둜 prototype 기반의 객체 λͺ¨λΈλ§μ„ μ§„ν–‰ν–ˆλ‹€. (같은 객체λ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜ 포함)

### ✏️ constructor

- 객체 (클래슀 μΈμŠ€ν„΄μŠ€) λ₯Ό μƒμ„±ν•˜κΈ° μœ„ν•΄ μ‚¬μš©λ˜λŠ” 특수 λ©”μ„œλ“œλ‹€.

### ✏️ property

- 클래슀 λ‚΄λΆ€μ—μ„œ μ •μ˜ν•  수 μžˆλŠ” 속성 값을 μ˜λ―Έν•œλ‹€.
- Typescript 의 경우 protected, private 와 같이 속성 μ ‘κ·Ό μ œν•œμžλ₯Ό μ‚¬μš©ν•  수 있고, JS μ—μ„œλ„ `#` 을 μ‚¬μš©ν•˜μ—¬ νŠΉμ • 속성을 private ν•˜κ²Œ 지정할 수 μžˆλ‹€.

### ✏️ getter, setter

- 클래슀 λ‚΄λΆ€μ—μ„œ νŠΉμ •ν•œ 값을 κ°€μ Έμ˜¬ λ•Œ μ“°μ΄λŠ” νŒ¨ν„΄μ΄λ‹€.
- getter ν•¨μˆ˜μ˜ 경우 μ•žμ— `get` 을, setter ν•¨μˆ˜μ˜ 경우 `set` 을 뢙인닀.

### ✏️ μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œ

- 클래슀 λ‚΄λΆ€μ—μ„œ μ„ μ–Έν•œ λ©”μ„œλ“œλ₯Ό μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œλΌκ³  ν•œλ‹€.
- μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œμ˜ 경우 μ½”λ“œ μƒμœΌλ‘œλŠ” Class 내뢀에 μ •μ˜λ˜λ‚˜, λŸ°νƒ€μž„ ν™˜κ²½μ—μ„œλŠ” prototype 에 μ„ μ–Έλ˜μ–΄ prototype λ©”μ„œλ“œλΌκ³  λΆˆλ¦°λ‹€.
- JS λŠ” 기본적으둜 ν”„λ‘œν† νƒ€μž… 언어이기 λ•Œλ¬Έμ—, 객체 λ‚΄λΆ€μ˜ λ©”μ„œλ“œλ‚˜ 속성듀이 μ „λΆ€ prototype 을 기반으둜 μ •μ˜λœ 것을 λ³Ό 수 μžˆλ‹€.


```js
class Car {
constructor(name) {
this.name = name;
}

getName() {
return this.name
}
}

const myCar = new Car('레이');
console.log(Object.getPrototypeOf(myCar)) // { constructor: f, getName: Ζ’ }

```

> Prototype Chaining
- ν•΄λ‹Ή λ©”μ„œλ“œλ₯Ό κ°μ²΄μ—μ„œ μ„ μ–Έν•˜μ§€ μ•Šμ•˜μœΌλ‚˜ ν”„λ‘œν† νƒ€μž… 내뢀에 μ‘΄μž¬ν•˜λŠ” λ©”μ„œλ“œλ₯Ό μ°Ύμ•„ μ‹€ν–‰ν•˜λŠ” 방식을 Prototype Chaining 이라 ν•œλ‹€.
- λͺ¨λ“  κ°μ²΄λŠ” Object λ₯Ό μ΅œμƒμœ„ 객체둜 가지기 λ•Œλ¬Έμ—, λ³„λ„μ˜ μ •μ˜ 없이도 Object λ‚΄λΆ€ prototype 에 μ •μ˜λœ λ©”μ„œλ“œλ“€μ„ 기본적으둜 μ‚¬μš©ν•  수 μžˆλ‹€.
- `toString()` λ©”μ„œλ“œμ˜ κ²½μš°μ—λ„ λ³„λ„μ˜ μ •μ˜ 없이 μ–΄λŠ κ°μ²΄μ—μ„œλ‚˜ μ‚¬μš©ν•  수 μžˆλ‹€.


### ✏️ static (정적) λ©”μ„œλ“œ

- λ³„λ„μ˜ 클래슀 μΈμŠ€ν„΄μŠ€ 없이도 클래슀 λͺ…을 기반으둜 ν˜ΈμΆœν•  수 μžˆλŠ” λ©”μ„œλ“œ
- 정적 λ©”μ„œλ“œ λ‚΄λΆ€μ˜ this λŠ” 클래슀 μΈμŠ€ν„΄μŠ€κ°€ μ•„λ‹Œ 클래슀 μžμ‹ μ„ 가리킀기 λ•Œλ¬Έμ— μœ μ˜ν•΄μ•Ό ν•œλ‹€.

### ✏️ 상속

- 기쑴의 클래슀λ₯Ό 상속 λ°›μ•„ μžμ‹ ν΄λž˜μŠ€μ— 이λ₯Ό ν™•μž₯μ‹œν‚€λŠ” 문법
- 클래슀λ₯Ό 상속받은 λŒ€μƒμ€ λΆ€λͺ¨ ν΄λž˜μŠ€μ—μ„œ μ •μ˜λœ λ©”μ„œλ“œμ™€ 클래슀 속성을 λͺ¨λ‘ μ‚¬μš©ν•  수 μžˆλ‹€.

# βœ’οΈ ν΄λž˜μŠ€μ™€ ν•¨μˆ˜μ˜ 관계

- ES6 μ΄μ „μ—λŠ” prototype 기반으둜 Class 의 역할을 λŒ€μ‹ ν•΄μ™”κΈ° λ•Œλ¬Έμ—, Class μ½”λ“œλ₯Ό ES5둜 트랜슀파일링 ν•  경우 μ•„λž˜μ™€ 같이 λ°˜ν™˜λœ μ½”λ“œκ°€ λ‚˜μ˜¨λ‹€.

```js
'use strict';

function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ('value' in descriptor) descriptor.writable = true;
Object.defineProperty(
target,
_toPropertyKey(descriptor.key),
descriptor,
);
}
}

function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
Object.defineProperty(Constructor, 'prototype', { writable: false });
return Constructor;
}

function _toPropertyKey(arg) {
var key = _toPrimitive(arg, 'string');
return _typeof(key) === 'symbol' ? key : String(key);
}

function _toPrimitive(input, hint) {
if (_typeof(input) !== 'object' || input === null) return input;
var prim = input[Symbol.toPrimitive];
if (prim !== undefined) {
var res = prim.call(input, hint || 'default');
if (_typeof(res) !== 'object') return res;
throw new TypeError('@@toPrimitive must return a primitive value.');
}
return (hint === 'string' ? String : Number)(input);
}

function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError('Cannot call a class as a function');
}
}
var Cat = /*#__PURE__*/ _createClass(function Cat(name) {
_classCallCheck(this, Cat);
this.name = name;
});
```

> 트랜슀파일링 된 μ½”λ“œλ“€μ΄ 각각 μ–΄λ–€ 역할을 ν•˜λŠ”μ§€ μ•Œμ•„λ³΄μž.
1. `_createClass` ν•¨μˆ˜

```js
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
Object.defineProperty(Constructor, 'prototype', { writable: false });
return Constructor;
}
```

- `_createClass` ν•¨μˆ˜λŠ” 첫 번째 인자둜 Constructor (μƒμ„±μž) ν•¨μˆ˜λ₯Ό λ°›λŠ”λ‹€.
- 이후 protoProps 와 staticProps λ₯Ό λ°›λŠ”λ° 각각 μƒμ„±μž 호좜둜 λ°˜ν™˜λœ 객체의 prototype ν˜Ήμ€ μƒμ„±μž 내뢀에 μƒˆλ‘œμš΄ 속성을 μΆ”κ°€ν•˜κ³  싢을 λ•Œ 쓰인닀.
- Constructor ν•¨μˆ˜μ˜ prototype 속성 쀑 writable flag λ₯Ό false 둜 μˆ˜μ •ν•¨μœΌλ‘œμ„œ μˆ˜μ •μ΄ λΆˆκ°€ν•˜λ„λ‘ ν•œλ‹€. (configurable 은 true 이기에 μ™„μ „ν•œ μˆ˜μ • λΆˆκ°€λŠ” μ•„λ‹ˆλ‹€)
- μˆ˜μ •μ΄ μ™„λ£Œλœ ν•¨μˆ˜κ°€ λ°˜ν™˜λ˜κ³ , 이후 ν•΄λ‹Ή ν•¨μˆ˜λ₯Ό `new` ν‚€μ›Œλ“œλ‘œ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•˜μ—¬ prototype 에 적재된 λ©”μ„œλ“œλ“€μ΄ ν¬ν•¨λœ 객체λ₯Ό λ°˜ν™˜ν•œλ‹€.

2. `_classCallCheck` ν•¨μˆ˜

```js
var Cat = /*#__PURE__*/ _createClass(function Cat(name) {
_classCallCheck(this, Cat);
this.name = name;
});

function _classCallCheck(instance, Constructor) {
// λ§Œμ•½ Cat ν•¨μˆ˜κ°€ new Cat() 이 μ•„λ‹Œ Cat() 으둜 ν˜ΈμΆœλ˜μ—ˆλ‹€λ©΄ μ—λŸ¬ λ°œμƒ.
if (!(instance instanceof Constructor)) {
throw new TypeError('Cannot call a class as a function');
}
}
```

- ν•¨μˆ˜λŠ” 일반 호좜과 `new` ν‚€μ›Œλ“œλ₯Ό 기반으둜 ν•œ μƒμ„±μž 호좜둜 λ‚˜λ‰˜λŠ”λ°, μ—¬κΈ°μ„œλŠ” μƒμ„±μžλ₯Ό ν˜ΈμΆœν•΄μ•Ό ν•˜λ―€λ‘œ 이λ₯Ό κ²€μ‚¬ν•˜κΈ° μœ„ν•΄ μΆ”κ°€λœ ν•¨μˆ˜λ‹€.
- 일반적으둜 ν•¨μˆ˜λ₯Ό κ·Έλƒ₯ μ‹€ν–‰ν•  경우 this 바인딩이 μ „μ—­ 객체둜 이어지기 λ•Œλ¬Έμ—, `instance instanceof Constructor` 쑰건문을 톡과할 수 μ—†λ‹€.

3. `_defineProperties` ν•¨μˆ˜

```js
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ('value' in descriptor) descriptor.writable = true;
Object.defineProperty(
target,
_toPropertyKey(descriptor.key),
descriptor,
);
}
}
```

- ES5 μŠ€νŽ™μ˜ `Object.defineProperties` ν•¨μˆ˜λ₯Ό λž˜ν•‘ν•œ ν•¨μˆ˜λ‹€.
- `value` κ°€ μ‘΄μž¬ν•˜λŠ” property 인 경우 μˆ˜μ •μ΄ κ°€λŠ₯ν•˜λ„λ‘ writable flag λ₯Ό true 둜 μ„€μ •ν•œλ‹€.
- configurable flag λŠ” true 이며, enumerable flag 의 경우 property 에 μ •μ˜λœ 값을 따라간닀. (default λŠ” false)

0 comments on commit 5805e3d

Please sign in to comment.