Secondo MDN:
Un'espressione è qualsiasi unità valida di codice che possa avere un valore.
Come tale, qualsiasi cosa che può essere utilizzata come valore di rvalore è un'espressione.
Il criterio è non se esistono effetti collaterali. Le espressioni possono sicuramente avere effetti collaterali. Per esempio. a=2
è un'espressione in quanto ha un valore (2) e assegna anche un valore a una variabile. Quale è il motivo per cui si possono fare cose come:
let a;
let b = 1 + (a = 2); // a is now 2 and b is 3
E 'possibile che lo stesso (testualmente) blocco di codice da considerare sia l'espressione e una dichiarazione in base al contesto. Per esempio. il frammento di testo function f(){}
è un'espressione sulla linea 1 e una dichiarazione in linea 2 nel seguente codice:
let g = function f() {};
function f() {};
Quindi, se qualcosa è un'espressione o di una dichiarazione non può (nel caso generale) essere pronunciata cercando in un pezzo di codice testuale fuori dal contesto; piuttosto è una proprietà di un nodo in un albero di sintassi e può essere pronunciata solo dopo che il codice è stato analizzato (mentalmente o effettivamente).
Inoltre, e forse ancora più importante, le istruzioni di funzione (a.k.a dichiarazioni di funzioni) all'interno di una funzione f
fanno parte del contesto di esecuzione che viene creato quando viene richiamata la funzione f
. Tuttavia, le espressioni di funzione non fanno parte del contesto di esecuzione.
Un effetto spesso citato di questo è che le dichiarazioni di funzione vengono "issate" mentre le espressioni di funzione no.
Un effetto più sottile può anche essere osservato sperimentalmente in ricorsioni profonde dato che le istruzioni di funzione occupano spazio nel contesto di esecuzione mentre le espressioni di funzione no. Per esempio. il codice seguente utilizza la ricorsione infinita di una funzione f
. Funzione f
nel primo caso include una funzione di espressione al suo interno, nel secondo caso esso include la dichiarazione equivalente funzione di:
// Function Expression
{
let i = 0;
try {
function f() {
i++;
(function g() {})(); // this is an expression
f();
}
f();
} catch (err) {
console.log(`Function Expressions case: depth of ${i} reached. Error: ${err.name}`);
}
}
// Function Declaration
{
let i = 0;
try {
function f() {
i++;
function g() {}; // this is a statement
g();
f();
}
f();
} catch (err) {
console.log(`Functions Declarations case: depth of ${i} reached. Error: ${err.name}`);
}
}
Sulla mia macchina ho sempre ottenere il seguente (in node.js):
Function Expressions case: depth of 17687 reached. Error: RangeError
Functions Declarations case: depth of 15476 reached. Error: RangeError
& hellip; che è coerente con il fatto che le dichiarazioni di funzione aumentano la quantità di spazio necessaria per contenere un contesto di esecuzione e quindi consumano lo spazio dello stack un po 'più velocemente e quindi riducono leggermente la profondità massima di ricorsione.
Il fatto che si può 'eval'uate codice JS mi fa pensare che tutte le dichiarazioni sono espressioni di JS –