2015-10-09 4 views
60

Sono interessato se ci sono dei limiti a quali tipi di valori possono essere impostati utilizzando const in JavaScript, in particolare le funzioni. È valido? Certo che funziona, ma è considerato una cattiva pratica per qualsiasi motivo?Uso corretto di const per la definizione di funzioni in JavaScript

const doSomething =() => { 
    ... 
} 

Tutte le funzioni devono essere definite in questo modo in ES6? Non sembra che questo sia accaduto, se è così.

Grazie per eventuali commenti!

+0

Lei sembra di chiedere multipla domande: 1) * "Mi interessa se ci sono dei limiti su quali tipi di valori possono essere impostati usando const in JavaScript" * No. 2) * "È valido?" * Sì. 3) * "è considerato negativo pratica per qualsiasi motivo "* Suppongo che non sia stato in giro abbastanza a lungo da poter dire qualcosa a riguardo, ma non vedo perché questa dovrebbe essere la pratica del pad. Non è molto diversa da' var doSomething = ; ' 4) * "Tutte le funzioni devono essere definite in questo modo in ES6 ? "* Sembra ingombrante per me. Mi piacciono le dichiarazioni di funzione. Ognuno di loro. –

+1

Il modo in cui lo vedo (opinione, non un fatto), ha senso se si desidera disabilitare la ridefinizione delle funzioni. Che sia sano di mente o che abbia qualche utilità funzionale, è discutibile. Se pensi che si adatti al tuo scenario d'uso, non penso * che qualcuno possa discutere la tua decisione e ritenerla una cattiva pratica. – Mjh

+2

Immagino che la domanda sia ciò che vuoi ottenere con 'const'. Vuoi impedire a te stesso di scavalcare la funzione? Immagino che tu sappia che il tuo codice non lo fa comunque. Vuoi esprimere l'intento di 'doSomething', cioè che detiene una funzione e non modifica il suo valore? Penso che le dichiarazioni di funzione comunichino chiaramente anche questo intento. Quindi, se hai bisogno di "protezione di runtime" da ignorare, provaci. Altrimenti non vedo molti benefici. Naturalmente se si usasse principalmente 'var foo = function() {};', userei 'const' invece di' var'. –

risposta

82

Non c'è alcun problema con quello che hai fatto, ma devi ricordare la differenza tra le dichiarazioni di funzione e le espressioni di funzione.

Una dichiarazione di funzione, cioè:

function doSomething() {} 

viene issata interamente all'inizio della portata (e come let e const sono blocco scope pure).

Ciò significa che il seguente funzionerà:

doSomething() // works! 
function doSomething() {} 

un'espressione di funzione, vale a dire:

[const | let | var] = function() {} (or() => 

è la creazione di una funzione anonima (function() {}) e la creazione di una variabile, e quindi l'assegnazione di quella funzione anonima a quella variabile.

Quindi le solite regole intorno a sollevamento variabile all'interno di un ambito - le variabili di blocco con ambito (let e const) non issare come undefined alla parte superiore del loro campo di applicazione del blocco.

Ciò significa:

if (true) { 
    doSomething() // will fail 
    const doSomething = function() {} 
} 

fallirà poiché doSomething non è definito. (Si lancerà una ReferenceError)

Se si decide di utilizzare gli var si ottiene il sollevamento della variabile, ma sarà inizializzato a undefined così quel blocco di codice di cui sopra ancora non funziona. (Questo getterà un TypeError dal doSomething non è una funzione al momento in cui viene chiamato)

Per quanto riguarda le pratiche standard, è necessario utilizzare sempre lo strumento adeguato per il lavoro.

Axel Rauschmayer ha un grande post su portata e sollevamento tra cui la semantica ES6: Variables and Scoping in ES6

+0

Vorrei solo aggiungere che es6 classi usa const internamente per proteggere il nome della classe da essere riassegnato all'interno della classe. – user2342460

-1

È davvero brutto farlo in questo modo, ma è certamente valido.

Dove lavoro ho progettato una classe di fabbrica semplice che accetta un oggetto parent e una serie di funzioni, quindi espone queste funzioni al genitore tramite getter utilizzando defineProperty.

Ha lo stesso effetto: una funzione non può essere modificata dopo che è stata definita, ma a mio parere sembra molto più pulita.

Il più importante è essere coerenti nel progetto. Riunisci i membri del tuo team e fai accordi chiari su come lo farai.

+1

MOLTO off-topic: non sarei sorpreso di vedere 'const function name() {}' in futuro per semplificare JS con altre lingue. –

+4

"È davvero brutto farlo in questo modo". Questa sintassi sta effettivamente guadagnando un po 'di trazione. Vedi, ad esempio, https://github.com/reactjs/redux/tree/master/examples/todos. – Izhaki

+0

Sì, lo sto facendo anche in questo modo per "pin" l'oscilloscopio, immagino che ci si stia solo abituando. –

-2

Stephan Bijzitter dice
© E 'piuttosto brutto a farlo in questo modo

const foo = (a, _foo, b) => _foo(a, a, b) 
 
const bar = (a, b, c) => (c - 1) ? bar((a * b), b, (c - 1)) : a 
 

 
alert(
 
    foo(3, bar, 4) 
 
)

davvero?

34

Sebbene l'utilizzo di const definire funzioni sembra un hack, ma si tratta con alcuni grandi vantaggi che lo rendono superiore (a mio parere)

  1. Rende la funzione immutabile, quindi non si fa devi preoccuparti che la funzione venga modificata da qualche altra parte di codice.

  2. È possibile utilizzare la sintassi della freccia grossa, che è più breve pulitore &.

  3. L'utilizzo delle funzioni di freccia si prende cura di this vincolante per l'utente.

esempio con function

// define a function 
 
function add(x, y) { return x + y; } 
 

 
// use it 
 
console.log(add(1, 2)); // 3 
 

 
// oops, someone mutated your function 
 
add = function (x, y) { return x - y; }; 
 

 
// now this is not what you expected 
 
console.log(add(1, 2)); // -1

stesso esempio con const

// define a function (wow! that is 8 chars shorter) 
 
const add = (x, y) => x + y; 
 

 
// use it 
 
console.log(add(1, 2)); // 3 
 

 
// someone tries to mutate the function 
 
add = (x, y) => x - y; // Uncaught TypeError: Assignment to constant variable. 
 
// the intruder fails and your function remains unchanged

+0

E puoi dichiarare due volte function function (x, y), ma non puoi dichiarare due volte const add = ... – TatianaP

+0

1. L'immutabilità è un vantaggio reale, ma è molto raro che qualcuno in realtà sovrascriva una funzione. 2. La sintassi della freccia grassa non è più breve a meno che la tua funzione non sia un'espressione. 'function f (x, y) {' è di 18 caratteri, 'const f = (x, y) => {' ha 21 caratteri, quindi 3 caratteri più lunghi. 3. Mantenere questo legame conta solo se le funzioni sono definite all'interno di un metodo (o altre funzioni che lo hanno significativo). Lo script di livello superiore non ha senso. Non sto dicendo che ti sbagli, solo che i motivi che hai menzionato non sono molto rilevanti. – Nakedible

0

C'è un altro scenario in cui una funzione costante potrebbe essere utile. Se hai un sacco di costanti nel codice e hanno bisogno di una funzione che opera in particolare su queste costanti, potrebbe essere una buona idea di trasformare questa funzione in una stessa costante:

const FLAG_ONE = 1; 
const FLAG_TWO = 2; 
const FLAG_THREE = 4; 
// etc. 

// resolves flag into string for debugging purposes: 
const FLAG_NAME = flag => { 
    switch (flag) { 
     case FLAG_ONE: return 'one'; 
     // etc. 
    } 
}; 

Non è necessaria in alcun modo per definire FLAG_NAME come costante, ma migliorerà la leggibilità del tuo codice per farlo.

3

Ci sono alcuni vantaggi molto importanti per l'uso di const e alcuni direbbero che dovrebbe essere usato ovunque possibile a causa di quanto sia intenzionale e indicativo.

È, per quanto posso dire, la dichiarazione più indicativa e prevedibile delle variabili in Javascript, e una delle più utili, PERCHÉ di quanto sia limitato. Perché? Perché elimina alcune possibilità disponibili per var e lascia le dichiarazioni.

Cosa puoi dedurre quando leggi un 'const'? Conoscete tutto ciò che segue solo leggendo la dichiarazione di const, AND senza ricercare altri riferimenti a quella variabile: il valore è legato a quella variabile (sebbene il suo oggetto sottostante non sia profondamente immutabile); non è possibile accedervi al di fuori del suo blocco immediatamente contenente; e il binding non è mai accessibile prima della dichiarazione, a causa delle regole della Zona Morta Temporale (TDZ).

Da un articolo sostenendo i benefici del let e const, e anche risponde più direttamente le tue domande su della parola chiave vincoli/limiti:

"Vincoli, come quelli offerti da lasciare e const sono un potente mezzo per fare codice più facile da capire: cerca di accumulare quanti più limiti possibili nel codice che scrivi. Più vincoli dichiarativi che limitano ciò che un pezzo di codice potrebbe significare, più facile e veloce è per gli esseri umani leggere, analizzare e capire

Concesso, ci sono più regole per una dichiarazione const rispetto a una dichiarazione var: a scope, TDZ, assign at declaration, no re assegnazione. Mentre le istruzioni var segnalano solo lo scope delle funzioni. Il conteggio delle regole, tuttavia, non offre molte informazioni. È meglio valutare queste regole in termini di complessità: la regola aggiunge o sottrae complessità? Nel caso di const, scope scope significa un ambito più ristretto rispetto all'ambito della funzione, TDZ significa che non è necessario analizzare l'ambito indietro dalla dichiarazione per individuare l'utilizzo prima della dichiarazione e le regole di assegnazione significano che il binding conserverà sempre lo stesso riferimento.

Più dichiarazioni vincolate, più semplice diventa una parte di codice. Quando aggiungiamo dei vincoli a ciò che potrebbe significare una dichiarazione, il codice diventa meno imprevedibile. Questo è uno dei principali motivi per cui i programmi con tipizzazione statica sono generalmente più facili da leggere rispetto a quelli tipizzati dinamicamente. La tipizzazione statica pone un grosso limite allo scrittore del programma, ma pone anche un grosso limite su come interpretare il programma, rendendo più comprensibile il suo codice.

Con questi argomenti in mente, si consiglia di utilizzare const, se possibile, in quanto è l'affermazione che ci dà meno possibilità di pensare "

Fonte:. https://ponyfoo.com/articles/var-let-const