firejune / javascript

JavaScript Style Guide

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Airbnb JavaScript 스타일 가이드() {

자바 스크립트에 대한 가장 합리적인 접근 방식

Downloads ![Gitter](https://badges.gitter.im/Join Chat.svg)

다른 스타일 가이드들

목차

  1. 유형(Types)
  2. 참조(References)
  3. 객체(Objects)
  4. 배열(Arrays)
  5. 구조화 대입(Destructuring)
  6. 문자열(Strings)
  7. 함수(Functions)
  8. 애로우 함수(Arrow Functions)
  9. 생성자(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. ECMAScript 5 호환성(ECMAScript 5 Compatibility)
  27. ECMAScript 6 스타일(ECMAScript 6 Styles)
  28. 테스팅(Testing)
  29. 성능(Performance)
  30. 참고(Resources)
  31. 기여(In the Wild)
  32. 번역(Translation)
  33. 자바스크립트 스타일 가이드 안내서(The JavaScript Style Guide Guide)
  34. 자바스크립트 스타일 가이드 채팅(Chat With Us About JavaScript)
  35. 참여자(Contributors)
  36. 라이센스(License)

유형(Types)

  • 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 type)은 참조를 통해 값을 조작합니다.

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

⬆ 목록으로

참조(References)

  • 2.1 모든 참조에는 const를 사용하고 var를 사용하지 않습니다.

    왜죠? 참조를 다시 할당할 수 없어서, 버그로 연결되거나 이해하기 어려운 코드가 되는 것을 예방합니다.

    eslint rules: prefer-const, no-const-assign.

    // bad
    var a = 1;
    var b = 2;
    
    // good
    const a = 1;
    const b = 2;
  • 2.2 참조를 다시 할당해야 하는 경우 var 대신에 let을 사용하세요.

    왜죠? var는 함수-범위(function-scoped)이고 let은 블록-범위(block-scoped)이기 때문입니다.

    eslint rules: no-var.

    // bad
    var count = 1;
    if (true) {
      count += 1;
    }
    
    // good, use the let.
    let count = 1;
    if (true) {
      count += 1;
    }
  • 2.3 letconst는 모두 블록-범위(block-scoped)인 것에 주의해야 합니다.

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

⬆ 목록으로

객체(Objects)

  • 3.1 객체를 만들 때에는 리터럴 구문을 사용합니다.

    eslint rules: no-new-object.

    // bad
    const item = new Object();
    
    // good
    const item = {};
  • 3.2 코드가 브라우저에서 실행되는 경우 예약어를 키로 사용하지 마세요. 이것은 IE8에서 작동하지 않습니다. 더 알아보기. ES6 모듈과 서버 사이드에서는 사용할 수 있습니다.

    // bad
    const superman = {
      default: { clark: 'kent' },
      private: true,
    };
    
    // good
    const superman = {
      defaults: { clark: 'kent' },
      hidden: true,
    };
  • 3.3 예약어 대신에 알기 쉬운 동의어(Readable Synonyms)를 사용하세요.

    // bad
    const superman = {
      class: 'alien',
    };
    
    // bad
    const superman = {
      klass: 'alien',
    };
    
    // good
    const superman = {
      type: 'alien',
    };

  • 3.4 동적인 속성 이름을 가진 객체를 만들 때에는 계산된 속성 이름(Computed Property Names)을 사용하세요.

    왜죠? 이렇게하면 객체 속성을 한 개의 장소에서 정의 할 수 있습니다.

    function getKey(k) {
      return `a 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.5 메소드에 단축 구문(Object Shorthand)을 사용하세요.

    eslint rules: 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.6 속성에 단축 구문(Object Concise)을 사용하세요.

    왜죠? 표현이나 설명이 간결해지기 때문입니다.

    eslint rules: object-shorthand.

    const lukeSkywalker = 'Luke Skywalker';
    
    // bad
    const obj = {
      lukeSkywalker: lukeSkywalker,
    };
    
    // good
    const obj = {
      lukeSkywalker,
    };
  • 3.7 속성의 단축 구문(Object Concise)은 객체 선언의 시작 부분에 무리를 지어줍니다.

    왜죠? 어떤 속성이 단축 구문을 사용하고 있는지를 알기가 쉽기 때문입니다.

    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.8 속성 이름에 작은 따옴표를 사용하는 경우는 오직 잘못된 식별자(Invalid Identifiers)일 때입니다.

왜죠? 주관적으로 쉽게 읽을 수 있는 것을 항상 고민해야 합니다. 이 것은 구문이 강조되고, 수많은 JS엔진에 쉽게 최적화되어 있습니다.

eslint rules: quote-props.

// bad
const bad = {
  'foo': 3,
  'bar': 4,
  'data-blah': 5,
};

// good
const good = {
  foo: 3,
  bar: 4,
  'data-blah': 5,
};

⬆ 목록으로

배열(Arrays)

  • 4.1 배열을 만들 때 리터럴 구문을 사용하세요.

    eslint rules: 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 배열을 복사하는 경우, 배열의 확장 연산자인 ...을 사용하세요.

    // 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 Array-Like 객체를 배열로 변환하려면 Array#from을 사용하세요.

    const foo = document.querySelectorAll('.foo');
    const nodes = Array.from(foo);

⬆ 목록으로

구조화 대입(Destructuring)

  • 5.1 여러 속성에서 객체에 접근할 때 객체 구조화 대입(Destructuring)을 사용하세요.

    왜죠? 구조화 대입을 이용하여 그 속성에 대한 중간 참조를 줄일 수 있습니다.

    // bad
    function getFullName(user) {
      const firstName = user.firstName;
      const lastName = user.lastName;
    
      return `${firstName} ${lastName}`;
    }
    
    // good
    function getFullName(user) {
      const { firstName, lastName } = user;
      return `${firstName} ${lastName}`;
    }
    
    // best
    function getFullName({ firstName, lastName }) {
      return `${firstName} ${lastName}`;
    }
  • 5.2 배열에 구조화 대입(Destructuring)을 사용하세요.

    const arr = [1, 2, 3, 4];
    
    // bad
    const first = arr[0];
    const second = arr[1];
    
    // good
    const [first, second] = arr;
  • 5.3 여러 값을 반환하는 경우, 배열의 구조화 대입이 아니라 객체의 구조화 대입을 사용하세요.

    왜죠? 이렇게하면 나중에 새 속성을 추가하거나 호출에 영향을 주지않고 순서를 변경할 수 있습니다.

    // bad
    function processInput(input) {
      // 그러면 기적이 일어난다
      return [left, right, top, bottom];
    }
    
    // 호출자에 반환되는 데이터의 순서를 고려해야 함
    const [left, __, top] = processInput(input);
    
    // good
    function processInput(input) {
      // 그러면 기적이 일어난다
      return { left, right, top, bottom };
    }
    
    // 호출하면서 필요한 데이터만 선택할 수 있음
    const { left, right } = processInput(input);

⬆ 목록으로

문자열(Strings)

  • 6.1 문자열에는 작은 따옴표''를 사용하세요.

    eslint rules: quotes.

    // bad
    const name = "Capt. Janeway";
    
    // good
    const name = 'Capt. Janeway';
  • 6.2 100자 이상의 문자열은 여러 행을 사용하여 연결할 수 있습니다.

  • 6.3 주의: 문자열 연결이 많으면 성능에 영향을 줄 수 있습니다. jsPerf & Discussion.

    // 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.';

  • 6.4 프로그램에서 문자열을 생성하는 경우, 문자열 연결이 아니라 템플릿 문자열(Template Strings)을 사용하세요.

    왜죠? 템플릿 문자열의 문자열 완성 기능과 다중 문자열 기능을 가진 간결한 구문으로 가독성이 좋아지기 때문입니다.

    eslint rules: prefer-template.

    // 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.5 절대로 eval()을 사용하지 않습니다. 이것은 지금까지 수많은 취약점을 만들어 왔기 때문입니다.

⬆ 목록으로

함수(Functions)

  • 7.1 함수 선언 대신에 함수 표현식을 사용합니다.

    왜죠? 이름이 붙은 함수 선언은 콜스택에서 쉽게 알수 있습니다. 또한 함수 선언의 몸 전체가 Hoist됩니다. 반면 함수는 참조만 Hoist됩니다. 이 규칙은 함수 부분을 항상 애로우 함수로 대체 사용할 수 있습니다.

    // bad
    const foo = function () {
    };
    
    // good
    function foo() {
    }
  • 7.2 함수 표현식(Function expressions):

    // 즉시-호출(Immediately-Invoked) 함수 표현식(IIFE)
    (() => {
      console.log('Welcome to the Internet. Please follow me.');
    })();
  • 7.3 함수 이외의 블록 (ifwhile 등)에 함수를 선언하지 않습니다. 브라우저는 변수에 함수를 할당하는 처리를 할 수는 있지만, 모두 다르게 해석됩니다.

  • 7.4 주의: ECMA-262에서 block은 statements 목록에 정의되지만, 함수 선언은 statements가 없습니다. 이 문제는 ECMA-262의 설명을 참조하세요.

    // bad
    if (currentUser) {
      function test() {
        console.log('Nope.');
      }
    }
    
    // good
    let test;
    if (currentUser) {
      test = () => {
        console.log('Yup.');
      };
    }
  • 7.5 매개변수(parameter)에 arguments를 절대로 지정하지 않습니다. 이것은 함수 영역으로 전달 될 arguments객체의 참조를 덮어 써버릴 것입니다.

    // bad
    function nope(name, options, arguments) {
      // ...stuff...
    }
    
    // good
    function yup(name, options, args) {
      // ...stuff...
    }

  • 7.6 arguments를 사용하지 않습니다. 대신 레스트(Rest) 문법인 ...을 사용하세요.

    왜죠? ... 를 이용하여 여러가지 매개변수를 모두 사용할 수 있습니다. 추가로 rest 매개변수인 arguments는 Array-Like 객체가 아니라 진정한 배열(Array)입니다.

    // bad
    function concatenateAll() {
      const args = Array.prototype.slice.call(arguments);
      return args.join('');
    }
    
    // good
    function concatenateAll(...args) {
      return args.join('');
    }

  • 7.7 함수의 매개변수를 조작하지 말고 기본 매개변수(Default Parameters)를 사용하세요.

    // really bad
    function handleThings(opts) {
      // 안되! 함수의 매개변수를 조작하지 않습니다. 
      // 만약 opts가 falsy 인 경우는 바란대로 객체가 설정됩니다. 
      // 그러나 미묘한 버그를 일으키는 원인이 될수도 있습니다. 
      opts = opts || {};
      // ...
    }
    
    // still bad
    function handleThings(opts) {
      if (opts === void 0) {
        opts = {};
      }
      // ...
    }
    
    // good
    function handleThings(opts = {}) {
      // ...
    }
  • 7.8 부작용이 있는 기본 매개변수를 사용하지 않습니다.

    왜죠? 혼란스럽기 때문입니다.

    var b = 1;
    // bad
    function count(a = b++) {
      console.log(a);
    }
    count();  // 1
    count();  // 2
    count(3); // 3
    count();  // 3
  • 7.9 항상 기본 매개변수는 앞쪽에 배치하세요.

    // bad
    function handleThings(opts = {}, name) {
      // ...
    }
    
    // good
    function handleThings(name, opts = {}) {
      // ...
    }
  • 7.10 새로운 함수를 만드는 데 Function 생성자를 사용하지 않습니다.

    왜죠? 이 방법은 문자열을 구분하는 새로운 함수를 만들 수 있는 eval()과 같은 취약점이 발생할 수 있습니다.

    // bad
    var add = new Function('a', 'b', 'return a + b');
    
    // still bad
    var subtract = Function('a', 'b', 'return a - b');
  • 7.11 함수에 사용되는 공백

    왜죠? 일관성이 좋고, 함수이름을 추가 하거나 삭제할 때 공백을 제거할 필요가 없습니다.

    // bad
    const f = function(){};
    const g = function (){};
    const h = function() {};
    
    // good
    const x = function () {};
    const y = function a() {};
  • 7.12 절대로 매개변수를 조작하지 않습니다.

    왜죠? 매개변수로 전달 된 객체를 조작하는 것은 원래의 호출에 원치 않는 변수 부작용을 일으킬 수 있습니다.

    eslint rules: no-param-reassign.

    // bad
    function f1(obj) {
      obj.key = 1;
    };
    
    // good
    function f2(obj) {
      const key = Object.prototype.hasOwnProperty.call(obj, 'key') ? obj.key : 1;
    };
  • 7.13 절대로 매개변수를 다시 지정하지 않습니다.

    왜죠? arguments 객체에 접근하는 경우 다시 지정된 매개변수는 예기치 않은 동작이 발생할 수 있습니다. 그리고 특히 V8 최적화에 문제가 발생할 수 있습니다.

    eslint rules: no-param-reassign.

    // 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) {
    }

⬆ 목록으로

애로우 함수(Arrow Functions)

  • 8.1 함수 표현식을 사용하는 경우(익명 함수와 같은), 애로우 함수(Arrow Functions)를 사용하세요.

    왜죠? 애로우 함수는 함수가 실행되는 컨텍스트의 this를 가두어줍니다. 이것은 너무나 원했던 것이며 구문도 더욱 간결해집니다.

    언제 쓰죠? 복잡한 함수 논리를 정의한 함수의 바깥쪽으로 이동하고 싶은 경우입니다.

    eslint rules: 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 함수의 본체가 하나의 표현식으로 구성되어있는 경우 중괄호{}를 생략하고 암묵적 return을 사용할 수 있습니다. 그렇지 않으면 return 문을 사용해야 합니다.

    왜죠? 가독성이 좋아지기 때문입니다. 여러 함수가 연결되는 경우에 쉽게 읽을 수 있습니다.

    언제 쓰죠? 객체를 반환하는 경우.

    eslint rules: arrow-parens, arrow-body-style.

    // good
    [1, 2, 3].map(number => `A string containing the ${number}.`);
    
    // bad
    [1, 2, 3].map(number => {
      const nextNumber = number + 1;
      `A string containing the ${nextNumber}.`;
    });
    
    // good
    [1, 2, 3].map(number => {
      const nextNumber = number + 1;
      return `A string containing the ${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 rules: 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’ve broken it ` +
      'over multiple lines!'
    ));
    
    // 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;
    });

⬆ 목록으로

생성자(Constructors)

  • 9.1 prototype의 직접 조작을 피하고 항상 class를 사용하세요.

    왜죠? 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를 사용하세요.

    왜죠? 프로토타입을 상속하기 위해 내장된 방식으로 instanceof 를 파괴할 수 없기 때문입니다.

    // 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() 메소드를 쓰는 것도 좋습니다. 단, 제대로 작동하는지, 부작용이 없는 지를 꼭 확인하세요.

    class Jedi {
      constructor(options = {}) {
        this.name = options.name || 'no name';
      }
    
      getName() {
        return this.name;
      }
    
      toString() {
        return `Jedi - ${this.getName()}`;
      }
    }

⬆ 목록으로

모듈(Modules)

  • 10.1 비표준 모듈 시스템이 아니라면 항상 (import/export) 를 사용하세요. 이렇게 함으로써 원하는 모듈 시스템에 언제든지 트랜스파일(Transpile) 할 수 있습니다.

    왜죠? 모듈은 곧 미래입니다. 미래를 선점하고 애용합시다.

    // 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 와일드카드를 이용한 가져오기는 사용하지 않습니다.

    왜죠? single default export인 것에 주의할 필요가 있기 때문입니다.

    // bad
    import * as AirbnbStyleGuide from './AirbnbStyleGuide';
    
    // good
    import AirbnbStyleGuide from './AirbnbStyleGuide';
  • 10.3 import 문에서 직접 추출(Export)하지 않습니다.

    왜죠? 한개의 라인이라 간결하기는 하지만, import와 export하는 방법을 명확하게 구분함으로써 일관성을 유지할 수 있습니다.

    // bad
    // filename es6.js
    export { es6 as default } from './airbnbStyleGuide';
    
    // good
    // filename es6.js
    import { es6 } from './AirbnbStyleGuide';
    export default es6;

⬆ 목록으로

이터레이터와 제너레이터(Iterators and Generators)

  • 11.1 이터레이터(Iterators)를 사용하지 않습니다. for-of 루프 대신 map()reduce()같은 자바스크립트의 고급함수(higher-order functions)를 사용하세요.

    왜죠? 이것은 불변(Immutable)의 규칙을 적용합니다. 값을 반환하는 함수를 처리하는 것이 부작용을 예측하기가 더 쉽습니다.

    eslint rules: no-iterator.

    const numbers = [1, 2, 3, 4, 5];
    
    // bad
    let sum = 0;
    for (let num of numbers) {
      sum += num;
    }
    
    sum === 15;
    
    // good
    let sum = 0;
    numbers.forEach((num) => sum += num);
    sum === 15;
    
    // best (use the functional force)
    const sum = numbers.reduce((total, num) => total + num, 0);
    sum === 15;
  • 11.2 현재 제너레이터(Generators)는 사용하지 않는 것이 좋습니다.

    왜죠? ES5에서 트랜스파일(Transpile)이 올바로 작동하지 않습니다.

⬆ 목록으로

속성(Properties)

  • 12.1 속성에 접근하려면 점.을 사용하세요.

    eslint rules: 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');

⬆ 목록으로

변수(Variables)

  • 13.1 변수를 선언 할 때는 항상 const를 사용하세요. 그렇지 않을 경우 전역 변수로 선언됩니다. 글로벌 네임 스페이스가 오염되지 않도록 캡틴 플래닛(역자주: 환경보호와 생태를 테마로 한 슈퍼히어로 애니메이션)도 경고하고 있습니다.

    // bad
    superPower = new SuperPower();
    
    // good
    const superPower = new SuperPower();
  • 13.2 하나의 변수 선언에 대해 하나의 const를 사용하세요.

    왜죠? 이 방법은 새로운 변수를 쉽게 추가할 수 있습니다. 또한 구분 기호의 차이에 의한 ;,로 다시금 대체하는 작업에 대해 신경쓸 필요가 없습니다.

    eslint rules: 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는 함수 범위에는 없는 블록 범위이기 때문입니다.

    // good
    function () {
      test();
      console.log('doing stuff..');
    
      //..other stuff..
    
      const name = getName();
    
      if (name === 'test') {
        return false;
      }
    
      return name;
    }
    
    // bad - unnecessary function call
    function (hasName) {
      const name = getName();
    
      if (!hasName) {
        return false;
      }
    
      this.setFirstName(name);
    
      return true;
    }
    
    // good
    function (hasName) {
      if (!hasName) {
        return false;
      }
    
      const name = getName();
      this.setFirstName(name);
    
      return true;
    }

⬆ 목록으로

호이스팅(Hoisting)

  • 14.1 var 선언은 할당이 없는 상태로 범위(Scope)의 위로 Hoist될 수 있습니다. 하지만 constlet 선언은 시간적 데드 존(Temporal Dead Zones (TDZ))이라는 새로운 개념의 혜택을 받고 있습니다. 이것은 왜 typeof가 안전하지 않은가(typeof is no longer safe)를 알고있는 것이 중요합니다.

    // (notDefined가 글로벌 변수에 존재하지 않는다고 가정했을 경우)
    // 이것은 잘 작동하지 않습니다. 
    function example() {
      console.log(notDefined); // => throws a ReferenceError
    }
    
    // 변수를 참조하는 코드 후에 그 변수를 선언한 경우
    // 변수가 Hoist되어서 작동합니다.
    // 주의: `true` 값 자체는 Hoist할 수 없습니다.
    function example() {
      console.log(declaredButNotAssigned); // => undefined
      var declaredButNotAssigned = true;
    }
    
    // 인터프린터는 변수 선언을 범위(Scope)의 시작부분에 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 명명된 함수의 경우도 마찬가지로 변수가 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');
      }
    }
  • 더 자세한 정보는 Ben CherryJavaScript Scoping & Hoisting을 참조하세요.

⬆ 목록으로

조건식과 등가식(Comparison Operators & Equality)

  • 15.1 ==!= 보다는 ===!==를 사용하세요.

  • 15.2 if와 같은 조건문은 ToBoolean방법에 의한 강제 형(Type) 변환으로 구분되고 항상 다음과 같은 간단한 규칙을 따릅니다:

    eslint rules: eqeqeq.

    • Objectstrue로 구분됩니다.
    • Undefinedfalse로 구분됩니다.
    • Nullfalse로 구분됩니다.
    • Booleansboolean형의 값으로 구분됩니다.
    • Numberstrue로 구분됩니다. 그러나, +0, -0, 또는 NaN인 경우 false로 구분됩니다.
    • Stringstrue로 구분됩니다. 그러나, 비어있는 ''경우는 false로 구분됩니다.
    if ([0]) {
      // true
      // 배열은 객체이므로 true로 구분됩니다.
    }
  • 15.3 손쉬운 방법을 사용하세요.

    // 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.

⬆ 목록으로

블록(Blocks)

  • 16.1 여러 줄의 블록은 중괄호{}를 사용합니다.

    // bad
    if (test)
      return false;
    
    // good
    if (test) return false;
    
    // good
    if (test) {
      return false;
    }
    
    // bad
    function () { return false; }
    
    // good
    function () {
      return false;
    }
  • 16.2 여러 블록에 걸친 ifelse를 사용하는 경우, elseif블록의 끝 중괄호{}와 같은 행에 두세요.

    eslint rules: brace-style.

    // bad
    if (test) {
      thing1();
      thing2();
    }
    else {
      thing3();
    }
    
    // good
    if (test) {
      thing1();
      thing2();
    } else {
      thing3();
    }

⬆ 목록으로

주석(Comments)

  • 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 문제를 지적하고 재고를 촉구하거나 문제의 해결책을 제시하는 경우 등, 주석 앞에 FIXME 또는 TODO 를 붙이는 것으로 다른 개발자의 빠른 이해를 도울 수 있습니다. 이들은 어떠한 액션을 따른다는 의미에서 일반 댓글과 다를 수 있습니다. 액션은 FIXME -- 해결책 필요 또는 TODO -- 구현 필요.

  • 17.4 문제에 대한 주석으로 // FIXME:를 사용하세요.

    class Calculator extends Abacus {
      constructor() {
        super();
    
        // FIXME: shouldn't use a global here
        total = 0;
      }
    }
  • 17.5 해결책에 대한 주석으로 // TODO:를 사용하세요.

    class Calculator extends Abacus {
      constructor() {
        super();
    
        // TODO: total should be configurable by an options param
        this.total = 0;
      }
    }

⬆ 목록으로

공백(Whitespace)

  • 18.1 탭에 공백 2개를 설정하세요.

    eslint rules: indent.

    // bad
    function () {
    ∙∙∙∙const name;
    }
    
    // bad
    function () {
    ∙const name;
    }
    
    // good
    function () {
    ∙∙const name;
    }
  • 18.2 중괄호{} 앞에 공백을 넣어주세요.

    eslint rules: 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 등)의 괄호() 앞에 공백을 넣어주세요. 함수 선언과 함수 호출시 인수 목록 앞에는 공백을 넣지 않습니다.

    eslint rules: space-after-keywords, space-before-keywords.

    // bad
    if(isJedi) {
      fight ();
    }
    
    // good
    if (isJedi) {
      fight();
    }
    
    // bad
    function fight () {
      console.log ('Swooosh!');
    }
    
    // good
    function fight() {
      console.log('Swooosh!');
    }
  • 18.4 연산자 사이에는 공백이 있습니다.

    eslint rules: space-infix-ops.

    // bad
    const x=y+5;
    
    // good
    const x = y + 5;
  • 18.5 파일의 마지막에 빈 줄을 하나 넣어주세요.

    // bad
    (function (global) {
      // ...stuff...
    })(this);
    // bad
    (function (global) {
      // ...stuff...
    })(this);
    
    // good
    (function (global) {
      // ...stuff...
    })(this);
  • 18.6 메소드 체인이 길어지는 경우 적절히 들여쓰기(indentation) 하세요. 행이 메소드 호출이 아닌 새로운 문장임을 강조하기 위해 선두에 점.을 배치하세요.

    // 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').class('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);
  • 18.7 블록과 다음 Statement 사이에 빈 줄을 넣어주세요.

    // 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 rules: 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 rules: 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 rules: 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 rules: object-curly-spacing.

    // bad
    const foo = {clark: 'kent'};
    
    // good
    const foo = { clark: 'kent' };
  • 18.12 한 줄에 100문자(공백 포함)가 넘는 코드는 피하세요.

    왜죠? 가독성과 유지 보수성을 보장합니다.

    eslint rules: max-len.

    // bad
    const foo = 'Whatever national crop flips the window. The cartoon reverts within the screw. Whatever wizard constrains a helpful ally. The counterpart ascends!';
    
    // bad
    $.ajax({ method: 'POST', url: 'https://airbnb.com/', data: { name: 'John' } }).done(() => console.log('Congratulations!')).fail(() => console.log('You have failed this city.'));
    
    // good
    const foo = 'Whatever national crop flips the window. The cartoon reverts within the screw. ' +
      'Whatever wizard constrains a helpful ally. The counterpart ascends!';
    
    // good
    $.ajax({
      method: 'POST',
      url: 'https://airbnb.com/',
      data: { name: 'John' },
    })
      .done(() => console.log('Congratulations!'))
      .fail(() => console.log('You have failed this city.'));

⬆ 목록으로

쉼표(Commas)

  • 19.1 쉼표로 시작: 제발 그만하세요.

    eslint rules: 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 rules: comma-dangle.

    왜죠? 이것은 git의 diff를 깨끗하게 합니다. 또한 Babel과 같은 트랜스 컴파일러는 끝에 불필요한 쉼표를 알아서 제거합니다. 이것은 기존 브라우저에서 불필요한 쉼표 문제를 걱정할 필요가 없다는 것을 의미합니다.

    // 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',
    ];

⬆ 목록으로

세미콜론(Semicolons)

  • 20.1 물론 사용합시다.

    eslint rules: semi.

    // bad
    (function () {
      const name = 'Skywalker'
      return name
    })()
    
    // good
    (() => {
      const name = 'Skywalker';
      return name;
    })();
    
    // good (guards against the function becoming an argument when two files with IIFEs are concatenated)
    ;(() => {
      const name = 'Skywalker';
      return name;
    })();

    Read more.

⬆ 목록으로

형변환과 강제(Type Casting & Coercion)

  • 21.1 문장의 시작 부분에서 형(Type)을 강제합니다.

  • 21.2 String:

    //  => this.reviewScore = 9;
    
    // bad
    const totalScore = this.reviewScore + '';
    
    // good
    const totalScore = String(this.reviewScore);
  • 21.3 Number: Number형으로 변환하려면 parseInt를 사용하세요. 항상 형변환을 위한 기수(radix)를 인수로 전달합니다.

    eslint rules: 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를 사용해야 하는 경우, 무엇을(what) 왜(why)에 대한 설명을 댓글로 남겨 주세요.

    // good
    /**
     * parseInt가 병목이되고 있었기 때문에, 
     * Bitshift 문자열을 수치로 강제로 변환하여 
     * 성능을 향상시킵니다.
     */
    const val = inputValue >> 0;
  • 21.5 주의: Bitshift를 사용하는 경우 수치는 64-비트 값들로 표현되어 있지만, Bitshift를 연산하면 항상 32-비트 단 정밀도로 돌려 주어집니다(source). 32-비트 이상의 값을 비트 이동하면 예상치 못한 행동을 일으킬 가능성이 있습니다. Discussion. 부호있는 32-비트 정수의 최대 값은 2,147,483,647입니다:

    2147483647 >> 0 //=> 2147483647
    2147483648 >> 0 //=> -2147483648
    2147483649 >> 0 //=> -2147483647
  • 21.6 Booleans:

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

⬆ 목록으로

명명 규칙(Naming Conventions)

  • 22.1 하나의 문자로 구성된 이름은 피하세요. 이름에서 의도를 읽을 수 있도록 해야 합니다.

    // bad
    function q() {
      // ...stuff...
    }
    
    // good
    function query() {
      // ..stuff..
    }
  • 22.2 객체, 함수 인스턴스에는 camelCase(소문자로 시작)를 사용하세요.

    eslint rules: camelcase.

    // bad
    const OBJEcttsssss = {};
    const this_is_my_object = {};
    function c() {}
    
    // good
    const thisIsMyObject = {};
    function thisIsMyFunction() {}
  • 22.3 클래스와 생성자는 PascalCase(대문자로 시작)를 사용하세요.

    // 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 rules: no-underscore-dangle.

    // bad
    this.__firstName__ = 'Panda';
    this.firstName_ = 'Panda';
    
    // good
    this._firstName = 'Panda';
  • 22.5 this에 대한 참조를 저장하지 않습니다. 애로우 함수 또는 Function#bind를 사용하세요.

    // 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 파일을 하나의 클래스로 추출(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 export-default 함수의 경우, camelCase(소문자로 시작)를 사용하세요. 파일이름은 함수이름과 동일해야 합니다.

    function makeStyleGuide() {
    }
    
    export default makeStyleGuide;
  • 22.8 싱글톤(singleton) / 함수 라이브러리(function library) / 단순한 객체(bare object)를 추출하는 경우, PascalCase(대문자로 시작)를 사용하세요.

    const AirbnbStyleGuide = {
      es6: {
      }
    };
    
    export default AirbnbStyleGuide;

⬆ 목록으로

액세서(Accessors)

  • 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];
      }
    }

⬆ 목록으로

이벤트(Events)

  • 24.1 (DOM 이벤트, Backbone 이벤트)처럼 자신의 이벤트 페이로드 값을 전달하려면 원시값 대신 해시인수를 전달합니다. 이렇게 하면 나중에 개발자가 이벤트에 관련된 모든 핸들러를 찾아 업데이트하지 않고 이벤트 페이로드에 값을 추가할 수 있습니다. 예를 들면:

    // bad
    $(this).trigger('listingUpdated', listing.id);
    
    ...
    
    $(this).on('listingUpdated', function (e, listingId) {
      // do something with listingId
    });

    보다 아래쪽이 더 선호됨:

    // good
    $(this).trigger('listingUpdated', { listingId: listing.id });
    
    ...
    
    $(this).on('listingUpdated', function (e, data) {
      // do something with data.listingId
    });

⬆ 목록으로

jQuery

  • 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 DOM의 검색에는 $('.sidebar ul') 또는 $('.sidebar > ul')과 같은 Cascading을 사용하세요. jsPerf

  • 25.4 jQuery 객체의 검색에는 범위가있는 find 를 사용하세요.

    // bad
    $('ul', '.sidebar').hide();
    
    // bad
    $('.sidebar').find('ul').hide();
    
    // good
    $('.sidebar ul').hide();
    
    // good
    $('.sidebar > ul').hide();
    
    // good
    $sidebar.find('ul').hide();

⬆ 목록으로

ECMAScript 5 호환성(ECMAScript 5 Compatibility)

⬆ 목록으로

ECMAScript 6 스타일(ECMAScript 6 Styles)

  • 27.1 이것은 ES6 명세 링크를 모아 놓은 것입니다.
  1. 애로우 함수(Arrow Functions)
  2. 클래스(Classes)
  3. 객체 단축 구문(Object Shorthand)
  4. 속성 단축 구문(Object Concise)
  5. 계산된 속성 이름(Object Computed Properties)
  6. 템플릿 문자열(Template Strings)
  7. 구조화 대입(Destructuring)
  8. 기본 매개변수(Default Parameters)
  9. 레스트(Rest)
  10. 배열 스프레드(Array Spreads)
  11. Let과 Const(Let and Const)
  12. 이터레이터와 제너레이터(Iterators and Generators)
  13. 모듈(Modules)

⬆ 목록으로

테스팅(Testing)

  • 28.1 물론 해야 합니다.

    function () {
      return true;
    }
  • 28.2 물론 심각하게:

  • 대부분 테스트 프레임워크를 이용하여 테스트를 작성합니다.

  • 작은 기능의 함수를 자주 쓰고 이변이 발생할 수 있는 부분을 최소화하기 위해 노력합니다.

  • stubs와 mocks에 주의하세요. 이 것들로 인해 테스트가 깨지기 쉽습니다.

  • Airbnb는 mocha를 이용하고 있습니다. 작게 분할된 개별 모듈은 tape을 사용합니다.

  • 지금은 달성할 필요가 없어도 100%의 테스트 커버리지를 목표로하는 것이 좋습니다.

  • 버그를 수정할 때 마다 회귀 테스트를 씁니다. 회귀 테스트 없는 버그 수정은 나중에 반드시 다시 출현할 것입니다.

⬆ 목록으로

성능(Performance)

⬆ 목록으로

참고(Resources)

Learning ES6

Read This

Tools

Other Style Guides

Other Styles

Further Reading

Books

Blogs

Podcasts

⬆ 목록으로

기여(In the Wild)

이 것은 본 스타일 가이드를 사용하는 조직의 목록입니다. 이 목록에 추가하고 싶다면, pull request를 하거나 issue를 통해 알려주세요.

⬆ 목록으로

번역(Translation)

이 스타일 가이드는 다른 언어로도 이용할 수 있습니다.

자바스크립트 스타일 가이드 안내서(The JavaScript Style Guide Guide)

자바스크립트 스타일 가이드 채팅(Chat With Us About JavaScript)

참여자(Contributors)

라이센스(License)

(The MIT License)

Copyright (c) 2014 Airbnb

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

⬆ 목록으로

조항(Amendments)

We encourage you to fork this guide and change the rules to fit your team's style guide. Below, you may list some amendments to the style guide. This allows you to periodically update your style guide without having to deal with merge conflicts.

};

About

JavaScript Style Guide


Languages

Language:JavaScript 100.0%