Podivná zmena podivností (pamätáte WAT?) rubrika: Programování: JavaScript
Zdravím,
dnes som si pozrel video WAT? to určite všetci znajú: https://www.destroyallsoftware.com/talks/wat
čo ma však prekvapilo že podivnosti sa hodne zmenili (neviem či sú teraz podivnejšie, alebo boli predtým), no ešte viac ma prekvapila silná nekonzistentnosť medzi rôznymi Interpretmi a verziami.
Príkladom budiš: {} + {}
ktorý vo videu WAT dalo výsledok NaN,... Chrome však vypapuluje "[object Object][object Object]" FireFox však vypapuluje NaN,... Node vypapuluje hádajte čo? '[object Object][object Object]' (len s apostrofmi, nie s úvodzovkami)
príkladom je však aj: {} + []
ktorý vráti 0, to platí aj vo Firefoxe, a aj v Chrome, no Node vypapuluje '[object Object]'. Pri tom Chrome i Node vlastne používajú rovnaký engine a V8. Špecifikácia nijako ale tieto zmeny nejak neriešila, prečo vlastne takéto zmeny vznikli a kde vlastne vznikli a prečo je to takto nekonzistentné? Ja už neviem...
TLTR:
Nekonzistentní je to pouze u výpisu dočasných nikde nepoužitých hodnot zadaných pomocí literálů {}
a []
S "použitím" výsledku je chování konzistentní a dle specifikace.
Nekonzistence je IMO způsobena samotnými konzolemi a tím jak řeší tento dost hraniční případ.
Asi bych začal citací MDN (v sekci aritmetické operátory) a ze specifikace:
The addition operator (+) produces the sum of numeric operands or string concatenation.
The addition operator either performs string concatenation or numeric addition.
a šlo by to rovnou zakončit tím, že takhle by se plus dle specifikace používat nemělo a proto se výsledky implementací liší (že to asi příliš neřeší).
Pro info, dle specifikace:
- nejdříve se sčítance převedou na primitivní hodnotu
- když alespoň jedna primitivní hodnota je řetězec, převedou se obě hodnoty na řetězce a provede se spojení řetězců
- jinak se hodnoty převedou na čísla a provede se sčítání čísel
Převod na primitivní hodnotu probublá až do funkce OrdinaryToPrimitive, kde "normální objekt" vrátí toString()
, takže cokoliv s objektem vrátí řetězec.
Další "gotchas" pro {}+[]
:
{}+[] // 0 v Chromu, "[object Object]" v node
console.log({}+[]) // "[object Object]" všude
var n={}+[] // "[object Object]" všude
var o={}; o+[] // "[object Object]" všude
var a=[]; {}+a // "[object Object]" v node, ale 0 v Chrome i FF
var o={}, a=[]; o+a // "[object Object]" všude
Další "gotchas" pro {}+{}
:
{}+{} // "[object Object][object Object]" v Chromu a node, NaN ve FF
console.log({}+{}) // "[object Object][object Object]" všude
var n={}+{} // "[object Object][object Object]" všude
var o={}; o+{} // "[object Object][object Object]" všude
var o={}; {}+o // "[object Object][object Object]" v node, ale NaN v Chrome i FF
var o={}; o+o // "[object Object][object Object]" všude
console.log
a to přiřazení výsledku do proměnné je v obou případech to podstatné.
EDIT:
Jinak teda zajímavé a poučné. Konzole "blbnou" u hodnot "od nikud nikam"
(odnikud={},[]
, nikam=s výsledkem se nic nedělá)
Video je samozřejmě vtipné, ale v tomhle světle trochu nespravedlivé - takto použité v kódu je úplně jedno co je výsledek, na nic to nemá vliv.
Pro zobrazení všech 2 odpovědí se prosím přihlaste:
Nebo se přihlaste jménem a heslem:
Komentáře