Skip to content
This repository has been archived by the owner on Nov 16, 2023. It is now read-only.

Latest commit

 

History

History
2515 lines (1947 loc) · 64.9 KB

STYLE_GUIDE.md

File metadata and controls

2515 lines (1947 loc) · 64.9 KB

Naver JavaScript Style Guide

네이버 자바스크립트 스타일 가이드는 Airbnb 자바스크립트 스타일 가이드를 기준으로 작성되었습니다.

Table of Contents

  1. Types
  2. References
  3. Objects
  4. Arrays
  5. Destructuring
  6. Strings
  7. Functions
  8. Arrow Functions
  9. Classes & Constructors
  10. Modules
  11. Iterators and Generators
  12. Properties
  13. Variables
  14. Hoisting
  15. Comparison Operators & Equality
  16. Blocks
  17. Comments
  18. Whitespace
  19. Commas
  20. Semicolons
  21. Type Casting & Coercion
  22. Naming Conventions
  23. Accessors
  24. Events
  25. jQuery
  26. Resources

Types

Airbnb와 동일합니다.

  • 1.1 Primitives: primitive type은 그 값을 직접 조작한다.

    • string
    • number
    • boolean
    • null
    • undefined
    const foo = 1;
    let bar = foo;
    
    bar = 9;
    
    console.log(foo, bar); // => 1, 9
  • 1.2 Complex: 참조형(Complex)은 참조를 통해 값을 조작한다.

    • object
    • array
    • function
    const foo = [1, 2];
    const bar = foo;
    
    bar[0] = 9;
    
    console.log(foo[0], bar[0]); // => 9, 9

⬆ back to top

References

Airbnb와 동일합니다.

  • 2.1 변수 선언은 가급적 const 를 사용하고, var 를 사용하지 않는다. eslint: prefer-const, no-const-assign

    // bad
    var a = 1;
    var b = 2;
    
    // good
    const a = 1;
    const b = 2;
  • 2.2 참조를 재할당 해야한다면 var 대신 let 을 사용한다. eslint: no-var jscs: disallowVar

    // bad
    var count = 1;
    if (true) {
      count += 1;
    }
    
    // good, use the let.
    let count = 1;
    if (true) {
      count += 1;
    }
  • 2.3 letconst 는 선언된 블록 안에서만 존재하는 블록 스코프이다.

    // const 와 let 은 선언된 블록의 안에서만 존재한다.
    {
      let a = 1;
      const b = 1;
    }
    console.log(a); // ReferenceError
    console.log(b); // ReferenceError

⬆ back to top

Objects

3.6 항목을 제외하고는 Airbnb와 동일합니다.

  • 3.1 오브젝트를 작성할 때는, 리터럴 구문을 사용한다. eslint: no-new-object

    // bad
    const item = new Object();
    
    // good
    const item = {};
  • 3.2 동적 프로퍼티명을 갖는 오브젝트를 작성할 때, 계산된 프로퍼티명(computed property names)을 이용한다.

    function getKey(k) {
      return `key named ${k}`;
    }
    
    // bad
    const obj = {
      id: 5,
      name: "San Francisco",
    };
    obj[getKey("enabled")] = true;
    
    // good
    const obj = {
      id: 5,
      name: "San Francisco",
      [getKey("enabled")]: true
    };
  • 3.3 메서드의 단축 구문을 이용한다. eslint: object-shorthand

    // bad
    const atom = {
      value: 1,
    
      addValue: function (value) {
        return atom.value + value;
      },
    };
    
    // good
    const atom = {
      value: 1,
    
      addValue(value) {
        return atom.value + value;
      },
    };
  • 3.4 속성의 단축구문을 이용한다. eslint: object-shorthand

    const lukeSkywalker = "Luke Skywalker";
    
    // bad
    const obj = {
      lukeSkywalker: lukeSkywalker,
    };
    
    // good
    const obj = {
      lukeSkywalker,
    };
  • 3.5 속성의 단축 구문은 오브젝트 선언의 시작 부분에 그룹화한다.

    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.6 속성명이 키워드(default, if, ...)일 경우에는 꼭 따옴표를 붙인다. 또한, -문자와 같이 속성명으로 지정할수 없는 경우에는 꼭 따옴표를 붙인다. eslint: quote-props

    // bad
    const bad = {
      foo: 3,
      default: 20,
      data-blah: 5
    };
    
    // good
    const good = {
      foo: 3,
      "default": 20,
      "data-blah": 5,
      10: "naver"
    };
  • 3.7 hasOwnProperty, propertyIsEnumerable, isPrototypeOf 와 같은 Object.prototype 메서드를 직접적으로 사용하지 않는다. eslint: no-prototype-builtins

    // bad
    console.log(object.hasOwnProperty(key));
    
    // good
    console.log(Object.prototype.hasOwnProperty.call(object, key));
    
    // best
    const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
    /* or */
    import has from "has";
    // ...
    console.log(has.call(object, key));
  • 3.8 얕은 복사(shallow-copy)를 하기 위해서 Object.assign 보다는 spread 연산자(...)를 선호한다. 오브젝트에서 몇몇 속성을 제거한 새로운 오브젝트를 얻고자 할때는 rest 파라미터(...)를 사용한다.

    // very bad
    const original = { a: 1, b: 2 };
    const copy = Object.assign(original, { c: 3 }); // this mutates `original`
    delete copy.a; // so does this
    
    // bad
    const original = { a: 1, b: 2 };
    const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 }
    
    // good
    const original = { a: 1, b: 2 };
    const copy = { ...original, c: 3 }; // copy => { a: 1, b: 2, c: 3 }
    
    const { a, ...noA } = copy; // noA => { b: 2, c: 3 }

⬆ back to top

Arrays

4.4 ~ 5 항목을 제외하고는 Airbnb와 동일합니다.

  • 4.1 배열을 작성 할 때는 리터럴 구문을 사용한다. eslint: no-array-constructor

    // bad
    const items = new Array();
    // good
    const items = [];
  • 4.2 아이템을 배열에 추가하는 경우, 직접 배열에 항목을 대입하지 말고 Array#push를 이용한다.

    const someStack = [];
    
    // bad
    someStack[someStack.length] = "abracadabra";
    
    // good
    someStack.push("abracadabra");
  • 4.3 배열을 복사할 때는 배열의 spread 연산자(...) 를 이용한다.

    // bad
    const len = items.length;
    const itemsCopy = [];
    let i;
    
    for (i = 0; i < len; i++) {
      itemsCopy[i] = items[i];
    }
    
    // good
    const itemsCopy = [...items];
  • 4.4 Airbnb와 다르게 array-like 오브젝트를 배열로 변환하는 경우에 대해서는 별도로 가이드 하지 않는다.

  • 4.5 Airbnb와 다르게 배열의 메서드 콜백에 대해서는 별도로 가이드 하지 않는다. eslint: array-callback-return

  • 4.6 배열이 멀티 라인인 경우, 배열의 시작(before)과 끝(after)은 개행한다.

    // bad
    const arr = [
      [0, 1], [2, 3], [4, 5],
    ];
    
    const objectInArray = [{
      id: 1,
    }, {
      id: 2,
    }];
    
    const numberInArray = [
      1, 2,
    ];
    
    // good
    const arr = [[0, 1], [2, 3], [4, 5]];
    
    const objectInArray = [
      {
        id: 1,
      },
      {
        id: 2,
      },
    ];
    
    const numberInArray = [
      1,
      2,
    ];

⬆ back to top

Destructuring

Airbnb와 다르게 별도의 가이드를 제공하지 않습니다.

Strings

6.1,6.2 항목을 제외하고는 Airbnb와 동일합니다.

  • 6.1 따옴표는 쌍따옴표를 사용한다. 이스케이프한 경우는 예외로 홑따옴표를 사용할 수 있다. eslint: quotes

    // bad
    var key = 'naver';
    var obj = {
      'key': '1'
    }
    
    // good
    var key = "naver";
    var obj = {
      "key": "1"
    }
  • 6.2 문자열은 100자를 넘지 않는다. 100자가 넘는 긴 문자열인 경우 줄바꿈시 escape 문자()를 사용하지 않는다. escape문자 대신 + 연산자를 사용한다. ES6의 template strings가 사용 가능한 환경에서는 6.3 룰을 적용한다.

    // 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.";
  • 6.3 프로그램에서 문자열을 생성하는 경우는 문자열 연결이 아닌 template strings를 이용한다. eslint: prefer-template template-curly-spacing

    // 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.4 절대로 eval() 을 사용하지 않는다.

  • 6.5 문자열에 불필요한 escape 문자를 사용하지 않는다. eslint: no-useless-escape

    // bad
    const foo = "\'this\' \i\s \'quoted\'";
    
    // good
    const foo = "\"this\" is 'quoted'";
    const foo = `my name is '${name}'`;

⬆ back to top

Functions

7.1 ~ 2, 7.11 ~ 14 항목을 제외하고는 Airbnb와 동일합니다.

  • 7.1 함수 스타일에 대해서는 별도의 스타일 가이드를 제공하지 않는다. eslint: func-style

    // type 1
    function foo() {
      // ...
    }
    
    // type 2
    const foo = function() {
      // ...
    };
    
    // type 3
    const foo = function bar() {
      // ...
    };
  • 7.2 즉시 실행함수는 함수를 괄호로 감싼다. eslint: wrap-iife

    // bad
    !function()) {
      console.log("Welcome to the Internet. Please follow me.");
    }();
    
    // bad
    (function() {
      console.log("Welcome to the Internet. Please follow me.");
    }());
    
    // good
    (function() {
      console.log("Welcome to the Internet. Please follow me.");
    })();
  • 7.3 함수 이외의 블록 (if나 while같은) 안에서 함수를 선언하지 않는다. eslint: no-loop-func

    // bad
    let i;
    for (i = 10; i; i--) {
        (function() { 
          return i; 
        })();
    }
    
    // bad
    while(i) {
        let a = function() {
          return i;
        };
        a();
    }
    
    // good
    const a = function() {};
    let i;
    for (i = 10; i; i--) {
        a();
    }
  • 7.4 Airbnb와 다르게 block 내의 함수선언에 대해서는 별도로 가이드 하지 않는다.

  • 7.5 절대로 파라미터에 arguments 를 지정하지 않는다. 이것은 함수 스코프에 전해지는 arguments 오브젝트의 참조를 덮어 버린다.

    // bad
    function nope(name, options, arguments) {
      // ...stuff...
    }
    
    // good
    function yup(name, options, args) {
      // ...stuff...
    }
  • 7.6 절대 arguments 를 이용하지 않는다. 대신에 rest 파라미터(...) 를 이용한다. eslint: prefer-rest-params

    // bad
    function concatenateAll() {
      const args = Array.prototype.slice.call(arguments);
      return args.join("");
    }
    
    // good
    function concatenateAll(...args) {
      return args.join("");
    }
  • 7.7 함수의 파라미터를 재정의하지 않는다. 대신 default 파라미터를 이용한다.

    // really bad
    function handleThings(opts) {
      opts = opts || {};
      // ...
    }
    
    // still bad
    function handleThings(opts) {
      if (opts === void 0) {
        opts = {};
      }
      // ...
    }
    
    // good
    function handleThings(opts = {}) {
      // ...
    }
  • 7.8 side effect 를 유발하는 default 파라미터의 이용을 피한다.

    var b = 1;
    // bad
    function count(a = b++) {
      console.log(a);
    }
    count();  // 1
    count();  // 2
    count(3); // 3
    count();  // 3
  • 7.9 항상 default 파라미터는 뒤쪽에 둔다.

    // bad
    function handleThings(opts = {}, name) {
      // ...
    }
    
    // good
    function handleThings(name, opts = {}) {
      // ...
    }
  • 7.10 절대 새 함수를 작성하기 위해 Function constructor를 이용하지 않는다. eslint: no-new-func

    // bad
    var add = new Function("a", "b", "return a + b");
    
    // still bad
    var subtract = Function("a", "b", "return a - b");
  • 7.11 익명함수는 function과 괄호 사이에 공백이 없다. 기명 함수(named function)는 함수 이름과 괄호 사이에 공백이 없다.
    async arrow function인 경우 async와 arrow function 사이에 공백이 있다.
    eslint: space-before-function-paren space-before-blocks

    // bad
    const f = function () {};
    const g = function a (){};
    const h = async(v,i) => {};
    
    // good
    const x = function() {};
    const y = function a() {};
    const z = async (v,i) => {};
  • 7.12 가급적 mutate parameter는 사용하지 않는다. 하지만, 필요에 의해서는 주의하여 사용한다. eslint: no-param-reassign

    // 권장하지 않음.
    function f1(obj) {
      obj.key = 1;
    }
  • 7.13 파라미터를 재할당하지 않는다. 단, 파라미터의 속성에 대해서는 재할당이 가능하다. eslint: no-param-reassign

    // bad
    function f1(a) {
      a = 1;
      // ...
    }
    
    // bad
    function f2(a) {
      if (!a) { a = 1; }
      // ...
    }
    
    
    // good
    function f3(a) {
      const b = a || 1;
      // ...
    }
    
    // good
    function f4(a) {
      if (!a) { a.b = 1; }
      // ...
    }    
  • 7.14 가변함수를 호출할 때는 spread 연산자 (...)를 사용한다. eslint: prefer-spread

    // bad
    const x = [1, 2, 3, 4, 5];
    console.log.apply(console, x);
    
    // good
    const x = [1, 2, 3, 4, 5];
    console.log(...x);
    
    // bad
    new (Function.prototype.bind.apply(Date, [null, 2016, 8, 5]));
    
    // good
    new Date(...[2016, 8, 5]);
  • 7.15 함수의 정의가 멀티라인 인 경우, 오브젝트와 같은 스타일 가이드를 따른다. 19.1을 참조한다.

    // bad
    function foo(bar,
                 baz,
                 quux) {
      // ...
    }
    
    // good
    function foo(
      bar,
      baz,
      quux,
    ) {
      // ...
    }
    
    // bad
    console.log(foo,
      bar,
      baz);
    
    // good
    console.log(
      foo,
      bar,
      baz,
    );

⬆ back to top

Arrow Functions

8.2, 8.4 항목을 제외하고는 Airbnb와 동일합니다.

  • 8.1 익명함수를 전달하는 경우, arrow function 표기를 이용한다. eslint: prefer-arrow-callback, arrow-spacing

    // 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;
    });
  • 8.2 함수의 몸체(body)가 단일 표현식이라면 중괄호({})를 생략하고, 묵시적으로 그 값은 반환값이 된다. 그렇지 않으면, 중괄호({})는 생략할 수 없고, 반환값이 필요한 경우는 return 을 명시한다. eslint: arrow-parens, arrow-body-style

    // bad
    [1, 2, 3].map(number => {
      const nextNumber = number + 1;
      `A string containing the ${nextNumber}.`;
    });
    
    // good
    [1, 2, 3].map(number => `A string containing the ${number}.`);
    
    // good
    [1, 2, 3].map(number => {
      const nextNumber = number + 1;
      return `A string containing the ${nextNumber}.`;
    });
    
    // good
    [1, 2, 3].map((number, index) => ({
      [index]: number,
    }));
    
    // good
    [1, 2, 3].forEach(number => {
      console.log(nextNumber);
    });
  • 8.3 식이 복수행에 걸쳐 있을 경우는 가독성을 더욱 좋게하기 위해 소괄호(())로 감싼다.

    // 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."
    ));
  • 8.4 함수가 단일 파라미터인 경우, 소괄호(())는 생략한다. eslint: arrow-parens

    // bad
    [1, 2, 3].map((x) => x * x);
    
    // good
    [1, 2, 3].map(x => x * x);
    
    // good
    [1, 2, 3].map(number => (
      `A long string with the ${number}. It’s so long that we don’t want it to take up space on the .map line!`
    ));
    
    // bad
    [1, 2, 3].map((x) => {
      const y = x + 1;
      return x * y;
    });
    
    // good
    [1, 2, 3].map(x => {
      const y = x + 1;
      return x * y;
    });
  • 8.5 arrow function 문법(=>)과 비교 연산자 (<=, >=)를 함께 사용할 경우, 소괄호(())를 이용하여 혼란스럽지 않도록 표현한다. eslint: no-confusing-arrow

    // bad
    const itemHeight = item => item.height > 256 ? item.largeSize : item.smallSize;
    
    // bad
    const itemHeight = (item) => item.height > 256 ? item.largeSize : item.smallSize;
    
    // good
    const itemHeight = item => (item.height > 256 ? item.largeSize : item.smallSize);
    
    // good
    const itemHeight = (item) => {
      const { height, largeSize, smallSize } = item;
      return height > 256 ? largeSize : smallSize;
    };

⬆ back to top

Classes & Constructors

Airbnb와 동일합니다.

  • 9.1 prototype을 직접 조작하는 것을 피하고 항상 class를 이용한다.

    // 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;
      }
    }
  • 9.2 상속은 extends 를 이용한다.

    // 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];
      }
    }
  • 9.3 필요하다면, 메서드의 반환값으로 this 를 반환하는 것으로 메서드체이닝을 할 수 있다.

    // bad
    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 Jedi {
      jump() {
        this.jumping = true;
        return this;
      }
    
      setHeight(height) {
        this.height = height;
        return this;
      }
    }
    
    const luke = new Jedi();
    
    luke.jump()
      .setHeight(20);
  • 9.4 toString()을 작성하는 것을 허용하지만 올바르게 동작하는 지와 side effect 가 없는지를 꼭 확인한다.

    class Jedi {
      constructor(options = {}) {
        this.name = options.name || "no name";
      }
    
      getName() {
        return this.name;
      }
    
      toString() {
        return `Jedi - ${this.getName()}`;
      }
    }
  • 9.5 불필요한 빈 default constructor는 사용하지 않는다. eslint: no-useless-constructor

    // bad
    class Jedi {
      constructor() {}
    
      getName() {
        return this.name;
      }
    }
    
    // bad
    class Rey extends Jedi {
      constructor(...args) {
        super(...args);
      }
    }
    
    // good
    class Rey extends Jedi {
      constructor(...args) {
        super(...args);
        this.name = 'Rey';
      }
    }
  • 9.6 클래스에는 동일 멤버가 있어서는 안된다. eslint: no-dupe-class-members

    // bad
    class Foo {
      bar() { return 1; }
      bar() { return 2; }
    }
    
    // good
    class Foo {
      bar() { return 1; }
    }
    
    // good
    class Foo {
      bar() { return 2; }
    }

⬆ back to top

Modules

10.5, 10.9 항목을 제외하고는 Airbnb와 동일합니다.

  • 10.1 비표준 모듈시스템이 아닌 (import/export) 를 항상 사용한다.

    // bad
    const AirbnbStyleGuide = require("./AirbnbStyleGuide");
    module.exports = AirbnbStyleGuide.es6;
    
    // ok
    import AirbnbStyleGuide from "./AirbnbStyleGuide";
    export default AirbnbStyleGuide.es6;
    
    // best
    import {es6} from "./AirbnbStyleGuide";
    export default es6;
  • 10.2 wildcard import 는 이용하지 않는다.

    // bad
    import * as AirbnbStyleGuide from "./AirbnbStyleGuide";
    
    // good
    import AirbnbStyleGuide from "./AirbnbStyleGuide";
  • 10.3 import 문으로부터 직접 export 하지 않는다.

    // bad
    // filename es6.js
    export {es6 as default} from "./airbnbStyleGuide";
    
    // good
    // filename es6.js
    import {es6} from "./AirbnbStyleGuide";
    export default es6;
  • 10.4 import는 중복되지 않게 한 곳에서 import 한다. eslint: no-duplicate-imports

    // bad
    import foo from "foo";
    // … some other imports … //
    import {named1, named2} from "foo";
    
    // good
    import foo, {named1, named2} from "foo";
    
    // good
    import foo, {
      named1,
      named2
    } from "foo";
  • 10.5 mutable 객체를 export 하는 것에 대해 강제하지 않는다. eslint: import/no-mutable-exports

    // good
    // let은 변경 가능한 객체
    let foo = {
      a: 10
    }
    export {foo};
    
    // good
    // const는 변경 가능하지 않는 객체
    const foo = 3;
    export {foo};
  • 10.6 export가 하나일 경우, default export를 사용한다. eslint: import/prefer-default-export

    // bad
    export function foo() {}
    
    // good
    export default function foo() {}
  • 10.7 모든 import문은 상위에 위치한다. eslint: import/first

    // bad
    import foo from "foo";
    foo.init();
    
    import bar from "bar";
    
    // good
    import foo from "foo";
    import bar from "bar";
    
    foo.init();
  • 10.8 멀티 라인 imports 문은 배열이나 오브젝트의 literal과 같이 표현한다. 19.1을 참조한다.

    // good
    import {
      longNameA,
      longNameB,
      longNameC,
      longNameD,
      longNameE,
    } from "path";
  • 10.9 웹팩 로더 문법 사용에 대해 강제하지 않는다. eslint: import/no-webpack-loader-syntax

    // good
    import fooSass from 'css!sass!foo.scss';
    import barCss from 'style!css!bar.css';
    
    // good
    import fooSass from 'foo.scss';
    import barCss from 'bar.css';

⬆ back to top

Iterators and Generators

Airbnb와 다르게 별도의 가이드를 제공하지 않습니다.

Properties

Airbnb와 동일합니다.

  • 12.1 프로퍼티에 억세스하는 경우는 점 . 을 사용한다. eslint: dot-notation

    const luke = {
      jedi: true,
      age: 28,
    };
    
    // bad
    const isJedi = luke["jedi"];
    
    // good
    const isJedi = luke.jedi;
  • 12.2 변수를 사용해 프로퍼티에 억세스하는 경우는 대괄호([])를 사용한다.

    const luke = {
      jedi: true,
      age: 28,
    };
    
    function getProp(prop) {
      return luke[prop];
    }
    
    const isJedi = getProp("jedi");

⬆ back to top

Variables

13.4, 13.6 항목을 제외하고는 Airbnb와 동일합니다.

  • 13.1 변수를 선언 할 때는 가급적 constlet을 사용한다. 그렇게 하지 않으면 글로벌 변수로 선언된다. eslint: no-undef prefer-const

    // bad
    superPower = new SuperPower();
    
    // good
    const superPower = new SuperPower();
  • 13.2 변수 선언은 변수당 하나씩 사용한다. eslint: one-var

    // bad
    const items = getItems(),
        goSportsTeam = true,
        dragonball = "z";
    
    // bad
    // (compare to above, and try to spot the mistake)
    const items = getItems(),
        goSportsTeam = true;
        dragonball = "z";
    
    // good
    const items = getItems();
    const goSportsTeam = true;
    const dragonball = "z";
  • 13.3 우선 const 를 그룹화하고 다음에 let 을 그룹화 한다.

    // bad
    let i, len, dragonball,
        items = getItems(),
        goSportsTeam = true;
    
    // bad
    let i;
    const items = getItems();
    let dragonball;
    const goSportsTeam = true;
    let len;
    
    // good
    const goSportsTeam = true;
    const items = getItems();
    let dragonball;
    let i;
    let length;
  • 13.4 letconst을 사용할 때는 블럭 스코프 이기 때문에, 변수가 사용될 적당한 위치에 변수를 선언한다. 단, letconst를 사용할 수 없다면, var로 상단에 변수를 선언한다.

    // bad
    function foo() {
      var i = 0;
      if (i > 0) {
        var j = 0;
      }
    }
    
    // good
    function foo() {
      var i = 0;
      var j = 0;
      if (i > 0) {
        j = 0;
      }
    }
    
    // bad - 불필요한 함수 호출
    function checkName(hasName) {
      const name = getName();
    
      if (hasName === "test") {
        return false;
      }
    
      if (name === "test") {
        this.setName('');
        return false;
      }
    
      return name;
    }
    
    // good
    function checkName(hasName) {
      if (hasName === "test") {
        return false;
      }
    
      const name = getName();
    
      if (name === "test") {
        this.setName("");
        return false;
      }
    
      return name;
    }
  • 13.5 여러 개의 변수를 한 줄에 동일한 값으로 설정하지 않는다. eslint no-multi-assign

    // bad
    (function example() {
      let a = b = c = 1;
    }());
    
    // good
    (function example() {
      let a = 1;
      let b = a;
      let c = a;
    }());
  • 13.6 ++, -- 연산자 사용이 가능하다. 연산자와 피연산자 사이에 공백을 두지 않는다. eslint no-plusplus

    // bad
    ++ i;
    i ++;
    
    // good
    ++i;
    i++;

⬆ back to top

Hoisting

Airbnb와 동일합니다.

  • 14.1 var 선언은 할당 없이 스코프의 선두에 hoist 된다. constlet 선언은Temporal Dead Zones (TDZ) 라고 불리는 새로운 컨셉의 혜택을 받고 있다.

    // notDefined 가 글로벌변수에 존재하지 않는다고 판정한 경우, 잘 동작하지 않는다.
    function example() {
      console.log(notDefined); // => throws a ReferenceError
    }
    
    // 그 변수를 참조하는 코드의 뒤에서 그 변수를 선언한 경우
    // 변수가 hoist 된 상태에서 동작한다.
    // 주의:`true` 라는 값 자체는 hoist 되지 않는다.
    function example() {
      console.log(declaredButNotAssigned); // => undefined
      var declaredButNotAssigned = true;
    }
    
    // 인터프리터는 변수선언을 스코프의 선두에 hoist 한다.
    // 위의 예는 다음과 같이 다시 쓸수 있다.
    function example() {
      let declaredButNotAssigned;
      console.log(declaredButNotAssigned); // => undefined
      declaredButNotAssigned = true;
    }
    
    // const 와 let 을 이용한 경우
    function example() {
      console.log(declaredButNotAssigned); // => throws a ReferenceError
      console.log(typeof declaredButNotAssigned); // => throws a ReferenceError
      const declaredButNotAssigned = true;
    }
  • 14.2 익명 함수의 경우 함수가 할당되기 전의 변수가 hoist 된다.

    function example() {
      console.log(anonymous); // => undefined
    
      anonymous(); // => TypeError anonymous is not a function
    
      var anonymous = function() {
        console.log('anonymous function expression');
      };
    }
  • 14.3 기명 함수(named function)의 경우도 똑같이 변수가 hoist 된다. 함수명이나 함수본체는 hoist 되지 않는다.

    function example() {
      console.log(named); // => undefined
    
      named(); // => TypeError named is not a function
    
      superPower(); // => ReferenceError superPower is not defined
    
      var named = function superPower() {
        console.log('Flying');
      };
    }
    
    // 함수명과 변수명이 같은 경우도 같은 현상이 발생합니다.
    function example() {
      console.log(named); // => undefined
    
      named(); // => TypeError named is not a function
    
      var named = function named() {
        console.log("named");
      }
    }
  • 14.4 함수선언은 함수명과 함수본체가 hoist 된다.

    function example() {
      superPower(); // => Flying
    
      function superPower() {
        console.log("Flying");
      }
    }

⬆ back to top

Comparison Operators & Equality

Airbnb와 동일합니다.

  • 15.1 == 이나 != 보다 ===!== 을 사용한다.

  • 15.2 if 문과 같은 조건식은 ToBoolean 메서드에 의한 강제형변환으로 평가되어 항상 다음과 같은 심플한 룰을 따른다.

    • Objecttrue 로 평가된다.
    • undefinedfalse 로 평가된다.
    • nullfalse 로 평가된다.
    • Boolanboolean형의 값 으로 평가된다.
    • Numbertrue 로 평가된다. 하지만 +0, -0, or NaN 의 경우는 false 이다.
    • Stringtrue 로 평가된다. 하지만 빈문자 "" 의 경우는 false 이다.
    if ([0]) {
      // true
      // 배열은 오브젝트이므로 true 로 평가된다.
    }
  • 15.3 Boolen에 대해서는 단축형을 사용한다.

    // bad
    if (name !== "") {
      // ...stuff...
    }
    
    // good
    if (name) {
      // ...stuff...
    }
    
    // bad
    if (collection.length > 0) {
      // ...stuff...
    }
    
    // good
    if (collection.length) {
      // ...stuff...
    }
  • 15.4 비교에 대한 자세한 정보는 Truth Equality and JavaScript by Angus Croll. 을 참조한다.

  • 15.5 case, default 구문에서 let, const, function, class가 사용 되는 경우에는 중괄호({})를 사용한다. eslint rules: no-case-declarations.

    // bad
    switch (foo) {
      case 1:
        let x = 1;
        break;
      case 2:
        const y = 2;
        break;
      case 3:
        function f() {
          // ...
        }
        break;
      default:
        class C {}
    }
    
    // good
    switch (foo) {
      case 1: {
        let x = 1;
        break;
      }
      case 2: {
        const y = 2;
        break;
      }
      case 3: {
        function f() {
          // ...
        }
        break;
      }
      case 4:
        bar();
        break;
      default: {
        class C {}
      }
    }
  • 15.6 중첩 3항 연산자는 사용하지 않는다. eslint rules: no-nested-ternary.

    // bad
    const foo = maybe1 > maybe2
      ? "bar"
      : value1 > value2 ? "baz" : null;
    
    // better
    const maybeNull = value1 > value2 ? "baz" : null;
    
    const foo = maybe1 > maybe2
      ? "bar"
      : maybeNull;
    
    // best
    const maybeNull = value1 > value2 ? "baz" : null;
    
    const foo = maybe1 > maybe2 ? "bar" : maybeNull;
  • 15.7 불필요한 3항 연산자는 사용하지 않는다. eslint rules: no-unneeded-ternary.

    // bad
    const foo = a ? a : b;
    const bar = c ? true : false;
    const baz = c ? false : true;
    
    // good
    const foo = a || b;
    const bar = !!c;
    const baz = !c;

⬆ back to top

Blocks

Airbnb와 다른 가이드를 제공합니다.

  • 16.1 중괄호({})는 클래스, 메서드, 제어문의 블럭을 구분한다. 중괄호는 클래스 선언, 메서드 선언, 조건/반복문/제어문,줄의 마지막에서 시작한다.

    // bad
    const Empty = function()
    {
    }
    
    // good
    const Empty = function() {
    }
    
    switch (type) {
      case 0:
        break;
      case 1: {
        break;
      }
      default:
        common();
    }
    
    if (true) {
      return;
    } else if (false) {
      return;
    } else {
    }
  • 16.2 조건/반복문/제어문에 중괄호 사용한다. 조건/반복문/제어문이 한줄로 끝이라도 중괄호를 활용한다. eslint: brace-style

    // bad
    if (exp == null) return false;
    for (var i in obj) if ( i === "key" ) return obj[i];
    
    // good
    if (exp == null) {
      return false;
    }
    
    for (var i in obj) {
      if ( i === "stop" ) {
        return obj[i];
      }
    }

⬆ back to top

Comments

Airbnb와 동일합니다.

  • 17.1 복수행의 코멘트는 /** ... */ 을 사용한다. 그 안에는 설명과 모든 파라미터, 반환값에 대해 형이나 값을 기술한다.

    // bad
    // make() returns a new element
    // based on the passed in tag name
    //
    // @param {String} tag
    // @return {Element} element
    function make(tag) {
    
      // ...stuff...
    
      return element;
    }
    
    // good
    /**
     * make() returns a new element
     * based on the passed in tag name
     *
     * @param {String} tag
     * @return {Element} element
     */
    function make(tag) {
    
      // ...stuff...
    
      return element;
    }
  • 17.2 단일행 코멘트에는 // 을 사용한다. 코멘트를 추가하고 싶은 코드의 상부에 배치한다. 또한, 코멘트의 앞에 공백을 넣는다.

    // bad
    const active = true;  // is current tab
    
    // good
    // is current tab
    const active = true;
    
    // bad
    function getType() {
      console.log("fetching type...");
      // set the default type to "no type"
      const type = this._type || "no type";
    
      return type;
    }
    
    // good
    function getType() {
      console.log("fetching type...");
    
      // set the default type to "no type"
      const type = this._type || "no type";
    
      return type;
    }
    
    // also good
    function getType() {
      // set the default type to "no type"
      const type = this._type || "no type";
    
      return type;
    }
  • 17.3 문제를 지적하고 재고를 촉구하는 경우나 문제의 해결책을 제안하는 경우 등, 코멘트의 앞에 FIXMETODO 를 붙이는 것으로 다른 개발자가 빠르게 이해할 수 있도록 한다. 이런 것들은 어떤 액션을 따른다는 의미이다. 액션이라는 것은 FIXME -- 해결이 필요 또는 TODO -- 구현이 필요 를 뜻한다.

  • 17.4 문제의 해결이 필요하다는 주석으로써 // FIXME: 를 사용한다.

    class Calculator extends Abacus {
      constructor() {
        super();
    
        // FIXME: total은 글로벌 변수를 사용해야한다.
        total = 0;
      }
    }
  • 17.5 구현이 필요하다는 주석으로 // TODO: 를 사용한다.

    class Calculator extends Abacus {
      constructor() {
        super();
    
        // TODO: total 은 옵션 파라미터로 설정해야한다.
        this.total = 0;
      }
    }

⬆ back to top

Whitespace

18.1, 18.6, 18. 11 ~ 13 항목을 제외하고는 Airbnb와 동일합니다.

  • 18.1 공백은 탭을 사용한다. eslint: indent

    // bad
    function() {
    ∙∙∙∙var name;
    }
    
    // bad
    function() {
    ∙var name;
    }
    
    // good
    function() {
      var name;
    }
  • 18.2 주요 중괄호 ({}) 앞에는 공백을 1개 넣는다. eslint: space-before-blocks

    // bad
    function test(){
      console.log("test");
    }
    
    // good
    function test() {
      console.log("test");
    }
    
    // bad
    dog.set("attr",{
      age: "1 year",
      breed: "Bernese Mountain Dog",
    });
    
    // good
    dog.set("attr", {
      age: "1 year",
      breed: "Bernese Mountain Dog",
    });
  • 18.3 제어구문 (if 문이나 while 문 등) 의 소괄호(()) 앞에는 공백을 1개 넣는다. 함수선언이나 함수호출시 인수리스트의 앞에는 공백을 넣지 않는다. eslint: keyword-spacing

    // bad
    if(isJedi) {
      fight ();
    }
    
    // good
    if (isJedi) {
      fight();
    }
    
    // bad
    function fight () {
      console.log ("Swooosh!");
    }
    
    // good
    function fight() {
      console.log("Swooosh!");
    }
  • 18.4 연산자 사이에는 공백을 넣는다. eslint: space-infix-ops

    // bad
    const x=y+5;
    
    // good
    const x = y + 5;
  • 18.5 파일 끝에는 개행문자를 1개 넣는다. eslint: eol-last

    // bad
    (function(global) {
      // ...stuff...
    })(this);
    // bad
    (function(global) {
      // ...stuff...
    })(this);
    
    // good
    (function(global) {
      // ...stuff...
    })(this);
  • 18.6 메서드 체인이 2개를 초과한 경우, 적절히 줄 바꿈을 하여 사용한다. 메서드 체이닝을 하여 줄바꿈을 할 때에는 마침표(.) 다음에 줄 바꿈을 한다. 줄 바꿈 후에는 가독성을 위하여 자동 들여쓰기를 한다. eslint: newline-per-chained-call no-whitespace-before-property

    // bad
    $("#items").find(".selected").highlight().end().find(".open").updateCount();
    
    // bad
    $("#items").
      find(".selected").
        highlight().
        end().
      find(".open").
        updateCount();
    
    // good
    $("#items")
      .find(".selected")
        .highlight()
        .end()
      .find(".open")
        .updateCount();
    
    // bad
    const leds = stage.selectAll(".led").data(data).enter().append("svg:svg").classed("led", true)
        .attr("width", (radius + margin) * 2).append("svg:g")
        .attr("transform", `translate(${radius + margin},${radius + margin})`)
        .call(tron.led);
    
    // good
    const leds = stage.selectAll(".led")
        .data(data)
      .enter().append("svg:svg")
        .classed("led", true)
        .attr("width", (radius + margin) * 2)
      .append("svg:g")
        .attr("transform", `translate(${radius + margin},${radius + margin})`)
        .call(tron.led);
    
    // good
    const leds = stage.selectAll(".led").data(data);
  • 18.7 문의 앞과 블록의 뒤에는 빈행을 남겨둔다.

    // bad
    if (foo) {
      return bar;
    }
    return baz;
    
    // good
    if (foo) {
      return bar;
    }
    
    return baz;
    
    // bad
    const obj = {
      foo() {
      },
      bar() {
      },
    };
    return obj;
    
    // good
    const obj = {
      foo() {
      },
    
      bar() {
      },
    };
    
    return obj;
    
    // bad
    const arr = [
      function foo() {
      },
      function bar() {
      },
    ];
    return arr;
    
    // good
    const arr = [
      function foo() {
      },
    
      function bar() {
      },
    ];
    
    return arr;
  • 18.8 블록에 빈행을 끼워 넣지 않는다. eslint: padded-blocks

    // bad
    function bar() {
    
      console.log(foo);
    
    }
    
    // also bad
    if (baz) {
    
      console.log(qux);
    } else {
      console.log(foo);
    
    }
    
    // good
    function bar() {
      console.log(foo);
    }
    
    // good
    if (baz) {
      console.log(qux);
    } else {
      console.log(foo);
    }
  • 18.9 소괄호(())의 안쪽에 공백을 추가하지 않는다. eslint: space-in-parens

    // bad
    function bar( foo ) {
      return foo;
    }
    
    // good
    function bar(foo) {
      return foo;
    }
    
    // bad
    if ( foo ) {
      console.log(foo);
    }
    
    // good
    if (foo) {
      console.log(foo);
    }
  • 18.10 대괄호([])의 안쪽에 공백을 추가하지 않는다. eslint: array-bracket-spacing

    // bad
    const foo = [ 1, 2, 3 ];
    console.log(foo[ 0 ]);
    
    // good
    const foo = [1, 2, 3];
    console.log(foo[0]);
  • 18.11 괄호 안에 공백을 삽입하지 않는다. eslint: object-curly-spacing

    // bad
    var obj = { };
    var obj = { "a": 2 };
    var arr = [ ];
    var arr = [ 1, 2 ];
    function foo( a, b ) {
    
    }
    
    // good
    var obj = {};
    var obj = {"a": 2};
    var arr = [];
    var arr = [1, 2];
    function foo(a, b) {
    
    }
  • 18.12 최대 줄 너비는 100 이다. 고해상도 모니터(해상도 1280*1024)사용이 보편화 됨에 따라, 최대 줄 사용 너비는 100자까지 가능하다. eslint: max-len

    // bad
    const foo = jsonData && jsonData.foo && jsonData.foo.bar && jsonData.foo.bar.baz && jsonData.foo.bar.baz.quux && jsonData.foo.bar.baz.quux.xyzzy;
    
    // bad
    $.ajax({ method: "POST", url: "https://www.naver.com/", data: { name: "John" } }).done(() => console.log("Congratulations!")).fail(() => console.log("You have failed this city."));
    
    // good
    const foo = jsonData &&
      jsonData.foo &&
      jsonData.foo.bar &&
      jsonData.foo.bar.baz &&
      jsonData.foo.bar.baz.quux &&
      jsonData.foo.bar.baz.quux.xyzzy;
  • 18.13 연산식의 경우에는 연산자 후에 줄 바꿈을 한다. 상위 레벨의 깊이에 맞게 들여쓰기를 한다

    // bad
    const sum = 100 + 200 + 300 
    + 400 + 500 + 600 + 700 + 800;
    
    // good
    const sum = 100 + 200 + 300 + 
         400 + 500 + 600 + 700 + 800;

⬆ back to top

Commas

Airbnb와 동일합니다.

  • 19.1 콤마는 뒤에 표기한다. eslint: comma-style

    // bad
    const story = [
        once
      , upon
      , aTime
    ];
    
    // good
    const story = [
      once,
      upon,
      aTime,
    ];
    
    // bad
    const hero = {
        firstName: "Ada"
      , lastName: "Lovelace"
      , birthYear: 1815
      , superPower: "computers"
    };
    
    // good
    const hero = {
      firstName: "Ada",
      lastName: "Lovelace",
      birthYear: 1815,
      superPower: "computers"
    };
  • 19.2 끝에 콤마를 넣는다. eslint: comma-dangle

    // bad - git diff without trailing comma
    const hero = {
         firstName: "Florence",
    -    lastName: "Nightingale"
    +    lastName: "Nightingale",
    +    inventorOf: ["coxcomb graph", "modern nursing"]
    };
    
    // good - git diff with trailing comma
    const hero = {
         firstName: "Florence",
         lastName: "Nightingale",
    +    inventorOf: ["coxcomb chart", "modern nursing"],
    };
    
    // bad
    const hero = {
      firstName: "Dana",
      lastName: "Scully"
    };
    
    const heroes = [
      "Batman",
      "Superman"
    ];
    
    // good
    const hero = {
      firstName: "Dana",
      lastName: "Scully",
    };
    
    const heroes = [
      "Batman",
      "Superman",
    ];

⬆ back to top

Semicolons

Airbnb와 동일합니다.

  • 20.1 ;은 문장의 끝에 표기한다. eslint: semi

    // bad
    (function() {
      const name = "Skywalker"
      return name
    })()
    
    // good
    (() => {
      const name = "Skywalker";
      return name;
    })();
    
    // good
    ;(() => {
      const name = "Skywalker";
      return name;
    })();

⬆ back to top

Type Casting & Coercion

Airbnb와 동일합니다.

  • 21.1 문의 선두에서 형의 강제를 수행한다.

  • 21.2 문자열의 경우:

    //  => this.reviewScore = 9;
    
    // bad
    const totalScore = this.reviewScore + "";
    
    // good
    const totalScore = String(this.reviewScore);
  • 21.3 수치의 경우: Number 로 형변환하는 경우는 parseInt 를 이용하고, 항상 형변환을 위한 기수를 인수로 넘겨 준다. eslint: radix

    const inputValue = "4";
    
    // bad
    const val = new Number(inputValue);
    
    // bad
    const val = +inputValue;
    
    // bad
    const val = inputValue >> 0;
    
    // bad
    const val = parseInt(inputValue);
    
    // good
    const val = Number(inputValue);
    
    // good
    const val = parseInt(inputValue, 10);
  • 21.4 parseInt를 사용하는 경우 성능적인 이유로 문제가 되면, Bitshift를 사용한다. 이때에는 꼭! Bitshift를 사용한 이유를 주석으로 남긴다.

    // good
    /**
     * parseInt로 인해 느려졌음
     * Bitshift를 통한 수치로의 문자열 강제 형변환으로 성능을 개선시킴.
     */
    const val = inputValue >> 0;
  • 21.5 주의: Bitshift를 사용하는 경우의 주의사항. 수치는 64비트 값으로 표현되어 있으나 bitshift 연산한 경우는 항상 32비트 integer 로 넘겨진다.

    2147483647 >> 0 //=> 2147483647
    2147483648 >> 0 //=> -2147483648
    2147483649 >> 0 //=> -2147483647
  • 21.6 Boolean의 경우:

    const age = 0;
    
    // bad
    const hasAge = new Boolean(age);
    
    // good
    const hasAge = Boolean(age);
    
    // good
    const hasAge = !!age;

⬆ back to top

Naming Conventions

22.2, 22.4 ~ 5, 22.10 ~ 15 항목을 제외하고는 Airbnb와 동일합니다.

  • 22.1 1문자의 이름은 사용하지 않는다. eslint: id-length

    // bad
    function q() {
      // ...stuff...
    }
    
    // good
    function query() {
      // ..stuff..
    }
  • 22.2 네임스페이스, 오브젝트, 함수 그리고 인스턴스에는 camelCase를 사용한다. eslint: camelcase

    // bad
    naver.FOO.bar = function() {};
    const OBJEcttsssss = {};
    const this_is_my_object = {};
    function c() {}
    
    // good
    naver.foo.bar = function() {};
    const thisIsMyObject = {};
    function thisIsMyFunction() {}
  • 22.3 클래스나 constructor에는 PascalCase 를 사용한다. eslint: new-cap

    // bad
    function user(options) {
      this.name = options.name;
    }
    
    const bad = new user({
      name: "nope",
    });
    
    // good
    class User {
      constructor(options) {
        this.name = options.name;
      }
    }
    
    const good = new User({
      name: "yup",
    });
  • 22.4 함수명이나 속성명의 앞에 _가 있는 경우는 private을 의미한다. 외부에서 접근할 수 있는 경우, 사용하면 안되는 메서드명 또는 속성명은 _을 사용한다. 외부에서 접근할 수 없다면, 메서드명 이나 속성명에 _을 사용하지 않는다. eslint: no-underscore-dangle

    // bad - 외부에서 접근할 수 있는 경우, 사용하면 안되는 메서드명 또는 속성명은 `_`을 사용한다.
    class User({
       constructor() {
          privateState: true
       }
       privateMethod() {
       }
       _publicMethod() {
       }
    }
    
    // good - 외부에서 접근할 수 있는 경우, 사용하면 안되는 메서드명 또는 속성명은 `_`을 사용한다.
    class User({
       constructor() {
          _privateState: true
       }
       _privateMethod() {
       }
       publicMethod() {
       }
    }
    
    // bad -  외부에서 접근할 수 없다면, 메서드명 이나 속성명에 `_`을 사용하지 않는다.
    (function(){
       var _privateState = true;
       function _privateMethod() {
       }
       function publicMethod() {
          _privateMethod();
       }
    })();
    
    // good -  외부에서 접근할 수 없다면, 메서드명 이나 속성명에 `_`을 사용하지 않는다.
    (function() {
       var privateState = true;
       function privateMethod() {
       }
       function publicMethod() {
           privateMethod();
       }
    })();
  • 22.5 가능한 this를 캐싱하지 않는다. arrow functions 또는 Function#bind를 사용한다. jQuery를 사용하는 경우라면, $.proxy를 사용한다. 만약, this의 참조를 저장하는 경우라면 self 를 사용한다.

    // bad
    function foo() {
      const self = this;
      return function () {
        console.log(self);
      };
    }
    
    // bad
    function foo() {
      const that = this;
      return function () {
        console.log(that);
      };
    }
    
    // good
    function foo() {
      return () => {
        console.log(this);
      };
    }
  • 22.6 파일을 1개의 클래스로 export 하는 경우, 파일명은 클래스명과 완전히 일치시킨다.

    // file contents
    class CheckBox {
      // ...
    }
    export default CheckBox;
    
    // in some other file
    // bad
    import CheckBox from "./checkBox";
    
    // bad
    import CheckBox from "./check_box";
    
    // good
    import CheckBox from "./CheckBox";
  • 22.7 Default export가 함수일 경우, camelCase를 이용한다. 파일명은 함수명과 동일해야 한다.

    function makeStyleGuide() {
    }
    
    export default makeStyleGuide;
  • 22.8 Singleton / function library / 빈 오브젝트를 export 하는 경우에는 PascalCase를 사용한다.

    const AirbnbStyleGuide = {
      es6: {
      }
    };
    
    export default AirbnbStyleGuide;
  • 22.9 약어 및 이니셜은 항상 모두 대문자이거나 모두 소문자이어야 한다.

    // bad
    import SmsContainer from "./containers/SmsContainer";
    
    // bad
    const HttpRequests = [
      // ...
    ];
    
    // good
    import SMSContainer from "./containers/SMSContainer";
    
    // good
    const HTTPRequests = [
      // ...
    ];
    
    // best
    import TextMessageContainer from "./containers/TextMessageContainer";
    
    // best
    const Requests = [
      // ...
    ];
  • 22.10 소스의 변수명, 클래스명 등에는 영문 이외의 언어를 사용하지 않는다.

  • 22.11 한글 발음을 그대로 사용하지 않는다.

    // ''무형자산''이라는 의미의 변수를 선언한 예.
    // bad
    const moohyungJasan;
    
    // good
    const intangibleAssets;
  • 22.12 클래스, 메서드 등의 이름에는 특수 문자를 사용하지 않는다. jQuery 변수의 경우 $을 사용하는 것은 예외사항으로 한다.

    // bad
    funtion $some() {
    
    }
  • 22.13 클래스명과 변수명은 명사 사용을 준수한다.

  • 22.14 메서드명은 동사 사용을 준수한다.

  • 22.15 상수명은 대문자를 사용하고, 단어와 단어사이는 _로 연결한다.

    // bad
    const firefox = 1;
    const is_left = true;
    
    // good
    const FIREFOX = 1;
    const IS_LEFT = true;

⬆ back to top

Accessors

Airbnb와 동일합니다.

  • 23.1 프로퍼티를 위한 접근자 (Accessor) 함수는 필수가 아니다.

  • 23.2 접근자 함수가 필요한 경우, getVal() 이나 setVal('hello') 로 한다.

    // bad
    dragon.age();
    
    // good
    dragon.getAge();
    
    // bad
    dragon.age(25);
    
    // good
    dragon.setAge(25);
  • 23.3 프로퍼티가 boolean 인 경우, isVal() 이나 hasVal() 로 한다.

    // bad
    if (!dragon.age()) {
      return false;
    }
    
    // good
    if (!dragon.hasAge()) {
      return false;
    }
  • 23.4 일관된 경우, get()set() 으로 함수를 작성해도 좋다.

    class Jedi {
      constructor(options = {}) {
        const lightsaber = options.lightsaber || "blue";
        this.set('lightsaber', lightsaber);
      }
    
      set(key, val) {
        this[key] = val;
      }
    
      get(key) {
        return this[key];
      }
    }

⬆ back to top

Events

Airbnb와 다르게 별도의 가이드를 제공하지 않습니다.

jQuery

25.3 ~ 4 항목을 제외하고는 Airbnb와 동일합니다.

  • 25.1 jQuery오브젝트의 변수는 선두에 $ 를 부여한다.

    // bad
    const sidebar = $(".sidebar");
    
    // good
    const $sidebar = $(".sidebar");
    
    // good
    const $sidebarBtn = $(".sidebar-btn");
  • 25.2 jQuery의 검색결과를 캐시하여 사용한다.

    // bad
    function setSidebar() {
      $('.sidebar').hide();
    
      // ...stuff...
    
      $(".sidebar").css({
        "background-color": "pink"
      });
    }
    
    // good
    function setSidebar() {
      const $sidebar = $(".sidebar");
      $sidebar.hide();
    
      // ...stuff...
    
      $sidebar.css({
        "background-color": "pink"
      });
    }
  • 25.3 Airbnb와 다르게 DOM 검색에 대해서는 별도로 가이드 하지 않는다.

  • 25.4 Airbnb와 다르게 DOM 검색에 대해서는 별도로 가이드 하지 않는다.

⬆ back to top

Resources

⬆ back to top