티스토리 뷰

목차

    1편에서 이어지는 글입니다.



    accessor-pairs

    set 구문의 페어가 되는 get 구문의 정의를 강제합니다.


    // NG

    var object = {

      set foo (val) {

        this.val = val

      }

    }


    // OK

    var object = {

      set foo (val) {

        this.val = val

      },

      get foo () {

        return this.val

      }

    }


    array-callback-return

    Array 메소드의 콜백 함수에서 return 문장을 강제합니다.


    // NG

    let numList = [1, 2, 3].map((item) => {

      item * item

    })


    // OK

    let numList = [1, 2, 3].map((item) => {

      return item * item

    })

    block-scoped-var

    var 변수를 블록 외부에서 사용했을 때 경고합니다.

    이건 호이스팅에 의한 버그를 피할 수 있습니다.


    // NG

    function something () {

      if (true) {

        var foo = 'hello'

      }

      console.log(foo)

    }


    // OK

    function something () {

      var foo

      if (true) {

        foo = 'hello'

      }

      console.log(foo)

    }


    class-methods-use-this

    class 메소드가 this 이용하는 것을 강요합니다.

    this를 이용하지 않는 경우, 정적 함수(static)로 정의할 수 있습니다.


    // NG

    class Something {

      constructor () {

        this.num = 1

      }

      print () {

        console.log(1)

      }

    }


    // OK

    class Something {

      constructor () {

        this.num = 1

      }

      static print () {

        console.log(1)

      }

    }

    class Something {

      constructor () {

        this.num = 1

      }

      print () {

        console.log(this.num)

      }

    }


    complexity

    복잡도를 제한합니다.


    // NG: eslint complexity: ["error", 2]

    function something (i) {

      if (i === 1) {

        console.log('foo') // 1

      } else if (i === 2) {

        console.log('bar') // 2

      } else {

        console.log('baz') // 3

      }

    }


    consistent-return

    return문이 항상 뭔가를 돌려주는지, 항상 아무것도 돌려주지 않는지 강제합니다.


    // NG

    function something1 (i) {

      if (i === 1) {

        return 'foo'

      } else {

        return

      }

    }


    // OK

    function something2 (i) {

      if (i === i) {

        return 'foo'

      } else {

        return 'bar'

      }

    }

    function something3 (i) {

      if (i === i) {

        return

      }

    }


    curly

    중괄호 사용을 요구합니다.

    JavaScript에서는 블록 문이 하나만 존재하면 중괄호를 생략할 수 있지만, 이것은 버그의 원인이 되거나 코드를 읽을 때 헷갈릴 수 있으므로 중괄호를 생략하지 않는 것이 모범 사례로 간주하고 있습니다.


    // NG

    if (foo) return 'foo'


    // OK

    if (foo) {

      return 'foo'

    }


    default-case

    switch문에서 defaultCase 적을 것을 요구합니다.

    defaultCase를 항상 명시하는 것이 개발자의 의도를 명확하게 이해시키기 위해 좋은 일이라고 생각합니다.


    // NG

    switch (foo) {

      case 1:

        console.log('foo is 1')

        break

      case 2:

        console.log('foo is 2')

        break

    }


    // OK

    switch (foo) {

      case 1:

        console.log('foo is 1')

        break

      case 2:

        console.log('foo is 2')

        break

      default:

        break

    }


    switch (foo) {

      case 1:

        console.log('foo is 1')

        break

      case 2:

        console.log('foo is 2')

        break

      // no default

    }


    dot-location

    dot 도트 점(.)의 앞뒤에 줄 바꿈 넣는 것을 요구합니다.

    점 위치에 일관성이 있으므로 가독성이 향상됩니다.


    /* eslint dot-location: ["error", "object"] */

    // NG

    let property = object

      .property


    // OK

    let property = object.

      property

    let property = object.property


    /* eslint dot-location: ["error", "property"] */

    // NG

    let property = object.

      property


    // OK

    let property = object

      .property

    let property = object.property


    dot-notation

    개체 속성에 엑세스할 때 점 표기법을 요구합니다.

    JavaScript에서는 브래킷 표기법에서 객체 속성으로 엑세스할 수 있지만, 도트 표기법이 가독성과 압축 효율이 우수합니다.


    // NG

    let foo = object['property']


    // OK

    let foo = object.property


    let propertyName = 'property'

    let foo = object[propertyName]


    eqeqeq

    ==와 != 대신 ===와 !==를 요구합니다.

    ==와 !=은 애매한 문제를 찾기 어렵기 때문에 ===과 !== 쪽의 형식이 안전하고 좋은 습관입니다.


    // NG

    if (foo == 'foo') {


    }


    // OK

    if (foo === 'foo') {


    }


    guard-for-in

    for in 문장을 사용할 때 if 문장에서 조사하는 것을 강요합니다.

    for in은 프로토타입 체인에서 상속된 속성도 루프에 포함하는 것을 의도한 것으로 오독할 수 있기 때문입니다.


    // NG

    for (const key in object) {

      console.log(key)

    }


    // OK

    for (const key in object) {

      if (object.hasOwnProperty(key)) {

        console.log(key)

      }

    }

    no-alert

    alert 함수 사용을 금지합니다.

    alert과 confirm, prompt 함수로 표시되는 UI는 더 나은 사용자 정의 UI로 대체합니다. 또한, 디버깅에 이용하는 일도 있으므로 production에서 빌드할 때 삭제해야 합니다.


    // NG

    alert('foo')

    confirm('bar')

    prompt('baz')


    no-caller

    arguments.caller와 arguments.callee 사용하는 것을 금지합니다.

    이러한 기능은 향후 JavaScript, ECMAScript5, strict mode에서 금지됩니다.


    // NG

    function foo () {

      console.log(arguments.caller)

      arguments.callee()

    }


    no-case-declarations

    lexical declarations(let, const, function, class)를 case, default 절에서 사용하는 것을 금지합니다.

    switch 문 전체에 정의된 것처럼 보이지만, 실제론 그 코드에 도달했을 때만 초기화되지 않습니다.


    lexical declarations을 case에서 이용하는 경우 괄호로 묶어야 합니다.


    // NG

    switch (something) {

      case 1:

        let foo = 'foo'

        break

      case 2:

        const bar = 'bar'

        break

      case 3:

        function baz () {

          console.log('baz')

        }

        break

      default:

        class qux {

        }

    }


    // OK

    switch (something) {

      case 1: {

        let foo = 'foo'

      }

      case 2: {

        const bar = 'bar'

      }

      case 3: {

        function baz () {

          console.log('baz')

        }

      }

      default: {

        class qux {


        }

      }

    }


    no-div-regex

    정규표현식 시작 부분에서 나누기 연산자를 허용하지 않습니다.


    // NG

    let foo = /=foo/


    // OK

    let foo = /\=foo/


    no-else-return

    else 전에 return하는 것을 금지합니다.


    // NG

    function something () {

      if (foo) {

        return 'foo'

      } else {

        return 'bar' 

      }

    }


    // OK

    function something () {

      if (foo) {

        return 'foo'

      }

      return 'bar'

    }


    no-empty-function

    빈 함수를 금지합니다. 의도적으로 정의할 경우 주석을 추가합니다.


    // NG

    function empty () {


    }


    // OK

    function empty () {

      // do nothing.

    }


    no-empty-pattern

    빈 디스트럭처 패턴을 금지합니다.

    많은 경우 기본값을 지정하는 것은 실수입니다.


    // NG

    let {property: {}} = object


    // OK

    let {property = {}} = object


    no-eq-null

    null 비교 시에는 엄격한 비교를 요구합니다.

    의도하지 않은 비교에 의한 잠재적인 버그를 방지합니다.


    // NG

    if (foo == null) {


    }

    if (foo != null)


    // OK

    if (foo === null) {


    }

    if (foo !== null) {


    }


    no-eval

    eval 함수 사용을 금지합니다.

    eval 함수는 위험하고 악용될 가능성이 높습니다.


    // NG

    var foo  = eval('{a: 1, b: 2}')


    no-extend-native

    내장 객체 확장을 금지합니다.


    // NG

    Object.prototype.foo = 'foo'


    no-extra-bind

    불필요한 bind 기능을 금지합니다.


    // NG

    let foo = function () {

      console.log('bar')

    }.bind(this)


    let foo = function () {

      (function () {

        console.log(this.bar)

      })

    }.bind({bar: 'bar'})


    // OK

    let foo = function () {

      console.log(this.bar)

    }.bind({bar: 'bar'})


    no-extra-label

    불필요한 라벨을 금지합니다.


    // NG

    LOOP1: while(true) {

      break LOOP1

    }


    // OK

    LOOP1: while(true) {

      while (true) {

        break LOOP1

      }

    }


    no-fallthrough

    case 문장에서 폴스루를 금지합니다.

    의도적으로 개행할 경우 주석으로 설명합니다.


    // NG

    switch (foo) {

      case 1:

        doSomething1()

      case 2:

        doSomething2()

    }


    // OK

    switch (foo) {

      case 1:

        doSomething1()

        break

      case 2:

        doSomething2()

        break

    }


    switch (foo) {

      case 1:

        doSomething1()

        // fall through

      case 2:

        doSomething2()

    }

    no-floating-decimal

    소수점 앞의 숫자 생략을 금지합니다.

    숫자와 dot 도트 점을 쉽게 구별하기 위함입니다.


    // NG

    let decimal = .1


    // OK

    let decimal = 0.1


    no-global-assign

    읽기 전용 전역 변수에 대입을 금지합니다.


    // NG

    window = false

    Object = {}

    undefined = 'undefined'


    no-implicit-coercion

    짧은 코드 기법에 의한 암시적 변환을 금지합니다. 형식 변환하는 경우 명시적인 방법을 사용합니다.


    // NG

    let isFoo = !!foo


    if (~foo.indexOf(0)) {


    }


    // OK

    let isFoo = Boolean(foo)


    if (foo.indexOf(0) !== -1) {


    }


    no-implicit-globals

    전역 글로벌 변수와 함수 선언하는 것을 금지합니다.

    의도적으로 전역으로 선언한 경우 window 및 버튼 self를 명시합니다.


    // NG

    function foo () {}

    var foo = 'foo'


    // OK

    window.foo = function () {}

    self.foo = 'foo'


    no-implied-eval

    암묵적인 eval()을 금지합니다.

    setTimeout(), setInterval(), execScript()의 첫 번째 인수에 문자열을 지정한 경우 암시적으로 eval()이 실행되어 버립니다. (Internet Explorer only)


    // NG

    setTimeout(`function () {

      console.log("foo") 

    }`, 1000)


    no-invalid-this

    this 키워드를 클래스와 클래스 객체 외부에서 사용하는 것을 금지합니다.

    strict mode 경우 this는 undefined 되고 TypeError 발생시킬 가능성이 있습니다.


    // NG

    this.foo = 'foo'


    function func () {

      this.foo = 'foo'

    }


    let foo = () => {

      this.foo = 'foo'

    }


    // OK

    function Func () {

      this.foo = 'foo'

    }


    class Foo {

      constructor () {

        this.foo = 'foo'

      }

    }


    no-iterator

    비추천 ... __iterator__ 프로퍼티를 금지합니다.

    ES6의 Iterator와 Generator를 대신 사용합니다.


    // NG

    Foo.prototype.__iterator__ = function () {}


    no-labels

    label 문장을 금지합니다.

    label은 그다지 사용하지 않는 경향이 있지만, 제어 흐름을 이해하기 어렵고 오류가 발생하기 쉽습니다.


    // NG

    label:

      while(foo) {

        while (bar) {

          break label

        }

      }


    // OK

    while(foo) {

      while (bar) {

        break

      }

      break

    }


    no-lone-blocks

    불필요한 중첩 블록을 금지합니다.


    // NG

    {

      var foo = 'foo'

    }


    // OK

    {

      let foo = 'foo'

    }


    no-loop-func

    루프에서 함수 선언 시, 함수 표현식 사용을 금지합니다.

    상황에 따라 예기치 않은 동작할 가능성이 있습니다.


    // NG

    var funcs = []

    for (var i = 0; i < 10; i++) {

      funcs[i] = function () {

        return i

      }

    }


    for (var i = 0; i < 10; i++) {

      function foo () {

        console.log(i)

      }

      foo()

    }


    // OK

    var funcs = []

    for (let i = 0; i < 10; i++) {

      funcs[i] = function () {

        return i

      }

    }

    for (let i = 0; i < 10; i++) {

      function foo () {

        console.log(i)

      }

      foo()

    }


    no-magic-numbers

    매직 넘버를 금지합니다.

    매직 넘버를 명명된 상수로 선언하는 것이 읽고 이해하기 쉬우며 리팩토링도 쉬워집니다.


    // NG

    let array = ['foo', 'bar', 'baz']

    console.log(array[2])


    // OK

    let array = ['foo', 'bar', 'baz']

    let index = 2

    console.log(array[index])


    no-multi-spaces

    조건식, 선언, 배열, 오브젝트, 시퀀스, 함수 매개 변수의 주위에 공백 여러 개 추가를 금지합니다.


    // NG

    if (foo  === 'foo') {


    }

    function foo  () {


    }

    const foo = [1,  2, 3]


    no-multi-str

    여러 줄의 문자열을 금지합니다.

    \ 줄 바꿈 앞에 지정함으로써 여러 줄의 문자열을 만들 수 있습니다만, 원래 JavaScript에서 공식적으로 규정된 것이 없으므로 나쁜 습관이라 생각하는 사람들이 있습니다.


    // NG

    let foo = 'foo \

      bar \

      baz'


    // OK

    let foo = 'foo \n' +

      'bar \n' +

      'baz'

    no-new

    변수에 할당하지 않은 인스턴스 생성(new)을 금지합니다.

    변수에 할당하지 않으면 많은 생성자가 필요하지 않으며 함수로 대체할 수 있습니다.


    // NG

    new Foo()


    // OK

    let foo = new Foo()

    foo()


    no-new-func

    Function 생성자 사용을 금지합니다.

    Function은 가독성이 낮고, 디버깅이 어렵기 때문에 나쁜 습관입니다.


    // NG

    let func = new Function('a', 'b', 'return a + b')


    no-new-wrappers

    new String, new Number, new Boolean 사용을 금지합니다.

    프리미티브 값을 생성하지 않고 실제로는 Object가 생성되므로 개발자 혼란을 초래할 수 있습니다.


    // NG

    let str = new String('str')

    let num = new Number(1)

    let bool = new Boolean(false)


    no-octal

    8진수 표기를 금지합니다. 8진수 표기는 EcmaScript5에서 폐지되어 strict 모드에서 오류가 발생합니다.


    // NG

    let foo = 071


    no-octal-escape

    8진수 이스케이프 시퀀스 사용을 금지합니다.


    // NG

    let foo = "Copyright \251";


    // OK

    let foo = "Copyright \u00A9"; 


    no-param-reassign

    함수 매개 변수(인수)에 다시 대입하는 것을 금지합니다.

    개발자가 의도하지 않은 오류가 발생하는 것을 방지합니다.


    // NG

    function doSomething(arg) {

      arg = 'foo'

    }


    // OK

    function doSomething(arg) {

      let foo = arg

      foo = 'foo'

    }


    no-proto

    __proto__ 사용을 금지합니다.

    __proto__는 EcmaScript 3.1 이상에서 폐지되었으므로 대신 getPrototypeOf를 사용하세요.


    // NG

    let proto = obj.__proto__


    // OK

    let proto = Object.getPrototypeOf(obj)


    no-redeclare

    같은 범위 내에서 같은 이름의 변수 선언을 금지합니다.


    // NG

    var foo = 'foo1'

    var foo = 'foo2'


    // OK

    var bar = 'bar1'

    bar = 'bar2'


    no-restricted-properties

    지정된 객체 속성의 사용을 금지할 수 있습니다.


    /*

    "no-restricted-properties": [2, {

      "object": "obj",

      "property": "prop"

    }]

    */


    // NG

    let obj = {}

    console.log(obj.prop)


    no-return-assign

    return 문장에 대입하는 것을 금지합니다.

    개발자 혼란을 초래하고 오류를 발생시킬 여지가 있습니다.


    // NG

    function doSomething() {

      return a = 1 + 2

    }


    no-return-await

    return await 문장을 금지합니다.

    async function을 이해하지 않고 실제로는 쓸모없이 처리되기 때문입니다.


    // NG

    async function doSomething() {

      return await foo()

    }


    // OK

    async function doSomething() {

      await foo()

      return

    }


    no-script-url

    JavaScript 프로토콜 javascript: 사용을 금지합니다.


    // NG

    location.href = 'javascript:void(0)'


    no-self-assign

    자신에게 할당을 금지합니다.


    // NG

    window = window


    no-self-compare

    자신과의 비교를 금지합니다.


    // NG

    if (foo === foo) {


    }


    no-sequences

    다음 예외를 제외하고 쉼표 연산자 사용을 금지합니다.


    for 문의 초기화 또는 업데이트 부분

    식의 순서가 명시적이고 괄호 안에 있는 경우


    // NG

    foo = doSomething(), val


    // OK

    foo = (doSomething(), val)


    no-throw-literal

    예외 발생 시 Error 객체를 throw를 강제합니다.

    예외 처리에 일관성을 갖기 위해서입니다.


    // NG

    throw 1

    throw { error: true }


    // OK

    throw new Error()

    throw new Error('error')


    no-unmodified-loop-condition

    루프 조건이 변경되지 않는 것을 금지합니다.

    개발자 실수를 미연에 방지합니다.


    // NG

    while (node) {

      doSomething(node);

    }


    // OK

    while (node) {

      doSomething(node);

      node = node.parent;

    }

    no-unused-expressions

    사용되지 않는 표현을 금지합니다.


    // NG

    function doSomething() {

      foo + 1

    }


    // OK

    function doSomething() {

      return foo + 1

    }


    no-unused-labels

    사용하지 않는 라벨을 금지합니다.


    // NG

    A: var foo = 0;


    // OK

    A: {

      if (foo()) {

          break A;

      }

      bar();

    }


    no-useless-call

    불필요한 .call()과 .apply() 사용을 금지합니다.

    함수 호출에 사용할 수 있지만, 일반 함수 호출보다 느립니다.


    // NG

    foo.call(undefined, 1, 2, 3);

    foo.call(null, 1, 2, 3);

    obj.foo.call(obj, 1, 2, 3);


    // OK

    foo.call(obj, 1, 2, 3);

    obj.foo.call(null, 1, 2, 3);

    obj.foo.call(otherObj, 1, 2, 3);


    no-useless-concat

    불필요한 문자 연결을 금지합니다.


    // NG

    var a = `some` + `string`;

    var a = '1' + '0';


    // OK

    var c = a + b;

    var c = '1' + a;

    var a = 1 + '1';


    no-useless-escape

    불필요한 이스케이프를 금지합니다.


    // NG

    "\'";

    `\"${foo}\"`;

    `\#{foo}`;


    // OK

    "\"";

    `\${${foo}}`;

    `$\{${foo}}`;


    no-useless-return

    불필요한 return 문장을 금지합니다.


    // NG

    function foo() {

      doSomething();

      return;

    }


    // OK

    function foo() {

      return doSomething();

    }


    no-void

    void 연산자를 금지합니다.

    어떤 코딩 스타일에서는 void 연산자는 읽기 어렵습니다.


    // NG

    void foo

    var foo = void bar();


    no-warning-comments

    경고 코멘트를 금지합니다.

    경고 코멘트는 배포 환경 구성하기 전에 제거해야 합니다.


    // NG

    function callback(err, results) {

      if (err) {

        console.error(err);

        return;

      }

      // TODO

    }


    // OK

    function callback(err, results) {

      if (err) {

        console.error(err);

        return;

      }

      // NOT READY FOR PRIME TIME

      // but too bad, it is not a predefined warning term

    }


    no-with

    with 문장 사용을 금지합니다.

    with 문장은 비추천이며, EcmaScript5의 strict 모드는 금지되어 있습니다.


    // NG

    with (point) {

      r = Math.sqrt(x * x + y * y);

    }


    // OK

    const r = ({x, y}) => Math.sqrt(x * x + y * y);


    prefer-promise-reject-errors

    Promise에서 reject 하려면 Error 오브젝트 설정을 요구합니다.


    // NG

    Promise.reject("something bad happened");

    Promise.reject();


    // OK

    Promise.reject(new Error("something bad happened"));

    Promise.reject(new TypeError("something bad happened"));


    radix

    parseInt 함수 사용 시 radix 지정을 요구합니다.

    EcmaScript5 이전까지 0으로 시작하는 숫자의 문자열을 8진수로 해석해 버리는 일이 있었습니다.


    // NG

    var num = parseInt("071");

    var num = parseInt(someValue);


    // OK

    var num = parseInt("071", 10);

    var num = parseInt("071", 8);


    require-await

    await 없는 async 함수를 금지합니다.

    리팩토링 등 의도하지 않은 결과를 방지합니다.


    // NG

    async function foo() {

      doSomething();

    }


    bar(async () => {

      doSomething();

    });


    // OK

    async function foo() {

      await doSomething();

    }


    bar(async () => {

      await doSomething();

    });


    vars-on-top

    변수 선언을 맨 앞에서 할 것을 강요합니다.


    // NG

    function doSomething() {

      var a = 1

      console.log(a)

      var b = 2

    }


    for (var i = 0; i < 10; i++) {

      console.log(i)

    }


    // OK

    function doSomething() {

      var a = 1

      var b = 2

      console.log(a)

    }


    for (let i = 0; i < 10; i++) {

      console.log(i)

    }

    wrap-iife

    즉시 함수(IIFE)를 괄호로 둘러서 쌓아야 합니다.

    함수 표현식이 괄호 없이 실행되는 데 비해 함수 선언은 괄호가 없는 경우 동작하지 않습니다.


    // NG

    var x = function () { return { y: 1 } }()


    // OK

    var x = (function () { return { y: 1 } }())


    yoda

    요다 기법을 강제하거나 금지합니다.

    변수와 리터럴 값을 비교할 때 피연산자의 위치에 일관성을 갖게 하기 위해서입니다.


    /* "yoda": "error" */

    // NG

    if ('red' === color) {


    }


    // OK

    if (color === 'red') {


    }


    /* "yoda": ["error", "always"] */

    // NG

    if (color === 'red') {


    }


    // OK

    if ('red' === color) {


    }



    다 읽으셨으면 이전 글도 함께 읽어보세요.