파일 이름은 모두 소문자, _ - 는 포함 가능 구두점은 불가. 확장자는 .js
소스 파일은 UTF-8
|", ||, |B, |F, |n, |r, |t 가 있는 경우 해당 숫자 이스케이프 |v 대신 해당 시퀀스 사용. 레거시 8진수 이스케이프는 사용 x
코드를 더 쉽게 읽고 이해하는 것에 집중
모든 새로운 소스 파일은 goog.module or ECMAScript(ES) 모듈 (import or export) 이어야 함.
1. 라이센스 또는 저작권 정보(있는 경우)
2. @fileovervie JSDoc(있는 경우)
3. oog.module 명령문 (goog.module 파일인 경우)
4. ES import 문(ES 모듈인 경우)
5. goog.require 그리고 goog.requireType 진술
6. 파일의 구현
80열 제한이 있으나 import 문 등 줄바꿈 안되는 것은 예외
import 를 통해 가져온 기호는 동일한 이름 유지 앨리어싱 가져오기 (import {SomeThing as SomeOtherThing}) 피하기.
네임스페이스를 위해 정적 메서드나 속성이 포함된 컨테이너 클래스 개체 내보내지 말기.
-> 개별 상수와 함수 내보내기
if 본문에 단일 문만 포함된 경우에도 중괄호 사용
예외 : 아주짧은 경우 가능
if (shortCondition()) foo();
빈 블록 or 유사 구문은 공백 또는 줄 바꿈 없이 열린 후 즉시 닫힐 수 있음
함수 doNothing() {}
하지만 이런 것은 안됨
if(조건) {
// …
} else if(otherCondition) {} else {
// …
}
try {
// …
} catch(e) {}
아래는 모두 유효
const a = [
0,
1,
2,
];
const b =
[0, 1, 2];
const c = [0, 1, 2];
someMethod(foo, [
0, 1, 2,
], bar);
명령문 뒤에는 줄바꿈
기본적으로 열 제한 준수를 위한 줄바꿈이지만, 작성자 재량에 따라 하기
good
currentEstimate =
calc(currentEstimate + x * currentEstimate) /
2.0;
bad
currentEstimate = calc(currentEstimate + x *
currentEstimate) / 2.0;
연산자 래핑 순서
1. 연산자에서 줄이 끊어지면 기호 뒤에 줄이 옴
2. 메서드 또는 생성자 이름은 ( 그뒤에 오는 )에 계속 붙어 있음
3. 쉼표 는 앞에 오는 토큰에 붙어있음.
단일 빈 줄
1. 클래스 또는 객체 리터럴의 연속 메서드 사이
- 객체 리터럴의 두 연속 속성 정의 사이에 빈 줄은 선택
2. 메서드 본문 내에서 문의 논리적 그룹을 드물게 생성. 함수 본문의 시작이나 끝 부분에는 빈 줄 허용 x
3. 선택적 클래스 객체 리터럴의 첫 번째 메서드 앞이나 뒤 (오롯이 선택)
4. 이 문서의 다른 섹션 요구 대로
여러 개 연속 빈 줄도 허용이지만 권장하지는 않습니다.
선행 공백은 다른 곳에서 다뤄짐. 후행 공백은 금지
1. and를 제이환 모든 예약어를 해당 줄에서 뒤에 오는 여는 괄호()에서 구분
2. 해당 줄에서 앞에 있는 닫는 중괄호()와 예약어 사이 else catch 등
3. 이항, 삼항 연산자의 양쪽
4. 쉼표, 세미콜론 뒤. 앞에는 불가
5. : 객체 리터럴 콜론 뒤
6. 줄 끝 주석 시작 이중 슬래시 양쪽
8. 열린 블록 주석 문자 뒤와 닫는 문자 양쪽
함수 인수는 함수 이름과 같은 줄에
여러 줄의 경우 /* */ 안에 넣기 들여쓰기는 주변과 맞춰서
매개변수 이름 주석은 값과 메소드 이름이 의미를 충분히 전달하지 못할 때 사용
someFunction(obviousParam, /* shouldRender= */ true, /* name= */ 'hello');
someFunction(obviousParam, true /* shouldRender */, 'hello' /* 이름 */);
둘다 가능
모든 지역 변수는 기본적으로 const, 값이 변하는 경우 let, var는 사용 금지
배열에서 숫자 아닌 속성 정의 및 사용 x Map 을 사용
배열 리터럴은 구조 분해 수행을 위해 할당 왼쪽에 사용 가능
이것은 가능
[, b,, d] = someArray;
/** @param {!Array<number>=} param1 */
function optionDestructuring([a = 4, b = 2] = []) { … };
이것은 불가
function badDestructuring([a, b] = [4, 2]) { … };
스프레드 연산자의 사용은 권장
[...foo] // Array.prototype.slice.call(foo)보다 선호됨
[...foo, ...bar] // foo.concat(bar)보다 선호됨
Object 사용 금지. {} 객체 리터럴 사용해서 만들기
{
width: 42, // 구조체 스타일 인용되지 않은 키
'maxWidth': 43, // 사전 스타일 인용 키
}
객체 구조 분해 패턴은 할당의 왼쪽에 사용되어 구조 분해를 수행하고 단일 객체에서 여러 값의 압축을 풀 수 있음.
예)
/**
* @param {string} 일반
* @param {{num: (number|undefine), str: (string|undefine)}=} param1
* num: 작업을 수행할 횟수입니다.
* str: 작업을 수행할 문자열입니다.
*/
구조 해제된 함수(일반, {num, str = '일부 기본값'} = {})
잘못된 예시(허용 X)
/** @param {{x: {번호: (번호|정의되지 않음), str: (문자열|정의되지 않음)}}} param1 */
functionnestedTooDeeply({x: {num, str}}) {};
/** @param {{num: (숫자|정의되지 않음), str: (문자열|정의되지 않음)}=} param1 */
function nonShorthandProperty({num: a, str: b} = {}) {};
/** @param {{a: 숫자, b: 숫자}} param1 */
function ComputedKey({a, b, [a + b]: c}) {};
/** @param {{a: 숫자, b: 문자열}=} param1 */
function nontrivialDefault({a, b} = {a: 2, b: 4}) {};
@enum 열거형은 객체 리터럴에 주석을 추가하여 정의. 열거형 정의 후에는 추가 속성 금지
/**
* 지원되는 온도 단위.
* @enum {string}
*/
const ThermalScale = {
CELSIUS: '섭씨',
FAHRENHEIT: '화씨',
};
/**
* 두 가지 옵션이 있는 열거형입니다.
* @enum {number}
*/
const Option = {
/** 사용된 옵션은 첫 번째 옵션이어야 합니다. */
FIRST_OPTION: 1,
/** 두 옵션 중 두 번째입니다. */
SECOND_OPTION: 2,
};
생성자는 선택 사항. super() 하위 클래스 생성자는 필드 설정 전, or 엑세스 전에 호출
가독성 방해 하지 않는 경우 개인 정적 메서드보다 모듈 로컬 함수 선호
허용되지 않음
class Base { /** @nocollapse */ static foo() {} }
class Sub extends Base {}
function callFoo(cls) { cls.foo(); } // 권장하지 않음: 정적 메서드를 동적으로 호출하지 마세요
Sub.foo(); // 허용되지 않음: 자체적으로 정의하지 않은 하위 클래스에서는 정적 메서드를 호출하지 마세요.
최상위 함수는 exports 객체에 직접 정의허간 로컬로 선언하고 선택적으로 내보낼 수 있음.
화살표 함수는 간결한 함수 구문을 제공하고 this 중첩 함수의 범위 지정을 단순화합니다. 특히 중첩된 함수의 경우 키워드보다 화살표 함수를 선호.
매개 변수 1개일 시 주위 괄호는 선택
함수 매개변수와 반환 유형은 일반적으로 JSDoc 주석으로 문서화해야 함.
/**
* @param {string} 필수 이 매개변수는 항상 필요합니다.
* @param {string=} 선택사항 이 매개변수는 생략될 수 있습니다.
* @param {!Node=} node 또 다른 선택적 매개변수입니다.
*/
function mightDoSomething(required, option = '', node = undefine) {}
/** @interface */
class MyInterface {
/**
* 인터페이스 및 추상 메서드는 기본 매개변수 값을 생략해야 합니다.
* @param {string=} 선택 사항
*/
someMethod(선택 사항) {}
}
함수 호출은 스프레드 연산자(...) 사용 가능(더 선호)
function myFunction(...elements) {}
myFunction(...array, ...iterable, ...generator());
일반 문자열 리터럴은 큰따옴표 x 작은따옴표 O
여러 문자열 리터럴이 관련된 경우 ``(템플릿 문자열) 사용
const longString = '80 \
열 제한을 훨씬 초과하는 매우 긴 문자열입니다.
불행하게도 연속된 줄 의 들여쓰기로 인해 \ 긴 공백이 포함되어 있습니다 .';
권장
const longString = '80개의 ' + '열 제한을 훨씬 초과하는 매우 긴 문자열입니다
.
' + '연결된 문자열이 더 깔끔하기 때문에 긴 공백을 포함하지 않습니다 .';
For of 가 가장 권장
new Error를 이용해 Error 던지기
스위치 블록 내에서 갑자기 명령문 그룹이 종료되거나 다음 명령문 등으로 계속되는 것을 나타내는 주석 표시
스위치(입력) {
사례 1:
사례 2:
prepareOneOrTwo();
// 사례 3을
통과합니다 .
handlerOneTwoOrThree();
부서지다;
기본값:
handlerLargeNumber(input);
}
eval 또는 새엇ㅇ자 사용 금지
세미클론은 필수
비표준 기능 사용 금지(WeakMap.clear 등...)
ECMA-262 또는 WHATWG 표준에 정의된 기능만 사용
new 사용 금지
허용 x
const /** 부울 */ x = new Boolean(false);
if (x) 경고(x 유형); // '객체' 경고 - WAT?
권장
const /** boolean */ x = Boolean(0);
if (!x) alert(x 유형); // alerts 'boolean', as expected