WTFJS? EnterJS 2014 Matthias Reuter / @gweax
Grafik: Angus Croll @angustweets
0.1 + 0.2» 0.30000000000000004 CC-BY-SA https://www.flickr.com/photos/keith_and_kasia/7902026314/
Computer! Binärsystem! Endliche Präzision!
0.1 0.1 = 0.000110011001100 dec bin IEEE 754 double keine Integerzahlen in JavaScript!
e ± 2 m IEEE 754 DOUBLE 64 bit: 1 bit Vorzeichen, 11 bit Exponent, 53 (52) bit Mantisse 0 01111111011 1001 10011001 10011001 10011001 10011001 10011001 10011010 0.100000000 000000005 551115123 125782702 118158340 4541015625 dec http://www.binaryconvert.com/convert_double.html
LÖSUNG function equals(a, b) { var epsilon = Math.pow(2, -53); return Math.abs(a - b) < epsilon; } Geeignetes Epsilon wählen Tipp: Bei Geldbeträgen immer in Cent, nicht in Euro rechnen
typeof NaN» "number" CC-BY-NC-ND http://darkdoomer.deviantart.com/art/wtf-7508738
NAN IEEE 754 Software- und Hardware-Implementierungen Alles muss eine Zahl sein NaN signalisiert eine ungültige Operation
UNGÜLTIGE OPERATIONEN Infinity - Infinity Math.sqrt(-1) 0/0 Number("wtf")
DARSTELLUNG 0 11111111111 xxxxx (Mantisse 0)
NaN === NaN» false isnan(nan)» true isnan(43)» false isnan("wft")» true
Number.isNaN() LÖSUNG (ES6) LÖSUNG (NACHBAU) function betterisnan(a) { return typeof a === "number" && isnan(a); } LÖSUNG (SCHLAU) function cleverisnan(a) { return a!== a; }
"0" == false» true 0 == false» true "" == false» true [] == false» true CC-BY-NC-SA http://dobotibi.deviantart.com/art/omg-wtf-t-shirt-design-110818957
== BEDEUTET NICHT GLEICH, EHER BEDEUTET ES ÄHNLICH Für Mathematiker: == ist keine Äquivalenzrelation "0" == falseund false == [], aber nicht "0" == []
ÄHNLICH? CC-PD http://pixabay.com/
PPK on Javascript: An empty string becomes false. All other values become true. Matthias: Echt? Auch "0"? Matthias: Wie erzwinge ich denn die Umwandlung von "0" in ein Boolean? Matthias (dumme Idee): "0" == true; Browser: false
ABSTRACT EQUALITY COMPARISON ALGORITHM 11.9.3 THE ABSTRACT EQUALITY COMPARISON ALGORITHM The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows: 1. If Type(x) is different from Type(y), go to step 14. (22 Schritte insgesamt, in ES 262-5 umformuliert, 10 Schritte)
"0" == false "0" == 0 0 == 0 true
"" == false "" == 0 0 == 0 true 9.3.1 TONUMBER APPLIED TO THE STRING TYPE A StringNumericLiteral that is empty or contains only white space is converted to +0.
[] == false [] == 0 "" == 0 0 == 0 true
Matthias an PPK: Dein Buch hat einen Fehler! PPK an Matthias: Nein! Verwende explizite Typkonvertierung
LÖSUNG Algorithmus auswendig lernen LÖSUNG (TYP ERZWINGEN) Boolean("0") === true LÖSUNG (VERGLEICHEN) "0" === false Ist === eine Äquivalenzrelation?
[5, 10, 1].sort()» [1, 10, 5] https://twitter.com/iamdevloper/status/421279034124013568
15.4.4.11 ARRAY.PROTOTYPE.SORT (COMPAREFN) When the SortCompare abstract operation is called with two arguments j and k, the following steps are taken: 1. Let jstring be ToString(j). 2. Let kstring be ToString(k). Äpfel, Birnen..., diesmal Strings
LÖSUNG [5, 10, 1].sort(function (a, b) { return a - b; });
null == undefined» true CC-BY-SA https://www.flickr.com/photos/sanfranannie/3178105727/
4.3.9 UNDEFINED VALUE primitive value used when a variable has not been assigned a value 4.3.11 Null Value primitive value that represents the intentional absence of any object value
UNDEFINED var a; arr[2014] NULL "enterjs".match(/\d/); new Date("foo").toJSON();
GEMEINSAMKEITEN Sind ähnlich (==) Sind falsy UNTERSCHIEDE Konvertierung in Number/String JSON kennt nur null
undefined = 3» 3 typeof null» "object"
3.toString(2)» SyntaxError 3..toString(2)» "11" CC-BY http://commons.wikimedia.org/wiki/file:what_the...gif
7 LEXICAL CONVENTIONS The source text is scanned from left to right, repeatedly taking the longest possible sequence of characters as the next input element.
7.8.3 NUMERIC LITERALS DecimalLiteral :: DecimalIntegerLiteral. DecimalDigits opt ExponentPart. DecimalDigits ExponentPart opt DecimalIntegerLiteral ExponentPart opt opt
3. tostring (2) 3..toString (2)
var a = 10, b = 20; a+b» 30 a++b» SyntaxError a+++b» 30 CC-PD http://pixabay.com/de/comics-verh%c3%b6r-frage-sprechblase-151341/
a + b a++ b a++ + b
ALLES GUT MIT ===? Nein, es gibt ja noch < und Verwandte
"536.26" > 536.20» true
11.8.5 THE ABSTRACT RELATIONAL COMPARISON ALGORITHM 3. If it is not the case that both Type(px) is String and Type(py) is String, then a. Let nx be the result of calling ToNumber(px). [...] b. Let ny be the result of calling ToNumber(py). Äpfel, Birnen..., diesmal Zahlen
Bug in Safari, ab Webkit-Version 536.20 Version aus dem User-Agent (böse, ich weiß) Vergleich mit Zahl
klappt wunderbar, bis... "Mozilla/5.0 (Macintosh; Intel Mac OS X 1084) AppleWebKit/536.30.1 (KHTML like Gecko) Version/6.0.5 Safari/536.30.1" "536.30.1" > 536.20» false
Number("536.30.1")» NaN parsefloat("536.30.1")» 536.3
console.log(11111111111111111);» 11111111111111112 parseint(1000000000000000000000.1)» 1 CC-BY http://commons.wikimedia.org/wiki/file:what_the_duck%3f.jpg
11111111111111111 > 2 53 IEEE 754: Runden zur nächstgelegenen Zahl
15.1.2.2 PARSEINT (STRING, RADIX) 1. Let inputstring be ToString(string).
String(1000000000000000000000.1)» "1e+21" parseint("1e+21")» 1
IEEE 754 Dyn. Typ. Syntax 0.1 + 0.2 "0" == false 3..toString(2) NaN [5, 10, 1].sort() a+++b 11111111111111111 null == undefined parseint("1e+21") "536.30.1" > 536.20
JAVASCRIPT HAT GENAU ZWEI WTFS: 1. IEEE 754 2. Dynamische Typisierung
LEKTÜRE Weitere WTFs: wtfjs.com ECMAScript 262-5 online: www.ecma262-5.com gedruckte Version kostenlos bestellen: ecma-international.org/publications/getit.php