Share
Embed
Underhanded Javascript - How to be a Complete Arsehole with Bad Javascript
My talk for Javascript.my's Unshift miniconf in Kuala Lumpure
Javascript Interview Questions: https://leanpub.com/jsinterviewquestions
Underhanded Javascript: https://leanpub.com/underhandedjavascript
The transcript can be found here: http://blog.chewxy.com/2014/01/27/javascript-wat-again/
Xuanyi
January 24, 2014
Transcript
31 slides
-
UNDERHANDED JAVASCRIPT HOW TO BE A COMPLETE ARSEHOLE WITH BAD
JAVASCRIPT @chewxy #assholejavascript -
AGENDA • A bunch of small examples • (Hopefully) One
big example • Throughout: How to be an arsehole. @chewxy #assholejavascript -
NAMED FUNCTION EXPRESSION What does this return? var foo =
function bar() { console.log("baz") }; bar(); @chewxy #assholejavascript -
NAMED FUNCTION EXPRESSION Why? • It’s a named Function Expression
(the other type is a Function Declaration, which cannot be unnamed) • The name can only be referenced from inside the function. @chewxy #assholejavascript -
NAMED FUNCTION EXPRESSION Why? • It’s a named Function Expression
(the other type is a Function Declaration, which cannot be unnamed) • The name can only be referenced from inside the function. Useful When: • Making recursive function expressions. • This will lead to a lot of undefined: var foo = function(x) { while (x < 10) { console.log(foo()) x++ } } foo(1) • Replacing old code that has arguments.callee in them @chewxy #assholejavascript -
IMMEDIATELY INVOKED FUNCTION EXPRESSIONS What do these return? Answer: Depends
on where you run it Example 1 Example 2 Example 3 function foo(x) { console.log(arguments) return x } foo(1, 2, 3, 4, 5) function foo(x) { console.log(arguments) return x }(1, 2, 3, 4, 5) (function foo(x) { console.log(arguments) return x }(1, 2, 3, 4, 5)) @chewxy #assholejavascript -
IMMEDIATELY INVOKED FUNCTION EXPRESSIONS Even more fun: function foo(x) {
return arguments } ! foo)( Example 1 Example 2 Example 3 function foo(x) { console.log(arguments) return x } foo(1, 2, 3, 4, 5) function foo(x) { console.log(arguments) return x }(1, 2, 3, 4, 5) (function foo(x) { console.log(arguments) return x }(1, 2, 3, 4, 5)) @chewxy #assholejavascript -
IMMEDIATELY INVOKED FUNCTION EXPRESSIONS Results: Example 1 Example 2 Example
3 Chrome/Firefox [1, 2, 3, 4, 5] 5 [1, 2, 3, 4, 5] Node.js REPL [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] @chewxy #assholejavascript -
IMMEDIATELY INVOKED FUNCTION EXPRESSIONS Results: Example 1 Example 2 Example
3 Chrome/Firefox [1, 2, 3, 4, 5] 5 [1, 2, 3, 4, 5] Node.js REPL [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] But Node.js runs on V8??!! @chewxy #assholejavascript -
IMMEDIATELY INVOKED FUNCTION EXPRESSIONS Why? • Example 2 is not
an IIFE. It just looks like one. • Automatic semicolon insertion happens • 5 is the result of parsing the group expression that follows. • Basically this: function foo(x){ // code }; (1, 2, 3, 4, 5) // group expression @chewxy #assholejavascript -
IMMEDIATELY INVOKED FUNCTION EXPRESSIONS Why? • Older versions of Node.js
REPL wraps every command in (), making Example 2 an IIFE. • foo)( is basically this: (foo)() • Fixed in latest Node.js :( * * I like shennanigans. It gives people reason to consult me. @chewxy #assholejavascript -
IMMEDIATELY INVOKED FUNCTION EXPRESSIONS Being an arsehole – because this
looks like an IIFE, no one will give it a double look: function NotActuallyGoingToBeCalled() { // blablabla // make this code block as long as possible // just to confuse other people }(function ActualFunctionThatGivesEffect() { // The name of the function is optional. // do evil things here }()) Even more arseholish move: Give the evil IIFE the same name as the function declaration. @chewxy #assholejavascript -
QUICK QUIZ Remember that Function Expressions have optional names to
facilitate recursion. Remember that only Function Expressions can be immediately invoked. What does this return? Why? (function foo(foo) { console.log(foo()) })(function() { return 1 }) @chewxy #assholejavascript -
THE COMMA TRICK What does this return? arr = [1,
2, 3, 4][1, 2, 3] @chewxy #assholejavascript -
THE COMMA TRICK Why? arr = [1, 2, 3, 4][1,
2, 3] Array Literal Array Accessor @chewxy #assholejavascript -
THE COMMA TRICK ¿Por qué? arr = [1, 2, 3,
4][1, 2, 3] Array Literal Array Accessor [((1, 2), 3)] @chewxy #assholejavascript -
THE COMMA TRICK 为什么? arr = [1, 2, 3, 4][1,
2, 3] Array Literal Array Accessor [((1, 2), 3)] Evaluate ((1, 2), 3) Evaluate (1, 2) Evaluate 1 è Discard Evaluate 2 è Return Evaluate (2, 3) Evaluate 2 è Discard Evaluate 3 è Return -
STATEMENTS! These are statements: • if – else •
for loop • while loop • switch statements • Block statements delimited by { and } @chewxy #assholejavascript -
TRUTHY AND FALSEY Everyone knows this: var x = "true”
if (x) { console.log(x == true) } else { console.log("x is not a truthy value") } But why?! @chewxy #assholejavascript -
TRUTHY AND FALSEY And then trip up on this!: var
x = [0] if (x) { console.log([0] == 0) } else { console.log("[0] is not a truthy value") } But why?! @chewxy #assholejavascript -
TRUTHY AND FALSEY Why? • Truthy and Falsey values are
coerced to Booleans when in statements • Values are coerced to Numbers when in relational (equality) expressions • Doesn’t mean you should NOT use ==. Instead, use with care @chewxy #assholejavascript -
QUICK QUIZ What do these return? {}[0] == true
{}[1] == true !{}[0] == true !{}[1] == true @chewxy #assholejavascript -
STATEMENTS! These are statements: • if – else •
for loop • while loop • switch statements • Block statements delimited by { and } @chewxy #assholejavascript -
TRUTHY AND FALSEY Why? • Truthy and Falsey values are
coerced to Booleans when in statements • Values are coerced to Numbers when in relational (equality) expressions • Doesn’t mean you should NOT use ==. Instead, use with care @chewxy #assholejavascript -
QUICK QUIZ What does this return? var x = 1;!
switch(x) {! !case '1':! ! !console.log("Hey I just met you");! !case '2':! ! !console.log("And this is craaaazy");! !case 1:! ! !console.log("But here's my number");! !case 2:! ! !console.log("So call me maybe");! } @chewxy #assholejavascript -
LAST ONE (I PROMISE) Did you know that V8 has
block level variable scoping without ES 6 syntax? What happens when you call foo() and what is the value of x? function foo() { var x = 1 { function x(){ return 2; } } return x } function foo() { x = 1 { function x(){ return 2; } } return x } @chewxy #assholejavascript -
STATEMENTS! These are statements: • if – else •
for loop • while loop • switch statements • Block statements delimited by { and } @chewxy #assholejavascript -
LAST ONE (I PROMISE) Did you know that V8 has
block level variable scoping without ES 6 syntax? What happens when you call foo() and what is the value of x? function foo() { var x = 1 { function x(){ return 2; } } return x } function foo() { x = 1 { function x(){ return 2; } } return x } @chewxy #assholejavascript -
LAST ONE (I PROMISE) Did you know that V8 has
block level variable scoping without ES 6 syntax? Just kidding. It doesn’t. But it åppears to have block level scoping @chewxy #assholejavascript -
BUY MY BOOK It’s helluva less inconsistent than Javascript. It’s
flexible like Javascript: Only 2 titles to choose from! https://leanpub.com/underhandedjavascript https://leanpub.com/jsinterviewquestions @chewxy #assholejavascript