Schrödinger kódja

Eredetileg ide egy elemzést írtam arról, hogy ebben a kommentben felvetett JavaScript kifejezések miért adnak furcsa eredményeket, de persicsb írt egy jobbat.

Viszont a 4. kifejezés nem egyértelmű, Chrome konzolja szerint '[object Object][object Object]' az eredmény, a Wat talk szerint NaN. Repl.it-ben kipróbálva már Chrome-ban is NaN az eredmény.

Szerintem a 3-as és 4-es kifejezésekben az elülső kapcsos zárójelek nem egy object literált, hanem egy kódblokkot jelölnek, ez megmagyarázza a kifejezések eredményét. Csakhogy van egy probléma: amint megpróbáljuk a kifejezést valaminek értékül adni, a szabályok megváltoznak, és az elülső zárójel pár is object literálként értelmeződik. Vagyis lehetetlen megjeleníteni a kifejezés eredményét. Ezért ezt a kódot ünnepélyesen elnevezem Schrödinger kódjának. :)

Akinek van ötlete, hogy a repl.it hogy csinálja, ne tartsa magában.

Szerk: na jó, rájöttem:

eval('{} + {}')

Hozzászólások

Miért magyarázná meg?

A kódblokk + kódblokk alakú kifejezés nem értelmezhető sehogysem, az parse error.

Hasonlóan a kódblokk + tömb sem.

Az "[object Object][object Object]" valóban a helyes eredmény, a NaN hülyeség, implementációs hiba.
Még akkor is, ha eval-ban van.

Szerintem a {} + [] implementációja is rossz, annak "[object Object]"-nek kéne lennie, nem pedig 0-nak.


function f() {
 return {} + {};
}

function g() {
 return {} + [];
}
var a = f();
var b = g();

a értéke helyesen "[object Object][object Object]" lesz, b értéke pedig megint csak helyesen "[object Object]".

Szóval itt igazából maga az eval() a ludas. És itt viszont bejön a parser működése, mert ugyebár az eval a paraméterében megkapott stringet parzolja mint Program
http://www.ecma-international.org/ecma-262/5.1/index.html#sec-15.1.2.1

A Program:
http://www.ecma-international.org/ecma-262/5.1/index.html#sec-14
Ez ugyebár Statementekből áll.
A Statement pedig lehet Block és Expression is.
http://www.ecma-international.org/ecma-262/5.1/index.html#sec-12

Viszont: "An ExpressionStatement cannot start with an opening curly brace because that might make it ambiguous with a Block."

Azaz így már egyértelmű, hogy {} + {} micsoda: attól függ, hogy Programként vagy értékkifejezésként tekintünk rá.

Azaz eval()-ban hajtatjuk végre, vagy mint blokk belsejében kifejezésként értékeljük ki.

Valóban. Viszont a kérdés fennáll: hogyan kéne működnie a Chrome konzolnak?

REPL-ként, minden kifejezést eval()-on keresztülküldve? Mert akkor a {} + {} valóban NaN kéne, hogy legyen Chrome-ban is.

És a kérdés azért nem éppen lényegtelen: a Chrome-ot (és a DevTools) rendkívül sokan használják fejlesztésre. Talán az elsődleges webes debug platform. Baromira nem mindegy, hogyan működik a konzolja.

Valaki árulja el, akkor most él a macska?