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

Stop being Perfect

Stop being Perfect

Presented at Web Rebels, Oslo, Norway
May 22nd 2014

Angus Croll

May 22, 2014
Tweet

More Decks by Angus Croll

Other Decks in Technology

Transcript

  1. @angustweets
    STOP BEING PERFE T
    C

    View Slide

  2. I’m British but I live in America
    I work at Twitter
    (used by twitter.com, tweetdeck,
    airbnb, beats music etc.)
    I co-wrote Flight

    View Slide

  3. and I’m writing a Book...

    View Slide

  4. View Slide

  5. The 5 steps to
    JavaScript Perfectionism

    View Slide

  6. 1. Discovery

    View Slide

  7. (weird shit)
    JAVA!!
    But Easier!!
    (Deceptively Familiar
    Syntax)
    (weird shit)
    WTF?
    JavaScript

    View Slide

  8. 2. Consternation

    View Slide

  9. View Slide

  10. 3. Despair

    View Slide

  11. JavaScript
    developer
    JavaScript

    View Slide

  12. 4. The Shining Knight

    View Slide

  13. View Slide

  14. 5. The JavaScript Police™

    View Slide

  15. http://stackoverflow.com/questions/3959211/fast-factorial-function-in-javascript

    View Slide

  16. So why do we need imperfection?

    View Slide

  17. 1. Technology thrives on Open Minds

    View Slide

  18. Jed Schmidt has an open mind

    View Slide

  19. View Slide

  20. Web Rebels
    2014

    View Slide

  21. ‘Oslo’ === ‘Oslo’; //true
    new String(‘Oslo’) === new String(‘Oslo’); //false
    Objects have identity, primitives don’t

    View Slide

  22. View Slide

  23. (picture)
    2. Context > Dogma

    View Slide

  24. -Classical Inheritance-

    View Slide

  25. var Widget = function(color) {
    this.color = color;
    };
    Widget.prototype.render = function() {
    console.log('render...', 'width:', this.width,
    'height:', this.height, 'color:', this.color);
    }
    var Button = function(width, height, cb, label, color) {
    this.width = width;
    this.height = height;
    this.cb = cb;
    this.label = label;
    Widget.call(this, color);
    };
    Button.prototype = new Widget();
    Button.prototype.constructor = Button;
    Button.prototype.initialize = function() {
    console.log('init...', 'onclick:', this.cb, 'label:', this.label);
    };
    var b = new Button(20, 30, alert, 'hello', 'blue')
    b.initialize();
    b.render();

    View Slide

  26. This is why people hate JavaScript

    View Slide

  27. But wait...

    View Slide

  28. var widget = {
    render : function() {
    console.log('render...', 'width:', this.width,
    'height:', this.height, 'color:', this.color);
    }
    }
    var button = {
    initialize: function() {
    console.log('init...', 'onclick:', this.cb, 'label:', this.label);
    widget.render.call(this);
    }
    }
    var myButton = {
    width:20, height:30, cb:alert, label:'hello', color:'blue'};
    button.initialize.call(myButton);

    View Slide

  29. var widget = {
    render : function() {
    console.log('render...', 'width:', this.width,
    'height:', this.height, 'color:', this.color);
    }
    }
    var button = {
    initialize: function() {
    console.log('init...', 'onclick:', this.cb, 'label:', this.label);
    widget.render.call(this);
    }
    }
    var myButton = {
    width:20, height:30, cb:alert, label:'hello', color:'blue'};
    button.initialize.call(myButton);

    View Slide

  30. or just forget OO entirely

    View Slide

  31. var widget = {
    render : function(width, height, color) {
    console.log('render...', 'width:', width,
    'height:', height, 'color:', color);
    }
    }
    var button = {
    initialize: function(cb, label, width, height, color) {
    console.log('init...', 'onclick:', cb, 'label:', label);
    widget.render(width, height, color);
    }
    }
    button.initialize(20, 30, alert, 'hello', 'blue');

    View Slide

  32. var widget = {
    render : function(width, height, color) {
    console.log('render...', 'width:', width,
    'height:', height, 'color:', color);
    }
    }
    var button = {
    initialize: function(cb, label, width, height, color) {
    console.log('init...', 'onclick:', cb, 'label:', label);
    widget.render(width, height, color);
    }
    }
    button.initialize(20, 30, alert, 'hello', 'blue');

    View Slide

  33. -hasOwnProperty-

    View Slide

  34. “Only hasOwnProperty will give
    the correct and expected result;
    this is essential when iterating
    over the properties of any object”
    —JavaScript Garden

    View Slide

  35. var obj = Object.create(null);
    obj.a = 3;
    obj.b = 5;
    for (var p in obj) {
    if (obj.hasOwnProperty(p)) {
    console.log(obj[p]);
    }
    }

    View Slide

  36. var obj = Object.create(null);
    obj.a = 3;
    obj.b = 5;
    for (var p in obj) {
    if (obj.hasOwnProperty(p)) {
    console.log(obj[p]);
    }
    }

    View Slide

  37. var obj = Object.create(null);
    obj.a = 3;
    obj.b = 5;
    for (var p in obj) {
    if (obj.hasOwnProperty(p)) {
    console.log(obj[p]);
    }
    }
    TypeError: [Object Object] has no method hasOwnProperty

    View Slide

  38. -Array constructor-

    View Slide

  39. [] or new Array?

    View Slide

  40. Google Style Guide
    google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml?
    showone=Array_and_Object_literals#Array_and_Object_literals

    View Slide

  41. View Slide

  42. Google Developer Day
    V8 Performance Tuning Tricks
    https://mkw.st/p/gdd11-berlin-v8-performance-tuning-tricks/#44

    View Slide

  43. View Slide

  44. more importantly you can write neat
    functions like...

    View Slide

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

    View Slide

  46. and...

    View Slide

  47. function range(max) {
    return Array.apply(0,Array(max)).map(function(e,i){
    return i+1;
    })
    }
    range(10); //[1,2,3,4,5,6,7,8,9,10]

    View Slide

  48. -equality-

    View Slide

  49. “Always use === and !==”
    - Douglas Crockford, The Good Parts

    View Slide

  50. if (x == null)
    //is exactly equivalent to...
    if (x === null || x === undefined)

    View Slide

  51. if (typeof x == “function”)

    View Slide

  52. -with-

    View Slide

  53. //using Ramanujan's approximation
    function factorial(n){
    var r = Math.sqrt(Math.PI)*Math.pow(n/Math.E,n);
    r *= Math.pow(8*Math.pow(n, 3) + 4*(n*n) + n + 1/30, 1/6);
    return r;
    }

    View Slide

  54. //using Ramanujan's approximation
    function factorial(n){
    var r = Math.sqrt(Math.PI)*Math.pow(n/Math.E,n);
    r *= Math.pow(8*Math.pow(n, 3) + 4*(n*n) + n + 1/30, 1/6);
    return r;
    }

    View Slide

  55. //using Ramanujan's approximation
    function factorial(n){
    with(Math) {
    var r = sqrt(PI)*pow(n/E,n);
    r *= pow(8*pow(n, 3) + 4*(n*n) + n + 1/30, 1/6);
    return r;
    }
    }

    View Slide

  56. //using Ramanujan's approximation
    function factorial(n){
    with(Math) {
    var r = sqrt(PI)*pow(n/E,n);
    r *= pow(8*pow(n, 3) + 4*(n*n) + n + 1/30, 1/6);
    return r;
    }
    }

    View Slide

  57. with as equivalent to let

    View Slide

  58. apparently this is our worst nightmare...

    View Slide

  59. var addHandlers = function(nodes) {
    for (var i = 0; i < nodes.length; i++) {
    nodes[i].onclick =
    function(e) {alert(i);}
    }
    };

    View Slide

  60. you could wrap it in function scope...

    View Slide

  61. var addHandlers = function(nodes) {
    for (var i = 0; i < nodes.length; i++) {
    nodes[i].onclick = function(i) {
    return function(e) {alert(i)};
    }(i);
    }
    };

    View Slide

  62. or use with
    (safely)

    View Slide

  63. var addHandlers = function(nodes) {
    for (var i = 0; i < nodes.length; i++) {
    with ({i:i}) {
    nodes[i].onclick = function(e) {alert(i)}
    }
    }
    };

    View Slide

  64. -comma operator-

    View Slide

  65. “but it’s really complicated”

    View Slide

  66. doThis(), doThat();
    1) do this 2) then do that

    View Slide

  67. lets you do two things when JavaScript
    expects one

    View Slide

  68. var addHandlers = function(nodes) {
    for (var i = 0; i < nodes.length; i++) {
    nodes[i].onclick =
    function(e) {alert(i);}
    }
    };

    View Slide

  69. var addHandlers = function(nodes) {
    for (var i = 0; i < nodes.length; console.log(i),i++) {
    nodes[i].onclick =
    function(e) {alert(i);}
    }
    };

    View Slide

  70. var addHandlers = function(nodes) {
    for (var i = 0; i < nodes.length; console.log(i),i++) {
    nodes[i].onclick =
    function(e) {alert(i);}
    }
    };

    View Slide

  71. another example

    View Slide

  72. function getRandomPrime() {
    while(n = Math.round(Math.random()*1000), !isPrime(n));
    return n;
    }

    View Slide

  73. make eval run globally

    View Slide

  74. (function() {
    var localStorage = "bwahahahaha!"
    return eval("localStorage")
    })(); //"bwahahahaha!"

    View Slide

  75. (function() {
    var localStorage = "bwahahahaha!"
    return (0,eval)("localStorage")
    })(); //"Storage {length: 0}"

    View Slide

  76. //see http://perfectionkills.com/global-eval-what-
    are-the-options/ by Kangax
    (function() {
    var localStorage = "bwahahahaha!"
    return (0,eval)("localStorage")
    })(); //"Storage {length: 0}"

    View Slide

  77. Thanks Comma
    Operator!!!
    ,
    Really it was
    Nothing!

    View Slide

  78. functional programming

    View Slide

  79. View Slide

  80. functional programming

    View Slide

  81. functional programming
    languages

    View Slide

  82. JavaScript is not a functional language
    But it has functional idioms

    View Slide

  83. function passing
    higher order functions
    function composition

    View Slide

  84. Use them and have fun with them
    You don’t need to be functionally pure

    View Slide

  85. 3. Play == Learning

    View Slide

  86. experiment
    code outside your comfort zone

    View Slide

  87. Future Java
    Developer

    View Slide

  88. View Slide

  89. Some replies...

    View Slide

  90. “use [] not new Array”
    “aren't r and i also global?”
    “eval.....”
    “global arr variable :P”
    “Why is it Useful?”
    “evil() is like cheating”
    “no global functions!”

    View Slide

  91. me

    View Slide

  92. View Slide

  93. Don’t let best practices do your thinking
    for you

    View Slide

  94. JavaScript is not a Science

    View Slide

  95. There is no Panacea

    View Slide

  96. Your code will Break - it always does.
    Keep it simple and human readable so
    it’s easier to fix.

    View Slide

  97. Most importantly...

    View Slide

  98. Don’t take anything I’ve said seriously
    I’m just exploring.
    You should explore too.

    View Slide

  99. Picture Credits
    Mr Perfect by Roger Hargreaves
    http://www.mrmen.com/characters/mr-perfect/index.html
    If Hemingway wrote JavaScript by Angus Croll
    No Starch Press
    Bayeux Tapestry Maker
    http://bayeux.datensalat.net
    The Scream by Edvard Munch
    JavaScript: Good Parts by Douglas Crockford
    http://shop.oreilly.com/product/9780596517748.do
    cheetah cubs
    2013bestpicz.blogspot.co.uk
    lion cubs
    https://c2.staticflickr.com/6/5339/6947068456_0b99b8fa58_z.jpg

    View Slide

  100. @angustweets
    STOP BEING PERFE T
    C
    Tusen Takk!

    View Slide