On Github patrickarlt / dev-summit-2015-javascript-the-weird-parts
Experience Developer - ArcGIS for Developers
I will convince you that you are all crazy for liking JavaScript by the end of this talk.
var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar();
var a = 1; function b() { a = 10; return; function a() {}; } b(); alert(a);
Variable declarations and local functions are "hoisted" to the top of the function scope.
var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar();
var foo = 1; function bar() { var foo; // declaration hoisted if (!foo) { // foo is undefined foo = 10; } alert(foo); // 10 } bar();
var a = 1; function b() { a = 10; return; function a() {}; } b(); alert(a);
var a = 1; function b() { function a() {} // a is now a local declaration in function b a = 10; // assign a, now in the local scope to 10 return; } b(); alert(a); // 1
There is a reason your linter yells at you about declaring all variables and functions at the top.
Math.max() > Math.min()
false
Math.max() // > -Infinity Math.min() // > Infinity
isFinite(42)
true
isFinite(1/0)
false
isFinite(undefined)
false
undefined == Infinity
false
isFinite(null)
true
But JavaScript doesn't have types!
[] + []
""
{} + {}
NaN
[] + {}
"[object Object]"
{} + []
0
'wat' + 1
"wat1"
'wat' - 1
NaN
This is why you use ===.
This is also why things like TypeScript exist.
0 = +[] 1 = +!![] 2 = !+[]+!![] 3 = !+[]+!![]+!![] 4 = !+[]+!![]+!![]+!![] 5 = !+[]+!![]+!![]+!![]+!![] 6 = !+[]+!![]+!![]+!![]+!![]+!![] 7 = !+[]+!![]+!![]+!![]+!![]+!![]+!![] 8 = !+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![] 9 = !+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]
true = !![] false = ![] undefined = [+[]] NaN = +{} (object to number) [object object] = []+{}
(!![]+{})[+[]] // > "t"
Make strings "1e100" and "1e1000" and convert them back to numbers to get "1e+100" and Infinity. This gets you "y", "I" and "+".
SPACE, [ ] + a b c d e f i I j l n N o O r s t u y
Functions available with our current characters.
Function = array["sort"]["constructor"] Array = array["constructor"] Boolean = false["constructor"] Number = 0["constructor"] Object fom {}["constructor"] String fom string["constructor"] Function.prototype.call = f["call"] String.prototype.concat = string["concat"] Array.prototype.join = array["join"] Array.prototype.slice = array["slice"] Array.prototype.sort = array["sort"]
If you get a "p" and "%" you can use unescape("%" + HEXA_ASCII_VAL) to get any character.
([+[]]["sort"]["constructor"]("return location")()+(+{}))[3] = "p"
escape('[')[0] = "%"
www.esri.com/RateMyDevSummitSession
Twitter: @patrickarlt
Slides: http://arcg.is/1wFtcQK