Skip to content

Latest commit

ย 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
ย 
ย 
ย 
ย 

README.md

ref: Airbnb JavaScript ์Šคํƒ€์ผ ๊ฐ€์ด๋“œ

Types

Primitives

์›์‹œํƒ€์ž…(Primitive type)์€ ๊ทธ ๊ฐ’์„ ์ง์ ‘ ์กฐ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

  • string
  • number
  • boolean
  • null
  • undefined
var foo = 1,
    bar = foo;

bar = 9;

console.log(foo, bar);  // 1, 9


Complex

์ฐธ์กฐํ˜•(Complex)์€ ์ฐธ์กฐ๋ฅผ ํ†ตํ•ด ๊ฐ’์„ ์กฐ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

  • object
  • array
  • function
var foo = [1, 2],
    bar = foo;

bar[0] = 9;

console.log(foo[0], bar[0]);  // 9, 9

Objects

  • Object๋ฅผ ๋งŒ๋“ค ๋•Œ๋Š” ๋ฆฌํ„ฐ๋Ÿด ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•  ๊ฒƒ

    // bad
    var item = new Object();
    
    // good
    var item = {};
  • IE8์—์„œ ๋™์ž‘ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์˜ˆ์•ฝ์–ด(reserved words)๋ฅผ ํ‚ค๋กœ ์‚ฌ์šฉํ•˜์ง€ ๋ง ๊ฒƒ

    // bad
    var superman = {
      default: { clark: 'kent' },
      private: true
    };
    
    // good
    var superman = {
      defaults: { clark: 'kent' },
      hidden: true
    };
  • ์˜ˆ์•ฝ์–ด ๋Œ€์‹  ์•Œ๊ธฐ ์‰ฌ์šด ๋™์˜์–ด(readable synonyms)๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ

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

Arrays

  • Array๋ฅผ ๋งŒ๋“ค ๋•Œ ๋ฆฌํ„ฐ๋Ÿด ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•  ๊ฒƒ

    // bad
    var items = new Array();
    
    // good
    var items = [];
  • ๊ธธ์ด๋ฅผ ์•Œ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ๋Š” Array#push๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ

    var someStack = [];
    
    // bad
    someStack[someStack.length] = 'abracadabra';
    
    // good
    someStack.push('abracadabra');
  • ๋ฐฐ์—ด์„ ๋ณต์‚ฌ ํ•  ํ•„์š”๊ฐ€์žˆ๋Š” ๊ฒฝ์šฐ Array#slice๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ

    var len = items.length,
        itemsCopy = [],
        i;
    
    // bad
    for (i = 0; i < len; i++) {
      itemsCopy[i] = items[i];
    }
    
    // good
    itemsCopy = items.slice();
  • Array์™€ ๋น„์Šทํ•œ(Array-Like)ํ•œ Object๋ฅผ Array์— ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” Array#slice๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ

    function trigger() {
      var args = Array.prototype.slice.call(arguments);
      ...
    }

Strings

  • ๋ฌธ์ž์—ด์€ ์ž‘์€ ๋”ฐ์˜ดํ‘œ('')๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ

    // bad
    var name = "Bob Parr";
    
    // good
    var name = 'Bob Parr';
    
    // bad
    var fullName = "Bob " + this.lastName;
    
    // good
    var fullName = 'Bob ' + this.lastName;
  • 80 ๋ฌธ์ž ์ด์ƒ์˜ ๋ฌธ์ž์—ด์€ ๋ฌธ์ž์—ด ์—ฐ๊ฒฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ์ค„์— ๊ฑธ์ณ ๊ธฐ์ˆ  ํ•  ๊ฒƒ

    • ๋ฌธ์ž์—ด ์—ฐ๊ฒฐ์„ ๋‚จ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์Œs
      // bad
      var 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
      var 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
      var 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.';
  • ํ”„๋กœ๊ทธ๋žจ์—์„œ ๋ฌธ์ž์—ด์„ ์ƒ์„ฑ ํ•  ํ•„์š”๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ (ํŠนํžˆ IE๋Š”) ๋ฌธ์ž์—ด ์—ฐ๊ฒฐ ๋Œ€์‹  Array#join์„ ์‚ฌ์šฉํ•  ๊ฒƒ

    var items,
        messages,
        length,
        i;
    
    messages = [{
        state: 'success',
        message: 'This one worked.'
    },{
        state: 'success',
        message: 'This one worked as well.'
    },{
        state: 'error',
        message: 'This one did not work.'
    }];
    
    length = messages.length;
    
    // bad
    function inbox(messages) {
      items = '<ul>';
    
      for (i = 0; i < length; i++) {
        items += '<li>' + messages[i].message + '</li>';
      }
    
      return items + '</ul>';
    }
    
    // good
    function inbox(messages) {
      items = [];
    
      for (i = 0; i < length; i++) {
        items[i] = messages[i].message;
      }
    
      return '<ul><li>' + items.join('</li><li>') + '</li></ul>';
    }

Functions

  • ํ•จ์ˆ˜์‹(Function expressions)

    // ์ต๋ช…ํ•จ์ˆ˜์‹(anonymous function expression)
    var anonymous = function() {
      return true;
    };
    
    // ๋ช…๋ช…๋œ ํ•จ์ˆ˜์‹(named function expression)
    var named = function named() {
      return true;
    };
    
    // ์ฆ‰์‹œ์‹คํ–‰ ํ•จ์ˆ˜์‹(immediately-invoked function expression (IIFE))
    (function() {
      console.log('Welcome to the Internet. Please follow me.');
    })();
    • if ๋ฐ while ๋“ฑ ๋ธ”๋ก ๋‚ด์—์„œ ๋ณ€์ˆ˜์— ํ•จ์ˆ˜๋ฅผ ํ• ๋‹นํ•˜๋Š” ๋Œ€์‹  ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•˜์ง€ ๋ง ๊ฒƒ
      • ๋ธŒ๋ผ์šฐ์ €๋Š” ํ—ˆ์šฉํ•˜์ง€๋งŒ ๋ชจ๋‘ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ํ•ด์„
      • ECMA-262์—์„œ๋Š” block์€ statements์˜ ๋ชฉ๋ก์— ์ •์˜๋˜์–ด ์žˆ์œผ๋‚˜ ํ•จ์ˆ˜ ์„ ์–ธ์€ statements๊ฐ€ ์—†์Œ
        // bad
        if (currentUser) {
          function test() {
            console.log('Nope.');
          }
        }
        
        // good
        var test;
        if (currentUser) {
          test = function test() {
            console.log('Yup.');
          };
        }
  • ๋งค๊ฐœ ๋ณ€์ˆ˜(parameter)์— arguments๋ฅผ ์ ˆ๋Œ€ ์ง€์ •ํ•˜์ง€ ๋ง ๊ฒƒ

    • ์ด๊ฒƒ์€ ํ•จ์ˆ˜ ๋ฒ”์œ„๋กœ ์ „๋‹ฌ ๋  arguments ๊ฐ์ฒด์˜ ์ฐธ์กฐ๋ฅผ ๋ฎ์–ด์”€
      // bad
      function nope(name, options, arguments) {
        // ...stuff...
      }
      
      // good
      function yup(name, options, args) {
        // ...stuff...
      }

Properties

  • ์†์„ฑ์— ์•ก์„ธ์Šคํ•˜๋ ค๋ฉด ๋„ํŠธ(.)๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ

    var luke = {
      jedi: true,
      age: 28
    };
    
    // bad
    var isJedi = luke['jedi'];
    
    // good
    var isJedi = luke.jedi;
  • ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์†์„ฑ์— ์ ‘๊ทผํ•˜๋ ค๋ฉด ๋Œ€๊ด„ํ˜ธ([])๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ

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

Variables

  • ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธ ํ•  ๋•Œ๋Š” ํ•ญ์ƒ var๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ.

    • ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ „์—ญ ๋ณ€์ˆ˜๋กœ ์„ ์–ธ๋จ
    • ์ „์—ญ ๋„ค์ž„ ์ŠคํŽ˜์ด์Šค๋ฅผ ์˜ค์—ผ์‹œํ‚ค์ง€ ์•Š๋„๋ก Captain Planet๋„ ๊ฒฝ๊ณ ํ•จ
      // bad
      superPower = new SuperPower();
      
      // good
      var superPower = new SuperPower();
  • ์—ฌ๋Ÿฌ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋ ค๋ฉด ํ•˜๋‚˜์˜ var๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ€์ˆ˜๋งˆ๋‹ค ์ค„๋ฐ”๊ฟˆํ•˜์—ฌ ์„ ์–ธํ•  ๊ฒƒ

    // bad
    var items = getItems();
    var goSportsTeam = true;
    var dragonball = 'z';
    
    // good
    var items = getItems(),
        goSportsTeam = true,
        dragonball = 'z';
  • ์ •์˜๋˜์ง€ ์•Š์€ ๋ณ€์ˆ˜๋ฅผ ๋งˆ์ง€๋ง‰์œผ๋กœ ์„ ์–ธํ•  ๊ฒƒ

    • ๋‚˜์ค‘์— ์ด๋ฏธ ํ• ๋‹น๋œ ๋ณ€์ˆ˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ์ง€์ •ํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ์— ์œ ์šฉ
      // bad
      var i, len, dragonball,
          items = getItems(),
          goSportsTeam = true;
      
      // bad
      var i, items = getItems(),
          dragonball,
          goSportsTeam = true,
          len;
      
      // good
      var items = getItems(),
          goSportsTeam = true,
          dragonball,
          length,
          i;
  • ๋ณ€์ˆ˜์˜ ํ• ๋‹น์€ ์Šค์ฝ”ํ”„์˜ ์‹œ์ž‘ ๋ถ€๋ถ„์—์„œ ํ•˜๋ฉฐ ์ด๊ฒƒ์€ ๋ณ€์ˆ˜ ์„ ์–ธ๊ณผ Hoisting ๊ด€๋ จ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•จ

    // bad
    function() {
      test();
      console.log('doing stuff..');
    
      //..other stuff..
    
      var name = getName();
    
      if (name === 'test') {
        return false;
      }
    
      return name;
    }
    
    // good
    function() {
      var name = getName();
    
      test();
      console.log('doing stuff..');
    
      //..other stuff..
    
      if (name === 'test') {
        return false;
      }
    
      return name;
    }
    
    // bad
    function() {
      var name = getName();
    
      if (!arguments.length) {
        return false;
      }
    
      return true;
    }
    
    // good
    function() {
      if (!arguments.length) {
        return false;
      }
    
      var name = getName();
    
      return true;
    }

Hoisting

  • ํ•ด๋‹น ์Šค์ฝ”ํ”„์˜ ์‹œ์ž‘ ๋ถ€๋ถ„์— Hoist๋œ ๋ณ€์ˆ˜์„ ์–ธ์€ ํ• ๋‹น๋˜์ง€ ์•Š์Œ

    // (notDefined๊ฐ€ ์ „์—ญ ๋ณ€์ˆ˜์— ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ์„ ๊ฒฝ์šฐ)
    // ์ด๊ฒƒ์€ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    function example() {
      console.log(notDefined); // => throws a ReferenceError
    }
    
    // ๊ทธ ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์ฝ”๋“œ ํ›„์— ๊ทธ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธ ํ•œ ๊ฒฝ์šฐ
    // ๋ณ€์ˆ˜๊ฐ€ Hoist๋œ ์ƒํƒœ์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
    // Note : `true`๋ผ๋Š” ๊ฐ’ ์ž์ฒด๋Š” Hoist๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    function example() {
      console.log(declaredButNotAssigned); // => undefined
      var declaredButNotAssigned = true;
    }
    
    // ์ธํ„ฐ ํ”„๋ฆฐํ„ฐ๋Š” ๋ณ€์ˆ˜ ์„ ์–ธ์„ ์Šค์ฝ”ํ”„์˜ ์‹œ์ž‘ ๋ถ€๋ถ„์— Hoistํ•ฉ๋‹ˆ๋‹ค.
    // ์œ„์˜ ์˜ˆ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‹ค์‹œ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    function example() {
      var declaredButNotAssigned;
      console.log(declaredButNotAssigned); // => undefined
      declaredButNotAssigned = true;
    }
  • ์ต๋ช… ํ•จ์ˆ˜์˜ ๊ฒฝ์šฐ ํ•จ์ˆ˜๊ฐ€ ํ• ๋‹น๋˜๊ธฐ ์ „์— ๋ณ€์ˆ˜๊ฐ€ Hoist๋  ์ˆ˜ ์žˆ์Œ

    function example() {
      console.log(anonymous); // => undefined
    
      anonymous(); // => TypeError anonymous is not a function
    
      var anonymous = function() {
        console.log('anonymous function expression');
      };
    }
  • ๋ช…๋ช… ๋œ ํ•จ์ˆ˜์˜ ๊ฒฝ์šฐ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ณ€์ˆ˜๊ฐ€ 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');
      }
    }
  • ํ•จ์ˆ˜ ์„ ์–ธ์€ ํ•จ์ˆ˜์ด๋ฆ„๊ณผ ํ•จ์ˆ˜๋ณธ๋ฌธ์ด Hoist ๋จ

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

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

  • == ๋‚˜ != ๋ณด๋‹ค๋Š” === ์™€ !== ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ

  • ์กฐ๊ฑด์‹์€ ToBoolean ๋ฉ”์„œ๋“œ์— ์˜ํ•ด ์•„๋ž˜์™€ ๊ฐ™์ด ์—„๋ฐ€ํ•˜๊ฒŒ ๋น„๊ต

    • Objects ๋Š” true ๋กœ ํ‰๊ฐ€
    • undefined ๋Š” false ๋กœ ํ‰๊ฐ€
    • null ๋Š” false ๋กœ ํ‰๊ฐ€
    • Booleans ๋Š” boolean ํ˜•์˜ ๊ฐ’์œผ๋กœ ํ‰๊ฐ€
    • Numbers ๋Š” true ๋กœ ํ‰๊ฐ€๋˜๋‚˜ +0, -0, or NaN ์˜ ๊ฒฝ์šฐ๋Š” false
    • Strings ๋Š” true ๋กœ ํ‰๊ฐ€๋˜๋‚˜ ๋นˆ๋ฌธ์ž '' ์˜ ๊ฒฝ์šฐ๋Š” false
      if ([0]) {
        // true
        // Array๋Š” Object ์ด๋ฏ€๋กœ true ๋กœ ํ‰๊ฐ€๋ฉ๋‹ˆ๋‹ค.
      }
  • ์งง์€ ํ˜•์‹์„ ์‚ฌ์šฉํ•  ๊ฒƒ

    // bad
    if (name !== '') {
      // ...stuff...
    }
    
    // good
    if (name) {
      // ...stuff...
    }
    
    // bad
    if (collection.length > 0) {
      // ...stuff...
    }
    
    // good
    if (collection.length) {
      // ...stuff...
    }

Blocks

  • ๋ณต์ˆ˜ํ–‰ ๋ธ”๋ก์€ ์ค‘๊ด„ํ˜ธ({})๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ
    // bad
    if (test)
      return false;
    
    // good
    if (test) return false;
    
    // good
    if (test) {
      return false;
    }
    
    // bad
    function() { return false; }Comments 
    
    // good
    function() {
      return false;
    }

Comments

  • ๋ณต์ˆ˜ํ–‰์˜ ์ฝ”๋ฉ˜ํŠธ๋Š” /** ... */ ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ

    • ๊ทธ ์•ˆ์—๋Š” ์„ค๋ช…๊ณผ ๋ชจ๋“  ๋งค๊ฐœ ๋ณ€์ˆ˜์™€ ๋ฐ˜ํ™˜ ๊ฐ’์— ๋Œ€ํ•œ ํ˜•์‹๊ณผ ๊ฐ’์„ ์„ค๋ช…
      // 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;
      }
  • ํ•œ ์ค„ ์ฃผ์„์—๋Š” // ...๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ

    • ์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์€ ์ฝ”๋“œ์˜ ์ƒ๋‹จ์— ์ž‘์„ฑํ•˜๊ณ , ์ฃผ์„ ์•ž์— ๋นˆ ์ค„์„ ๋„ฃ์„ ๊ฒƒ
      // bad
      var active = true;  // is current tab
      
      // good
      // is current tab
      var active = true;
      
      // bad
      function getType() {
        console.log('fetching type...');
        // set the default type to 'no type'
        var type = this._type || 'no type';
      
        return type;
      }
      
      // good
      function getType() {
        console.log('fetching type...');
      
        // set the default type to 'no type'
        var type = this._type || 'no type';
      
        return type;
      }
  • ๋ฌธ์ œ๋ฅผ ์ง€์ ํ•˜๊ณ  ์žฌ๊ณ ๋ฅผ ์ด‰๊ตฌํ•˜๊ฑฐ๋‚˜ ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์„ ์ œ์‹œํ•˜๋Š” ๋“ฑ ์˜๊ฒฌ์˜ ์•ž์— FIXME ๋‚˜ TODO๋ฅผ ๋ถ™์ผ ๊ฒƒ

    • ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž์˜ ๋น ๋ฅธ ์ดํ•ด๋ฅผ ๋„์šฐ๋ฉฐ ์ด๋Ÿฌํ•œ ์–ด๋–ค ์•ก์…˜์„ ๋™๋ฐ˜ํ•œ๋‹ค๋Š” ์˜๋ฏธ์—์„œ ์ผ๋ฐ˜ ์ฝ”๋ฉ˜ํŠธ์™€๋Š” ๋‹ค๋ฆ„
    • ์•ก์…˜์€ FIXME - ํ•ด๊ฒฐ์ฑ…์ด ํ•„์š” ๋˜๋Š” TODO - ๊ตฌํ˜„์ด ํ•„์š”
  • ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ฝ”๋ฉ˜ํŠธ๋กœ // FIXME :๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ

    function Calculator() {
    
      // FIXME: ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ๋Š” ์•ˆ๋ฉ๋‹ˆ๋‹ค.
      total = 0;
    
      return this;
    }
  • ๋ฌธ์ œ ํ•ด๊ฒฐ์ฑ…์— ๋Œ€ํ•œ ์ฝ”๋ฉ˜ํŠธ๋กœ // TODO :๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ

    function Calculator() {
    
      // TODO: total์€ ์˜ต์…˜ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์„ค์ •๋˜์–ด์•ผ ํ•จ.
      this.total = 0;
      return this;
    }

Whitespace

  • ํƒญ์—๋Š” ๊ณต๋ฐฑ 2๊ฐœ๋ฅผ ์„ค์ •ํ•  ๊ฒƒ

    // bad
    function() {
    โˆ™โˆ™โˆ™โˆ™var name;
    }
    
    // bad
    function() {
    โˆ™var name;
    }
    
    // good
    function() {
    โˆ™โˆ™var name;
    }
    
  • ์ค‘๊ด„ํ˜ธ({})์˜ ์•ž์— ๊ณต๋ฐฑ์„ ํ•˜๋‚˜ ๋„ฃ์„ ๊ฒƒ

    // 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'
    });
  • ํŒŒ์ผ์˜ ๋งˆ์ง€๋ง‰์—๋Š” ๋นˆ ์ค„์„ ํ•˜๋‚˜ ๋„ฃ์–ด์ฃผ์‹ญ์‹œ์˜ค.

    // bad
    (function(global) {
      // ...stuff...
    })(this);
    // good
    (function(global) {
      // ...stuff...
    })(this);
  • ๋ฉ”์„œ๋“œ ์ฒด์ธ์ด ๊ธธ์–ด์ง€๋Š” ๊ฒฝ์šฐ ์ ์ ˆํžˆ ๋“ค์—ฌ์“ฐ๊ธฐ(indentation)๋ฅผ ํ•  ๊ฒƒ

    // bad
    $('#items').find('.selected').highlight().end().find('.open').updateCount();
    
    // good
    $('#items')
      .find('.selected')
        .highlight()
        .end()
      .find('.open')
        .updateCount();
    
    // bad
    var 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
    var 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);

Commas

  • ์„ ๋‘์˜ comma๋Š” ํ•˜์ง€ ๋ง ๊ฒƒ

    // bad
    var once
      , upon
      , aTime;
    
    // good
    var once,
        upon,
        aTime;
    
    // bad
    var hero = {
        firstName: 'Bob'
      , lastName: 'Parr'
      , heroName: 'Mr. Incredible'
      , superPower: 'strength'
    };
    
    // good
    var hero = {
      firstName: 'Bob',
      lastName: 'Parr',
      heroName: 'Mr. Incredible',
      superPower: 'strength'
    };
  • ๋ง๋ฏธ์˜ ๋ถˆํ•„์š”ํ•œ ์‰ผํ‘œ๋„ ํ•˜์ง€ ๋ง ๊ฒƒ. ์ด๊ฒƒ์€ IE6/7๊ณผ quirksmode์˜ IE9์—์„œ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ์œผ๋ฉฐ ES3์˜ ์ผ๋ถ€ ๊ตฌํ˜„์—์„œ ๋ถˆํ•„์š”ํ•œ ์‰ผํ‘œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, ๋ฐฐ์—ด ๊ธธ์ด๋ฅผ ์ถ”๊ฐ€ํ•จ

    // bad
    var hero = {
      firstName: 'Kevin',
      lastName: 'Flynn',
    };
    
    var heroes = [
      'Batman',
      'Superman',
    ];
    
    // good
    var hero = {
      firstName: 'Kevin',
      lastName: 'Flynn'
    };
    
    var heroes = [
      'Batman',
      'Superman'
    ];

Semicolons

  • ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•  ๊ฒƒ
    // bad
    (function() {
      var name = 'Skywalker'
      return name
    })()
    
    // good
    (function() {
      var name = 'Skywalker';
      return name;
    })();
    
    // good
    ;(function() {
      var name = 'Skywalker';
      return name;
    })();

Type Casting & Coercion(๊ฐ•์ œ) ์›๋ฌธ

  • ๋ฌธ์˜ ์‹œ์ž‘ ๋ถ€๋ถ„์—์„œ ํ˜•์„ ๊ฐ•์ œํ•  ๊ฒƒ

  • Strings:

    //  => this.reviewScore = 9;
    
    // bad
    var totalScore = this.reviewScore + '';
    
    // good
    var totalScore = '' + this.reviewScore;
    
    // bad
    var totalScore = '' + this.reviewScore + ' total score';
    
    // good
    var totalScore = this.reviewScore + ' total score';
  • ์ˆซ์ž๋Š” parseInt๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ. ํ•ญ์ƒ ํ˜•๋ณ€ํ™˜์„ ์œ„ํ•œ ๊ธฐ์ˆ˜(radix)๋ฅผ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•  ๊ฒƒ

    var inputValue = '4';
    
    // bad
    var val = new Number(inputValue);
    
    // bad
    var val = +inputValue;
    
    // bad
    var val = inputValue >> 0;
    
    // bad
    var val = parseInt(inputValue);
    
    // good
    var val = Number(inputValue);
    
    // good
    var val = parseInt(inputValue, 10);
  • ์–ด๋–ค ์ด์œ ์— ์˜ํ•ด parseInt๊ฐ€ ๋ณ‘๋ชฉ์ด ๋˜๊ณ , ์„ฑ๋Šฅ์ ์ธ ์ด์œ ๋กœ Bitshift๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ, ํ•˜๋ ค๊ณ  ํ•˜๋Š”๊ฒƒ์— ๋Œ€ํ•ด why(์™œ)์™€ what(๋ฌด์—‡)์˜ ์„ค๋ช…์„ ์ฝ”๋ฉ˜ํŠธ๋กœ ๋‚จ๊ธธ ๊ฒƒ

    // good
    /**
     * parseInt๊ฐ€ ๋ณ‘๋ชฉ์„ ์ผ์œผํ‚ค๋ฏ€๋กœ
     * Bitshift๋กœ ๋ฌธ์ž์—ด์„ ์ˆ˜์น˜๋กœ ๊ฐ•์ œ์ ์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ
     * ์„ฑ๋Šฅ์„ ๊ฐœ์„ ์‹œํ‚ต๋‹ˆ๋‹ค.
     */
    var val = inputValue >> 0;
  • Booleans:

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

Naming Conventions

  • ํ•œ๋ฌธ์ž ์ด๋ฆ„์€ ํ”ผํ•˜๊ณ  ์ด๋ฆ„์—์„œ ์˜๋„๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋„๋ก ํ•  ๊ฒƒ

    // bad
    function q() {
      // ...stuff...
    }
    
    // good
    function query() {
      // ..stuff..
    }
  • Object, ํ•จ์ˆ˜, ๊ทธ๋ฆฌ๊ณ  ์ธ์Šคํ„ด์Šค๋กœ๋Š” camelCase๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ

    // bad
    var OBJEcttsssss = {};
    var this_is_my_object = {};
    var this-is-my-object = {};
    function c() {};
    var u = new user({
      name: 'Bob Parr'
    });
    
    // good
    var thisIsMyObject = {};
    function thisIsMyFunction() {};
    var user = new User({
      name: 'Bob Parr'
    });
  • Class์™€ ์ƒ์„ฑ์ž์—๋Š” PascalCase๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ

    // bad
    function user(options) {
      this.name = options.name;
    }
    
    var bad = new user({
      name: 'nope'
    });
    
    // good
    function User(options) {
      this.name = options.name;
    }
    
    var good = new User({
      name: 'yup'
    });
  • private ์†์„ฑ ์ด๋ฆ„์€ ๋ฐ‘์ค„ _ ์„ ์‚ฌ์šฉํ•  ๊ฒƒ

    // bad
    this.__firstName__ = 'Panda';
    this.firstName_ = 'Panda';
    
    // good
    this._firstName = 'Panda';
  • this์˜ ์ฐธ์กฐ๋ฅผ ์ €์žฅํ•  ๋•Œ _this ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ

    // bad
    function() {
      var self = this;
      return function() {
        console.log(self);
      };
    }
    
    // bad
    function() {
      var that = this;
      return function() {
        console.log(that);
      };
    }
    
    // good
    function() {
      var _this = this;
      return function() {
        console.log(_this);
      };
    }
  • ํ•จ์ˆ˜์— ์ด๋ฆ„์„ ๋ถ™์—ฌ stack traces๋ฅผ ์ถ”์ ํ•˜๊ธฐ ์‰ฝ๊ฒŒํ•  ๊ฒƒ

    // bad
    var log = function(msg) {
      console.log(msg);
    };
    
    // good
    var log = function log(msg) {
      console.log(msg);
    };

Constructors ์›๋ฌธ

  • ์ƒˆ Object์—์„œ ํ”„๋กœํ† ํƒ€์ž…์„ ์žฌ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํ”„๋กœํ† ํƒ€์ž… ๊ฐ์ฒด์— ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ๊ฒƒ

    • ํ”„๋กœํ† ํƒ€์ž…์„ ์žฌ์ •์˜ํ•˜๋ฉด ์ƒ์†์ด ๋ถˆ๊ฐ€๋Šฅํ•จ
    • ํ”„๋กœํ† ํƒ€์ž…์„ ๋ฆฌ์…‹ํ•˜๋Š”๊ฒƒ์œผ๋กœ ๋ฒ ์ด์Šค ํด๋ž˜์Šค๋ฅผ ์žฌ์ •์˜ ํ•  ์ˆ˜ ์žˆ์Œ
      function Jedi() {
        console.log('new jedi');
      }
      
      // bad
      Jedi.prototype = {
        fight: function fight() {
          console.log('fighting');
        },
      
        block: function block() {
          console.log('blocking');
        }
      };
      
      // good
      Jedi.prototype.fight = function fight() {
        console.log('fighting');
      };
      
      Jedi.prototype.block = function block() {
        console.log('blocking');
      };
  • ๋ฉ”์„œ๋“œ์˜ ๋ฐ˜ํ™˜ ๊ฐ’์œผ๋กœ this๋ฅผ ๋ฐ˜ํ™˜ํ•จ์œผ๋กœ์จ ๋ฉ”์„œ๋“œ ์ฒด์ธ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    // bad
    Jedi.prototype.jump = function() {
      this.jumping = true;
      return true;
    };
    
    Jedi.prototype.setHeight = function(height) {
      this.height = height;
    };
    
    var luke = new Jedi();
    luke.jump(); // => true
    luke.setHeight(20) // => undefined
    
    // good
    Jedi.prototype.jump = function() {
      this.jumping = true;
      return this;
    };
    
    Jedi.prototype.setHeight = function(height) {
      this.height = height;
      return this;
    };
    
    var luke = new Jedi();
    
    luke.jump()
      .setHeight(20);
  • ๋…์ž์ ์ธ toString()์„ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€, ๋ถ€์ž‘์šฉ์ด ์—†๋Š” ๊ฒƒ๋งŒ์€ ํ™•์ธํ•ด ์ฃผ์‹ญ์‹œ์˜ค.

    function Jedi(options) {
      options || (options = {});
      this.name = options.name || 'no name';
    }
    
    Jedi.prototype.getName = function getName() {
      return this.name;
    };
    
    Jedi.prototype.toString = function toString() {
      return 'Jedi - ' + this.getName();
    };

Events

  • DOM ์ด๋ฒคํŠธ๋‚˜ Backbone events์™€ ๊ฐ™์€ ๊ณ ์œ ์˜ ์ด๋ฒคํŠธ ํƒ‘์žฌ์ฒด(payloads)์˜ ๊ฐ’์„ ์ „๋‹ฌํ•˜๋Š” ๊ฒฝ์šฐ ์›์‹œ ๊ฐ’(raw value) ๋Œ€์‹  ํ•ด์‹œ ์ธ์ˆ˜(hash)๋ฅผ ์ „๋‹ฌ

    • ์ด๋ ‡๊ฒŒํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋‚˜์ค‘์— ๊ฐœ๋ฐœ์ž๊ฐ€ ์ด๋ฒคํŠธ์™€ ๊ด€๋ จ๋œ ๋ชจ๋“  ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ฐพ์•„ ์—…๋ฐ์ดํŠธ ํ•˜์ง€ ์•Š๊ณ  ์ด๋ฒคํŠธ ํƒ‘์žฌ์ฒด(payloads)์— ๊ฐ’์„ ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์žˆ์Œ
  • ์ด๊ฒƒ๋ณด๋‹จ

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

Modules

  • ๋ชจ๋“ˆ์˜ ์‹œ์ž‘์€ ! ๋กœ ์‹œ์ž‘ํ•  ๊ฒƒ
    • ์ด ํ–‰์œ„๋Š” ๋ฌธ๋ง์— ์„ธ๋ฏธ์ฝœ๋ก ์„ ๋„ฃ๋Š” ๊ฒƒ์„ ์žŠ์€ ๋ชจ๋“ˆ์„ ์—ฐ๊ฒฐํ• ๋•Œ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•จ
    • ํŒŒ์ผ ์ด๋ฆ„์€ camelCase๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ™์€ ์ด๋ฆ„์˜ ํด๋”์— ์ €์žฅํ•˜๊ณ , ๋‹จ๋…์œผ๋กœ ๊ณต๊ฐœํ•  ๊ฒฝ์šฐ ์ด๋ฆ„์„ ์ผ์น˜์‹œํ‚ฌ ๊ฒƒ
    • noConflict() ๋ผ๋Š” ๋ช…์นญ์œผ๋กœ (์ด๋ฆ„์ด ๊ฒน์ณ ๋ฎ์–ด ์จ์ง€๊ธฐ ์ „์˜) ๋ชจ๋“ˆ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ๊ฒƒ
    • ํ•ญ์ƒ ๋ชจ๋“ˆ์˜ ์‹œ์ž‘ ๋ถ€๋ถ„์—์„œ 'use strict'; ๋ฅผ ์„ ์–ธํ•  ๊ฒƒ
      // fancyInput/fancyInput.js
      
      !function(global) {
        'use strict';
      
        var previousFancyInput = global.FancyInput;
      
        function FancyInput(options) {
          this.options = options || {};
        }
      
        FancyInput.noConflict = function noConflict() {
          global.FancyInput = previousFancyInput;
          return FancyInput;
        };
      
        global.FancyInput = FancyInput;
      }(this);

jQuery

  • jQuery Object์˜ ๋ณ€์ˆ˜ ์•ž์—๋Š” $์„ ๋ถ€์—ฌํ•  ๊ฒƒ

    // bad
    var sidebar = $('.sidebar');
    
    // good
    var $sidebar = $('.sidebar');
  • jQuery ์ฟผ๋ฆฌ๊ฒฐ๊ณผ๋ฅผ ์บ์‹œํ•  ๊ฒƒ

    // bad
    function setSidebar() {
      $('.sidebar').hide();
    
      // ...stuff...
    
      $('.sidebar').css({
        'background-color': 'pink'
      });
    }
    
    // good
    function setSidebar() {
      var $sidebar = $('.sidebar');
      $sidebar.hide();
    
      // ...stuff...
    
      $sidebar.css({
        'background-color': 'pink'
      });
    }
  • DOM ๊ฒ€์ƒ‰์€ Cascading $('.sidebar ul') ์ด๋‚˜ parent &gt; child $('.sidebar > ul') ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ

  • jQuery Object ๊ฒ€์ƒ‰์€ ์Šค์ฝ”ํ”„๊ฐ€ ๋ถ™์€ find๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ

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