Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

ESLint Rules眺めるだけでJavaScriptの知識が深まった

More than 1 year has passed since last update.

ESLint Rulesには、JavaScriptの歴史と先人の知見が詰まっています。ESLint Rulesを眺めるだけでJavaScriptの知識が深まりました。先人よ、ありがとう...。

下記のコードはあくまで代表例として上げておりますが、それぞれのルールにはオプションによってルールを変更できるものも多く、必ずしも記載しているコードがベストという訳ではないと思います。
また、とても長文になってしまったので、もしかしたら和訳や実装に誤りがあるかもしれません。もし、何か不備がありましたら、コメント・編集リクエストを頂けると助かります!

Possible Errors

for-direction

for文の更新式が正の方向に動作する事を強制します。

// NG
for (var i = 0; i < 10; i--) {
  console.log(i)
}

// OK
for (var i = 0; i < 10; i++) {
  console.log(i)
}

getter-return

get構文でreturnを記述する事を強制します。

// NG
var hoge = {
  get name () {
    console.log('hoge')
  }
}

// OK
var hoge = {
  get name () {
    return 'hoge'
  }
}

no-await-in-loop

awaitをループ処理の中で使用する事を禁止します。

// NG
async function ngHoge () {
  let dataList = []
  let data
  for (let i = 0; i < 10; i++) {
    data = await doSomething(i)
    dataList.push(data)
  }
  return dataList
}

// OK
async function okHoge () {
  let dataList = []
  for (let i = 0; i < 10; i++) {
    dataList.push(doSomething)
  }
  return await Promise.all(dataList)
}

no-compare-neg-zero

-0と比較する事を禁止します。

// NG
var i = 0
if (i === -0) {
  console.log(i)
}

no-cond-assign

条件式に代入式を挿れる事を禁止します。

// NG
const obj = {}
if (obj.hoge = true) {
  console.log(i)
}

no-console

consoleを使用する事を禁止します。
consoleはproduction環境にプッシュされる前に除去されるべきです。

// NG
console.log('log')
console.warn('warn')
console.error('error'

no-constant-condition

条件式に定数(例えば、リテラル)を挿れる事を禁止します。

// NG
if (false) {
  doSomethingForDevelopment()
}

// OK
if (env === 'development') {
  doSomethingForDevelopment()
}

no-control-regex

正規表現の中で制御文字を指定する事を禁止します。
正規表現の中で制御文字を使用する事は稀であり、ほとんどの場合は入力ミスです。

// NG
var pattern1 = /Hello¥x0aWorld/
var pattern2 = new RegExp("Hello¥x0aWorld")

// OK
var pattern1 = /Hello¥sWorld/
var pattern2 = new RegExp("Hello¥sWorld"

no-debugger

debugger文を使用する事を禁止します。
debuggerはデバッグのために使用するため、本番環境のコードに含むべきではありません。

// NG
function hoge () {
  debugger
  console.log('hoge')
}

no-dupe-args

関数定義の際に重複した引数を禁止します。

// NG
function example (hoge, fuga, hoge) {
  console.log(hoge)
}

no-dupe-keys

オブジェクト定義の際に重複したキー名を禁止します。

// NG
const obj = {
  key1: 'key1',
  key1: 'key2'
}

no-duplicate-case

switch文で重複したケースラベルを禁止します。

// NG
switch (hoge) {
  case 1:
    console.log('This is case 1')
    break
  case 2:
    console.log('This is case 2')
    break
  case 1:
    console.log('This is case 3')
    break
}

no-empty

空のブロックを禁止します。
技術的には誤りではないですが、コードを読む際に混乱を招く可能性があります。

// NG
function example (x) {
  if (x) {
  }
  switch (x) {
  }
}

no-empty-character-class

正規表現の中で空のcharacter classes[]を使用する事を禁止します。
空の[]は何にもマッチしないため、おそらくタイプミスです。

// NG
var hoge = /abc[]/

// OK
var fuga = /abc[a-z]/

no-ex-assign

cache節の中で例外オブジェクトへの再代入を禁止します。
例外オブジェクトへの代替アクセスは存在しないので、再代入は完全に破壊的です。

// NG
try {

} catch (e) {
  e = new Error()
}

no-extra-boolean-cast

不要なBoolean型への変換を禁止します。
if文などの条件式では式の結果が強制的にBooleanになります。

var example = 10

// NG
if (Boolean(example)) {

}
if (!!example) {

}

// OK
if (example) {

}
if (!example) {

}

no-extra-parens

不要な括弧を禁止します。

// NG
var total = (10 * 20) - 30

no-extra-semi

不要なセミコロンを禁止します。
不要なセミコロンは技術的なエラーではないですが、コードを読む際に混乱を招きます。

// NG
var example = 5;;

function example () {
  console.log('sample')
};

no-func-assign

関数に対して再代入を禁止します。

// NG
function example () {
  console.log('before')
}
example = true

no-inner-declarations

ブロック内での関数宣言を禁止します。ただし、ブロック内での関数式は許容されます。

// NG
if (true) {
  function example () {
    console.log('example')
  }
}

// OK
if (true) {
  var example = function () {
    console.log('example')
  }
}

no-invalid-regexp

RegExpコンストラクタで無効な正規表現を指定する事を禁止します。
これは正規表現リテラルを使用した際にはコードをパースした際にSyntaxErrorが発生するのに対し、RegExpオブジェクトの場合はコードが実行された時にSyntaxErrorが発生するためです。

// NG
var regexp = new RegExp('[')

no-irregular-whitespace

無効なホワイトスペースを禁止します。
無効、または不規則なホワイトスペースはECMAScript5のパーサーで問題を引き起こし、コードのデバッグを困難にします。

// NG
function thing() {
    return 'test';/*<ENSP>*/
}
function thing() {
    return `template <NBSP>string`;
}

no-obj-calls

グローバルオブジェクトを関数として呼び出す事を禁止します。
EcmaScriptは大文字のグローバルオブジェクトを提供しますが、それらは関数で実行するとエラーになります。

// NG
Math()
var json = JSON()
var reflect = Reflect()

no-prototype-builtins

Object.createで生成したオブジェクトに対して、Object.prototypesのメソッドを直接呼ぶ事を禁止します。

var parent = function () {
  return this
}
parent.prototype.hoge = function () {
  console.log('hoge')
}

var child = Object.create(parent)

// NG
var hasHoge = child.hasOwnProperty('hoge')

// OK
var hasHoge = Object.hasOwnProperty.call(child, 'hoge')

no-regex-spaces

正規表現の中で複数のスペースを禁止します。
正規表現はミスを無くすために出来るだけシンプルに保つべきです。

// NG
var regex = /Hell   World/
var regex = new RegExp("Hello   World")

// OK
var regex = /Hell {3}World/
var regex = new RegExp("Hello {3}World")

no-sparse-arrays

空の配列を作成するためにスパース配列を使用する事を禁止します。
スパース配列は実装者の意図が分かりにくくし、混乱を招きます。

// NG
var array1 = [,,]
var array2 = ['red',,'blue']

// OK
var array1 = new Array(3)
var array2 = ['red', 'blue', ] // 最後のカンマはOK

no-template-curly-in-string

通常文字列の中でテンプレート文字列のプレースホルダーの使用を禁止します。
テンプレート文字列と間違って通常文字列を使用してしまう事を防止します。

// NG
var str1 = "Hello ${wld}"
var str2 = 'Hello ${wld}'

no-unexpected-multiline

紛らわしい複数行のコードを禁止します。
改行文字はいくつかのルールを除いて自動セミコロン挿入により文を終了します。

// NG
var foo = bar
(1 || 2).baz();

// OK
var foo = bar;
(1 || 2).baz();

no-unreachable

return, throw, continue, break文において到達不能なコードを禁止します。

// NG
function hoge () {
  return 'hoge'
  console.log('hoge')
}

no-unsafe-finally

return, throw, continue, break文をfanallyブロックに定義する事を禁止します。
これはtry~catch構文において予期しない動作を防止するためです。

// NG
try {
  return 1
} catch (e) {
  return 2
} finally {
  return 3
}

no-unsafe-negation

関係演算子の左オペランドにおいて否定する事を禁止します。
これは開発者の意図と異なる動作をする可能性があるためです。

// NG
if (!hoge in obj) {

}
if (!hoge instanceof Object) {

}

// OK
if (!(hoge in obj)) {

}
if (!(hoge instanceof Object)) {

}

use-isnan

NaNを判定する時にはisNaN()を使用する事を求めます。
これはNaNを比較した場合の結果が混乱を招くためです。

// NG
if (hoge === NaN) {

}

// OK
if (isNaN(hoge)) {

}

valid-jsdoc

JSDocのコメントを記述する事を強制します。

// NG
/**
 * Add two numbers.
 * @param {number} num The first number.
 * @returns The sum of the two numbers.
 */
function add(num1, num2) {
  return num1 + num2;
}

// OK
/**
 * Add two numbers.
 * @param {number} num1 The first number.
 * @param {number} num2 The second number.
 * @returns {number} The sum of the two numbers.
 */
function add(num1, num2) {
  return num1 + num2;
}

valid-typeof

typeofで比較する時の文字列が有効である事を強制します。

// NG
if (typeof hoge === 'undefiend') {

}
if (typeof hoge === 'stirng') {

}

// OK
if (typeof hoge === 'undefined') {

}
if (typeof hoge === 'object') {

}

Best Practices

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ではブロック内に文が1つしか存在しない場合は中括弧を省略する事ができますが、これはバグの原因になったり、コードの明瞭性が低くなるため、中括弧を省略しない事がベストプラクティスと見なされています。

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

ドット(.)の前後に改行を入れる事を要求します。
ドットの位置に一貫性がある事で読みやすさが向上します。

/* 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関数を使用する事を禁止します。
alertconfirmprompt関数で表示されるUIは、より適切なカスタムUIに置き換えられるべきです。また、デバッグに利用される事もあるため、productionでビルドする際には削除すべきです。

// NG
alert('foo')
confirm('bar')
prompt('baz')

no-caller

arguments.callerarguments.calleeを使用する事を禁止します。
これらの関数は将来的にJavaScriptやECMAScript5のstrict modeで禁止されています。

// NG
function foo () {
  console.log(arguments.caller)
  arguments.callee()
}

no-case-declarations

lexical declarations(let, const, function, class)をcasedefault節内で使用する事を禁止します。
これら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する事を禁止します。
これは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

グローバルスコープで変数と関数を宣言する事を禁止します。
意図的にグローバルに宣言する場合はwindowselfを明示します。

// 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の場合、上記のケースでthisundefinedになり、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

変数宣言をスコープの先頭で行う事を強制します。
これはJavaScriptインタプリタが自動的に行うホイスティングを実装者に意識させます。

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

}

終わりに

今回は個人的にリサーチしたかったので、ESLint Rulesの中から、"Possible Errors"と"Best Practice"を追ってみたのですが、めちゃめちゃ大変でした...。ちなみに、ESLint Rulesの日本語訳は探すといくつか出回っています。こちらの記事でも書かれていますが、ESLint Rulesから学ぶ事はあっても、全て手動で設定するのは大変なので気をつけましょう。

cawpea
Frontend / UI / UX / Agile / Coffee
https://blog.cawpea.me/
goodpatch
Goodpatch(株式会社グッドパッチ)はUI/UXデザインを強みにビジネスモデルやブランド、組織をデザインし、デザインの価値向上を目指すグローバルデザインカンパニーです。2020年6月30日、デザイン会社初の東証マザーズ上場。サービスやプロダクトの企画設計から関わりコンセプトメイキング、UX設計、プロトタイピング、UIデザイン、実装までワンストップで提供しています。
https://goodpatch.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away