JavaScript

Francesco Soncina aka phra

  • Bachelor degree in Computer Science
  • Full Stack Developer
  • DevOps
  • JavaScript Enthusiast
  1. JavaScript
  2. ECMAScript 2015 (ES6)
  3. jQuery

Abstract

JavaScript

Storia

  • Standardizzato per la prima volta nel ~1998
  • Nato per rendere dinamiche le pagine HTML
  • La versione corrente è ECMAScript 2015
  • Utilizzato storicamente nel browser
  • Oggi si può utilizzare anche lato server (NodeJS)

Caratteristiche

  • Esecuzione single-thread
  • Asincrono per natura
  • Non ha vere classi come OOP
  • Simula ereditarietà degli oggetti linkandoli tra loro
  • Prototype-linked objects

Dati primitivi

  • Number
  • String
  • Boolean
  • Object
  • Array
  • Function
  • undefined
  • null
typeof 42             === "number";    // true
typeof true           === "boolean";   // true
typeof "42"           === "string";    // true
typeof { life: 42 }   === "object";    // true
typeof function a(){} === "function";  // true
typeof []             === "object";    // true
typeof undefined      === "undefined"; // true
typeof null           === "object";    // true

Operatori

"42" == 42  //true
"42" === 42 //false
42 === 42   //true
"42" != 42  //true
"42" !== 42 //true
42 !== 42   //false
42 >= 42    //true
42 >= "42"  //true
42 <= 42    //true

Valori falsy

  • ""
  • 0, -0, NaN
  • false
  • undefined
  • null

Array

var array = [1, "2", [3], {n: 4}];

Oggetti

var object = {
    key: "value",
    anotherKey: 42
};

Funzioni

function funzione(parametro1, parametro2) {
    console.log(parametro1, parametro2);
}
var funzione = function(parametro1, parametro2) {
    console.log(parametro1, parametro2);
}

Scope lessicale

this

function foo() {
    console.log( this.bar );
}

var bar = "global";

var obj1 = {
    bar: "obj1",
    foo: foo
};

var obj2 = {
    bar: "obj2"
};

foo();              // "global"
obj1.foo();         // "obj1"
foo.call( obj2 );   // "obj2"
new foo();          // undefined

IIFE

var p = "global";

(function iife(parametro) {
    var p = parametro;
    console.log(p); // "parametro"
})("parametro");

console.log(p); // "global"

(Immediately-Invoked Function Expression)

Closures

function CoolModule() {
    var something = "cool";
    var another = [1, 2, 3];

    function doSomething() {
        console.log( something );
    }

    function doAnother() {
        console.log( another.join( " ! " ) );
    }

    return {
        doSomething: doSomething,
        doAnother: doAnother
    };
}

var foo = CoolModule();

foo.doSomething(); // "cool"
foo.doAnother(); // "1!2!3"

Closures

for (var i=1; i<=5; i++) {
    setTimeout( function timer(){
        console.log( i );
    }, i*1000 );
}

// 6 6 6 6 6

Closures

for (var i=1; i<=5; i++) {
    (function(){
        var j = i;
        setTimeout( function timer(){
            console.log( j );
        }, j*1000 );
    })();
}

// 1 2 3 4 5

Prototype-linked objects

a: 42

b: "42"

foo

bar

prototype link

console.log(bar.b); // "42"
console.log(bar.a); // 42

JSON

(JavaScript Object Notation)

{
  "firstName": "John",
  "lastName": "Smith",
  "isAlive": true,
  "age": 25,
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postalCode": "10021-3100"
  },
  "phoneNumbers": [
    {
      "type": "home",
      "number": "212 555-1234"
    },
    {
      "type": "office",
      "number": "646 555-4567"
    }
  ],
  "children": []
}

ECMAScript 2015

Novità

  • Ultima versione dello standard
  • ECMAScript 2016 già in sviluppo
  • Introduce nuovi paradigmi e syntax-sugar
  • Oggi la compatibilità è quasi completa con gli ultimi browsers
  • Per versioni antecedenti possiamo transpilare in ES5
  • Transpiler più famosi: Babel, TypeScript, Closure

let keyword

var a = 2;

{
    let a = 3;
    console.log(a);   // 3
}

console.log(a);       // 2

const keyword

{
    const a = [1,2,3];
    a.push( 4 );
    console.log(a); // [1,2,3,4]

    a = 42;         // TypeError!
}

Spread / Rest

function foo(x,y,z) {
    console.log( x, y, z );
}

foo( ...[1,2,3] ); // 1 2 3

Spread / Rest

var a = [2,3,4];
var b = [ 1, ...a, 5 ];

console.log(b); // [1,2,3,4,5]

Spread / Rest

function foo(...args) {
    console.log(args);
}

foo( 1, 2, 3, 4, 5); // [1,2,3,4,5]

Default parameter values 

function foo(x = 11, y = 31) {
    console.log(x + y);
}

foo();               // 42
foo( 5, 6 );         // 11
foo( 0, 42 );        // 42
foo( 5 );            // 36
foo( 5, undefined ); // 36
foo( 5, null );      // 5
foo( undefined, 6 ); // 17
foo( null, 6 );      // 6

Destructuring

function foo() {
    return [1,2,3];
}

function bar() {
    return {x: 4, y: 5, z: 6};
}

var [ a, b, c ] = foo();
var { x: x, y: y, z: z } = bar();
console.log( a, b, c ); // 1 2 3
console.log( x, y, z ); // 4 5 6

Nested destructuring

var metadata = {
    obj: {
        objnested: {
            myarray:
                [1, 2, 3]
        }
    }
};

​var {obj:
        { objnested:
            { myarray:
                [a, b, c]
            }
        }
    } = metadata;

console.log(a,b,c); // 1 2 3

Concise methods

var obj = {
    x: function x(){
        // ..
    }
}

var obj = {
    x() {
        // ..
    }
}

Template Literals

function upper(s) {
    return s.toUpperCase();
}

var who = "reader";

var text =
`A very ${upper( "warm" )} welcome
to all of you ${upper( `${who}s` )}!`;

console.log( text );
// A very WARM welcome
// to all of you READERS!

Arrow functions

function foo(x,y) {
    return x + y;
}

// versus

var foo = (x,y) => x + y;

Arrow functions

var controller = {
    makeRequest: function(..){
        var self = this;

        btn.addEventListener( "click", function(){
            // ..
            self.makeRequest(..);
        }, false );
    }
};

var controller = {
    makeRequest: function(..){
        btn.addEventListener( "click", () => {
            // ..
            this.makeRequest(..);
        }, false );
    }
};

ES6 classes

class Widget {
    constructor(width,height) {
        this.width = width || 50;
        this.height = height || 50;
        this.$elem = null;
    }
    render($where){
        if (this.$elem) {
            this.$elem.css( {
                width: this.width + "px",
                height: this.height + "px"
            } ).appendTo( $where );
        }
    }
}

ES6 classes

class Button extends Widget {
    constructor(width,height,label) {
        super( width, height );
        this.label = label || "Default";
        this.$elem = $("<button>").text( this.label);
    }
    render($where) {
        super.render($where);
        this.$elem.click(this.onClick.bind(this));
    }
    onClick(evt) {
        console.log( "Button '"
            + this.label + "' clicked!");
    }
}

ES6  promises

var p = new Promise(function(resolve, reject) {  
   if (true) {
      resolve(42);
   }
   else {
      reject("error");
   }
});

p.then((val) => console.log("fulfilled:", val),  
       (err) => console.log("rejected: ", err));

ES6  generators

function* g() {
    for (let i = 0; i < 10; i++)
        yield i;
}

for (let i of g())
    console.log(i);

// 1 2 3 4 5 6 7 8 9

jQuery

Caratteristiche

  • Permette di separare completamente HTML e JavaScript
  • Fornisce un'interfaccia unificata multi-browser
  • Write less, do more
  • Estensibile
  • jQuery 1.x supporta IE6+
  • jQuery 2.x supporta IE9+

Funzionalità

  • Multi-browser support
  • DOM Traversing tramite selettori CSS
  • Gestione eventi
  • Gestione animazioni
  • AJAX (AJAJ, AHAH, ...)
  • Estensibile tramite plugins
  • Utilities
  • Promises
  • Polyfills per browsers datati

Installazione

<script src="https://code.jquery.com/jquery-latest.min.js"></script>

index.html

Utilizzo

<script type="text/javascript">
$(document).ready(function(){
        // jQuery code, event handling callbacks here
});
</script>

Event handlers

$('img').click ( function() {
    // handle the click event on any img element in the page
    console.log(this + ' was clicked!');
});

$( window ).resize(function() {
  console.log( "Handler for .resize() called." );
});

$( "#target" ).scroll(function() {
  console.log( "Handler for .scroll() called." );
});

Manipolazione DOM

$('select#carmakes').append($('<option />')
                    .attr({value:"VAG"})
                    .append("Volkswagen"));
$('select#carmakes').html(
    '<option value="VAG">Volkwagen</option>'
);
$('select#carmakes > option').text('Volkwagen');

Utilities

$.each([1,2,3], function() {
  console.log(this);
});
$("li").each(function(index) {
  console.log(index + ": " + $(this).text());
});

Animazioni

$('p').show();
$('p').hide();
$('p').fadeIn();
$('p').fadeOut();
$('p').slideDown();
$('p').slideUp);

AJAX

$.ajax({
  type: "POST",
  url: "example.php",
  data: "name=John&location=Boston"
}).done(function(msg) {
  alert("Data Saved: " + msg);
}).fail(function(xmlHttpRequest, statusText, errorThrown) {
  alert(
    "Your form submission failed.\n\n"
      + "XML Http Request: " + JSON.stringify(xmlHttpRequest)
      + ",\nStatus Text: " + statusText
      + ",\nError Thrown: " + errorThrown);
});

Live Coding

JavaScript & jQuery

By Francesco Soncina

JavaScript & jQuery

  • 371