티스토리 뷰
목차
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) {
}
다 읽으셨으면 이전 글도 함께 읽어보세요.