Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Break all the Rulez

Break all the Rulez

Presented at: jsconf.eu in Berlin, Oct 6th 2012
Video: http://www.youtube.com/watch?v=MFtijdklZDo&feature=plcp

Good programmers follow best practices; great programmers investigate them.

Many JavaScript sources proclaim (with miraculous certainty) that some tricky language features are anti-patterns that must be avoided at all costs, while offering little or nothing in the way of substantive evidence beyond alarmist warnings or references to their favorite gurus. We shouldn’t ask people to follow rules that we can’t explain or propose actions that we can’t defend.

This talk will demonstrate that, whether its double-equals coercion, iteration without hasOwnProperty, augmenting native prototypes or even fraternizing with the evil ‘eval’ and ‘with’, there is a time and place for virtually every feature of JavaScript and taking the time to study and understand their potential will enrich the programming experience, just as a broader vocabulary enriches the speaking experience. The talk will feature copius real life examples drawn from respected libaries and tools.

Angus Croll

October 06, 2012
Tweet

More Decks by Angus Croll

Other Decks in Technology

Transcript

  1. I work at Twitter We love JavaScript We embrace All

    The Parts We do everything in Strict Mode Sunday, October 7, 12
  2. “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
  3. Rules help us to do it right But who decides

    what is right? Sunday, October 7, 12
  4. Germaine de Staël (1766 - 1817) “Rules are only barriers

    to prevent children from falling” Sunday, October 7, 12
  5. *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
  6. Wikipedia Policy (2001) “If a rule prevents you from improving

    or maintaining Wikipedia, ignore it.” Sunday, October 7, 12
  7. Why are you not meant to use it? 1) accidental

    clobbering and implicit global creation. Sunday, October 7, 12
  8. var dragger = { increment: 1, direction: 'vertical', activationDrag: 2,

    onRelease: cleanUp } with(dragger) { interval = 2; direction = 'any'; } window.interval; //2 Sunday, October 7, 12
  9. 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
  10. Why are you not meant to use it? 2) cost

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

    of late compilation Sunday, October 7, 12
  12. //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
  13. //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
  14. //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
  15. //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
  16. Why are you not meant to use it? 1) code

    injection loophole Sunday, October 7, 12
  17. Why are you not meant to use it? 2) prevents

    closure optimization Sunday, October 7, 12
  18. Why are you not meant to use it? 3) cost

    of late compilation Sunday, October 7, 12
  19. “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
  20. “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
  21. It evaluates code in a direct lexical child of the

    global scope Sunday, October 7, 12
  22. Why is it useful? 1) Evaluated code will always run

    in a predictable scope. Sunday, October 7, 12
  23. Why is it useful? 2) Only globals are exposed to

    the evaluated code. Sunday, October 7, 12
  24. // 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
  25. //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
  26. 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
  27. //this... if ((x === null) || (x === undefined)) //...is

    logically identical to this if (x == null) Sunday, October 7, 12
  28. 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
  29. //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
  30. If you enjoyed breaking these rules you might consider breaking

    these ones too... Sunday, October 7, 12
  31. 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
  32. You can mitigate (or safely ignore) the concerns of the

    rulemakers and... Sunday, October 7, 12
  33. Kristine Kathryn Rusch “Become an expert at the rules. Then

    break them with creativity and style” Sunday, October 7, 12
  34. tl;dr Be Good. And if you can’t be good, Be

    Careful. Sunday, October 7, 12