함수 표현식보다는 함수 선언식을 활용한다. eslint : func-style
Use function declarations instead of function expressions
- 함수 표현식(=함수식)보다는 함수 선언문을 활용한다.
- 함수 선언문은 파일에서 함수가 정의되기 전에 함수를 참조할 수 있다.
- 함수 선언문은 함수 본체까지 호이스팅 되지만, 함수 표현식은 참조(함수 이름)만이 호이스팅 된다. 이 룰에 의해 함수식의 부분을 항상 Arrow함수에서 이용하는것이 가능하다.
- 함수 선언문은 함수의 정의가 파일의 나머지 부분을 이해하기 어려울 만큼 복잡하다면 모듈로 추출할 수 있다.
// bad
function foo() {
// ...
}
// bad
const foo = function () {
// ...
};
// good
// 변수 참조 호출과 구분되는 이름
const short = function longUniqueMoreDescriptiveLexicalFoo() {
// ...
};
즉시 호출 함수 표현식을 괄호로 감싸기 eslint: wrap-iife
- 즉시 호출 함수 표현식은 하나의 단위이며, 괄호로 이것을 감싸면 괄호 안의 표현을 명확하게 해준다.
- 모듈을 어디에서나 사용한다면 즉시 호출 표현식은 전혀 필요하지 않다는 점을 주의 해야한다.
// 즉시 호출 함수 표현식 (IIFE)
(function () {
console.log('Welcome to the Internet. Please follow me.');
}());
비함수블럭에서 함수 선언 X -> 변수에 함수 할당.
eslint: no-loop-func
Never declare a function in a non function block (if, while, etc). Assign the function to a variable instead. Browsers will allow you to do it, but they all interpret it differently, which is bad news bears.
- non-function block : if, while, etc
- if, while 등의 블록 내부에서 함수를 선언하지 않습니다.
- (if, while, etc). 브라우저마다 함수 block의 해석을 다르게 허용할 것이다
매개변수에 arguments 사용 X
Never name a parameter arguments.
This will take precedence over thearguments
object that is given to every function scope.`
- arguments 라는 이름을 갖는 파라미터를 사용하지 않습니다. 이는 함수 스코프 내에 주어지는 arguments라는 오브젝트를 덮어 쓰게 된다.
- 함수의 arguments 프로퍼티보다 매개변수의 arguments 가 우선시 된다.
// bad
function nope(name, options, arguments) {
// ...stuff...
}
// good
function yup(name, options, args) {
// ...stuff...
}
// 참고: arguments란?
/* 함수의 매개변수 목록을 가져오는 예약 변수
let what_is_arguments = function(a, b, c) {
console.log(arguments);
}
what_is_arguments(1, 2, 3); // { 0: 1, 1: 2, 2: 3 }
*/
prefer-rest-params : rest syntax ... > arguments X
Never use arguments
, opt to use rest syntax ...
instead.
- 함수 파라미터의
arguments
대신 rest 파라미터인...
를 사용합니다. ...
을 사용하는 것이 더 명시적이며, Array-like인arguments
와 달리...
은 진짜Array
이다.
// bad
function concatenateAll() {
const args = Array.prototype.slice.call(arguments);
return args.join('');
}
// good
function concatenateAll(...args) {
return args.join('');
}
// example
function aFunc(...args) {
console.log(arguments);
console.log(args);
}
aFunc(1, 2, 3);
/* 실행 결과
{ 0: 1, 1: 2, 2: 3 } // Array-like Object
[ 1, 2, 3 ] // Array
*/
default parameter syntax > 함수 인자 변경
Use default parameter syntax rather than mutating function arguments.
- 함수의 파라미터를 변경하는 것 보다, default 파라미터를 사용합니다.
// really bad
function handleThings(opts) {
// 절대 함수의 인자를 변경해선 안된다.
// opts 가 거짓이면 원하는 객체로 설정되지만 미묘한 버그가 발생할 수 있습니다.
opts = opts || {};
// ...
}
// still bad
function handleThings(opts) {
// 여전히 파라미터를 조건적으로 변경시키는 코드입니다.
if (opts === void 0) {
opts = {};
}
// ...
}
// good
function handleThings(opts = {}) {
// ...
}
사이드 이펙트를 유발하는 default parameter 사용 않을 것.
Avoid side effects with default parameters.
- 사이드 이펙트가 있을만한 default 파라미터는 사용하지 않는다.
- 이러한 파라미터는 가독성면에서 혼란을 줄 수 있다.
var b = 1;
// bad
function count(a = b++) {
console.log(a);
}
// default 파라미터에 후위 연산자를 사용함으로써 실행시 console.log에 의해 노출될 값을 예측하기 어렵다.
count(); // 1
count(); // 2
count(3); // 3
count(); // 3
default-param-last : default parameters 는 마지막에 적어줌.
// bad
function handleThings(opts = {}, name) {
// ...
}
// good
function handleThings(name, opts = {}) {
// ...
}
ECMA-262, block as statements(명령문),
함수선언 as not statements .
ECMA-262 명세는 블록을 구문의 일종으로 정의하고 있지만 함수선언은 구문이 아닙니다.
// bad
if (currentUser) {
function test() {
console.log('Nope.');
}
}
// good
let test;
if (currentUser) {
test = () => {
console.log('Yup.');
};
}
No-new-func : 함수 객체 생성, 함수 생성자 X.
Never use the Function constructor to create a new function.
- 절대 새 함수를 작성하기 위해 Function constructor를 이용하지 마십시오
- 문자열을 '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;
};
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() {};
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;
}
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) {
// ...
}
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);
'JS > 자바스크립트 Style Guide' 카테고리의 다른 글
8. Classes & Constructors(JS style guide) (0) | 2022.12.27 |
---|---|
7. Arrow Functions (JS style guide) (0) | 2022.12.21 |
5. Strings (JS style guide) (0) | 2022.12.07 |
4. Destructuring (JS style guide) (0) | 2022.12.02 |
3. Arrays (JS style guide) (0) | 2022.11.22 |