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

Javascript: le parti buone

E22edc988280c3b6ff183318bc1590c2?s=47 weLaika
April 11, 2016

Javascript: le parti buone

Tutti i linguaggi di programmazione contengono parti “buone” e parti “cattive”. JavaScript è stato sviluppato in dieci giorni e dopo la sua standardizzazione era ormai troppo tardi per corregge alcuni problemi di design.
Lavorare con framework JavaScript non ci esime dal conoscere a fondo le parti “buone” del linguaggio.
In questo talk prenderemo alcuni concetti dal famoso libro “JavaScript: The Good Parts” di D. Crockford, con un occhio di riguardo per ECMAScript 2015 (ES6).

E22edc988280c3b6ff183318bc1590c2?s=128

weLaika

April 11, 2016
Tweet

Transcript

  1. JavaScript “Le parti buone” 1 Torino Coding Society 11/04/2016 -

    @delphaber
  2. Slides' conventions (function () { 'use strict'; // slides' code

    }()); 2 Torino Coding Society 11/04/2016 - @delphaber
  3. Slides' conventions $ node -v v.5.10.1 Examples which include ES6

    code need to be transpiled first with https:/ /babeljs.io/repl. 3 Torino Coding Society 11/04/2016 - @delphaber
  4. Invocation 4 Torino Coding Society 11/04/2016 - @delphaber

  5. Method invocation pattern 5 Torino Coding Society 11/04/2016 - @delphaber

  6. Method invocation pattern var forrest = { name: 'Forrest', run:

    function() { console.log('Run ' + this.name + ', run!'); } }; forrest.run(); forrest['run'](); => "Run Forrest, run!" 6 Torino Coding Society 11/04/2016 - @delphaber
  7. Function invocation pattern 7 Torino Coding Society 11/04/2016 - @delphaber

  8. Function invocation pattern #1 function sum(a, b) { return a

    + b; } console.log(sum(5, 10)); => 15 8 Torino Coding Society 11/04/2016 - @delphaber
  9. Function invocation pattern #2 var forrest = { chocolatesCount: 10,

    eat: function() { function randomAmount() { return Math.floor((Math.random() * this.chocolatesCount) + 1); } this.chocolatesCount -= randomAmount(); } }; forrest.eat(); console.log("Chocolates left:", forrest.chocolatesCount); 9 Torino Coding Society 11/04/2016 - @delphaber
  10. Function invocation pattern #2 return Math.floor((Math.random() * this.chocolatesCount) + 1);

    ^ TypeError: Cannot read property 'chocolatesCount' of undefined 10 Torino Coding Society 11/04/2016 - @delphaber
  11. Function invocation pattern #2 Without 'use strict', this is bound

    to the global object. function randomAmount() { return Math.floor((Math.random() * this.chocolatesCount) + 1); } this.chocolatesCount -= randomAmount(); => Chocolates left: NaN 11 Torino Coding Society 11/04/2016 - @delphaber
  12. WAT? 12 Torino Coding Society 11/04/2016 - @delphaber

  13. Function invocation pattern #2 Solution #1 [...] eat: function() {

    var that = this; function randomAmount() { return Math.floor((Math.random() * that.chocolatesCount) + 1); } this.chocolatesCount -= randomAmount(); } [...] forrest.eat(); 13 Torino Coding Society 11/04/2016 - @delphaber
  14. Function invocation pattern #2 Solution #2 [...] eat: function() {

    function randomAmount() { return Math.floor((Math.random() * this.chocolatesCount) + 1); } this.chocolatesCount -= randomAmount.apply(this); } [...] forrest.eat(); 14 Torino Coding Society 11/04/2016 - @delphaber
  15. Function invocation pattern #2 Solution #3 ( ES5 ) [...]

    eat: function() { var randomAmount = function () { return Math.floor((Math.random() * this.chocolatesCount) + 1); }.bind(this); this.chocolatesCount -= randomAmount(); } [...] forrest.eat(); 15 Torino Coding Society 11/04/2016 - @delphaber
  16. Function invocation pattern #2 Solution #4 ( ES6 ) [...]

    eat: function() { var randomAmount = () => Math.floor((Math.random() * this.chocolatesCount) + 1); this.chocolatesCount -= randomAmount(); } [...] forrest.eat(); 16 Torino Coding Society 11/04/2016 - @delphaber
  17. Contructor invocation pattern 17 Torino Coding Society 11/04/2016 - @delphaber

  18. Contructor invocation pattern function Person(name) { this.name = name; }

    var forrest = new Person("Forrest"); console.log(forrest.name); => "Forrest" 18 Torino Coding Society 11/04/2016 - @delphaber
  19. Apply, Call and Bind1 invocation pattern 1 Actually it doesn't

    invoke, but creates a new function. 19 Torino Coding Society 11/04/2016 - @delphaber
  20. Apply, Call and Bind invocation pattern var forrest = {

    name: 'Forrest', run: function(arg1, arg2) { console.log('Run ' + this.name + ', run!'); } }; var bubba = { name: 'Bubba' }; forrest.run.apply(bubba, ["arg1", "arg2"]); forrest.run.call(bubba, "arg1", "arg2"); var newRun = forrest.run.bind(bubba, "arg1", "arg2"); newRun(); => Run Bubba, run! 20 Torino Coding Society 11/04/2016 - @delphaber
  21. Scope 21 Torino Coding Society 11/04/2016 - @delphaber

  22. Function scope function init() { var name = "Forrest"; function

    printName() { console.log(name); } printName(); } init(); 22 Torino Coding Society 11/04/2016 - @delphaber
  23. Function scope var x = 10; var y = 20;

    if (true) { var x = 0; console.log("Inner block: " + x); //0 console.log("Inner block: " + y); //20 } console.log("Inner block: " + x); //0 console.log("Inner block: " + y); //20 23 Torino Coding Society 11/04/2016 - @delphaber
  24. Block scope (ES6) var x = 10; let y =

    20; if (true) { let x = 0; console.log("Inner block: " + x); //0 console.log("Inner block: " + y); //20 } console.log("Outer block: " + x); //10 console.log("Outer block: " + y); //20 24 Torino Coding Society 11/04/2016 - @delphaber
  25. let is the new var 25 Torino Coding Society 11/04/2016

    - @delphaber
  26. Closures In other words, the function defined in the closure

    'remembers' the environment in which it was created. — MDN 26 Torino Coding Society 11/04/2016 - @delphaber
  27. Closure Example function init() { var name = "Forrest"; function

    logName() { console.log(name); } return logName; } var logName = init(); logName(); => "Forrest" 27 Torino Coding Society 11/04/2016 - @delphaber
  28. Use closure to hide implementation var forrest = (function() {

    var privateCounter = 10; return { chocolatesCount: function() { return privateCounter; }, eat: function() { privateCounter -= 1; } }; }()); forrest.eat(); console.log("Chocolates left:", forrest.chocolatesCount()); => "Chocolates left: 9" 28 Torino Coding Society 11/04/2016 - @delphaber
  29. Common mistake with closures var ids = ["div-1", "div-2"]; for(var

    i=0; i < ids.length; i++) { var divId = ids[i]; document.getElementById(divId).onclick = function() { alert("You clicked " + divId); }; } Clicking on div-1: "You clicked div-2" Clicking on div-2: "You clicked div-2" 29 Torino Coding Society 11/04/2016 - @delphaber
  30. Prototype Inheritance 30 Torino Coding Society 11/04/2016 - @delphaber

  31. Prototype Inheritance function Person(spec) { this.name = spec.name; } Person.prototype.run

    = function() { console.log('Run ' + this.name + ', run!'); }; Person.prototype.citizenship = "Italian"; 31 Torino Coding Society 11/04/2016 - @delphaber
  32. Prototype Inheritance console.log(Person.prototype); Object {citizenship: "Italian"} citizenship: "Italian" constructor: function

    Person(spec) run: function() __proto__: Object constructor: function Object() hasOwnProperty: function hasOwnProperty() isPrototypeOf: function isPrototypeOf() toString: function toString() __proto__ : null ... 32 Torino Coding Society 11/04/2016 - @delphaber
  33. Prototype Inheritance Object.getPrototypeOf(Person.prototype) === Object.prototype 33 Torino Coding Society 11/04/2016

    - @delphaber
  34. Prototype Inheritance var forrest = new Person({name: "Forrest"}); console.log(forrest.citizenship); //

    "Italian" console.log(forrest.hasOwnProperty("citizenship")); //false forrest.citizenship = "American"; console.log(forrest.citizenship); // "American" console.log(forrest.hasOwnProperty("citizenship")); //true delete forrest.citizenship; console.log(forrest.citizenship); // "Italian" console.log(forrest.hasOwnProperty("citizenship")); //false 34 Torino Coding Society 11/04/2016 - @delphaber
  35. Prototype Inheritance (Complete Example) function Soldier(spec) { Person.call(this, spec); this.weapons

    = spec.weapons || []; } Soldier.prototype = Object.create(Person.prototype); Soldier.prototype.constructor = Soldier; Soldier.prototype.fire = function() { this.weapons.forEach(function(w) { console.log("Fired", w); }); }; var lieutenantDan = new Soldier({name: "Dan", weapons: ["bar42", "beretta"]}); lieutenantDan.run(); //Run Dan, run! lieutenantDan.fire(); //Fired bar42 //Fired beretta 35 Torino Coding Society 11/04/2016 - @delphaber
  36. Prototype Inheritance (Complete Example) console.log(Soldier.prototype) Person {} constructor: function Soldier(spec)

    fire: function() __proto__: Object citizenship: "Italian" constructor: function Person(spec) run: function() __proto__: Object ... 36 Torino Coding Society 11/04/2016 - @delphaber
  37. More good parts in ES6 • Modules (export, import) •

    Destructuring Assignment • Default Parameter Values • Rest Parameter http:/ /es6-features.org/ 37 Torino Coding Society 11/04/2016 - @delphaber
  38. Thanks! • JavaScript: The Good Parts (Douglas Crockford) - http:/

    /www.amazon.it/dp/0596517742 • The Better Parts - https:/ /youtu.be/PSGEjv3Tqo0 • ECMAScript 6 New Features - http:/ /es6- features.org • MDN - https:/ /developer.mozilla.org/en-US/docs/ Web/JavaScript 38 Torino Coding Society 11/04/2016 - @delphaber