JavaScript Standard Style
English • Español (Latinoamérica) • Français • Bahasa Indonesia • Italiano (Italian) • 日本語 (Japanese) • 한국어 (Korean) • Português (Brasil) • 简体中文 (Simplified Chinese) • 繁體中文 (Taiwanese Mandarin)
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.
Regole
-
Usa due spazi per indentare.
eslint:
indentfunction hello (name) { console.log('hi', name) } -
Usa il singolo apostrofo per le stringhe tranne per evitare l'escaping.
eslint:
quotesconsole.log('hello there') $("<div class='box'>") -
Niente variabili inutilizzate.
eslint:
no-unused-varsfunction myFunction () { var result = something() // ✗ evita } -
Aggiungi uno spazio dopo le parole chiave.
eslint:
keyword-spacingif (condition) { ... } // ✓ ok if(condition) { ... } // ✗ evita -
Aggiungi uno spazio prima delle parenti di una dichiarazione di una funzione.
eslint:
space-before-function-parenfunction name (arg) { ... } // ✓ ok function name(arg) { ... } // ✗ evita run(function () { ... }) // ✓ ok run(function() { ... }) // ✗ evita -
Usa sempree
===invece di==.
Eccezione:obj == nullè consentito per controllarenull || undefined.eslint:
eqeqeqif (name === 'John') // ✓ ok if (name == 'John') // ✗ evitaif (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
errcome 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,consoleenavigator.eslint:
no-undefwindow.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`](http://eslint.org/docs/rules/operator-linebreak)
```js
// ✓ 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-spacingfunction foo () {return true} // ✗ evita function foo () { return true } // ✓ ok -
Utilizza il camelcase per i nomi delle variabili e funzioni.
eslint:
camelcasefunction my_function () { } // ✗ evita function myFunction () { } // ✓ ok var my_var = 'hello' // ✗ evita var myVar = 'hello' // ✓ ok -
I trailing comma non sono ammessi.
eslint:
comma-danglevar obj = { message: 'hello', // ✗ evita } -
The virgole devono essere messe alla fine della riga corrente
eslint:
comma-stylevar obj = { foo: 'foo' ,bar: 'bar' // ✗ avoid } var obj = { foo: 'foo', bar: 'bar' // ✓ ok } -
Il punto deve essere sulla stessa linea della proprietà.
eslint:
dot-locationconsole. 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-spacingconsole.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-spacingvar 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-capfunction 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-parensfunction Animal () {} var dog = new Animal // ✗ avoid var dog = new Animal() // ✓ ok -
Gli oggetti devono un getter quando un settere viene definito.
eslint:
accessor-pairsvar 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-superclass Dog { constructor () { super() // ✗ avoid } } class Dog extends Mammal { constructor () { super() // ✓ ok } } -
Usa gli array literals invece dei costruttori.
eslint:
no-array-constructorvar nums = new Array(1, 2, 3) // ✗ avoid var nums = [1, 2, 3] // ✓ ok -
Evita l'utilizzo di
arguments.calleeearguments.caller.eslint:
no-callerfunction 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-assignclass Dog {} Dog = 'Fido' // ✗ avoid -
Evita di modificare il varole di una variabile dichiarata usando
const.eslint:
no-const-assignconst score = 100 score = 125 // ✗ avoid -
Evita l'uso delle espressioni costanti all'interno delle condizioni (eccezione fatta per i cicli).
eslint:
no-constant-conditionif (false) { // ✗ avoid // ... } if (x === 0) { // ✓ ok // ... } while (true) { // ✓ ok // ... } -
No controllo dei caratteri nelle espressioni regolari.
eslint:
no-control-regexvar pattern = /\x1f/ // ✗ avoid var pattern = /\x20/ // ✓ ok -
No
debuggernel codice.eslint:
no-debuggerfunction sum (a, b) { debugger // ✗ avoid return a + b } -
Non usare
deletesulle variabili.eslint:
no-delete-varvar name delete name // ✗ avoid -
No argomenti doppi all'interno della definizione di una funzione.
eslint:
no-dupe-argsfunction sum (a, b, a) { // ✗ avoid // ... } function sum (a, b, c) { // ✓ ok // ... } -
No nomi doppi all'interno di una classe.
eslint:
no-dupe-class-membersclass Dog { bark () {} bark () {} // ✗ avoid } -
Non è possibile dichiarare chiavi doppie degli oggetti literals.
eslint:
no-dupe-keysvar user = { name: 'Jane Doe', name: 'John Doe' // ✗ avoid } -
Non è possibile dichiarare due
caseche controllano lo stesso valore all'interno di unoswitcheslint:
no-duplicate-caseswitch (id) { case 1: // ... case 1: // ✗ avoid } -
Utilizza un solo import per module.
eslint:
no-duplicate-importsimport { 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-classconst myRegex = /^abc[]/ // ✗ avoid const myRegex = /^abc[a-z]/ // ✓ ok -
Non è possibile usare il destructuring vuoto
eslint:
no-empty-patternconst { a: {} } = foo // ✗ avoid const { a: { b } } = foo // ✓ ok -
No all'uso di
eval().eslint:
no-evaleval( "var result = user." + propName ) // ✗ avoid var result = user[propName] // ✓ ok -
No all reassegnamento delle eccezioni all'interno di blocchi
catch.eslint:
no-ex-assigntry { // ... } catch (e) { e = 'new value' // ✗ avoid } try { // ... } catch (e) { const newVal = 'new value' // ✓ ok } -
Non è possibile estendere oggetti nativi.
eslint:
no-extend-nativeObject.prototype.age = 21 // ✗ avoid -
Evita il binding non necessari.
eslint:
no-extra-bindconst 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-castconst result = true if (!!result) { // ✗ avoid // ... } const result = true if (result) { // ✓ ok // ... } -
No parentesi non necessarie intorno alle funzioni.
eslint:
no-extra-parensconst myFunc = (function () { }) // ✗ avoid const myFunc = function () { } // ✓ ok -
Utilizza il
breakper evitare l'esecuzioni dei successivicaseall'interno di un bloccoswitch.eslint:
no-fallthroughswitch (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-decimalconst discount = .5 // ✗ avoid const discount = 0.5 // ✓ ok -
Evita la riassegnazione di una funzione dichiarata.
eslint:
no-func-assignfunction myFunc () { } myFunc = myOtherFunc // ✗ avoid -
Evita la riassegnazione di oggetti che possono essere solo letti.
eslint:
no-global-assignwindow = {} // ✗ avoid -
No agli
eval()sottointesi.eslint:
no-implied-evalsetTimeout("alert('Hello world')") // ✗ avoid setTimeout(function () { alert('Hello world') }) // ✓ ok -
No alla dichiarazione di funzioni all'interno di blocchi innestati.
eslint:
no-inner-declarationsif (authenticated) { function setAuthUser () {} // ✗ avoid } -
No a stringhe di expressioni regolari invalide all'interno dei costruttori
RegExp.eslint:
no-invalid-regexpRegExp('[a-z') // ✗ avoid RegExp('[a-z]') // ✓ ok -
No a spazi irregolari.
eslint:
no-irregular-whitespacefunction myFunc () /*<NBSP>*/{} // ✗ avoid -
No all'uso di
__iterator__.eslint:
no-iteratorFoo.prototype.__iterator__ = function () {} // ✗ avoid -
No a etichette che condividono lo stesso nome di una variabile all'interno dello stesso scope.
eslint:
no-label-varvar score = 100 function game () { score: while (true) { // ✗ avoid score -= 10 if (score > 0) continue score break } } -
No al blocco label.
eslint:
no-labelslabel: while (true) { break label // ✗ avoid } -
No a blocchi non necessari.
eslint:
no-lone-blocksfunction 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-spacesconst id = 1234 // ✗ avoid const id = 1234 // ✓ ok -
No a stringhe su più linee.
eslint:
no-multi-strconst message = 'Hello \ world' // ✗ avoid -
No all'uso del
newsenza l'assegnazione ad una variabile.eslint:
no-newnew Character() // ✗ avoid const character = new Character() // ✓ ok -
No all'uso del costruttore
Function.eslint:
no-new-funcvar sum = new Function('a', 'b', 'return a + b') // ✗ avoid -
No all'uso del costruttore
Object.eslint:
no-new-objectlet config = new Object() // ✗ avoid -
No all'uso di
new require.eslint:
no-new-requireconst myModule = new require('my-module') // ✗ avoid -
No all'uso del costruttore
Symbol.eslint:
no-new-symbolconst foo = new Symbol('foo') // ✗ avoid -
No all'uso di istanze di primitive.
eslint:
no-new-wrappersconst message = new String('hello') // ✗ avoid -
Non chiamare le proprietà di oggetti globali come funzioni.
eslint:
no-obj-callsconst math = Math() // ✗ avoid -
No agli ottali literals.
eslint:
no-octalconst octal = 042 // ✗ avoid const decimal = 34 // ✓ ok const octalString = '042' // ✓ ok -
No all'escape di sequenze di ottali nelle stringhe letterali.
eslint:
no-octal-escapeconst copyright = 'Copyright \251' // ✗ avoid -
Evita la concatenazione di strighe quando si usano
__dirnamee__filename.eslint:
no-path-concatconst pathToFile = __dirname + '/app.js' // ✗ avoid const pathToFile = path.join(__dirname, 'app.js') // ✓ ok -
Evita l'uso di
__proto__. Usa invecegetPrototypeOf.eslint:
no-protoconst foo = obj.__proto__ // ✗ avoid const foo = Object.getPrototypeOf(obj) // ✓ ok -
No alla ridichiarazione di variabili.
eslint:
no-redeclarelet name = 'John' let name = 'Jane' // ✗ avoid let name = 'John' name = 'Jane' // ✓ ok -
Evita spazi multipli all'interno di espressioni regolari literals.
eslint:
no-regex-spacesconst regexp = /test value/ // ✗ avoid const regexp = /test {3}value/ // ✓ ok const regexp = /test value/ // ✓ ok -
Gli assegnamenti nei blocchi
returndevono essere circondati da parentesi .eslint:
no-return-assignfunction 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-assignname = name // ✗ avoid -
Evita di confrontare una variabile con se stessa.
eslint:
no-self-compareif (score === score) {} // ✗ avoid -
Evita l'uso della virgola come operatore.
eslint:
no-sequencesif (doSomething(), !!test) {} // ✗ avoid -
Nomi protetti non possono essere reassegnati (shadowing).
eslint:
no-shadow-restricted-nameslet undefined = 'value' // ✗ avoid -
Array sparsi non sono consentiti.
eslint:
no-sparse-arrayslet 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-stringconst message = 'Hello ${name}' // ✗ avoid const message = `Hello ${name}` // ✓ ok -
super()deve essere chiamato prima dithis.eslint:
no-this-before-superclass Dog extends Animal { constructor () { this.legs = 4 // ✗ avoid super() } } -
Puoi usare
throwsolo su un oggettoError.eslint:
no-throw-literalthrow 'error' // ✗ avoid throw new Error('error') // ✓ ok -
Spazi bianchi banditi alla fine di una linea.
eslint:
no-trailing-spaces -
Inizializzare con
undefinednon è consentito.eslint:
no-undef-initlet name = undefined // ✗ avoid let name name = 'value' // ✓ ok -
No alla non-modifica delle condizioni all'interno dei cicli.
eslint:
no-unmodified-loop-conditionfor (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-ternarylet score = val ? val : 0 // ✗ avoid let score = val || 0 // ✓ ok -
No a codice non eseguibile dopo l'uso di
return,throw,continue, ebreak.eslint:
no-unreachablefunction doSomething () { return true console.log('never called') // ✗ avoid } -
No a controlli di flusso all'interno di blocchi
finally.eslint:
no-unsafe-finallytry { // ... } catch (e) { // ... } finally { return 42 // ✗ avoid } -
L'operando sinistro di una operazione relazionale non può essere negato.
eslint:
no-unsafe-negationif (!key in obj) {} // ✗ avoid -
Evita l'uso non necessario di
.call()e.apply().eslint:
no-useless-callsum.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-keyconst user = { ['name']: 'John Doe' } // ✗ avoid const user = { name: 'John Doe' } // ✓ ok -
No all'uso non necessario di costruttori.
eslint:
no-useless-constructorclass Car { constructor () { // ✗ avoid } } -
No all'uso non necessario degli escape.
eslint:
no-useless-escapelet message = 'Hell\o' // ✗ avoid -
Rinominare l'assegnamento di import, export, e destrutturazione (destructuring) usano lo stesso nome non è consentito.
eslint:
no-useless-renameimport { config as config } from './config' // ✗ avoid import { config } from './config' // ✓ ok -
No spazi prima di una proprietà
eslint:
no-whitespace-before-propertyuser .name // ✗ avoid user.name // ✓ ok -
No all'uso di
with.eslint:
no-withwith (val) {...} // ✗ avoid -
Mantere consistenza di nuove righe all'interno delle proprietà di un oggetto.
eslint:
object-property-newlineconst 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-blocksif (user) { // ✗ avoid const name = getName() } if (user) { const name = getName() // ✓ ok } -
No spazi tra l'operatore spread e la loro espressione.
eslint:
rest-spread-spacingfn(... args) // ✗ avoid fn(...args) // ✓ ok -
Le virgole devono avere uno spazio dopo e non prima.
eslint:
semi-spacingfor (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-blocksif (admin){...} // ✗ avoid if (admin) {...} // ✓ ok -
No spazi all'interno delle parentesi
eslint:
space-in-parensgetName( name ) // ✗ avoid getName(name) // ✓ ok -
Uso dello spazio dopo l'uso di un operatore unario.
eslint:
space-unary-opstypeof!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-spacingconst message = `Hello, ${ name }` // ✗ avoid const message = `Hello, ${name}` // ✓ ok -
Usa
IsNaN()quando controlliNaN.eslint:
use-isnanif (price === NaN) { } // ✗ avoid if (isNaN(price)) { } // ✓ ok -
typeofdeve essere comparato con una stringa valida.eslint:
valid-typeoftypeof name === 'undefimed' // ✗ avoid typeof name === 'undefined' // ✓ ok -
Espressioni di funzioni immediatamente invocate (IIFEs - Immediately Invoked Function Expressions) devono essere circondate da parentesi.
eslint:
wrap-iifeconst getName = function () { }() // ✗ avoid const getName = (function () { }()) // ✓ ok const getName = (function () { })() // ✓ ok -
Mettere uno spazio prima e dopo
*dentro le espressioniyield*.eslint:
yield-star-spacingyield* increment() // ✗ avoid yield * increment() // ✓ ok -
Evitare condizioni Yoda.
eslint:
yodaif (42 === age) { } // ✗ avoid if (age === 42) { } // ✓ ok
Semicolons
-
No punti e virgola (semicolons). (see: 1, 2, 3)
eslint:
semiwindow.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. Estandardti 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)
Letture utili
- An Open Letter to JavaScript Leaders Regarding Semicolons
- JavaScript Semicolon Insertion – Everything you need to know
E un video utile:
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: 1. 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,.) 2. The line is--or++(in which case it will decrement/increment the next token.) 3. It is afor(),while(),do,if(), orelse, and there is no{4. 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:
foo(); [1,2,3].forEach(bar);you could do this:
foo() ;[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.