# Functions
# func-style : 이름있는 함수 표현식 > 함수 선언식
- 함수 선언식
- 함수 선언이 호이스트된다. (TODO airbnb 스타일 가이드에서의 호이스팅의 의미가 다른가?)
- 파일에서 함수가 정의되기 전에 함수를 참조할 수 있다
- 가독성과 유지 보수성을 해친다.
- 함수의 정의가 파일의 나머지 부분을 이해하는 데 방해가 될만큼 충분히 크거나 복잡하다면 -> 모듈로 추출
- 이름있는 함수 표현식
- This eliminates any assumptions made about the Error’s call stack.
- 에러 콜스택에서의 가정(유추해야 하는일)을 없앤다? 에러를 더 잘찾아낼 수 있다라는 의미로 해석.
// bad
function foo() {
// ...
}
// bad
const foo = function () {
// ...
};
// good
// lexical name distinguished from the variable-referenced invocation(s)
const short = function longUniqueMoreDescriptiveLexicalFoo() {
// ...
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# wrap-iife : IIFE: parentheses 으로 감싸기
- 모듈 시스템에서의 IIFE 는 거의 사용되지 않는다.
// immediately-invoked function expression (IIFE)
(function () {
console.log('Welcome to the Internet. Please follow me.');
}());
1
2
3
4
2
3
4
# no-loop-func : 비함수블럭에서 함수 선언 X -> 변수에 함수 할당.
- non-function block :
if, while
, etc - 브라우저마다 비함수블럭에서의 함수블럭 해석을 다르게 한다.
# ECMA-262, block as statements(명령문), 함수선언 as not statements
// bad
if (currentUser) {
function test() {
console.log('Nope.');
}
}
// good
let test;
if (currentUser) {
test = () => {
console.log('Yup.');
};
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 매개변수에 arguments 사용 X
- 함수의 arguments 프로퍼티보다 매개변수의 arguments 가 우선시 된다.
// bad
function foo(name, options, arguments) {
// ...
}
// good
function foo(name, options, args) {
// ...
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# prefer-rest-params : rest syntax ... > arguments X
- 함수에서 arguments 은 절대 사용하지 말것.
- 나머지 인수는 유사배열이 아닌 실제 배열이다.
// bad
function concatenateAll() {
const args = Array.prototype.slice.call(arguments);
return args.join('');
}
// good
function concatenateAll(...args) {
return args.join('');
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# default parameter syntax > 함수 인자 변경
// really bad
function handleThings(opts) {
// 절대 함수의 인자를 변경해선 안된다.
// opts 가 거짓이면 원하는 객체로 설정되지만 미묘한 버그가 발생할 수 있습니다.
opts = opts || {};
// ...
}
// still bad
function handleThings(opts) {
if (opts === void 0) {
opts = {};
}
// ...
}
// good
function handleThings(opts = {}) {
// ...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 사이드 이펙트를 유발하는 default parameter 사용 말것.
var b = 1;
// bad
function count(a = b++) {
console.log(a);
}
count(); // 1
count(); // 2
count(3); // 3
count(); // 3
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# default-param-last : default parameters 는 마지막에 적는다.
// bad
function handleThings(opts = {}, name) {
// ...
}
// good
function handleThings(name, opts = {}) {
// ...
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# no-new-func : 함수 객체 생성, 함수 생성자 X
- 생성자로 함수 생성
- 문자열을 'eval()' 와 유사하게 평가한다.
- 취약점
// bad
var add = new Function('a', 'b', 'return a + b');
// still bad
var subtract = Function('a', 'b', 'return a - b');
// good
var x = function (a, b) {
return a + b;
};
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# space-before-function-paren, space-before-blocks : 함수 시그니처의 space 유지
-
- functions 그리고 methods 의 입력과 출력을 정의
- parameters와 그들의 types
- 반환값과 타입
- 던져지거나 콜백으로 반환되는 exceptions
- object-oriented 프로그램에서 메소드의 접근 권한에 대한 정보 (public, static, 혹은 prototype와 같은 키워드들).
일관성
이름 추가/제거 -> 공백 추가/제거 의 동작을 안해도됨
// bad
const f = function(){};
const g = function (){};
const h = function() {};
const a = function a() {};
// good
const x = function () {};
const y = function a() {};
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# no-param-reassign : 매개 변수로 전달 된 객체 조작 금지
- 함수의 (original)caller 에게 변수 부작용의 가능성.
// bad
function f1(obj) {
obj.key = 1;
}
// good
function f2(obj) {
const key = Object.prototype.hasOwnProperty.call(obj, 'key') ? obj.key : 1;
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# no-param-reassign : 매개변수 재할당 금지
- 매개변수 재할당
- arguments 객체 접근 -> 예기치 않은 행동 발생
- 최적화 이슈, especially in V8.
// bad
function f1(a) {
a = 1;
// ...
}
function f2(a) {
if (!a) { a = 1; }
// ...
}
// good
function f3(a) {
const b = a || 1;
// ...
}
function f4(a = 1) {
// ...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# prefer-spread : 가변 함수, spread operator ... > apply
- variadic functions (가변 함수)
- 가변 개수의 인수 허용
- apply 메서드로 context(this) 를 제공해 줄 필요 없어 깨끗하다.
- apply 메서드를 한번 더 적용하기 힘들다.
// bad
const x = [1, 2, 3, 4, 5];
console.log.apply(console, x);
// good
console.log(...x);
// bad
new (Function.prototype.bind.apply(Date, [null, 2016, 8, 5]));
// good
new Date(...[2016, 8, 5]);
var args = [1, 2, 3, 4];
// bad
Math.max.apply(Math, args);
// good
Math.max(...args);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# function-paren-newline : 함수의 여러줄의 시그니쳐/호출, 들여쓰기, 한줄에 하나씩
// bad
function foo(bar,
baz,
quux) {
// ...
}
// good
function foo(
bar,
baz,
quux,
) {
// ...
}
// bad
console.log(foo,
bar,
baz);
// good
console.log(
foo,
bar,
baz,
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27