Slide 1

Slide 1 text

bReaK aLL thE RuleZ @angustweets Sunday, October 7, 12

Slide 2

Slide 2 text

Sunday, October 7, 12

Slide 3

Slide 3 text

I work at Twitter We love JavaScript We embrace All The Parts We do everything in Strict Mode Sunday, October 7, 12

Slide 4

Slide 4 text

“Please don’t do this” Every tech forum. Ever. “The subset I carved out is vastly superior to the language as a whole” Douglas Crockford - The Good Parts Sunday, October 7, 12

Slide 5

Slide 5 text

Why are there Rules? Sunday, October 7, 12

Slide 6

Slide 6 text

Rules help us to do it right But who decides what is right? Sunday, October 7, 12

Slide 7

Slide 7 text

Right as it applies to Soup Sunday, October 7, 12

Slide 8

Slide 8 text

What is authentic minestrone soup? Oh!! Google Images will know.. Sunday, October 7, 12

Slide 9

Slide 9 text

Sunday, October 7, 12

Slide 10

Slide 10 text

>>>>>:-| Sunday, October 7, 12

Slide 11

Slide 11 text

Correctness is Subjective Sunday, October 7, 12

Slide 12

Slide 12 text

Each of us is unique. Each of us considers something harmful. Sunday, October 7, 12

Slide 13

Slide 13 text

Sunday, October 7, 12

Slide 14

Slide 14 text

Harmful is Subjective Sunday, October 7, 12

Slide 15

Slide 15 text

Germaine de Staël (1766 - 1817) “Rules are only barriers to prevent children from falling” Sunday, October 7, 12

Slide 16

Slide 16 text

*Andrew Dupont In Singapore everything runs smoothly but at the expense of personal freedom. Java is Singapore.* How Singapore do you want JavaScript to be? Sunday, October 7, 12

Slide 17

Slide 17 text

Wikipedia Policy (2001) “If a rule prevents you from improving or maintaining Wikipedia, ignore it.” Sunday, October 7, 12

Slide 18

Slide 18 text

How to Break the Rules... Sunday, October 7, 12

Slide 19

Slide 19 text

The with statement Sunday, October 7, 12

Slide 20

Slide 20 text

Why are you not meant to use it? 1) accidental clobbering and implicit global creation. Sunday, October 7, 12

Slide 21

Slide 21 text

var dragger = { increment: 1, direction: 'vertical', activationDrag: 2, onRelease: cleanUp } with(dragger) { interval = 2; direction = 'any'; } window.interval; //2 Sunday, October 7, 12

Slide 22

Slide 22 text

Obligatory Ironic Footnote ES 5 strict mode's implicit global error would have protected against the most egregious aspect of with... Instead ES 5 strict mode removed with. Sunday, October 7, 12

Slide 23

Slide 23 text

Why are you not meant to use it? 2) cost of closure scope resolution. Sunday, October 7, 12

Slide 24

Slide 24 text

Why are you not meant to use it? 3) cost of late compilation Sunday, October 7, 12

Slide 25

Slide 25 text

Why is it useful? 1) it powers your developer tools Sunday, October 7, 12

Slide 26

Slide 26 text

//Chrome Developer Tools IS._evaluateOn = function(evalFunction, obj, expression) { IS._ensureCommandLineAPIInstalled(); expression = "with (window._inspectorCommandLineAPI) {\ with (window) { " + expression + " } }"; return evalFunction.call(obj, expression); } Sunday, October 7, 12

Slide 27

Slide 27 text

Why is it useful? 2) it replicates block scope. Sunday, October 7, 12

Slide 28

Slide 28 text

//YES, THIS OLD CHESTNUT var addHandlers = function(nodes) { for (var i = 0; i < nodes.length; i++) { nodes[i].onclick = function(e) {alert(i);} } }; Sunday, October 7, 12

Slide 29

Slide 29 text

//you could wrap it in a function scope var addHandlers = function(nodes) { for (var i = 0; i < nodes.length; i++) { nodes[i].onclick = function(i) { return function(e) {alert(i);}; }(i); } }; Sunday, October 7, 12

Slide 30

Slide 30 text

//or use 'with' to mimic block scope var addHandlers = function(nodes) { for (var i = 0; i < nodes.length; i++) { with ({i:i}) { nodes[i].onclick = function(e) {alert(i);} } } }; Sunday, October 7, 12

Slide 31

Slide 31 text

The eval statement Sunday, October 7, 12

Slide 32

Slide 32 text

Why are you not meant to use it? 1) code injection loophole Sunday, October 7, 12

Slide 33

Slide 33 text

Why are you not meant to use it? 2) prevents closure optimization Sunday, October 7, 12

Slide 34

Slide 34 text

Why are you not meant to use it? 3) cost of late compilation Sunday, October 7, 12

Slide 35

Slide 35 text

Why is it useful? 1) when there is no JSON.parse Sunday, October 7, 12

Slide 36

Slide 36 text

“Using JavaScript’s eval is unsafe. Use a real JSON parser like the JSON parser from json.org instead.” Someone on Stack Overflow “One shouldn't use eval to parse JSON! Use Douglas Crockford’s json2.js script from json.org!” Someone else on Stack Overflow Sunday, October 7, 12

Slide 37

Slide 37 text

// From JSON2.org if (/^[\],:{}\s]*$/ .test(text.replace(/*regEx*/, '@') .replace(/*regEx*/, ']') .replace(/*regEx*/, ''))) { j = eval('(' + text + ')'); } Sunday, October 7, 12

Slide 38

Slide 38 text

Why is it useful? 2) It’s how your console rolls Sunday, October 7, 12

Slide 39

Slide 39 text

Do this in a Webkit Console or JSBin Sunday, October 7, 12

Slide 40

Slide 40 text

“eval and with are trivialized, misused, and outright condemned by most JavaScript programmers, but when used appropriately they allow for the creation of some fantastic pieces of code that wouldn’t be possible otherwise” John Resig Sunday, October 7, 12

Slide 41

Slide 41 text

The Function constructor Sunday, October 7, 12

Slide 42

Slide 42 text

new Function() is not just eval in disguise Sunday, October 7, 12

Slide 43

Slide 43 text

It evaluates code in a direct lexical child of the global scope Sunday, October 7, 12

Slide 44

Slide 44 text

Why is it useful? 1) Evaluated code will always run in a predictable scope. Sunday, October 7, 12

Slide 45

Slide 45 text

Why is it useful? 2) Only globals are exposed to the evaluated code. Sunday, October 7, 12

Slide 46

Slide 46 text

Why is it useful? 3) Removes closure optimization concerns. Sunday, October 7, 12

Slide 47

Slide 47 text

Where is it used? 1) jQuery’s parseJSON Sunday, October 7, 12

Slide 48

Slide 48 text

// jQuery parseJSON // Logic borrowed from http://json.org/json2.js if (rvalidchars.test(data.replace(rvalidescape,"@") .replace( rvalidtokens,"]") .replace( rvalidbraces,""))) { return ( new Function( "return " + data ) )(); } Sunday, October 7, 12

Slide 49

Slide 49 text

Where is it used? 2) Underscore.js string interpolation Sunday, October 7, 12

Slide 50

Slide 50 text

//from _.template // If a variable is not specified, // place data values in local scope. if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; //.. var render = new Function( settings.variable || 'obj', '_', source); Sunday, October 7, 12

Slide 51

Slide 51 text

The == operator Sunday, October 7, 12

Slide 52

Slide 52 text

Why are you not meant to use it? 1) coerces operands to the same type 2) oh, that’s it actually Sunday, October 7, 12

Slide 53

Slide 53 text

Why is it useful? 1) coerces operands to the same type Sunday, October 7, 12

Slide 54

Slide 54 text

Why is it useful? 2) undefined == null Sunday, October 7, 12

Slide 55

Slide 55 text

//this... if ((x === null) || (x === undefined)) //...is logically identical to this if (x == null) Sunday, October 7, 12

Slide 56

Slide 56 text

Why is it useful? 3) when it’s bloody obvious Sunday, October 7, 12

Slide 57

Slide 57 text

typeof thing == "function"; myArray.length == 2; myString.indexOf('x') == 0; Sunday, October 7, 12

Slide 58

Slide 58 text

Obligatory Ironic Footnote #2 if(x) coercion is used with much less reticence than == coercion but is generally no better understood Text if ("potato") { "potato" == true; //false } Sunday, October 7, 12

Slide 59

Slide 59 text

The Array constructor Sunday, October 7, 12

Slide 60

Slide 60 text

new Array() is evil right? Sunday, October 7, 12

Slide 61

Slide 61 text

But wait, this is gorgeous... Sunday, October 7, 12

Slide 62

Slide 62 text

//From prototype.js extension of //String.prototype function times(count) { return count < 1 ? '' : new Array(count + 1).join(this); } 'me'.times(10); //"memememememememememe" Sunday, October 7, 12

Slide 63

Slide 63 text

If you enjoyed breaking these rules you might consider breaking these ones too... Sunday, October 7, 12

Slide 64

Slide 64 text

Do not Extend Native Prototypes (es 5 shims are sensible) Always use hasOwnProperty on for/in (unnecessary for unextended object hashes) Put all var statements at the top (unintuitive with for loops) Don’t declare a function after you use it (useful for de-prioritizing implementation details) Don’t use comma as an operator (use multiple expressions when syntax expects one) Always pass the 10 argument to parseInt (unnecessary unless string begins with ‘0’ or ‘x’) Sunday, October 7, 12

Slide 65

Slide 65 text

It’s OK to break a Rule if... Sunday, October 7, 12

Slide 66

Slide 66 text

You understand why the rule exists and... Sunday, October 7, 12

Slide 67

Slide 67 text

You can mitigate (or safely ignore) the concerns of the rulemakers and... Sunday, October 7, 12

Slide 68

Slide 68 text

Breaking the rule would add value. Sunday, October 7, 12

Slide 69

Slide 69 text

Kristine Kathryn Rusch “Become an expert at the rules. Then break them with creativity and style” Sunday, October 7, 12

Slide 70

Slide 70 text

tl;dr Be Good. And if you can’t be good, Be Careful. Sunday, October 7, 12

Slide 71

Slide 71 text

qwEstionZ? @angustweets Sunday, October 7, 12