Cost in JavaScript: quando usarlo ed è necessario?


349

Di recente ho trovato la constparola chiave in JavaScript. Da quello che posso dire, è usato per creare variabili immutabili e ho testato per assicurarmi che non potesse essere ridefinito (in Node.js):

const x = 'const';
const x = 'not-const';

// Will give an error: 'constant 'x' has already been defined'

Mi rendo conto che non è ancora standardizzato su tutti i browser, ma sono interessato solo al contesto di Node.js V8 e ho notato che alcuni sviluppatori / progetti sembrano favorirlo fortemente quando la varparola chiave potrebbe essere utilizzata per il stesso effetto.

Quindi le mie domande sono:

  • Quando è appropriato utilizzare constal posto di var?
  • Dovrebbe essere usato ogni volta che viene dichiarata una variabile che non verrà riassegnata?
  • Fa davvero differenza se varviene usato al posto di consto viceversa?

1
Ciò non sembra essere ancora standardizzato (forse in EC6?). Ulteriori informazioni a riguardo sono disponibili qui: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Sebastien C.

1
Const ha prestazioni pessime anche se jsperf.com/const-vs-var-mod-3
Deepu

Risposte:


462

Ci sono due aspetti delle tue domande: quali sono gli aspetti tecnici dell'uso constanziché vare quali sono gli aspetti legati all'uomo nel farlo.

La differenza tecnica è significativa. Nei linguaggi compilati, una costante verrà sostituita al momento della compilazione e il suo utilizzo consentirà altre ottimizzazioni come la rimozione del codice morto per aumentare ulteriormente l'efficienza di runtime del codice. I motori JavaScript recenti (usati in modo approssimativo) in realtà compilano il codice JS per ottenere prestazioni migliori, quindi l'uso della parola chiave const li informerebbe che le ottimizzazioni sopra descritte sono possibili e dovrebbero essere fatte. Ciò si traduce in prestazioni migliori.

L'aspetto correlato all'uomo riguarda la semantica della parola chiave. Una variabile è una struttura di dati che contiene informazioni che dovrebbero cambiare. Una costante è una struttura di dati che contiene informazioni che non cambieranno mai. Se c'è spazio per l'errore, vardovrebbe sempre essere usato. Tuttavia, non tutte le informazioni che non cambiano mai nel corso della vita di un programma devono essere dichiarate const. Se, in circostanze diverse, le informazioni dovessero cambiare, utilizzare varper indicarlo, anche se la modifica effettiva non appare nel codice.


4
Saluti, ho ipotizzato che Mozilla / Google non avrebbero aggiunto il supporto const ai motori JS senza motivo. Mi assicurerò di usare const dove applicabile.
axdg,

6
constgli oggetti sembrano mutabili, quindi non sono sicuro di quanto sia rigoroso il compilatore JS. Forse anche la modalità "usa rigoroso" fa la differenza.
Rudie,

9
@Rudie La funzione che stai cercando si chiama congelamento dell'oggetto. constimpedisce solo di riassegnare la "variabile" a un altro valore. const a = {}; a = {};genererà un errore in modalità rigorosa.
Tibos,

Uso const in generale invece di lasciare la maggior parte delle variabili, proprio come in Java aggiungo final alla maggior parte delle dichiarazioni delle variabili.
codifica

2
If there is room for error, var should always be used. Oggi questo non si applica più, con strumenti come ESLint che indicano constsubito la violazione.
vitaly-t,

72

Aggiornamento 2017

Questa risposta riceve ancora molta attenzione. Vale la pena notare che questa risposta è stata pubblicata all'inizio del 2014 e da allora molte cose sono cambiate.il supporto è ora la norma. Tutti i browser moderni ora supportano, constquindi dovrebbe essere abbastanza sicuro da usare senza problemi.


Risposta originale del 2014

Pur avendo un supporto del browser abbastanza decente , per ora eviterei di usarlo. Da articolo di MDN onconst :

L'attuale implementazione di const è un'estensione specifica di Mozilla e non fa parte di ECMAScript 5. È supportata in Firefox e Chrome (V8). A partire da Safari 5.1.7 e Opera 12.00, se si definisce una variabile con const in questi browser, è comunque possibile modificarne il valore in un secondo momento. Non è supportato in Internet Explorer 6-10, ma è incluso in Internet Explorer 11. La parola chiave const attualmente dichiara la costante nell'ambito della funzione (come le variabili dichiarate con var).

Quindi continua dicendo:

constsarà definito da ECMAScript 6, ma con una semantica diversa. Analogamente alle variabili dichiarate con l'istruzione let, le costanti dichiarate con const saranno nell'ambito del blocco.

Se lo usi, constdovrai aggiungere una soluzione alternativa per supportare browser leggermente più vecchi.


6
Ottima risposta - anche se ho già letto l'articolo su MDN. Come ho detto, ero più interessato a sapere se V8 avrebbe effettivamente trattato const in modo diverso da var. Penso che @Tibos l'abbia chiarito.
axdg,

James grazie per aver sottolineato l'aspetto del supporto. imho tutte le risposte javascript dovrebbero includere una suddivisione del supporto del browser. ben spiegato
Hubson Bropa,

4
Nota ES6 ha ricevuto un blocco delle funzionalità nell'agosto 2014. Nel luglio 2015 lo standard è stato ufficialmente rilasciato. Se stai leggendo questo ora, significa che dovresti seguire la risposta accettata come indicato se il tuo codice è gestito da un motore aggiornato.
Filip Dupanović,

La domanda OP è specifica di node.js
Nicu Surdu,

@NicolaeSurdu certo. È anche da gennaio 2014, quindi è probabilmente per lo più ridondante ora nel 2017.
James Donnelly,

41

Perché usare const, la risposta di @ Tibos è fantastica.

Ma hai detto:

Da quello che posso dire, è usato per creare variabili immutabili

Questo è sbagliato . La mutazione di una variabile è diversa dalla riassegnazione:

var hello = 'world' // assigning
hello = 'bonjour!' // reassigning

Con const, non puoi farlo:

const hello = 'world'
hello = 'bonjour!' // error

Ma puoi mutare la tua variabile:

const marks = [92, 83]
marks.push(95)
console.log(marks) // [92, 83, 95] -> the variable has been mutated.

Quindi, qualsiasi processo che modifica il valore della variabile senza usare il =segno sta mutando la variabile.

Nota: +=ad esempio è ... riassegnare!

var a = 5
a += 2 // is the same as a = a + 2

Quindi, la linea di fondo è: constnon ti impedisce di mutare le variabili, ti impedisce di riassegnarle .


4
la tua affermazione "qualsiasi processo che modifica il valore della variabile senza utilizzare il =segno è muting" è tecnicamente errato. Ad esempio, const marks=[92,83]; marks[2]=95; console.log(marks)verrà emesso [92, 83, 95]. marksè stato modificato, tramite segno di uguale.
Chharvey,

5
"Ma hai detto: << Da quello che posso dire, è usato per creare variabili immutabili >> È sbagliato . La mutazione di una variabile è diversa dalla riassegnazione" No, non lo è. La riassegnazione sta mutando la variabile. Stai parlando di mutare l'oggetto a cui fa riferimento il riferimento nella variabile. Questa è una cosa completamente diversa.
TJ Crowder,

Sono arrivato perché sto cercando di capire constnel contesto degli array (simile all'esempio usato @chharvey). Nel caso del const countArray = countup(n - 1); countArray.push(n);l' constè ri-assegnato ogni volta. Quindi perché usare conste no var?
YCode

1
@YCode n. quando lo usi const countArray, non verrà mai riassegnato. Puoi comunque spingere verso l'array, che ne modifica i membri e la lunghezza, ma non lo chiamiamo riassegnazione. si utilizza al constposto di leto varquando si desidera impedire la riassegnazione. BTW se non desidera consentire la riassegnazione, letè quasi sempre meglio di var.
Chharvey,

@chharvey Grazie! La tua risposta mi ha portato a "passare per valore vs passare per riferimento", un nuovo concetto e uno strano - in cui la modifica del valore ≠ la riassegnazione. Chi avesse bisogno di ulteriori spiegazioni dovrebbe controllare le risposte qui: stackoverflow.com/q/46131828/5965865
YCode

38

Per integrare le risposte precedenti, esiste un evidente vantaggio nel dichiarare variabili costanti, a parte il motivo delle prestazioni: se si tenta di modificarle o di dichiararle nuovamente nel codice, il programma non modificherà il valore o genererà un errore.

Ad esempio, confronta:

// Will output 'SECRET'

const x = 'SECRET'
if (x = 'ANOTHER_SECRET') {  // Warning! assigning a value variable in an if condition
    console.log (x)
}

con:

// Will output 'ANOTHER_SECRET'

var y = 'SECRET'
if (y = 'ANOTHER_SECRET') { 
    console.log (y)
}

o

// Will throw TypeError: const 'x' has already been declared

const x = "SECRET"

/*  complex code */

var x = 0

con

// Will reassign y and cause trouble

var y = "SECRET"

/*  complex code */

var y = 0

Dovresti dire che questo comportamento "immutabile" è applicabile solo a stringhe, tipi di base. Utilizzando oggetti, matrici ecc. È possibile modificare i valori ma non è possibile riassegnare un nuovo "oggetto", ad es. Const a = ["a", "b"]; a = []; genererà un errore, altrimenti è possibile
Fer fino al

Dovresti avere un esempio in cui provi a cambiare anche il valore di una costante.
Joshua Pinter,

L'uso di const è molto simile ai modificatori di accesso, la vera immutabilità non è l'obiettivo.
StingyJack,

32

constnon è immutabile.

Dal MDN :

La dichiarazione const crea un riferimento di sola lettura a un valore. Non significa che il valore che detiene sia immutabile, ma solo che l'identificatore di variabile non può essere riassegnato.


24
Questo è un po 'fuorviante però. Per numeri, stringhe, booleani, ecc. (Primitivi) constè immutabile. Per oggetti e matrici non può essere riassegnato, ma il contenuto può essere modificato (ad es. Array.push).
Florian Wendelborn,

2
Tuttavia, i primitivi JS sono sempre immutabili. Se lo usi consto no, ciò non influisce su questo.
Me21,

1
@Dodekeract quindi non è immutabile per definizione. Se i valori possono cambiare non è immutabile, anche se funziona come immutabile per i primitivi che hai elencato
Anthony

13

var : dichiara una variabile, l'inizializzazione del valore è facoltativa.

let : dichiara una variabile locale con ambito di blocco.

const : dichiara una costante denominata di sola lettura.

Ex:

var a;
a = 1;
a = 2;//re-initialize possible
var a = 3;//re-declare
console.log(a);//3

let b;
b = 5;
b = 6;//re-initiliaze possible
// let b = 7; //re-declare not possible
console.log(b);

// const c;
// c = 9;   //initialization and declaration at same place
const c = 9;
// const c = 9;// re-declare and initialization is not possible
console.log(c);//9
// NOTE: Constants can be declared with uppercase or lowercase, but a common
// convention is to use all-uppercase letters.

10

Hai ottime risposte, ma manteniamolo semplice.

const dovrebbe essere usato quando hai una costante definita (leggi come: non cambierà durante l'esecuzione del tuo programma).

Per esempio:

const pi = 3.1415926535

Se ritieni che si tratti di qualcosa che potrebbe essere cambiato in un'esecuzione successiva, usa a var.

La differenza pratica, basata sull'esempio, è che con constte assumerai sempre che pi sarà 3.14 [...], è un dato di fatto.

Se lo definisci come a var, potrebbe essere 3,14 [...] o no.

Per una risposta più tecnica @Tibos ha ragione accademicamente.


7

Nella mia esperienza utilizzo const quando voglio impostare qualcosa che potrei voler cambiare in seguito senza dover cercare il codice alla ricerca di bit che sono stati hardcoded ad esempio un percorso di file o un nome di server.

L'errore nel tuo test è un'altra cosa, però, stai cercando di creare un'altra variabile chiamata x, questo sarebbe un test più accurato.

const x = 'const';
x = 'not-const';

9
Capisco cosa intendi, ma - è divertente che "costante" per te significhi "cosa che potrei voler cambiare". : P
Venryx,

4

Preferenza personale davvero. Puoi usare const quando, come dici tu, non verrà riassegnato ed è costante. Ad esempio se volevi assegnare il tuo compleanno. Il tuo compleanno non cambia mai, quindi puoi usarlo come costante. Ma la tua età cambia in modo che possa essere una variabile.


17
Sarebbe uno script molto lungo!
nullability

3
@nullability Dipende dall'età di quante persone stai monitorando. Più di qualche dozzina e lo script non dovrà funzionare a lungo :).
Millie Smith il

4

Sommario:

const crea un legame immutabile, il che significa che l'identificatore della variabile const non è riassegnabile.

const a = "value1";

non puoi riassegnarlo con

a = "value2";

Tuttavia, se l'identificatore const contiene un oggetto o un array, il suo valore può essere modificato nella misura in cui non lo stiamo riassegnando.

const x = { a: 1 }

x.a = 2; //is possible and allowed

const numbers = [1, 2];
numbers.push(3); //is possible and allowed

Si noti che const è un ambito con blocco proprio come let che non è uguale a var (che è con ambito funzione)

In breve, quando è improbabile che qualcosa cambi a seguito di una riassegnazione, usa const altrimenti usa let o var a seconda dell'ambito che desideri avere.

È molto più facile ragionare sul codice quando è ovvio cosa può essere cambiato attraverso la riassegnazione e cosa non può essere. Cambiare una const in una let è semplicissimo. E andare const di default ti fa pensare due volte prima di farlo. E questo è in molti casi una buona cosa.



2
Main point is that how to decide which one identifier should be used during development.
In java-script here are three identifiers.

1. var (Can re-declared & re-initialize)
2. const (Can't re-declared & re-initialize, can update array values by using push)
3. let (Can re-initialize but can't re-declare)

'var': Al momento della codifica quando parliamo di codice standard, di solito usiamo il nome dell'identificatore che è facilmente comprensibile da altri utenti / sviluppatori. Ad esempio, se stiamo lavorando, abbiamo pensato a molte funzioni in cui utilizziamo alcuni input ed elaboriamo questo e restituiamo alcuni risultati, come:

**Example of variable use**

function firstFunction(input1,input2)
{
 var process = input1 + 2; 
 var result = process - input2;
 return result;
}


function otherFunction(input1,input2)
{
 var process = input1 + 8; 
 var result = process * input2;
 return result;
}

Negli esempi precedenti entrambe le funzioni producono risultati 2 diversi ma utilizzano lo stesso nome di variabili. Qui possiamo vedere 'processo' e 'risultato' entrambi sono usati come variabili e dovrebbero esserlo.

 **Example of constant with variable**

 const tax = 10; 
 const pi = 3.1415926535; 

function firstFunction(input1,input2)
{
 var process = input1 + 2; 
 var result = process - input2;
 result = (result * tax)/100; 
 return result;
}


function otherFunction(input1,input2)
{
 var process = input1 + 8; 
 var result = process * input2 * pi;
 return result;
}

Prima di usare 'let' in java-script dobbiamo aggiungere 'use strict' nella parte superiore del file js

 **Example of let with constant & variable**

 const tax = 10; 
 const pi = 3.1415926535; 
 let trackExecution = '';

function firstFunction(input1,input2)
{
 trackExecution += 'On firstFunction'; 
 var process = input1 + 2; 
 var result = process - input2;
 result = (result * tax)/100; 
 return result;
}


function otherFunction(input1,input2)
{
 trackExecution += 'On otherFunction'; # can add current time 
 var process = input1 + 8; 
 var result = process * input2 * pi;
 return result;
}

 firstFunction();
 otherFunction();
 console.log(trackExecution);

Nell'esempio sopra è possibile tenere traccia di quale funzione è stata eseguita quando e quale funzione non è stata utilizzata durante un'azione specifica.


1

Innanzitutto, tre cose utili su const(oltre ai miglioramenti dell'ambito con cui condivide let):

  • Documenta per le persone che leggono il codice in seguito che il valore non deve cambiare.
  • Impedisce a te (o a chiunque ti insegua) di modificare il valore a meno che non torni indietro e cambi intenzionalmente la dichiarazione.
  • Si potrebbe salvare il motore JavaScript alcune analisi in termini di ottimizzazione. Ad esempio, hai dichiarato che il valore non può cambiare, quindi il motore non deve fare alcun lavoro per capire se il valore cambia in modo da poter decidere se ottimizzare in base al valore che non cambia.

Le tue domande:

Quando è appropriato utilizzare constal posto di var?

È possibile farlo in qualsiasi momento si sta dichiarando una variabile il cui valore non cambia mai. Il fatto che tu lo ritenga appropriato dipende interamente dalle tue preferenze / preferenze del tuo team.

Dovrebbe essere usato ogni volta che viene dichiarata una variabile che non verrà riassegnata?

Dipende da te / dalla tua squadra.

Fa davvero differenza se var is used in place ofconst` o viceversa?

Sì:

  • vare consthanno regole di ambito diverse. (Forse avresti voluto confrontarti con letpiuttosto che con var.) In particolare: conste letsono a ambito di blocco e, se utilizzati in ambito globale, non creano proprietà sull'oggetto globale (anche se creano globali). varha un ambito globale (se utilizzato in ambito globale) o un ambito funzione (anche se utilizzato in un blocco) e, se utilizzato in ambito globale, crea una proprietà sull'oggetto globale.
  • Vedi le mie "tre cose utili" sopra, si applicano tutte a questa domanda.

1

La semantica di varelet

vare letsono una dichiarazione alla macchina e ad altri programmatori:

Intendo che il valore di questo incarico cambi nel corso dell'esecuzione. Non fare affidamento sul valore finale di questa assegnazione.

Implicazioni dell'uso di varelet

vare letcostringere gli altri programmatori a leggere tutto il codice che intercorre tra la dichiarazione e l'uso finale, e ragionare sul valore dell'assegnazione in quel punto nell'esecuzione del programma.

Esse indeboliscono il ragionamento automatico per ESLint e altri servizi linguistici per rilevare correttamente i nomi delle variabili erroneamente assegnati nelle assegnazioni successive e il riutilizzo dell'ambito dei nomi delle variabili dell'ambito esterno in cui l'ambito interno dimentica di dichiarare.

Inoltre, fanno sì che i runtime eseguano molte iterazioni su tutti i codepati per rilevare che sono effettivamente, in effetti, costanti, prima che possano ottimizzarli. Anche se questo è meno un problema del rilevamento dei bug e della comprensibilità degli sviluppatori.

Quando usare const

Se il valore del riferimento non cambia nel corso dell'esecuzione, la sintassi corretta per esprimere l'intenzione del programmatore è const. Per gli oggetti, cambiare il valore del riferimento significa indicare un altro oggetto, poiché il riferimento è immutabile, ma l'oggetto no.

" const" oggetti

Per i riferimenti a oggetti, il puntatore non può essere modificato in un altro oggetto, ma l'oggetto che viene creato e assegnato a una constdichiarazione è mutabile. È possibile aggiungere o rimuovere elementi da un constarray referenziato e mutare le chiavi delle proprietà su un constoggetto referenziato.

Per ottenere oggetti immutabili (che ancora una volta, rendono più facile ragionare il tuo codice per esseri umani e macchine), puoi Object.freezel'oggetto alla dichiarazione / assegnazione / creazione, come questo:

const Options = Object.freeze(['YES', 'NO'])

Object.freeze ha un impatto sulle prestazioni, ma il codice è probabilmente lento per altri motivi. Vuoi profilarlo.

È inoltre possibile incapsulare l'oggetto mutabile in una macchina a stati e restituire copie profonde come valori (è così che funzionano gli stati Redux e React). Vedi Come evitare lo stato globale mutabile in Browser JS per un esempio di come costruire questo dai primi principi.

Quando vare letsono una buona partita

lete varrappresentano lo stato mutabile. A mio avviso, dovrebbero essere usati solo per modellare lo stato mutabile reale . Cose come " la connessione è viva? ".

Questi sono meglio incapsulati in macchine a stati verificabili che espongono valori costanti che rappresentano " lo stato corrente della connessione ", che è una costante in qualsiasi momento nel tempo e ciò a cui il resto del codice è effettivamente interessato.

La programmazione è già abbastanza difficile con la composizione di effetti collaterali e la trasformazione dei dati. Trasformando ogni funzione in una macchina a stati non verificabile creando uno stato mutabile con variabili che si accumulano solo sulla complessità.

Per una spiegazione più sfumata, vedi Shun the Mutant - The case forconst .



0

Non sono un esperto nel settore della compilazione JS, ma ha senso dire che v8 si serve del flag const

Normalmente dopo aver dichiarato e modificato un gruppo di variabili, la memoria viene frammentata e v8 si interrompe nell'esecuzione, fa una pausa di qualche secondo per fare gc o garbage collection.

se una variabile viene dichiarata con const v8, si può essere sicuri di metterla in un contenitore a dimensione fissa tra altre variabili const, poiché non cambierà mai. Può anche salvare le operazioni appropriate per quei tipi di dati poiché il tipo non cambierà.


0

Quando si tratta di decidere tra let e const , preferire sempre const in modo che l'uso sia chiaro nel codice. In questo modo, se provi a dichiarare nuovamente la variabile, otterrai un errore. Se non c'è altra scelta che rideclarla, passa a let . Si noti che, come dice Anthony , i valori non sono immutabili (ad esempio, un oggetto const può avere proprietà mutate).

Quando si tratta di var , dato che ES6 è uscito, non l'ho mai usato nel codice di produzione e non riesco a pensare a un caso d'uso. Tuttavia, attenzione che le variabili dichiarate con var non hanno ambito di blocco.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.