docs/RULES-iteu.md
Questo è un TL;DR (troppo lungo, non ho letto) delle regole JavaScript di standard.
Il modo migliore per imparare standard è quello di installarlo e provarlo sul tuo codice.
Usa due spazi per indentare.
eslint: indent
function hello (name) {
console.log('hi', name)
}
Usa il singolo apostrofo per le stringhe tranne per evitare l'escaping.
eslint: quotes
console.log('hello there')
$("<div class='box'>")
Niente variabili inutilizzate.
eslint: no-unused-vars
function myFunction () {
var result = something() // ✗ evita
}
Aggiungi uno spazio dopo le parole chiave.
eslint: keyword-spacing
if (condition) { ... } // ✓ ok
if(condition) { ... } // ✗ evita
Aggiungi uno spazio prima delle parenti di una dichiarazione di una funzione.
eslint: space-before-function-paren
function name (arg) { ... } // ✓ ok
function name(arg) { ... } // ✗ evita
run(function () { ... }) // ✓ ok
run(function() { ... }) // ✗ evita
Usa sempree === invece di ==.
Eccezione: obj == null è consentito per controllare null || undefined.
eslint: eqeqeq
if (name === 'John') // ✓ ok
if (name == 'John') // ✗ evita
if (name !== 'John') // ✓ ok
if (name != 'John') // ✗ evita
Operatori infisso necessitano sempre di uno spazio.
eslint: space-infix-ops
// ✓ ok
var x = 2
var message = 'hello, ' + name + '!'
// ✗ evita
var x=2
var message = 'hello, '+name+'!'
Le virgole devono avere uno spazio dopo di loro.
eslint: comma-spacing
// ✓ ok
var list = [1, 2, 3, 4]
function greet (name, options) { ... }
// ✗ evita
var list = [1,2,3,4]
function greet (name,options) { ... }
Tieni gli else sulla stessa linea della parentesi graffa.
eslint: brace-style
// ✓ ok
if (condition) {
// ...
} else {
// ...
}
// ✗ evita
if (condition) {
// ...
}
else {
// ...
}
Per dichiarazioni if su più righe, utilizza le parentesi graffe.
eslint: curly
// ✓ ok
if (options.quiet !== true) console.log('done')
// ✓ ok
if (options.quiet !== true) {
console.log('done')
}
// ✗ evita
if (options.quiet !== true)
console.log('done')
Gestisci sempre l'oggetto err come parametro di funzione.
eslint: handle-callback-err
// ✓ ok
run(function (err) {
if (err) throw err
window.alert('done')
})
// ✗ evita
run(function (err) {
window.alert('done')
})
Usa il prefisso per le variabili gloabli con window..
Eccezioni sono: document, console e navigator.
eslint: no-undef
window.alert('hi') // ✓ ok
Non sono consentite più di una riga vuota.
eslint: no-multiple-empty-lines
// ✓ ok
var value = 'hello world'
console.log(value)
// ✗ evita
var value = 'hello world'
console.log(value)
Per l'operatore ternario su più di una riga, piazza ? e : nelle righe che gli appartengono.
eslint: operator-linebreak
// ✓ ok
var location = env.development ? 'localhost' : 'www.api.com'
// ✓ ok
var location = env.development
? 'localhost'
: 'www.api.com'
// ✗ evita
var location = env.development ?
'localhost' :
'www.api.com'
Per l'utilizzo del var, ogni assegnazione deve avere la sua definizione
eslint: one-var
// ✓ ok
var silent = true
var verbose = true
// ✗ evita
var silent = true, verbose = true
// ✗ evita
var silent = true,
verbose = true
Circonda gli assegnatori condizionali con parentesi aggiuntive. Questo assicura che ci sia l'espressione è intenzionalmente un assegnamento (=) invece di un errore di scrittura (===).
eslint: no-cond-assign
// ✓ ok
while ((m = text.match(expr))) {
// ...
}
// ✗ evita
while (m = text.match(expr)) {
// ...
}
Aggiungi degli spazie all'interno di blocchi su una singola riga.
eslint: block-spacing
function foo () {return true} // ✗ evita
function foo () { return true } // ✓ ok
Utilizza il camelcase per i nomi delle variabili e funzioni.
eslint: camelcase
function my_function () { } // ✗ evita
function myFunction () { } // ✓ ok
var my_var = 'hello' // ✗ evita
var myVar = 'hello' // ✓ ok
I trailing comma non sono ammessi.
eslint: comma-dangle
var obj = {
message: 'hello', // ✗ evita
}
The virgole devono essere messe alla fine della riga corrente
eslint: comma-style
var obj = {
foo: 'foo'
,bar: 'bar' // ✗ avoid
}
var obj = {
foo: 'foo',
bar: 'bar' // ✓ ok
}
Il punto deve essere sulla stessa linea della proprietà.
eslint: dot-location
console.
log('hello') // ✗ avoid
console
.log('hello') // ✓ ok
I file devono terminare con una nuova linea.
eslint: eol-last
No spazi tra la definizione di una funzione e la sua invocazione
eslint: func-call-spacing
console.log ('hello') // ✗ avoid
console.log('hello') // ✓ ok
Aggiungi uno spazio tra i due punti e il valore della chiave all'interno di un oggetto.
eslint: key-spacing
var obj = { 'key' : 'value' } // ✗ avoid
var obj = { 'key' :'value' } // ✗ avoid
var obj = { 'key':'value' } // ✗ avoid
var obj = { 'key': 'value' } // ✓ ok
I nomi dei costruttori devono iniziare con la lettera maiuscola
eslint: new-cap
function animal () {}
var dog = new animal() // ✗ avoid
function Animal () {}
var dog = new Animal() // ✓ ok
I costruttori senza argomenti devono essere invocati con le parentesi.
eslint: new-parens
function Animal () {}
var dog = new Animal // ✗ avoid
var dog = new Animal() // ✓ ok
Gli oggetti devono un getter quando un settere viene definito.
eslint: accessor-pairs
var person = {
set name (value) { // ✗ avoid
this._name = value
}
}
var person = {
set name (value) {
this._name = value
},
get name () { // ✓ ok
return this._name
}
}
I costruttori di classi derivate devono chiamare super.
eslint: constructor-super
class Dog {
constructor () {
super() // ✗ avoid
}
}
class Dog extends Mammal {
constructor () {
super() // ✓ ok
}
}
Usa gli array literals invece dei costruttori.
eslint: no-array-constructor
var nums = new Array(1, 2, 3) // ✗ avoid
var nums = [1, 2, 3] // ✓ ok
Evita l'utilizzo di arguments.callee e arguments.caller.
eslint: no-caller
function foo (n) {
if (n <= 0) return
arguments.callee(n - 1) // ✗ avoid
}
function foo (n) {
if (n <= 0) return
foo(n - 1)
}
Non è possibile cambiare il nome delle classi.
eslint: no-class-assign
class Dog {}
Dog = 'Fido' // ✗ avoid
Evita di modificare il varole di una variabile dichiarata usando const.
eslint: no-const-assign
const score = 100
score = 125 // ✗ avoid
Evita l'uso delle espressioni costanti all'interno delle condizioni (eccezione fatta per i cicli).
eslint: no-constant-condition
if (false) { // ✗ avoid
// ...
}
if (x === 0) { // ✓ ok
// ...
}
while (true) { // ✓ ok
// ...
}
No controllo dei caratteri nelle espressioni regolari.
eslint: no-control-regex
var pattern = /\x1f/ // ✗ avoid
var pattern = /\x20/ // ✓ ok
No debugger nel codice.
eslint: no-debugger
function sum (a, b) {
debugger // ✗ avoid
return a + b
}
Non usare delete sulle variabili.
eslint: no-delete-var
var name
delete name // ✗ avoid
No argomenti doppi all'interno della definizione di una funzione.
eslint: no-dupe-args
function sum (a, b, a) { // ✗ avoid
// ...
}
function sum (a, b, c) { // ✓ ok
// ...
}
No nomi doppi all'interno di una classe.
eslint: no-dupe-class-members
class Dog {
bark () {}
bark () {} // ✗ avoid
}
Non è possibile dichiarare chiavi doppie degli oggetti literals.
eslint: no-dupe-keys
var user = {
name: 'Jane Doe',
name: 'John Doe' // ✗ avoid
}
Non è possibile dichiarare due case che controllano lo stesso valore all'interno di uno switch
eslint: no-duplicate-case
switch (id) {
case 1:
// ...
case 1: // ✗ avoid
}
Utilizza un solo import per module.
eslint: no-duplicate-imports
import { myFunc1 } from 'module'
import { myFunc2 } from 'module' // ✗ avoid
import { myFunc1, myFunc2 } from 'module' // ✓ ok
No caratteri vuoti all'iterno delle espressioni regolari.
eslint: no-empty-character-class
const myRegex = /^abc[]/ // ✗ avoid
const myRegex = /^abc[a-z]/ // ✓ ok
Non è possibile usare il destructuring vuoto
eslint: no-empty-pattern
const { a: {} } = foo // ✗ avoid
const { a: { b } } = foo // ✓ ok
No all'uso di eval().
eslint: no-eval
eval( "var result = user." + propName ) // ✗ avoid
var result = user[propName] // ✓ ok
No all reassegnamento delle eccezioni all'interno di blocchi catch.
eslint: no-ex-assign
try {
// ...
} catch (e) {
e = 'new value' // ✗ avoid
}
try {
// ...
} catch (e) {
const newVal = 'new value' // ✓ ok
}
Non è possibile estendere oggetti nativi.
eslint: no-extend-native
Object.prototype.age = 21 // ✗ avoid
Evita il binding non necessari.
eslint: no-extra-bind
const name = function () {
getName()
}.bind(user) // ✗ avoid
const name = function () {
this.getName()
}.bind(user) // ✓ ok
Evita di effettuare il cast di booleani che non sono necessari.
eslint: no-extra-boolean-cast
const result = true
if (!!result) { // ✗ avoid
// ...
}
const result = true
if (result) { // ✓ ok
// ...
}
No parentesi non necessarie intorno alle funzioni.
eslint: no-extra-parens
const myFunc = (function () { }) // ✗ avoid
const myFunc = function () { } // ✓ ok
Utilizza il break per evitare l'esecuzioni dei successivi case all'interno di un blocco switch.
eslint: no-fallthrough
switch (filter) {
case 1:
doSomething() // ✗ avoid
case 2:
doSomethingElse()
}
switch (filter) {
case 1:
doSomething()
break // ✓ ok
case 2:
doSomethingElse()
}
switch (filter) {
case 1:
doSomething()
// fallthrough // ✓ ok
case 2:
doSomethingElse()
}
No ai decimali con la virgola mobile.
eslint: no-floating-decimal
const discount = .5 // ✗ avoid
const discount = 0.5 // ✓ ok
Evita la riassegnazione di una funzione dichiarata.
eslint: no-func-assign
function myFunc () { }
myFunc = myOtherFunc // ✗ avoid
Evita la riassegnazione di oggetti che possono essere solo letti.
eslint: no-global-assign
window = {} // ✗ avoid
No agli eval() sottointesi.
eslint: no-implied-eval
setTimeout("alert('Hello world')") // ✗ avoid
setTimeout(function () { alert('Hello world') }) // ✓ ok
No alla dichiarazione di funzioni all'interno di blocchi innestati.
eslint: no-inner-declarations
if (authenticated) {
function setAuthUser () {} // ✗ avoid
}
No a stringhe di expressioni regolari invalide all'interno dei costruttori RegExp.
eslint: no-invalid-regexp
RegExp('[a-z') // ✗ avoid
RegExp('[a-z]') // ✓ ok
No a spazi irregolari.
eslint: no-irregular-whitespace
function myFunc () /*<NBSP>*/{} // ✗ avoid
No all'uso di __iterator__.
eslint: no-iterator
Foo.prototype.__iterator__ = function () {} // ✗ avoid
No a etichette che condividono lo stesso nome di una variabile all'interno dello stesso scope.
eslint: no-label-var
var score = 100
function game () {
score: while (true) { // ✗ avoid
score -= 10
if (score > 0) continue score
break
}
}
No al blocco label.
eslint: no-labels
label:
while (true) {
break label // ✗ avoid
}
No a blocchi non necessari.
eslint: no-lone-blocks
function myFunc () {
{ // ✗ avoid
myOtherFunc()
}
}
function myFunc () {
myOtherFunc() // ✓ ok
}
Evita di mixare spazi e tab per indentare.
eslint: no-mixed-spaces-and-tabs
Non usare spazi multipli per indentare.
eslint: no-multi-spaces
const id = 1234 // ✗ avoid
const id = 1234 // ✓ ok
No a stringhe su più linee.
eslint: no-multi-str
const message = 'Hello \
world' // ✗ avoid
No all'uso del new senza l'assegnazione ad una variabile.
eslint: no-new
new Character() // ✗ avoid
const character = new Character() // ✓ ok
No all'uso del costruttore Function.
eslint: no-new-func
var sum = new Function('a', 'b', 'return a + b') // ✗ avoid
No all'uso del costruttore Object.
eslint: no-new-object
let config = new Object() // ✗ avoid
No all'uso di new require.
eslint: no-new-require
const myModule = new require('my-module') // ✗ avoid
No all'uso del costruttore Symbol.
eslint: no-new-symbol
const foo = new Symbol('foo') // ✗ avoid
No all'uso di istanze di primitive.
eslint: no-new-wrappers
const message = new String('hello') // ✗ avoid
Non chiamare le proprietà di oggetti globali come funzioni.
eslint: no-obj-calls
const math = Math() // ✗ avoid
No agli ottali literals.
eslint: no-octal
const octal = 042 // ✗ avoid
const decimal = 34 // ✓ ok
const octalString = '042' // ✓ ok
No all'escape di sequenze di ottali nelle stringhe letterali.
eslint: no-octal-escape
const copyright = 'Copyright \251' // ✗ avoid
Evita la concatenazione di strighe quando si usano __dirname e __filename.
eslint: no-path-concat
const pathToFile = __dirname + '/app.js' // ✗ avoid
const pathToFile = path.join(__dirname, 'app.js') // ✓ ok
Evita l'uso di __proto__. Usa invece getPrototypeOf.
eslint: no-proto
const foo = obj.__proto__ // ✗ avoid
const foo = Object.getPrototypeOf(obj) // ✓ ok
No alla ridichiarazione di variabili.
eslint: no-redeclare
let name = 'John'
let name = 'Jane' // ✗ avoid
let name = 'John'
name = 'Jane' // ✓ ok
Evita spazi multipli all'interno di espressioni regolari literals.
eslint: no-regex-spaces
const regexp = /test value/ // ✗ avoid
const regexp = /test {3}value/ // ✓ ok
const regexp = /test value/ // ✓ ok
Gli assegnamenti nei blocchi return devono essere circondati da parentesi .
eslint: no-return-assign
function sum (a, b) {
return result = a + b // ✗ avoid
}
function sum (a, b) {
return (result = a + b) // ✓ ok
}
Evita di assegnare una variabile a se stessa
eslint: no-self-assign
name = name // ✗ avoid
Evita di confrontare una variabile con se stessa.
eslint: no-self-compare
if (score === score) {} // ✗ avoid
Evita l'uso della virgola come operatore.
eslint: no-sequences
if (doSomething(), !!test) {} // ✗ avoid
Nomi protetti non possono essere reassegnati (shadowing).
eslint: no-shadow-restricted-names
let undefined = 'value' // ✗ avoid
Array sparsi non sono consentiti.
eslint: no-sparse-arrays
let fruits = ['apple',, 'orange'] // ✗ avoid
I tab non dovrebbero essere utilizzati
eslint: no-tabs
Strighe regolari non devono contenere i placeholders propri dei template literal.
eslint: no-template-curly-in-string
const message = 'Hello ${name}' // ✗ avoid
const message = `Hello ${name}` // ✓ ok
super() deve essere chiamato prima di this.
eslint: no-this-before-super
class Dog extends Animal {
constructor () {
this.legs = 4 // ✗ avoid
super()
}
}
Puoi usare throw solo su un oggetto Error.
eslint: no-throw-literal
throw 'error' // ✗ avoid
throw new Error('error') // ✓ ok
Spazi bianchi banditi alla fine di una linea.
eslint: no-trailing-spaces
Inizializzare con undefined non è consentito.
eslint: no-undef-init
let name = undefined // ✗ avoid
let name
name = 'value' // ✓ ok
No alla non-modifica delle condizioni all'interno dei cicli.
eslint: no-unmodified-loop-condition
for (let i = 0; i < items.length; j++) {...} // ✗ avoid
for (let i = 0; i < items.length; i++) {...} // ✓ ok
No all'uso dell'operatore ternario quando esiste una alternativa migliore.
eslint: no-unneeded-ternary
let score = val ? val : 0 // ✗ avoid
let score = val || 0 // ✓ ok
No a codice non eseguibile dopo l'uso di return, throw, continue, e break.
eslint: no-unreachable
function doSomething () {
return true
console.log('never called') // ✗ avoid
}
No a controlli di flusso all'interno di blocchi finally.
eslint: no-unsafe-finally
try {
// ...
} catch (e) {
// ...
} finally {
return 42 // ✗ avoid
}
L'operando sinistro di una operazione relazionale non può essere negato.
eslint: no-unsafe-negation
if (!key in obj) {} // ✗ avoid
Evita l'uso non necessario di .call() e .apply().
eslint: no-useless-call
sum.call(null, 1, 2, 3) // ✗ avoid
Evita l'uso di una non necessario computed property all'interno di una chiave di un oggetto
eslint: no-useless-computed-key
const user = { ['name']: 'John Doe' } // ✗ avoid
const user = { name: 'John Doe' } // ✓ ok
No all'uso non necessario di costruttori.
eslint: no-useless-constructor
class Car {
constructor () { // ✗ avoid
}
}
No all'uso non necessario degli escape.
eslint: no-useless-escape
let message = 'Hell\o' // ✗ avoid
Rinominare l'assegnamento di import, export, e destrutturazione (destructuring) usano lo stesso nome non è consentito.
eslint: no-useless-rename
import { config as config } from './config' // ✗ avoid
import { config } from './config' // ✓ ok
No spazi prima di una proprietà
eslint: no-whitespace-before-property
user .name // ✗ avoid
user.name // ✓ ok
No all'uso di with.
eslint: no-with
with (val) {...} // ✗ avoid
Mantere consistenza di nuove righe all'interno delle proprietà di un oggetto.
eslint: object-property-newline
const user = {
name: 'Jane Doe', age: 30,
username: 'jdoe86' // ✗ avoid
}
const user = { name: 'Jane Doe', age: 30, username: 'jdoe86' } // ✓ ok
const user = {
name: 'Jane Doe',
age: 30,
username: 'jdoe86'
} // ✓ ok
No padding all'interno dei blocchi.
eslint: padded-blocks
if (user) {
// ✗ avoid
const name = getName()
}
if (user) {
const name = getName() // ✓ ok
}
No spazi tra l'operatore spread e la loro espressione.
eslint: rest-spread-spacing
fn(... args) // ✗ avoid
fn(...args) // ✓ ok
Le virgole devono avere uno spazio dopo e non prima.
eslint: semi-spacing
for (let i = 0 ;i < items.length ;i++) {...} // ✗ avoid
for (let i = 0; i < items.length; i++) {...} // ✓ ok
Avere uno spazio prima dei blocchi.
eslint: space-before-blocks
if (admin){...} // ✗ avoid
if (admin) {...} // ✓ ok
No spazi all'interno delle parentesi
eslint: space-in-parens
getName( name ) // ✗ avoid
getName(name) // ✓ ok
Uso dello spazio dopo l'uso di un operatore unario.
eslint: space-unary-ops
typeof!admin // ✗ avoid
typeof !admin // ✓ ok
Usa gli spazi dentro i commenti.
eslint: spaced-comment
//comment // ✗ avoid
// comment // ✓ ok
/*comment*/ // ✗ avoid
/* comment */ // ✓ ok
No spazi dentro le strighe template.
eslint: template-curly-spacing
const message = `Hello, ${ name }` // ✗ avoid
const message = `Hello, ${name}` // ✓ ok
Usa IsNaN() quando controlli NaN.
eslint: use-isnan
if (price === NaN) { } // ✗ avoid
if (isNaN(price)) { } // ✓ ok
typeof deve essere comparato con una stringa valida.
eslint: valid-typeof
typeof name === 'undefimed' // ✗ avoid
typeof name === 'undefined' // ✓ ok
Espressioni di funzioni immediatamente invocate (IIFEs - Immediately Invoked Function Expressions) devono essere circondate da parentesi.
eslint: wrap-iife
const getName = function () { }() // ✗ avoid
const getName = (function () { }()) // ✓ ok
const getName = (function () { })() // ✓ ok
Mettere uno spazio prima e dopo * dentro le espressioni yield* .
eslint: yield-star-spacing
yield* increment() // ✗ avoid
yield * increment() // ✓ ok
Evitare condizioni Yoda.
eslint: yoda
if (42 === age) { } // ✗ avoid
if (age === 42) { } // ✓ ok
No punti e virgola (semicolons). (see: 1, 2, 3)
eslint: semi
window.alert('hi') // ✓ ok
window.alert('hi'); // ✗ avoid
Mai iniziare una linea con (, [, o `. Questo è l'unico trucchetto che permette di omettere i punti e virgola. E standard ti protegge da potenziali errori.
eslint: no-unexpected-multiline
// ✓ ok
;(function () {
window.alert('ok')
}())
// ✗ avoid
(function () {
window.alert('ok')
}())
// ✓ ok
;[1, 2, 3].forEach(bar)
// ✗ avoid
[1, 2, 3].forEach(bar)
// ✓ ok
;`hello`.indexOf('o')
// ✗ avoid
`hello`.indexOf('o')
Nota: Se tendi a scrivere codice in questo modo, probabilmente stai cercando di essere troppo furbo.
È scoraggiato l'uso di scorciatoie, in favore di espressioni chiare e leggibili quando possibile.
Invece di:
;[1, 2, 3].forEach(bar)
È preferito questo approccio:
var nums = [1, 2, 3]
nums.forEach(bar)
Oggigiorno, tutti i più popolari minificatori di codice si basano su AST, quindi gestiscono il JavaScript senza punti e virgola (semicolons-less) senza problemi (visto che i punti e virgola non sono obbligatori in JavaScript).
[Relying on automatic semicolon insertion] is quite safe, and perfectly valid JS that every browser understands. Closure compiler, yuicompressor, packer, and jsmin all can properly minify it. There is no performance impact anywhere.
I am sorry that, instead of educating you, the leaders in this language community have given you lies and fear. That was shameful. I recommend learning how statements in JS are actually terminated (and in which cases they are not terminated), so that you can write code that you find beautiful.
In general,
\nends a statement unless:
- The statement has an unclosed paren, array literal, or object literal or ends in some other way that is not a valid way to end a statement. (For instance, ending with
.or,.)- The line is
--or++(in which case it will decrement/increment the next token.)- It is a
for(),while(),do,if(), orelse, and there is no{- The next line starts with
[,(,+,*,/,-,,,., or some other binary operator that can only be found between two tokens in a single expression.The first is pretty obvious. Even JSLint is ok with
\nchars in JSON and parenthesized constructs, and withvarstatements that span multiple lines ending in,.The second is super weird. I’ve never seen a case (outside of these sorts of conversations) where you’d want to do write
i\n++\nj, but, point of fact, that’s parsed asi; ++j, noti++; j.The third is well understood, if generally despised.
if (x)\ny()is equivalent toif (x) { y() }. The construct doesn’t end until it reaches either a block, or a statement.
;is a valid JavaScript statement, soif(x);is equivalent toif(x){}or, “If x, do nothing.” This is more commonly applied to loops where the loop check also is the update function. Unusual, but not unheard of.The fourth is generally the fud-inducing “oh noes, you need semicolons!” case. But, as it turns out, it’s quite easy to prefix those lines with semicolons if you don’t mean them to be continuations of the previous line. For example, instead of this:
jsfoo(); [1,2,3].forEach(bar);you could do this:
jsfoo() ;[1,2,3].forEach(bar)The advantage is that the prefixes are easier to notice, once you are accustomed to never seeing lines starting with
(or[without semis.