Skip to content

firejune/javascript

ย 
ย 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

782 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

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 let๊ณผ const๋Š” ๋ชจ๋‘ ๋ธ”๋ก-๋ฒ”์œ„(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 ํ•จ์ˆ˜ ์ด์™ธ์˜ ๋ธ”๋ก (if๋‚˜ while ๋“ฑ)์— ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๋Š” ๋ณ€์ˆ˜์— ํ•จ์ˆ˜๋ฅผ ํ• ๋‹นํ•˜๋Š” ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ, ๋ชจ๋‘ ๋‹ค๋ฅด๊ฒŒ ํ•ด์„๋ฉ๋‹ˆ๋‹ค.

  • 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 ๋ณ€์ˆ˜๋ฅผ ํ• ๋‹น์„ ํ•„์š”๋กœ ํ•˜๋Š” ๋ถ€๋ถ„์—์„œ ์ ๋‹นํ•œ ์žฅ์†Œ์— ๋ฐฐ์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    ์™œ์ฃ ? let๊ณผ const๋Š” ํ•จ์ˆ˜ ๋ฒ”์œ„์—๋Š” ์—†๋Š” ๋ธ”๋ก ๋ฒ”์œ„์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

    // 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๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ const์™€ let ์„ ์–ธ์€ ์‹œ๊ฐ„์  ๋ฐ๋“œ ์กด(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 Cherry์˜ JavaScript Scoping & Hoisting์„ ์ฐธ์กฐํ•˜์„ธ์š”.

โฌ† ๋ชฉ๋ก์œผ๋กœ

์กฐ๊ฑด์‹๊ณผ ๋“ฑ๊ฐ€์‹(Comparison Operators & Equality)

  • 15.1 ==์™€ != ๋ณด๋‹ค๋Š” ===์™€ !==๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.

  • 15.2 if์™€ ๊ฐ™์€ ์กฐ๊ฑด๋ฌธ์€ ToBoolean๋ฐฉ๋ฒ•์— ์˜ํ•œ ๊ฐ•์ œ ํ˜•(Type) ๋ณ€ํ™˜์œผ๋กœ ๊ตฌ๋ถ„๋˜๊ณ  ํ•ญ์ƒ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฐ„๋‹จํ•œ ๊ทœ์น™์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค:

    eslint rules: eqeqeq.

    • Objects๋Š” true๋กœ ๊ตฌ๋ถ„๋ฉ๋‹ˆ๋‹ค.
    • Undefined๋Š” false๋กœ ๊ตฌ๋ถ„๋ฉ๋‹ˆ๋‹ค.
    • Null์€ false๋กœ ๊ตฌ๋ถ„๋ฉ๋‹ˆ๋‹ค.
    • Booleans์€ booleanํ˜•์˜ ๊ฐ’์œผ๋กœ ๊ตฌ๋ถ„๋ฉ๋‹ˆ๋‹ค.
    • Numbers๋Š” true๋กœ ๊ตฌ๋ถ„๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜, +0, -0, ๋˜๋Š” NaN์ธ ๊ฒฝ์šฐ false๋กœ ๊ตฌ๋ถ„๋ฉ๋‹ˆ๋‹ค.
    • Strings๋Š” true๋กœ ๊ตฌ๋ถ„๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜, ๋น„์–ด์žˆ๋Š” ''๊ฒฝ์šฐ๋Š” 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 ์—ฌ๋Ÿฌ ๋ธ”๋ก์— ๊ฑธ์นœ if์™€ else๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, else๋Š” if๋ธ”๋ก์˜ ๋ ์ค‘๊ด„ํ˜ธ{}์™€ ๊ฐ™์€ ํ–‰์— ๋‘์„ธ์š”.

    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

Resources

Stars

Watchers

Forks

Packages

ย 
ย 
ย 

Contributors

Languages

  • JavaScript 100.0%