Skip to content

Instantly share code, notes, and snippets.

@kenmori
Last active July 14, 2018 01:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kenmori/e7b8d2c27a49c9d7f29e to your computer and use it in GitHub Desktop.
Save kenmori/e7b8d2c27a49c9d7f29e to your computer and use it in GitHub Desktop.
ESLintのエラールール。日本語ざっくり解説[ベストプラクティス編] ref: https://qiita.com/M-ISO/items/4cd183e2496c2937a53e
// Bad
var o = {
set a(value) {
this.val = value;
}
};
// Good
var o = {
set a(value) {
this.val = value;
},
get a() {
return this.val;
}
};
/*eslint block-scoped-var: 2*/
function doSomething() {
if (true) {
var build = true;
}
console.log(build); /*error "build" used outside of binding context.*/
}
////////////////////////////
//good
function doSomething() {
var build;
if (true) {
build = true;
}
console.log(build);//ok
}
alert("here!"); /*error Unexpected alert.*/
confirm("Are you sure?"); /*error Unexpected confirm.*/
prompt("What's your name?", "John Doe"); /*error Unexpected prompt.*/
/*eslint no-caller: 2*/
function foo(n) {
if (n <= 0) {
return;
}
arguments.callee(n - 1); /*error Avoid arguments.callee.*/
}
[1,2,3,4,5].map(function(n) {
return !(n > 1) ? 1 : arguments.callee(n - 1) * n; /*error Avoid arguments.callee.*/
});
function bar() { return /=foo/; } /*error A regular expression literal can be confused with '/='.*/
//ok
function bar() { return /\=foo/; }
function foo() {
if (x) {
return y;
} else { /*error Unexpected 'else' after 'return'.*/
return z;
}
}
//ok
function foo() {
if (x) {
return y;
}
return z;
}
labeled: /*error Unexpected label "labeled"*/
var x = 10;
if (foo == null) { /*error Use ‘===’ to compare with ‘null’.*/
bar();
}
while (qux != null) { /*error Use ‘===’ to compare with ‘null’.*/
baz();
}
//ok
if (foo === null) {
bar();
}
while (qux !== null) {
baz();
}
var obj = { x: "foo" },
key = "x",
value = eval("obj." + key); /*error eval can be harmful.*/
//ok
var obj = { x: "foo" },
key = "x",
value = obj[key];
//disallow
Object.prototype.a = "a";
Object.defineProperty(Array.prototype, "times", {value: 999});
//これらはチェックされない
var x = Object; x.prototype.thing = a;
eval("Array.prototype.forEach = 'muhahaha'");
with(Array) { prototype.thing = 'thing'; };
window.Function.prototype.bind = 'tight';
var boundGetName = (function getName() {
return this.name;
}).bind({ name: "ESLint" });
console.log(boundGetName()); // "ESLint"
// useless bind
var boundGetName = (function getName() {
return "ESLint";
}).bind({ name: "ESLint" });//とってオッケー
console.log(boundGetName()); // "ESLint"
switch(foo) {
case 1:
doSomething();
case 2:
doSomethingElse();
}
//上の場合fooが1の場合2も通る
switch(foo) {
case 1:
doSomething();
break;//good
case 2:
doSomethingElse();
}
function a(x) {
if (true) {
return x; // 1st path
} else if (false) {
return x+1; // 2nd path
} else {
return 4; // 3rd path
}
}
var num = .5; /*error A leading decimal point can be confused with a dot.*/
var num = 2.; /*error A trailing decimal point can be confused with a dot.*/
var num = -.7; /*error A leading decimal point can be confused with a dot.*/
//こういうやつ
var b = !!foo;
var b = ~foo.indexOf(".");
var n = +foo;
var n = 1 * foo;
var s = "" + foo;
//置き換えれる
var b = Boolean(foo);
var b = foo.indexOf(".") !== -1;
var n = Number(foo);
var n = Number(foo);
var s = String(foo);
//こういうやつ。setTimeout(), setInterval() or execScript()
setTimeout("alert('Hi!');", 100);
//good
setTimeout(function() {
alert("Hi!");
}, 100);
/*eslint no-invalid-this: 2*/
this.a = 0; /*error Unexpected `this`.*/
baz(() => this); /*error Unexpected `this`.*/
(function() {
this.a = 0; /*error Unexpected `this`.*/
baz(() => this); /*error Unexpected `this`.*/
})();
function foo() {
this.a = 0; /*error Unexpected `this`.*/
baz(() => this); /*error Unexpected `this`.*/
}
var foo = function() {
this.a = 0; /*error Unexpected `this`.*/
baz(() => this); /*error Unexpected `this`.*/
};
foo(function() {
this.a = 0; /*error Unexpected `this`.*/
baz(() => this); /*error Unexpected `this`.*/
});
obj.foo = () => {
// `this` of arrow functions is the outer scope's.
this.a = 0; /*error Unexpected `this`.*/
};
var obj = {
aaa: function() {
return function foo() {
// There is in a method `aaa`, but `foo` is not a method.
this.a = 0; /*error Unexpected `this`.*/
baz(() => this); /*error Unexpected `this`.*/
};
}
};
class Foo {
static foo() {
this.a = 0; /*error Unexpected `this`.*/
baz(() => this); /*error Unexpected `this`.*/
}
}
foo.forEach(function() {
this.a = 0; /*error Unexpected `this`.*/
baz(() => this); /*error Unexpected `this`.*/
});
/////////////////////////////////////////////////////////////////////
//以下は問題ではない
////////////////////////////////////////////////////////////////////
function Foo() {
// OK, this is in a legacy style constructor.
this.a = 0;
baz(() => this);
}
class Foo {
constructor() {
// OK, this is in a constructor.
this.a = 0;
baz(() => this);
}
}
var obj = {
foo: function foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}
};
var obj = {
foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}
};
var obj = {
get foo() {
// OK, this is in a method (this function is on object literal).
return this.a;
}
};
var obj = Object.create(null, {
foo: {value: function foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}}
});
Object.defineProperty(obj, "foo", {
value: function foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}
});
Object.defineProperties(obj, {
foo: {value: function foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}}
});
function Foo() {
this.foo = function foo() {
// OK, this is in a method (this function assigns to a property).
this.a = 0;
baz(() => this);
};
}
obj.foo = function foo() {
// OK, this is in a method (this function assigns to a property).
this.a = 0;
};
Foo.prototype.foo = function foo() {
// OK, this is in a method (this function assigns to a property).
this.a = 0;
};
class Foo {
foo() {
// OK, this is in a method.
this.a = 0;
baz(() => this);
}
}
var foo = (function foo() {
// OK, the `bind` method of this function is called directly.
this.a = 0;
}).bind(obj);
foo.forEach(function() {
// OK, `thisArg` of `.forEach()` is given.
this.a = 0;
baz(() => this);
}, thisArg);
/** @this Foo */
function foo() {
// OK, this function has a `@this` tag in its JSDoc comment.
this.a = 0;
}
Foo.prototype.__iterator__ = function() { /*error Reserved name '__iterator__'.*/
return new FooIterator(this);
};
foo.__iterator__ = function () {}; /*error Reserved name '__iterator__'.*/
foo["__iterator__"] = function () {}; /*error Reserved name '__iterator__'.*/
//ok
/*eslint no-iterator: 2*/
var __iterator__ = foo; // Not using the `__iterator__` property.
label: /*error Unexpected labeled statement.*/
while(true) {
// ...
}
label: /*error Unexpected labeled statement.*/
while(true) {
break label; /*error Unexpected label in break statement.*/
}
label: /*error Unexpected labeled statement.*/
while(true) {
continue label; /*error Unexpected label in continue statement.*/
}
//ok
var f = {
label: "foo"
};
while (true) {
break;
}
while (true) {
continue;
}
for (var i=10; i; i--) {
(function() { return i; })(); /*error Don't make functions within a loop*/
}
//ok
var a = function() {};
for (var i=10; i; i--) {
a();
}
if(foo === "bar") {}//スペース複数
var a = 1; /*error Multiple spaces found before '1'.*/
//ok
if(foo === "bar") {}
var a = 1;
var x = "Line 1 \
Line 2";//こういうのを許可しない
String = new Object(); /*error String is a read-only native object.*/
function doSomething(condition) {
if (condition) {
return true;
} else {
return; /*error Expected a return value.*/
}
}
//ok
function doSomething(condition) {
if (condition) {
return true;
} else {
return false;
}
}
var x = new Function("a", "b", "return a + b"); /*error The Function constructor is eval.*/
var x = Function("a", "b", "return a + b"); /*error The Function constructor is eval.*/
var stringObject = new String("Hello world"); /*error Do not use String as a constructor.*/
var numberObject = new Number(33); /*error Do not use Number as a constructor.*/
var booleanObject = new Boolean(false); /*error Do not use Boolean as a constructor.*/
var stringObject = new String; /*error Do not use String as a constructor.*/
var numberObject = new Number; /*error Do not use Number as a constructor.*/
var booleanObject = new Boolean; /*error Do not use Boolean as a constructor.*/
//OK
var text = String(someValue);
var num = Number(someValue);
var object = new MyString();
new Thing(); /*error Do not use 'new' for side effects.*/
//OK
var thing = new Thing();
Thing();
var foo = "Copyright \251"; /*error Don't use octal: '\251'. Use '\u....' instead.*/
//ok
var foo = "Copyright \u00A9"; // unicode
var foo = "Copyright \xA9"; // hexadecimal
var num = 071; /*error Octal literals should not be used.*/
//ok
var num = "071";
function foo(bar) {
bar = 13; /*error Assignment to function parameter 'bar'.*/
}
function foo(bar) {
bar++; /*error Assignment to function parameter 'bar'.*/
}
//ok
/*eslint no-param-reassign: 2*/
function foo(a) {
var b = a;
}
if(process.env.NODE_ENV === "development") { /*error Unexpected use of process.env.*/
//...
}
//ok
var config = require("./config");
if(config.env === "development") {
//...
}
var a = obj.__proto__; /*error The '__proto__' property is deprecated.*/
var a = obj["__proto__"]; /*error The '__proto__' property is deprecated.*/
//ok
/*eslint no-proto: 2*/
var a = Object.getPrototypeOf(obj);
var a = 3;
var a = 10; /*error "a" is already defined*/
//ok
var a = 3;
// ...
a = 10;
function doSomething() {
return foo = bar + 2; /*error Return statement should not contain assignment.*/
}
function doSomething() {
return foo += 2; /*error Return statement should not contain assignment.*/
}
//ok
function doSomething() {
return foo == bar + 2;
}
function doSomething() {
return foo === bar + 2;
}
function doSomething() {
return (foo = bar + 2);
}
if (foo) foo++; /*error Expected { after 'if' condition.*/
while (bar) /*error Expected { after 'while' condition.*/
baz();
//ok
if (foo) {
foo++;
}
while (bar) {
baz();
}
location.href = "javascript:void(0)"; /*error Script URL is a form of eval.*/
/*eslint no-self-compare: 2*/
var x = 10;
if (x === x) { /*error Comparing to itself is potentially pointless.*/
x = 20;
}
foo = doSomething, val; /*error Unexpected use of comma operator.*/
do {} while (doSomething(), !!test); /*error Unexpected use of comma operator.*/
for (; doSomething(), !!test; ); /*error Unexpected use of comma operator.*/
if (doSomething(), !!test); /*error Unexpected use of comma operator.*/
switch (val = foo(), val) {} /*error Unexpected use of comma operator.*/
while (val = foo(), val < 42); /*error Unexpected use of comma operator.*/
with (doSomething(), val) {} /*error Unexpected use of comma operator.*/
//ok
/*eslint no-sequences: 2*/
foo = (doSomething(), val);
(0,eval)("doSomething();");
do {} while ((doSomething(), !!test));
for (i = 0, j = 10; i < j; i++, j--);
if ((doSomething(), !!test));
switch ((val = foo(), val)) {}
while ((val = foo(), val < 42));
// with ((doSomething(), val)) {}
throw "error"; /*error Expected an object to be thrown.*/
throw 0; /*error Expected an object to be thrown.*/
throw undefined; /*error Do not throw undefined.*/
throw null; /*error Expected an object to be thrown.*/
var err = new Error();
throw "an " + err; /*error Expected an object to be thrown.*/
// err is recast to a string literal
var err = new Error();
throw `${err}` /*error Expected an object to be thrown.*/
//ok
throw new Error();
throw new Error("error");
var e = new Error("error");
throw e;
try {
throw new Error("error");
} catch (e) {
throw e;
}
0 /*error Expected an assignment or function call and instead saw an expression.*/
if(0) 0 /*error Expected an assignment or function call and instead saw an expression.*/
{0} /*error Expected an assignment or function call and instead saw an expression.*/
f(0), {} /*error Expected an assignment or function call and instead saw an expression.*/
a && b() /*error Expected an assignment or function call and instead saw an expression.*/
a, b() /*error Expected an assignment or function call and instead saw an expression.*/
/////////////////////////////////////////////////////////////////////
//default//ok
{}
f()
a = 0
new C
delete a.b
void a
c = a, b;
// foo(1, 2, 3);と同じ意味だし
foo.call(undefined, 1, 2, 3); /*error unnecessary ".call()".*/
foo.apply(undefined, [1, 2, 3]); /*error unnecessary ".apply()".*/
foo.call(null, 1, 2, 3); /*error unnecessary ".call()".*/
foo.apply(null, [1, 2, 3]); /*error unnecessary ".apply()".*/
// これと同じ意味だし、obj.foo(1, 2, 3);
obj.foo.call(obj, 1, 2, 3); /*error unnecessary ".call()".*/
obj.foo.apply(obj, [1, 2, 3]); /*error unnecessary ".apply()".*/
////////////////////////////////////////////////////////////////////
//ok
//thisのバインドは別.
foo.call(obj, 1, 2, 3);
foo.apply(obj, [1, 2, 3]);
obj.foo.call(null, 1, 2, 3);
obj.foo.apply(null, [1, 2, 3]);
obj.foo.call(otherObj, 1, 2, 3);
obj.foo.apply(otherObj, [1, 2, 3]);
// 引数リストのためはいい
foo.apply(undefined, args);
foo.apply(null, args);
obj.foo.apply(obj, args);
//10と同じ
var a = `some` + `string`; /*error Unexpected string concatenation of literals.*/
var a = '1' + '0'; /*error Unexpected string concatenation of literals.*/
var a = '1' + `0`; /*error Unexpected string concatenation of literals.*/
var a = `1` + '0'; /*error Unexpected string concatenation of literals.*/
var a = `1` + `0`; /*error Unexpected string concatenation of literals.*/
/////////////////////////////////////////
//ok
// when a non string is included
var c = a + b;
var c = '1' + a;
var a = 1 + '1';
var c = 1 - 2;
// when the string concatenation is multiline
var c = "foo" +
"bar";
void foo /*error Expected 'undefined' and instead saw 'void'.*/
var foo = void bar(); /*error Expected 'undefined' and instead saw 'void'.*/
// TODO: this /*error Unexpected todo comment.*/
// todo: this too /*error Unexpected todo comment.*/
// Even this: TODO /*error Unexpected todo comment.*/
/* /*error Unexpected todo comment.*/ /*error Unexpected fixme comment.*/ /*Unexpected any other term comment.*/ /*
* The same goes for this TODO comment
* Or a fixme
* as well as any other term
*/
//////////////////////////////////////////////
//ok
// This is to do
// even not any other term
// any other terminal
/*
* The same goes for block comments
* with any other interesting term
* or fix me this
*/
with (foo) { /*error Unexpected use of 'with' statement.*/
switch (a) { /*error Expected a default case.*/
case 1:
/* code */
break;
}
//ok
switch (foo) {
case 1:
doSomething();
break;
case 2:
doSomething();
break;
default:
// do nothing
}
var num = parseInt("071"); /*error Missing radix parameter.*/
var num = parseInt(someValue); /*error Missing radix parameter.*/
////////////////////////////////////
//ok
var num = parseInt("071", 10);
var num = parseFloat(someValue);
// Variable declarations in a block:
function doSomething() {
var first;
if (true) {
first = true;
}
var second;/*error All "var" declarations must be at the top of the function scope.*/
}
// Variable declaration in for initializer:
function doSomething() {
for (var i=0; i<10; i++) {} /*error All "var" declarations must be at the top of the function scope.*/
}
// Variables after other statements:
f();
var a;/*error All "var" declarations must be at the top of the function scope.*/
//////////////////////////////////////////////////
///ok
function doSomething() {
var first;//上
var second; //multiple declarations are allowed at the top
if (true) {
first = true;
}
}
function doSomething() {
var i;//宣言とそれは別
for (i=0; i<10; i++) {}
}
var x = function () { return { y: 1 };}(); /*error Wrap an immediate function invocation in parentheses.*/
if ("red" === color) { /*error Expected literal to be on the right side of ===.*/
// ...
}
if (true == flag) { /*error Expected literal to be on the right side of ==.*/
// ...
}
if (5 > count) { /*error Expected literal to be on the right side of >.*/
// ...
}
if (-1 < str.indexOf(substr)) { /*error Expected literal to be on the right side of <.*/
// ...
}
if (0 <= x && x < 1) { /*error Expected literal to be on the right side of <=.*/
// ...
}
/////////////////////////////////////////////
//ok
if (5 & value) {
// ...
}
if (value === "red") {
// ...
}
var x = (function () { return { y: 1 };})(); /*error Move the invocation into the parens that contain the function.*/
//////////////////////////////////////////////////
//ok
var x = (function () { return { y: 1 };}());
var x = (function () { return { y: 1 };}()); /*error Wrap only the function expression in parens.*/
//////////////////////////////////////////////////
//ok
var x = (function () { return { y: 1 };})();
if ("red" === color) { /*error Expected literal to be on the right side of ===.*/
// ...
}
if (true == flag) { /*error Expected literal to be on the right side of ==.*/
// ...
}
if (5 > count) { /*error Expected literal to be on the right side of >.*/
// ...
}
if (-1 < str.indexOf(substr)) { /*error Expected literal to be on the right side of <.*/
// ...
}
if (0 <= x && x < 1) { /*error Expected literal to be on the right side of <=.*/
// ...
}
/////////////////////////////////////////////
//ok
if (5 & value) {
// ...
}
if (value === "red") {
// ...
}
/*eslint dot-notation: 2*/
var x = foo.bar;
var x = foo[bar]; // Property name is a variable, square-bracket notation required
var foo = object
.property; /*error Expected dot to be on same line as object.*/
if (x == 42) { } /*error Expected '===' and instead saw '=='.*/
if ("" == text) { } /*error Expected '===' and instead saw '=='.*/
if (obj.getStuff() != undefined) { } /*error Expected '!==' and instead saw '!='.*/
/* eslint eqeqeq: [2, "smart"] */
typeof foo == 'undefined'
'hello' != 'world'
0 == 0
true == true
foo == null
for (key in foo) { /*error The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.*/
doSomething(key);
}
//ok
for (key in foo) {
if ({}.hasOwnProperty.call(foo, key)) {
doSomething(key);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment