티스토리 뷰
반응형
참고
- 더 사용이 잦을 것으로 보이는 항목부터 실습하였음.
- 아래의 내용은 '모든 JS 개발자가 이렇게 한다!'가 아닌 Airbnb의 작성 가이드를 repl.it에서 따라한 결과(안 따라한 것도 많음)
- 적절히 참고할 것 :D
1. Types
- Use
const
for all of your references; avoid usingvar
.- 모든 참조는 const를 사용하고, var를 지양합니다.
- 이는 재할당으로부터 비롯되는 버그, 또는 이해하기 어려운 코드의 사용을 방지해줍니다.
- If you must reassign references, use
let
instead ofvar
.- 부득이하게 재할당해야하는 경우, var 대신 let을 사용합니다.
- var : function scope / 재할당 가능
- let : block scope / 재할당 불가
- 부득이하게 재할당해야하는 경우, var 대신 let을 사용합니다.
{
let a = 1;
const b = 2;
var c = 3;
console.log(c);
console.log(b);
console.log(a);
}
console.log(c);
console.log(b);
console.log(a);
/* 결과
ReferenceError: b is not defined
at /stringfy.js:10:13
3
2
1
3
*/
2. Objects
- Use the literal syntax for object creation.
- 오브젝트는 literal 문법으로 생성합니다.
// bad
const item = new Object();
// good
const item = {};
- Use object method shorthand.
- 메소드는 단축 구문을 사용합니다.
// bad
const atom = {
value: 1,
addValue: function (value) {
return atom.value + value;
},
};
// good
const atom = {
value: 1,
addValue(value) {
return atom.value + value;
},
};
- Use property value shorthand.
- 프로퍼티 또한 단축 구문을 사용합니다.
const lukeSkywalker = 'Luke Skywalker';
// bad
const obj = {
lukeSkywalker: lukeSkywalker,
};
// good
const obj = {
lukeSkywalker,
};
/* console.log(obj)
{ lukeSkywalker: 'Luke Skywalker' }
*/
- Group your shorthand properties at the beginning of your object declaration.
- 프로퍼티를 단축 구문으로 사용한다면, 가독성을 위해 오브젝트 선언의 시작 부분에 모아둡니다.
const anakinSkywalker = 'Anakin Skywalker';
const lukeSkywalker = 'Luke Skywalker';
// bad
const obj = {
episodeOne: 1,
twoJediWalkIntoACantina: 2,
lukeSkywalker,
episodeThree: 3,
mayTheFourth: 4,
anakinSkywalker,
};
// good
const obj = {
lukeSkywalker,
anakinSkywalker,
episodeOne: 1,
twoJediWalkIntoACantina: 2,
episodeThree: 3,
mayTheFourth: 4,
};
3. Arrays
- Use the literal syntax for array creation.
- 배열 역시 literal 문법으로 생성합니다.
// bad
const items = new Array();
// good
const items = [];
- Use Array#push instead of direct assignment to add items to an array.
- 배열에 직접 항목을 추가하는 것보다 push를 사용합니다.
const someStack = [];
// bad
someStack[someStack.length] = 'abracadabra';
// good
someStack.push('abracadabra');
- Use array spreads
...
to copy arrays.- 배열을 복사할때는 ... 연산자를 사용합니다.
// bad
const len = items.length;
const itemsCopy = [];
let i;
for (i = 0; i < len; i++) {
itemsCopy[i] = items[i];
}
// good
const itemsCopy = [...items];
/*
const items = [1, 2, 3];
// good
const itemsCopy = [...items];
console.log(itemsCopy);
실행 결과
[ 1, 2, 3 ]
*/
- To convert an array-like object to an array, use Array#from
- Array-like 오브젝트를 배열로 변환하려면 from을 사용합니다.
const foo = document.querySelectorAll('.foo');
const nodes = Array.from(foo);
console.log(nodes);
/* 실행 결과
[ HTMLButtonElement {},
HTMLButtonElement {},
HTMLButtonElement {},
HTMLButtonElement {},
HTMLButtonElement {} ]
단순히 {a:1,b:2,c:3}을 Array.from할 경우 빈 배열로 나옴. Array-like Object를 찾아보기
*/
4. Destructing
- Use object destructuring when accessing and using multiple properties of an object.
- 단일 오브젝트의 여러 프로퍼티에 접근하는 경우 Destructing을 사용합니다.
- 이를 통해 프로퍼티를 위한 임시적인 참조를 줄일 수 있습니다.
// bad
function getFullName(user) {
const firstName = user.firstName;
const lastName = user.lastName;
return `${firstName} ${lastName}`;
}
// good
function getFullName(obj) {
const { firstName, lastName } = obj;
return `${firstName} ${lastName}`;
}
// best
function getFullName({ firstName, lastName }) {
return `${firstName} ${lastName}`;
}
- Use array destructing
- 배열 또한 destructing을 활용합니다.
const arr = [1, 2, 3, 4];
// bad
const first = arr[0];
const second = arr[1];
// good
const [first, second] = arr;
5. Strings
- Use single quotes
''
for strings.- 문자열에는 ''를 사용합니다.
- 쉬프트를 한 번 덜 누를 수 있습니다. (...)
- Strings longer than 100 characters should be written across multiple lines using string concatenation.
- 100문자 이상의 문자열(긴 문자열을 말하는 듯)은 문자열 연결을 사용합니다.
// bad
const errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.';
// bad
const errorMessage = 'This is a super long error that was thrown because \
of Batman. When you stop to think about how Batman had anything to do \
with this, you would get nowhere \
fast.';
// good
const errorMessage = 'This is a super long error that was thrown because ' +
'of Batman. When you stop to think about how Batman had anything to do ' +
'with this, you would get nowhere fast.';
- When programmatically building up strings, use template strings instead of concatenation.
- 문자열을 생성하는 경우에는 template string(``)을 사용합니다.
- 이는 간결한 구문을 통해 가독성을 향상시킵니다.
// bad
function sayHi(name) {
return 'How are you, ' + name + '?';
}
// bad
function sayHi(name) {
return ['How are you, ', name, '?'].join();
}
// good
function sayHi(name) {
return `How are you, ${name}?`;
}
6. Functions
- Use function declarations instead of function expressions.
- 함수 표현식보다는 함수 선언문을 활용합니다.
- 함수 선언문은 함수 본체까지 호이스팅되지만, 함수 표현식은 참조(함수 이름)만이 호이스팅됩니다.
- 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.
- if, while 등의 블록 내부에서 함수를 선언하지 않습니다.
- Never name a parameter
arguments
. This will take precedence over thearguments
object that is given to every function scope.- '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 }
*/
- 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
*/
- Use default parameter syntax rather than mutating function arguments.
- 함수의 파라미터를 변경하는 것 보다, default 파라미터를 사용합니다.
// really bad
function handleThings(opts) {
// 아래와 같이 함수 파라미터를 조건적으로 변경시키는 것보다 default 파라미터를 사용합니다.
// opts 파라미터가 falsy한 값으로 호출되었다면 원하는 대로 opts에 object가 초기화되겠지만,
// 여전히 버그 발생의 여지가 남습니다.
opts = opts || {};
// ...
}
// still bad
function handleThings(opts) {
// 여전히 파라미터를 조건적으로 변경시키는 코드입니다.
if (opts === void 0) {
opts = {};
}
// ...
}
// good
function handleThings(opts = {}) {
// ...
}
- 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
- Always put default parameters last.
- default 파라미터는 가장 뒤에 둡니다.
// bad
function handleThings(opts = {}, name) {
// ...
}
// good
function handleThings(name, opts = {}) {
// ...
}
- Never use the Function constructor to create a new function.
- 절대로 새로운 함수를 생성하기 위해 함수 생성자를 사용하지 않습니다.
- 이러한 방법으로 함수를 생성하는 것은 eval()과 같은 수준의 취약점을 일으킬 수 있습니다.
// bad
var add = new Function('a', 'b', 'return a + b');
// still bad
var subtract = Function('a', 'b', 'return a - b');
7. Arrow Functions
- When you must use function expressions (as when passing an anonymous function), use arrow function notation.
- 익명 함수를 사용하는 함수식을 사용하는 경우 화살표 함수를 사용합니다.
- 화살표 함수는 해당 this의 context로 실행되며, 가독성 측면에서 보다 간결함이 있습니다.
// bad
[1, 2, 3].map(function (x) {
const y = x + 1;
return x * y;
});
// good
[1, 2, 3].map((x) => {
const y = x + 1;
return x * y;
});
- If the function body consists of a single expression, feel free to omit the braces and use the implicit return. Otherwise use a
return
statement.- 화살표 함수의 함수식이 한 줄로 표현된 경우 중괄호를 생략하고 암시적 return을 사용합니다.
- 그 외의 경우에는 return을 명시적으로 작성합니다.
- 이는 다수의 함수가 연결(chaining)된 경우에 가독성 향상을 위한 문법 설탕에 해당합니다.
- In case the expression spans over multiple lines, wrap it in parentheses for better readability.
- 화살표 함수의 함수식이 여러 줄로 표현된 경우, 가독성을 위해 소괄호로 함수식을 감싸주세요.
- 이는 함수의 시작과 끝을 알기 쉽도록 하기 위함입니다.
// bad
[1, 2, 3].map(number => 'As time went by, the string containing the ' +
`${number} became much longer. So we needed to break it over multiple ` +
'lines.'
);
// good
[1, 2, 3].map(number => (
`As time went by, the string containing the ${number} became much ` +
'longer. So we needed to break it over multiple lines.'
));
- If your function only takes a single argument, feel free to omit the parentheses.
- 함수의 매개변수가 하나라면, 소괄호를 생략합니다.
- 역시 가독성 향상을 위함입니다.
// good
[1, 2, 3].map(x => x * x);
// good
[1, 2, 3].reduce((y, x) => x + y);
8. Classes & Constructors
- Always use
class
. Avoid manipulatingprototype
directly.- prototype을 직접 조작하는 것보다 class를 활용합니다.
- class 문법은 prototype의 조작보다 더 간결하며, 의미를 알기 쉽기 때문입니다.
// bad
function Queue(contents = []) {
this._queue = [...contents];
}
Queue.prototype.pop = function() {
const value = this._queue[0];
this._queue.splice(0, 1);
return value;
}
// good
class Queue {
constructor(contents = []) {
this._queue = [...contents];
}
pop() {
const value = this._queue[0];
this._queue.splice(0, 1);
return value;
}
}
/* 참고: 언더바(_) 변수
코딩 컨벤션의 일종이며, 해당 함수 내부에서 사용될 변수 또는 함수임을 암시하기 위함. (java의 private과 유사)
class Injuk {
constructor(contents = []) {
console.log(this);
console.log(this._injuk);
this._injuk = [...contents];
console.log(this._injuk);
}
}
let injuk = new Injuk([1, 2, 3]);
실행 결과:
Injuk {} // 실행 context는 Injuk{} 클래스
undefined // this._injuk 초기화 전
[ 1, 2, 3 ] // this._injuk 초기화 후
*/
- Use
extends
for inheritance.- 상속은 extends를 사용합니다.
- instanceof를 사용할 수 있도록 하면서도 프로토타입 상속을 받을 수 있게 구현된 Built-in 방식이기 때문입니다.
// bad
const inherits = require('inherits');
function PeekableQueue(contents) {
Queue.apply(this, contents);
}
inherits(PeekableQueue, Queue);
PeekableQueue.prototype.peek = function() {
return this._queue[0];
}
// good
class PeekableQueue extends Queue {
peek() {
return this._queue[0];
}
}
/* inherits 검증 필요
*/
- Methods can return
this
to help with method chaining.- 메소드의 반환값으로
this
를 반환하는 것으로 메소드채이닝을 할 수 있습니다.
- 메소드의 반환값으로
// bad
// prototype을 사용하며, return이 적절하지 않게 구현되었습니다.
Jedi.prototype.jump = function() {
this.jumping = true;
return true;
};
Jedi.prototype.setHeight = function(height) {
this.height = height;
};
const luke = new Jedi();
luke.jump(); // => true
luke.setHeight(20); // => undefined
// good
// class 방식을 사용하며, 메소드가 context(이 경우, Jedi{})를 반환하여 연속된 메소드 사용(메소드 체이닝)이 가능합니다.
class Jedi {
jump() {
this.jumping = true;
return this;
}
setHeight(height) {
this.height = height;
return this;
}
}
const luke = new Jedi();
luke.jump()
.setHeight(20);
- It's okay to write a custom toString() method, just make sure it works successfully and causes no side effects.
- class 별로 독자적인 toString()을 사용하는 것은 허용되나, 정상 동작 여부와 side effect 여부를 확인해주시기 바랍니다.
class Jedi {
constructor(options = {}) {
this.name = options.name || 'no name';
}
getName() {
return this.name;
}
// It's Okay... just make sure it
toString() {
return `Jedi - ${this.getName()}`;
}
}
'Dev. > javascript' 카테고리의 다른 글
[JS] 구조 분해 할당을 이용한 변수 초기화 (0) | 2021.04.05 |
---|---|
[JS] 문자열을 배열로 변환 (0) | 2021.04.01 |
[JS] Airbnb 스타일 가이드 12 - 15. (0) | 2021.04.01 |
[JS] 배열과 some (0) | 2021.04.01 |
[JS] 배열과 reduce (0) | 2021.03.31 |
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- etc
- mysql
- spring boot
- pgloader
- Spring Cloud Config
- JEST
- Node.js
- postgresql
- jQuery
- terraform
- eureka
- hashicorp
- Vault
- Docker
- Puppeteer
- Git
- Linux
- react
- kotlin
- Java
- IntelliJ
- Database
- shell
- dev
- javascript
- JPA
- AWS
- Gradle
- AWS IoT
- 코딩테스트
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 28 | 29 | 30 | 31 |
글 보관함