코드 스타일링 21.03.17
in Dev on Java Script
[알고리즘 문제 풀이] -문제 조건 쪼개기 -수도 코드를 JS 개념과 연결 -남들이 알아볼 수 있는 간결한 코드 + 주석 -타입확인과 변환 -이중 반복문 -반복문 내 다수의 조건문 -for vs while 언제 사용할지
[코드 스타일링] -가독성 좋은 코드 작성 필요 : 커뮤니케이션 비용을 줄일 수 있다.
1.들여쓰기
- GOOD
if (condition) {
action();
}
// 코드의 로직이 명확하게 종속적으로 나뉘는 코드를 쓸 때,
// 종속된 code block은 주인 code block보다 두 칸 들여쓰기 합니다.
- BAD
if (condition) {
action();
}
// 아래 코드의 들여쓰기를 수젖ㅇ하여 GOOD으로 옮기기
transmogrify({
a: {
b: function(){
}
}});
// code block이 바뀌고 해당 code block에 맞춰 줄을 바꿀 때 2칸 들여쓰기 규칙을 지켜야 합니다.
// 속성 a 안에 속성 b가 있는데, 마치 같은 범주에 있는 속성으로 보입니다. 또한 함수와 객체의 구분이 명확하지 않습니다.
(주의) tab vs space 두번 : 85% 이상이 스페이스 들여쓰기 사용. 피해야할 한가지는 스페이스와 탭을 혼용해서 쓰는 것.
2.변수 네이밍 변수명은 값의 본질적인 의미를 가지고 있어야 합니다.
변수의 이름은 한 단어(Descriptive word)로 표현하는 것이 가장 좋습니다. 개발 분야(domain)의 핵심을 잘 묘사해주는 단어일수록 좋습니다. 예를 들어 금융 관련 개발을 하는 경우, 그 산업 분야에서 사용하는 용어를 가능하면 그대로 쓰는 것이 좋습니다.
- GOOD vs BAD
// GOOD
let interestRate = 0.2;
// 이자율임을 쉽게 알 수 있습니다. 어떤 금융상품의 이자율인지 표기할 수 있으면 더 좋겠네요.
// BAD
let numA = 0.2;
// 단지 숫자라는 것 의미 외 다른 의미가 없어 무슨 변수인지 추정해야 합니다.
변수에 할당되는 값의 형식이 아닌, 그 값의 의미가 변수 이름에 반영되어야 합니다.
// GOOD
let animals = ['cat', 'dog', 'fish'];
// 변수가 가지는 의미를 명확하게 표현하고 있습니다.
// BAD
let targetInputs = ['cat', 'dog', 'fish'];
// 변수가 가지는 구조를 표현하고 있는 변수명으로, animals가 더 낫습니다.
데이터의 모음(collection)이 할당된 변수의 이름은 복수 명사가 좋습니다.
// GOOD
let animals = ['cat', 'dog', 'fish'];
// 하나의 동물이 아니라, 여러 마리의 동물이 있는 데이터임이 명시적으로 표현되어 있습니다.
// BAD
let animalList = ['cat', 'dog', 'fish'];
// animals로 표현되는 것이 의미를 조금 더 잘 표현합니다.
let animal = ['cat', 'dog', 'fish'];
// 하나의 동물인지, 여러 마리의 동물 리스트인지 알 수 없습니다.
boolean이 할당된 변수는 is 혹은 are을 붙여서 참 혹은 거짓임을 분명히 표현합니다.
// GOOD
let isDog = true;
let 강아지입니다 = true;
함수의 이름은 동사로 시작하는게 좋습니다. 함수의 기능을 담은 동사를 함수명에 포함하면 역할을 쉽게 파악할 수 있습니다. 또한, 함수의 입력값과 출력값, 그리고 둘 사이의 변환 과정을 파악하기가 쉽습니다.
// GOOD
let countBlocks = function() {
// 벽돌의 개수를 세는 함수임을 쉽게 알 수 있습니다.
}
let countWaterBlocksBetweenTowers = function() {
// 타워 사이의 벽돌의 개수를 세는 함수임을 쉽게 알 수 있습니다.
}
// BAD
let waterBlocks = function() {
// 변수명으로는 역할이 파악이 되지 않기 때문에, 아래의 주석이 없으면 무슨 역할을 하는지 파악하기 어렵습니다.
// 이 함수는 벽돌의 개수를 세는 함수입니다. 타워 사이의 벽돌을 세는 것을 의미합니다.
}
변수 할당 값이 Class인 경우에 주로 변수의 첫 글자를 대문자로 사용합니다.
class Animal(){
// ES6 부터 사용 가능한 class가 할당되는 변수는 첫 글자를 대문자로 적습니다.
}
new 키워드를 사용한 함수에 한해서 대문자를 쓰기도 합니다. class 역할을 하기 때문이죠.
function Animal() {
// class 생성자 함수가 될 함수임으로 대문자로 적습니다.
}
상수(변하지 않는 값)는 모두 대문자로 적습니다.
const MAX_ITEMS_IN_QUEUE = 100;
기호 및 구두점(punctuation)
문법적으로 생략 가능한 때에도 중괄호는 생략하지 않습니다.
// GOOD
for (key in object) {
alert(key);
}
// for문의 작동 범위를 눈으로 확인 가능합니다.
// BAD
for (key in object)
alert(key);
// for문의 작동 범위를 눈으로 확인할 수 없습니다.
JavaScript의 문자열 표시를 위해서 작은 따옴표를 권장합니다.
// GOOD
let dog = 'dog';
let cat = 'cat';
// BAD
let dog = 'dog';
let cat = "cat";
// 띄어쓰기와 tab과 같이 "", '', 혼용은 최악의 코드 스타일입니다.
줄 바꿈이 필요한 문자열을 정의할 때는 `(백틱, backtick) 사용을 권장합니다.
// GOOD
let multilineText = `this is line one
this is line two
this is line three`;
// 엔터가 명확하게 보입니다.
// BAD
let multilineText = 'this is line one' + '\n' + 'this is line two' + '\n' + 'this is line three';
// 엔터가 명확하게 보이지 않습니다.
코드 실행의 가장 작은 단위인 Statement(문)의 끝에 세미콜론을 사용합니다.
// GOOD
alert('hi');
// BAD
alert('hi')
(주의) if, for, while문의 끝에는 세미콜론을 사용하지 않아야 합니다. 중괄호로 끝나는 Statement는 이미 종료가 암시되어 있기 때문에, 세미콜론을 사용하지 않습니다.
// GOOD
if (condition) {
response();
}
// BAD
if (condition) {
response();
};
(주의) 함수 표현식의 끝에는 세미콜론을 사용합니다.
// GOOD
let greet = function () {
alert('hi');
};
// BAD
let greet = function () {
alert('hi');
}
최근의 자바스크립트는 다른 프로그래밍 언어와 달리 세미콜론을 엄밀하게 적지 않아도 에러가 나는 경우는 거의 없습니다. 세미콜론 자동 삽입 기능인 ASI(automatic semicolon insertion)이 대부분의 자바스크립트 엔진에서 작동하기 때문
연산자와 키워드
반드시 엄격한 동치 연산(strict equality, ===, !==)을 사용
// GOOD
if (0 === '') {
alert('looks like they\'re equal');
}
// 엄격한 동치 연산은 `0`과 `''`을 다르다고 평가합니다.
// BAD
if (0 == '') {
alert('looks like they\'re equal');
}
// 엄격하지 않은 동치 연산은 `0`과 `''`을 같다고 평가합니다.
3항 연산자(?)는 간결하고 가독성이 좋은 경우만 사용합니다. 3항 연산자는 코드를 간결하게 만듭니다. 그러나 장황한 경우 가독성이 떨어집니다.
// GOOD
if (actual !== expected) {
console.log('FAILED ' + testName + ': Expected ' + expected + ', but got ' + actual);
} else {
console.log('passed');
}
// BAD
return (actual === expected) ? 'passed' : 'FAILED ['+ testName + '] Expected "'+expected+'",but got '+'"'+actual+'"';
not 연산자(!)는 바로 앞에 붙여서 사용합니다.
// GOOD
if (!isEqual) {
// BAD
if (! isEqual) {
짧게 쓰기
// GOOD
function square(n) {
return n * n;
}
// BAD
function square(n) {
let squaredN = n * n;
return squaredN;
}
// 변수를 선언하지 않아도 됩니다.
부정의 의미가 명확한 곳에만 NOT 연산자를 사용합니다.
// GOOD
if(equalSizes && equalValues) {
// 사이즈가 같고, 값이 같은 경우
} else {
}
// BAD
if(!equalSizes || !equalValues) {
// 사이즈가 같지 않거나 값이 값지 않은 경우
} else {
}
// 이 조건문은 불필요하게 조건에 대해 고민을 해야 합니다.
(주의) Boolean으로 평가되는 표현문은 바로 return 하세요
// GOOD
return charSet.size > text.length;
// BAD
if(charSet.size < text.length) {
return false;
}
return true;
// 비교문은 무조건 true 혹은 false로 평가되기 때문에 장황하게 조건문을 작성하지 않습니다.
코드 문장과 구문 사이 공간
한 번에 더 많은 코드를 읽기 위해서, 줄 바꿈은 최소. 줄을 바꿔야할 때도 있고, 줄 바꿈을 자제해야 할 때도 있습니다. 판단 기준은 어떻게 작성해야 이해하기 쉬운가? 입니다.
// GOOD
function square(n) {
return n * n;
}
function assertEqual(actual, expected, testName) {
// compare actual and expected
}
// BAD
function square(n) {
return n * n;
}
function assertEqual(actual, expected, testName) {
// compare actual and expected
}
들여쓰기는 일관성있게, 최소화하여 사용
// GOOD
alert('I chose to put no visual padding around this string');
// 괄호와 따옴표 사이 공백이 없습니다.
alert( 'I chose to put visual padding around this string' );
// 괄호와 따옴표 사이 공백이 일관되게 있습니다.
// BAD
alert( 'I only put visual padding on one side of this string');
// 한 쪽에는 공백이 있고, 한 쪽에는 공백이 있습니다.
같은 라인에 값을 보기 위해 하는 들여쓰기는 지양합니다.
// GOOD
let firstItem = getFirst();
let secondItem = getSecond();
let thirteenthItem = getThirteenth();
// BAD
let firstItem = getFirst();
let secondItem = getSecond();
let thirteenthItem = getThirteenth();
// 불필요한 들여쓰기가 너무 많아졌습니다.
(주의) 콤마(,) 사이는 한 칸 띄어씁니다.
// GOOD
assertEqual(Math.pow(3, 2), 9, 'Math.pow squares properly');
// BAD
assertEqual(Math.pow(3,2),9,'Math.pow squares properly');
연산자 사이는 한 칸 띄어씁니다.
// GOOD
'Failed [' + testName + ']'...
if(actual === expected){
// action
} else {
// alternate action
}
// BAD
'Failed ['+testName+']'...
if(actual===expected){
// action
}else{
// alternate action
}
주석
- 주석은 꼭 필요한 경우에만 작성합니다.
- 주석을 적기 전에, 변수 이름과 구조로 코드의 목적이 명확히 표현되면 주석을 적을 필요가 없습니다.
- 주석으로 코드의 작동을 설명하는 것은 지양합니다. 코드를 보고 바로 이해할 수 있을 만큼 가독성이 좋게 코드를 작성해야 합니다.
- 주석을 공부 목적으로 활용하는 것은 좋으나, 숙달되어 이해할 수 있는 코드에 주석을 다는 것은 가독성을 떨어뜨립니다. 점차적으로 줄여나갑시다.
camelCase vs. snake_case
// GOOD
let camelCased = 'Used in javascript';
const MAX_ITEMS_IN_QUEUE = 100;
// JavaScript에서 'snake_case'을 사용하는 경우는, 상수 이름을 지을 때입니다.
// BAD
let snake_cased = 'Used in other languages';
유명 코드 스타일 가이드
- Google JavaScript Style Guide
- Airbnb JavaScript Style Guide
- The Modern JavaScript Tutorial - Coding Styling
- NHN 코딩 컨벤션 - HTML / CSS
- NHN 코딩 컨벤션 - Javascript