Skip to content

Commit 1f2f259

Browse files
committed
docs: 10장 정리
1 parent 991dd14 commit 1f2f259

File tree

1 file changed

+212
-0
lines changed

1 file changed

+212
-0
lines changed
+212
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
# 10. 일급 함수 1
2+
3+
- [요약](#요약)
4+
- [코드의 냄새: 함수 이름에 있는 암묵적 인자](#코드의-냄새-함수-이름에-있는-암묵적-인자)
5+
- [리팩터링: 암묵적 인자를 드러내기](#리팩터링-암묵적-인자를-드러내기)
6+
- [일급인 것과 일급이 아닌 것을 구별하기](#일급인-것과-일급이-아닌-것을-구별하기)
7+
- [데이터 지향](#데이터-지향)
8+
- [리팩터링: 함수 본문을 콜백으로 바꾸기](#리팩터링-함수-본문을-콜백으로-바꾸기)
9+
- [함수를 정의하는 방법](#함수를-정의하는-방법)
10+
11+
12+
# 요약
13+
14+
- 코드의 냄새: 함수 이름에 있는 암묵적 인자
15+
- 특징
16+
1. 거의 똑같이 구현된 함수가 있음
17+
2. 함수 이름이 구현에 있는 다른 부분을 가리킴
18+
- 리팩터링: 암묵적 인자를 드러내기 - 암묵적 인자가 일급 값이 되도록 함수에 인자 추가
19+
- 단계
20+
1. 함수 이름에 있는 암묵적 인자 확인
21+
2. 명시적 인자 추가
22+
3. 함수 본문에 하드 코딩된 값을 새로운 인자로 바꿈
23+
4. 함수를 호출하는 곳을 고침
24+
- 리팩터링: 함수 본문을 콜백으로 바꾸기 - 비슷한 함수에 있는 서로 다른 부분을 콜백으로 바꿔 함수에 동작 전달
25+
- 단계
26+
1. 함수 본문에서 바꿀 부분의 앞부분과 뒷부분 확인
27+
2. 리팩터링할 코드를 함수로 빼냄
28+
3. 빼낸 함수의 인자로 넘길 부분을 또 다른 함수로 빼냄
29+
30+
---
31+
32+
# 코드의 냄새: 함수 이름에 있는 암묵적 인자
33+
34+
- 함수 이름에 있는 암묵적 인자 특징
35+
1. 함수 구현이 거의 동일
36+
2. 함수 이름이 구현의 차이 만듦 - 함수 이름에서 서로 다른 부분이 암묵적 인자.
37+
38+
<br />
39+
40+
<details>
41+
<summary>코드 냄새 예시</summary>
42+
43+
function setPriceByName(cart, name, price) {
44+
var item = cart[name];
45+
// 모두 함수 이름과 이 문자열만 다름. 문자열이 함수 이름에 들어있음.
46+
var newItem = objectSet(item, "price", price);
47+
var newCart = objectSet(cart, name, newItem);
48+
return newCart;
49+
}
50+
51+
function setShippingByName(cart, name, ship) {
52+
var item = cart[name];
53+
var newItem = objectSet(item, "shipping", ship);
54+
var newCart = objectSet(cart, name, newItem);
55+
return newCart;
56+
}
57+
58+
function setQuantityByName(cart, name, quant) {
59+
var item = cart[name];
60+
var newItem = objectSet(item, "quantity", quant);
61+
var newCart = objectSet(cart, name, newItem);
62+
return newCart;
63+
}
64+
65+
function setTaxByName(cart, name, tax) {
66+
var item = cart[name];
67+
var newItem = objectSet(item, "tax", tax);
68+
var newCart = objectSet(cart, name, newItem);
69+
return newCart;
70+
}
71+
72+
function objectSet(object, key, value) {
73+
var copy = Object.assign({}, object);
74+
copy[key] = value;
75+
return copy;
76+
}
77+
78+
cart = setPriceByName(cart, "shoe", 13);
79+
cart = setQuantityByName(cart, "shoe", 3);
80+
cart = setShippingByName(cart, "shoe", 0);
81+
cart = setTaxByName(cart, "shoe", 2.34);
82+
83+
</details>
84+
85+
86+
87+
88+
89+
# 리팩터링: 암묵적 인자를 드러내기
90+
91+
- 단계
92+
1. 함수 이름에 있는 암묵적 인자 확인
93+
2. 명시적 인자 추가
94+
3. 함수 본문에 하드 코딩된 값을 새로운 인자로 바꿈
95+
4. 함수를 호출하는 곳을 고침
96+
- 리팩터링 - 어떤 필드값이든 설정할 수 있는 set`Field`ByName로 리팩터링
97+
98+
```tsx
99+
var validItemFields = ['price', 'quantity', 'shipping', 'tax', 'number'];
100+
var translations = { 'quantity': 'number' };
101+
102+
function setFieldByName(cart, name, field, value) {
103+
// 필드명이 문자열이라 발생할 버그 방지 - 런타임에 검사
104+
// 동적 타입 언어인 JS 대신 정적 타입 시스템 언어인 TS 사용하면 컴파일 타임에 검사 가능
105+
if (!validItemFields.includes(field))
106+
throw "Not a valid item field: '" + field + "'.";
107+
// 만약 필드명 바꿔야 하는 상황 - 내부에서 바꾸면 됨
108+
// 원래 필드명을 새로운 필드명으로 바꿔줌 (quantity를 number로)
109+
if (translations.hasOwnProperty(field)) {
110+
field = translations[field];
111+
}
112+
113+
var item = cart[name];
114+
var newItem = objectSet(item, field, value);
115+
var newCart = objectSet(cart, name, newItem);
116+
return newCart;
117+
}
118+
119+
// ? 기존 - 함수 이름에 암묵적 인자 존재
120+
// cart = setPriceByName(cart, "shoe", 13);
121+
// cart = setQuantityByName(cart, "shoe", 3);
122+
// cart = setShippingByName(cart, "shoe", 0);
123+
// cart = setTaxByName(cart, "shoe", 2.34);
124+
125+
// ? 변경 - 필드명을 일급 값으로 변경. (field라는 인자로 받음)
126+
cart = setFieldByName(cart, "shoe", 'price', 13);
127+
cart = setFieldByName(cart, "shoe", 'quantity', 3);
128+
cart = setFieldByName(cart, "shoe", 'shipping', 0);
129+
cart = setFieldByName(cart, "shoe", 'tax', 2.34);
130+
```
131+
132+
133+
## 일급인 것과 일급이 아닌 것을 구별하기
134+
135+
- 일급이 아닌 것
136+
1. 수식 연산자
137+
2. 반복문
138+
3. 조건문
139+
4. try/catch 블록
140+
- 일급으로 할 수 있는 것
141+
1. 변수에 할당
142+
2. 함수의 인자로 넘기기
143+
3. 함수의 리턴값으로 받기
144+
4. 배열이나 객체에 담기
145+
146+
## 데이터 지향
147+
148+
- 이벤트와 엔티티에 대한 사실을 표현하기 위해 일반 데이터 구조를 사용하는 프로그래밍 형식
149+
- 데이터를 데이터 그대로 사용 → 여러 방법으로 해석 가능
150+
151+
# 리팩터링: 함수 본문을 콜백으로 바꾸기
152+
153+
- 단계
154+
1. 함수 본문에서 바꿀 부분의 앞부분과 뒷부분 확인
155+
2. 리팩터링할 코드를 함수로 빼냄
156+
3. 빼낸 함수의 인자로 넘길 부분을 또 다른 함수로 빼냄
157+
- `고차 함수`(Higher-order function) - 함수를 인자로 받거나 함수를 리턴할 수 있는 함수
158+
- forEach()는 함수를 인자로 받는 고차함수. for문 대신 쓰면 됨.
159+
- 단계별로 리팩터링하기
160+
1. 함수 본문에서 바꿀 부분의 앞부분과 뒷부분 확인
161+
162+
```tsx
163+
try {
164+
saveUserData(user);
165+
} catch (error) {
166+
logToSnapErrors(error);
167+
}
168+
169+
try {
170+
fetchProduct(productId);
171+
} catch (error) {
172+
logToSnapErrors(error);
173+
}
174+
```
175+
176+
2. 리팩터링할 코드를 함수로 빼냄
177+
178+
```tsx
179+
function withLogging() {
180+
try {
181+
saveUserData(user);
182+
} catch (error) {
183+
logToSnapErrors(error);
184+
}
185+
}
186+
187+
withLogging();
188+
```
189+
190+
3. 빼낸 함수의 인자로 넘길 부분을 또 다른 함수로 빼냄
191+
192+
```tsx
193+
function withLogging(f) {
194+
try {
195+
f(); // 인자로 받은 함수 호출
196+
} catch (error) {
197+
logToSnapErrors(error);
198+
}
199+
}
200+
201+
// 인라인 정의 - 익명 함수 사용
202+
withLogging(function () {
203+
saveUserData(user);
204+
});
205+
```
206+
207+
208+
## 함수를 정의하는 방법
209+
210+
1. 전역으로 정의하기
211+
2. 지역적으로 정의하기
212+
3. 인라인으로 정의하기

0 commit comments

Comments
 (0)