Share
Embed
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).
weLaika
April 11, 2016
Transcript
38 slides
-
Slides' conventions (function () { 'use strict'; // slides' code
}()); 2 Torino Coding Society 11/04/2016 - @delphaber -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
Function scope function init() { var name = "Forrest"; function
printName() { console.log(name); } printName(); } init(); 22 Torino Coding Society 11/04/2016 - @delphaber -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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