La differenza tra (1,eval)e plain old evalè che il primo è un valore e il secondo è un lvalue. Sarebbe più ovvio se fosse qualche altro identificatore:
var x;
x = 1;
(1, x) = 1;
Questa è (1,eval)un'espressione che produce eval(proprio come dire, (true && eval)o (0 ? 0 : eval)sarebbe), ma non è un riferimento a eval.
Perché ti interessi?
Ebbene, il Ecma spec considera un riferimento ad evalessere una "chiamata eval diretta", ma un'espressione che semplicemente cede evalad essere uno indiretto - e le chiamate eval indiretti sono garantiti da eseguire in ambito globale.
Cose che ancora non so:
- In quali circostanze una chiamata eval diretta non viene eseguita in ambito globale?
- In quale circostanza il
thisdi una funzione a ambito globale non può produrre l'oggetto globale?
Ulteriori informazioni possono essere raccolte qui .
MODIFICARE
Apparentemente, la risposta alla mia prima domanda è "quasi sempre". Un direct evalviene eseguito dall'ambito corrente . Considera il codice seguente:
var x = 'outer';
(function() {
var x = 'inner';
eval('console.log("direct call: " + x)');
(1,eval)('console.log("indirect call: " + x)');
})();
Non sorprende (heh-heh), questo stampa:
direct call: inner
indirect call: outer
MODIFICARE
Dopo ulteriori esperimenti, dirò provvisoriamente che thisnon può essere impostato su nullo undefined. Può essere impostato su altri valori falsi (0, ", NaN, false), ma solo molto deliberatamente.
Dirò che la tua fonte soffre di una lieve e reversibile inversione cranio-rettale e potresti prendere in considerazione l'idea di trascorrere una settimana a programmare ad Haskell.