[]

JAVASCRIPT

  • Tipi primitivi o Tipi valore
    • String
      Number
      Boolean
      Symbol //unique value
      undefined
      null
  • Tipi Referenza
    • Object
      Functions (=Object)
      Array (=Object)
  • Lose equally (==)
    • 1=='1'; //true
      1==[1] //true
      '1'== [1] //true
  • Strict equally (===) , Strict inequality (!==)
    • 1 === '1'; //false
      1 === [1] //false
      '1' === [1] //false
  • Operatore esponenziale
    • let x=3;
      let y=2;
      let result = x ** y = 8; //3 alla seconda
  •  Falsy =>
    • undefined
      null
      Nan
      0, -0
      '', "" (empty string)
      false

      function countTruthy(array){
      let count = 0;
      let arrFalsy = [false, NaN, null, undefined, '', 0];

      for(const item of array){
      if(arrFalsy.includes(item))
      count++;
      }

      return count;
      }
  • Truthy => Ogni cosa che non è Falsy è Truphy
    • if(valore) => true 
      allora valore è truphy
  • Regola del corto-circuito =>
    • Una catena di operatori logici usati su variabili non booleane ritorna la prima variabile ad avere un valore (truthy) corto circuitando il resto della catena  
    • //Questa regola può essere usata per fornire un valore di default 
      //e solo eventualmente sovrascriverlo con quello scelto dall'utente
      //se selectedColor non ha un valore allora currentColor = defaultColor
      let defaultColor = 'red';
      let selectedColor = 'green';
      let currentColor = selectedColor || defaultCoror;
  • For-in (loop per iterare le proprietà di un oggetto)
    • let person = {
      name: 'Pippone',
      cognome: 'Red'
      }

      for (let key in person) {
      if (Object.hasOwnProperty.call(person, key)) {
      console.log(key, person[key]);
      }
      }
  • For-of (loop per iterare un array o ogni tipo iterable)
    • const colors = ['Red', 'Green', 'Blue'];
      for (let color of colors) {
      console.log(color);
      }
  • forEach
    • const colors = ['Red', 'Green', 'Blue'];
      colors.forEach((number, index) => console.log(index, number));
  • FizzBuzz
    • function fizzBuzz(input) {
      if (typeof input !== 'number')
      return NaN;

      let isby3 = (input % 3) == 0 ? true : false;
      let isby5 = (input % 5) == 0 ? true : false;

      if (isby3 && isby5)
      return 'FizzBuzz';

      if (isby3)
      return 'Fizz';

      if (isby5)
      return 'Buzz';

      return input;
      }
  • Numeri primi
    • showPrimes(20);

      function showPrimes(limit) {
      for (let number = 2; number <= limit; number++)
      if (isPrime(number)) console.log(number);
      }

      function isPrime(number) {
      for (let factor = 2; factor < number; factor++) {
      if (number % factor == 0)
      return false;
      }
      return true;
      }
  • Template literals
    • //usando il carattere backticj k (`) è possibile creare una string su più linee 
      //e senza la necessita di usare i caratteri di escape
      let firstName = 'Mosh';
      let stringa = `prima riga ${firstName}
      seconda' riga`;
  • Date
    • let now = new Date();
      let date1 = new Date('May 11 2018 09:00');
      let date2 = new Date('2018-05-11T09:00');
      let date2 = new Date(2018, 4, 11, 9);

 

OOP IN JAVASCRIPT

  • Creare oggetti
    • Factory Function
      • let circle1 = createCircle(1);
        let circle2 = createCircle(2);

        //Usare Camel case
        function createCircle(radius) {
        return {
        radius, //radius:radius,
        draw() {
        console.log('draw');
        }
        };
        }
    • Constructor
      • //la parola chiave 'new' permette in modo trasparente di =>
        //1- Creare un oggetto vuoto (obj = {})
        //2- Fare in modo che 'this' punti a tale oggetto
        //3- Ritornare tale oggetto via la funzione Circle

        let circle1 = new Circle(1); // equivale a fare => Circle.call({}, 1);
        let circle2 = new Circle(2); // equivale a fare => Circle.call({}, 2);

        //Usare Pascal case
        function Circle(radius) {
        this.radius = radius;
        this.draw = function () {
        console.log('draw');
        }
        }
  • Listare le proprietà di un oggetto => Object.keys , Object,entries
    • for(let key in cicle)
      console.log(key, circle[key]);

      for(let key of Object.keys(circle))
      console.log(key);


      for(let entry of Object.entries(circle))
      console.log(entry);

      if('radius' in circle) console.log('exists');
  • Clonare un oggetto => Object.assign
    • //Old JS method to clone an object
      const another1 = {}
      for (let key in circle)
        another[key] = circle[key];

      //New JS method to clone
      const another2 = Object.assign({}, circle);
      //Another new JS method to clone
      const another3 = { ...circle }; //spread operator
      //JSON
      const another4 = JSON.parse(JSON.stringify(circle));

  • Equal
    • //verifico se due oggetti sono uguali (le loro proprietà hanno lo stesso valore)
      function areEqual(object1, object2) {
        for (let key in object1) {
            if (object1[key] !== object2[key])
                return false;
        }
        return true;
      }

      //verifico se due oggetti sono in effetti lo stesso
      //(2 variabili puntano alla stessa cella di memoria)
      function areSame(object1, object2) {
        return (object1 === object2);
      }
  • Proprietà generali =>
    • Gli oggetti in JS sono DINAMICI. E’ possbile aggiungere o togliere membri ad un oggetto anche dopo averlo creato
      • delete circle1.radius
    • Ogni oggetto ha un costruttore 
    • Ogni oggetto ha i metodi call e apply 
      • MyFunction.call({}, param1, param2, ..);
        MyFunction.apply({}, [param1, param2, ..])
    • Le funzioni in JS sono degli oggetti
    • Hoisting =>
      • La JS engine a runtime sposta le dichiarazioni delle funzoni in cima al file cos’ che si possa chiamarle senza problemi. 
      • Non funziona con le classi.
    • Scope
      • <var>
        • In una funzione => Lo scope di una variabile dichiarata <var> è all’interno della funzione in cui la stessa è dichiarata.
        • Fuori da una funzione => E’ una variabile globale che è visibile anche nell’oggetto <window>.
      • <let>, <cons>t
        • In una funzione => Lo scope di una variabile dichiarata <let>, <const> è di tipo block.
        • Fuori da una funione=> E’ una variabile globale che non è visibile nell’oggetto <window>.
    • This
      • Se usato in un metodo referenzia l’oggetto stesso;
      • Se usato in una funzione classica referenzia l’oggetto <window>;
        • const video = {
          title: 'title1',
          tags: ['tag1', 'tag2'],

          //version1: passando this come parametro aggiuntivo al metodo forEach
          showTags() {
          this.tags.forEach(function(tag) {
          console.log(this.title, tag);
          }, this);
          },

          //versione2: usando Bind e passandogli this
          showTagsV2() {
          this.tags.forEach(function(tag) {
          console.log(this.title, tag);
          }.bind(this));
          },

          //usando la sintassi con la freccia, lo scope è preservato e anche nel forEach è possibile
          //referenziare this come l'oggetto Video e non <window>
          showTagsV3() {
          this.tags.forEach(
          (tag) => console.log(this.title, tag)
          );
          }

          };

          video.showTags();

 

ARRAY

  • Aggiungere elementi (<push> /<unshift> / <splice>) 
    • let numbers = [3,4];

      //aggiungo elementi alla fine
      numbers.push(5); // [3,4,5]

      //aggiungo elementi all'inizio
      numbers.unshift(2); // [2,3,4,5]

      //aggiungo in mezzo partendo dalla posizione indicata
      numbers.splice(<start_position>, 0, <elements_to_add>);
      numbers.splice(2, 0, 'a', 'b'); // [2, 3,'a', 'b', 4, 5];
  • Eliminare elementi (<pop>, / <shift> / <splice>)
    • let numbers = [1,2,3,4,5,6];

      //elimino alementi alla fine
      numbers.pop(); // [1,2,3,4,5];

      //elimino alementi alla fine
      numbers.shift(); // [2,3,4,5];

      //elimino elementi nel mezzo partendo dalla posizione indicata
      //numbers.splice(<start_position>, <delete_count>);
      numbers.splice(1,2) // [2,5];
  • Trovare elemento di tipo primitivo (<indexOf> / <includes>)
    • const numbers = [1, 2, 3, 4];

      //ricerca tipi primitivi, vecchia maniera
      console.log(numbers.indexOf('1') !== -1);

      //ricerca tipi primitivi, nuova maniera
      console.log(numbers.includes(1));
  • Trovare elemento di tipo referenza (<find> / <findIndex>)
    • const courses = [
        { id: 1, name: 'a' },
        { id: 2, name: 'b' },
      ];

      //ritorna il primo elemento che corrisponde al criterio indicato
      //se non trova nulla => undefined
      let course = courses.find(course => course.name === 'a');

      //ritorna l'indice del primo elemento che corrisponde al criterio indicato
      //se non trova nulla => -1
      let courseIndex = courses.findIndex((course) => course.name === 'a');
  • Svuotare un array
    • let numbers = [2,3,4,5];

      //solution 1
      numbers = [];

      //solution 2 (!la migliore!)
      numbers.length = 0;

      //solution 3
      numbers.splice(0, numbers.length);

      //solution 4
      while (numbers.length > 0)
        numbers.pop();
  • Unire o dividere array (<concat> ( <slice> /<spread operator>)
    • let first = [1,2,3];
      let second = [4,5];

      let combined = first.concat(second); // [1,2,3,4,5]
      let combined2 = [...first, 'a', ...second, 'b']; //[1,2,3,'a,',4,5,'b'];

      let sliceFirst = first.slice(0, 2); // [1,2]
  • Ordinare un array  (<sort>)
    • const courses = [
        { id: 1, name: 'Javascript' },
        { id: 2, name: 'Node.js' },
      ];

      courses.sort((a, b) => a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1);
  • Verificare elementi di un array (<every> / <some>)
    • const numbers = [-1, 2, 3];

      //verifico se ogni elemento dell'array rispetti il criterio indicato
      let isAllPositive = numbers.every(value => value > 0)); // false

      //verifico che almeno un elemento dell'array rispecchi il criterio indicato
      let atLeastOnePositive = numbers.some(value => value > 0)); //true
  • Filtrare elementi di un array (<filter>)
    • const numbers = [-1, 2, 3];

      let filteredNumbers = numbers.filter(value => value > 0); // [2,3]
  • Trasformare gli elementi di un array (<map>)
    • const numbers = [1, 2, 3];

      let mappedNumbers = numbers.map((value, index) => `<li id='${index}'>${value}</li>`);
      //<li id='0'>1</li>
      //<li id='1'>2</li>
      //<li id='2'>3</li>

      //è possibile mappare il risultato ad un oggetto
      let objectNumbers = numbers.map((value, index) => ({ indice: index, valore: value }));
  • Ridurre gli elementi di un array (<reduce>)
    • const numbers = [1, 2, 3];

      //E' possibile sommare gli elementi di un array
      //Il secondo parametro del metodo <reduce> indica il valore iniziale del parametro accumulator
      //Se non viene passato nessun parametro, il valore iniziale dell'accumulator sarà il primo valore dell'array
      //che verrà quindi saltato nei calcoli.
      let somma = numbers.reduce(
      (accumulator, number) => accumulator + number
      ); // 6

      let conta = numbers.reduce(
      (accumulator, number) => {
      return accumulator + number;
      }
      , 0);

      //ritorna il max
      let max = numbers.reduce((a,value) => (a > value) ? a: value);



      ----- esempio completo --- const movies = [ { title: 'a', year: 2018, rating: 4.5 }, { title: 'b', year: 2018, rating: 4.7 }, { title: 'c', year: 2018, rating: 3 }, { title: 'd', year: 2017, rating: 4.5 }, ]; let mov = movies .filter(movie => movie.rating > 4 && movie.year === 2018) .sort((a, b) => a.rating - b.rating) .reverse() .map(m => m.title); // [0:b, 1:a]

FUNZIONI

  • Parametri (<arguments>) e operatore […rest] 
    • let somma = sum(1,2,3,4,5) //15

      //In JS ogni funzione può accedere alla lista dei suoi parametri
      //grazie alla parola chiave <arguments>
      //Il numero di tali parametri non è fissato a priori ma può variare a piaceimento.
      function sum(){
      let total = 0;
      for(let valore of arguments)
      total += valore;

      return total;
      }

      //Modern JS: operatore rest
      //Il parametro di tipo rest deve essere forzatamente l'ultimo
      function sum(discount, ...args){
      const total = args.reduce((a,b) => a + b);
      return (total * (1-discount));
      }

      //Moders JS: esempio di utilizzo dell'operatore rest
      //Alla funzione sum posso passare sia una lista di valori che un array
      function sum(...items) {     //l'operatore ...rest trasforma i parametri in ingresso in un array     //Nel caso passi una sequenza di valori, allor avrò un array con tali valori     //Nel caso passi un'array, avrò un array di array     if (items.length === 1 && Array.isArray(items[0]))         items = [...items[0]];  //appiattisco l'array di array in un solo array (...spread)     return items.reduce((a, b) => a + b); } console.log(sum(1, 2, 3, 4)); console.log(sum([1, 2, 3, 4]));
  • Valori di default 
    • //Se passo un parametro con un valore di default, 
      //necessariamente tutti quelli che seguono devono anch'essi un valore di default
      function interest(principal, rate = 3.5, years = 5) {
      return principal * rate / 100 * years;
      }    
  • Getter, Setter
    • //Factory Function
      const person = {
        firstName: 'Mosh',
        lastName: 'Hamadani',
        get fullName() {
            return `${person.firstName} ${person.lastName}`;
        },
        set fullName(value) {
            const parts = value.split(' ');
            this.firstName = parts[0];
            this.lastName = parts[1];
        }
      };

      person.fullName = 'Nicola Riccardi';

      console.log(person.fullName);


      //Constructor function
      function Person(firstName, lastName) {
      this.firstName = firstName;
      this.lastName = lastName;

      Object.defineProperty(this, "fullName", {
      get: function() {
      return `${this.firstName} ${this.lastName}`;
      },
      set: function(value) {
      const parts = value.split(' ');
          this.firstName = parts[0];
          this,lastName = parts[1];
      }
      });
      }

  • Error Handling
    • if (typeof value !== 'string')
      throw new Error('Value is not a valid string');

      try {
      ...
      } catch(e) {
      alert(e);
      }
  • Stopwatch example
    • function Stopwatch() {
          let duration = 0, running = false, startTime, endTime;
      
          this.Reset = function () {
              duration = 0;
              running = false;
              startTime = null;
              endTime = null;
          }
      
          this.Start = function () {
              if (running)
                  throw new Error('Stopwatch has already started!');
      
              startTime = new Date();
              running = true;
          }
      
          this.Stop = function () {
              if (!running)
                  throw new Error('Stopwatch is not started!');
      
              endTime = new Date();
              running = false;
      
              const seconds = (endTime.getTime() - startTime.getTime()) / 1000;
              duration += seconds;
          }
      
          Object.defineProperty(this, 'duration', {
              get: function () {
                  return duration;
              }
          });
      }

PROTOTYPE

  • Prototypical inheritance => Ogni oggetto eredità i metodi e le proprità del suo prototipo. Se tale medoto è definito in entrambi padre e figlio, allora verrà eseguito in priorità quello del figlio.
    • // Prototypical inheritance 
      Circle.prototype = Object.create(Shape.prototype);
      Circle.prototype.constructor = Circle; 
      
  • Ogni oggetto in JS tranne l’oggetto root ha un parent/prototype. (root=objectBase).
  • Il prototype di un oggetto è uguale al prototipo del suo costruttore.
  • Quando istanzio più variabili di un oggetto. In memoria ci sarà solo un prototype per tutte le variabili istanziate.
  • In JS abbiamo proprità di tipo istanza (own property) (quelle legate all’oggetto) e proprità di tipo prototipo (quelle legate al prototype di tale oggetto).
    • let circle = new Circle(1);
      
      function Circle(radius) {
          this.radius = radius;
      //creo un metodo di tipo istanza chiamato move
      this.move = function() {
      ...
      } }
      //Creo un metodo di tipo prototype chiamato draw
      //in un membro di tipo protorype posso referenziare un metodo di tipo istanza (e viceversa)
      Circle.prototype.draw = function () {
      this.move(); console.log('draw'); }
      //Sovrascrivo uil metodo di tipo prototype toString Circle.prototype.toString = function () { return 'Circle with ' + this.radius; }
  • Descrittori di proprietà
    • let person = { name: 'Mosh' };


      Object.defineProperty(person, 'name', {
      writable:false, //imposto la proprità name dell'oggetto person come in solo lettura
      enumerable:false //imposto la proprità name dell'oggetto person non enumerabile
      //non viene mostrata con Object.keys(person)
      configurable:false //la proprità non può essere eliminata
      });
  • Object.create => Ereditarietà
    • //Imposto come prototype di Circle l'oggetto Shape
      //così da ereditare il medoto duplicate
      //Se ispeziono il __Proto__ di un'istanza di Circle avrò la seguente catena di ereditarietà
      // => istanza circle -> CircleBase -> ShapeBase -> ObjectBase

      //definisco un oggetto che sarà il nostro padre
      function Shape(color) {
      this.color = color; }

      //definisco un metodo e lo associo all'oggetto padre Shape.prototype.duplicate = function () { console.log('duplicate'); }
      //definisco un oggetto che sarà il nostro figlio function Circle(radius, color) {
      //setto la proprietà color definità nel padre => super constructor
      Shape.call(this, color);
      this.radius = radius; }
      //imposto Shape come padre (prototype) di Circle
      //E' necessario risettare anche il constructor a Circle, se no diventerebbe Shape
      Circle.prototype = Object.create(Shape.prototype);
      Circle.prototype.constructor = Circle; let circle = new Circle(1, 'red'); console.log(circle.duplicate());
  • Intermidiate inheritance function
    • //E' possibile riscrivere il codice precedente è usare una funzione generica
      //per extendere l'oggetto Circle con le proprietà dell'oggetto Shape
      //Il figlio eredità tutti i membri definiti nel prototype del padre
      function extend(Child, Parent) { Child.prototype = Object.create(Parent.prototype); Child.prototype.constructor = Child; }

      //Se voglio ereditare sia i membri istanza (own) che i membri prototipo devo
      Child.prototype = new Parent();
  • Overriding => Riemplemento un metodo nel figlio
    • //riprendendo l'esempio sopra, è possibile fare l'override del metodo duplicate
      //nell'oggetto fliglio Circle semplicemente aggiungendo la seguente definizione stando attendi
      /di aggiungerla dopo la definizione del metodo duplicate del padre
      Circle.prototype.duplicate = function () {
      //posso chiamare il metodo definito nel padre Shape.prototype.duplicate.call(this);
      //sovrascrivo il metodo definito nel padre console.log('duplicate circle'); }
  • Polimorfismo => Sfruttando l’ereditarietà e l’ovveriding è possibile ottenere un comportamento diverso di uno medesimo metodo ereditato da due oggetti diversi da uno stesso padre . 
  • Mixins => Per non esagerare con i livelli di ereditarietà.è possibile utilizzare la composizione per ottenere oggetti con caratteristiche diverse.
    • //Ho 3 proprietà che posso comporre per estendere le caratteristiche dei miei oggetti
      const canEat = { eat: function () { this.hunger--; console.log('eating'); } } const canWalk = { walk: function () { console.log('walking'); } } const canSwim = { swim: function () { console.log('swimming'); } }
      //Generalizzo il metodo per associare ad un oggetto le funzioni desiderate function mixin(target, ...sources) { //rest operator Object.apply(target, ...sources) //spread operator } //creo oggetto Person function Person() { } //aggiungo al prototype la capacità di mangiare e camminare mixin(Person.prototype, canEat, canWalk) //creo oggetto Goldfish function Goldfish() { } //aggiungo al prototype di Goldfish la capacità di mangiare e nuotare mixin(Goldfish.prototype, canEat, canSwim)
      //uso gli oggetti estesi a piacimento const person = new Person(); const fish = new Goldfish();

CLASSI (ES6)

  • //Class declaration
    //In realtà una classe in JS viene trasformata in una normale funzione dalla JS engine class Circle { constructor(radius) { this.radius = radius; //questa funzione non è presente nel prototype //dell'oggetto Circle this.move = function () { console.log('move') } } //questa funzione è presente nel prototype
    //Instance method draw() { console.log('draw'); }

    //static method
    static parse(str){
    const radius = JSON.parse(str).radius;
    return new Circle(radius);
    } } const c = new Circle(1);
    const c2 = Circle.parse('{"radius":1}');

    //Class expression
    let circle = class {
    }
  • Posso avere static method. In questo caso non sono accessibili in un’istanza di un oggetto ma direttamenta dall’oggetto stesso.
  • this => ‘use strict’ 
    • Quando si crea un oggetto tramite la parola chiave <new>, <this> punta a tale oggetto e non all'oggetto <window>. 
      A volte possiamo sbagliarci e per evitare di modificare senza volerlo l'oggetto globale <window> è possibile utilizzare
      la dichiarazione 'use strict' per forzare la JS engine a rendere <window> non accessibile nel caso si chiami un metodo come funzione.
      Infatti all'interno di tale metodo <this> non punterà più come dovrebbe a <window> ma verrà impostato = undefined.

      'use strict'

      const Circle = function(){
      this.draw = function() { console.log(this); }
      }

      const c = new Circle();
      //Method call => in questo caso this=oggetto Circle
      c.Draw();

      const draw = c.draw;
      //Function call
      //=> in questo caso this=<window> senza 'use strinct'
      //=> in questo caso this=undefined con 'use strict'
      draw();
    • Il corpo di una classe è eseguito dalla JS engine sempre in ‘strict mode’ anche se non lo usiamo esplicitamente. Questo per evitare accessi indesiderati all’oggetto globale <window>.
  • Definire metodi o proprietà private
    •  Symbol
      • //In una classe è' possibile definire proprietà o metodi usando delle variabili di tipo Symbol
        const _radius = Symbol(); //ritorna un unique value
        const _draw = Symbol();

        class Circle {
        constructor(radius) {
        //definisco la proprietà privata <_radius>
        this[_radius] = radius;
        }

        //definisco il metodo privato <_draw>
        [_draw]() {
        ...
        }
        }
    • WeakMap
      • //Un weakmap è un dictionary dove key=oggetti, value=qualsiasi cosa
        //Uso una variabile di tipo WeakMap per aggiungere la proprietà private _radius all'oggetto Circle
        const _radius = new WeakMap();
        const _draw = new WeakMap();

        class Circle() {
        constructor(radius){
        //setto la proprietà private _radius
        _radius.set(this, radius);

        _draw.set(this, function() { console.log('draw', this); }); //this = undefined
        //oppure uso la arrow function notation
        _draw.set(this, () => { console.log('draw', this); }); //this = Circle
        }

        move() {
        //accedo alla proprietà private _radius
        let radius = _radius.get(this); //1

        //accedo al metodo private _draw()
        _draw.get(this)();
        }
        }

        const c = new Circle(1);
  • Getter, Setter
    • const _radius = new WeakMap();

      class Circle() {
      constructor(radius){
      _radius.set(this, radius);
      }

      get radius() {
      return _radius.get(this);
      }

      set radius(value) {
      if(value<0) throw new Error('Invalid value!');
      _radius.set(this, value);
      }
      }

  • Ereditarietà
    • //Uso la parola chiave <extends> per creare una classe Circle figlia della classe Shape
      //<extends> automaticamente setta il prototype di Circle = Shape
      //<extends> automaticamente setta il prototype.constructor = Circle

      //oggetto padre
      Class Shape {
      constructor(color) {
      this.color = color;
      }

      //prototype method
      move() {
      console.log('move');
      }
      }

      //oggetto figlio
      //se dichiaro un construttore nella classe figlio devo
      //necessariamente chiamare prima il costruttore della classe padre
      Class Circle extends Shape {
      constructor(color, radius) {
      //chiamo il costruttore della classe padre => !è necessario!
      super(color);
      this.radius = radius;
      }

      //prototype method
      draw() {
      console.log('draw');
      }
      }

      const c = new Circle('red', 1);
      c.move();
      c.draw();
  • Override
    • class Shape {
      move() {
      console.log('Sono una forma');
      }
      }

      class Circle extends Shape {
      move() {
      //volendo posso richiamare il metodo del padre
      //super.move();
      console.log('Sono un cerchio');
      }
      }

      let c = new Circle();
      //Come conseguenza dell'eredità prototipale verrà eseguito il primo metodo move() trovato nel tree dei prototipi
      //passando dall'oggetto Circle, BaseCircle, Shape, BaseShape, ObjectBase
      c.move() //'Sono un cerchio'
  • Esempio classe Stack
    • const _items = new weakMap();

      class Stack { constructor() { _items.set(this, []); } get count() { return _items.get(this).length; } push(obj) { _items.get(this).push(obj); } peek() { const items = _items.get(this) if (items.length === 0) throw new Error('Stack is empty!'); return items[items.length - 1]; } pop() { const items = _items.get(this); if (items.length === 0) throw new Error('Stack is empty!'); return items.pop(); } }

MODULI

  • CommonJs (Node.js)
    • //my_module.js
      class Circle {
      draw() { ... }
      }
      module.exports.circle = Circle;


      //index.js
      const c = require('./circle');
      circle.draw();
  • ES6
    • //my_module.js
      export class Circle {
      draw() { ... }
      }

      //index.js
      import {Circle} from './circle'

      const c = new Circle();
      c.draw();

JQUERY

  • Linkare la libreria online (e non sul proprio server)
    • <script type="text/javascript"      
      src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js">
      </script>
  • Eseguire il codice Jquery assolutamente quando il DOM è stato completamente caricato
    • $(document).ready(function(){ ... });
  • Selezionare elementi =>
    • Comandi base:
      • //E' possibile usare indiferentemente $('') oppure $("")
        $("div"); //selects all HTML div elements
        $("#myElement"); //selects one HTML element with ID "myElement"
        $(".myClass"); //selects HTML elements with class "myClass"
        $("p#myElement"); //selects paragraph elements with ID "myElement"
        $("ul li a.navigation"); //selects anchors with class "navigation" nested in list
    • Selettori CSS3:
      • $("p > a"); //selects anchors that are direct children of paragraphs
        $("input[type=text]"); //selects inputs that have specified type
        $("a:first"); //selects the first anchor on the page
        $("p:odd"); //selects all odd numbered paragraphs
        $("li:first-child"); //every list item that's first child in a list
    • Selettori JQuery:
      • $(":animated"); //selects elements currently being animated
        $(":button"); //selects any button elements (inputs or buttons)
        $(":radio"); //selects radio buttons
        $(":checkbox"); //selects checkboxes
        $(":checked"); //selects selected checkboxes or radio buttons
        $(":header"); //selects header elements (h1, h2, h3, etc.)
  • Lavore con le classi =>
    • //aggiungere, rimuove o fare il toggle della class "content" in tutti i <div>
      $("div").addClass("content"); $("div").removeClass("content"); $("div").toggleClass("content");

      //verificare se un elemento ha una certa classe
      if ($("#myElement").hasClass("content")) { ... }
  • Lavorare con gli syles CSS =>
    • $("p").css("width", "400px"); // adds a width to all paragraphs
      $("#myElement").css("color", "blue") // makes text color blue on element #myElement
      $("ul").css("border", "solid 1px #ccc") // adds a border to all lists
  • Lavorare con elementi del DOM =>
    • //gets all HTML (including text) inside #myElement
      let
      myElementHTML = $("#myElement").html(); // similar to innerHTML in JavaScript

      //gets all text (excluding HTML) inside #myElement
      let myElementHTML = $("#myElement").text();

      //changes the HTML or text content of a specified element
      $("#myElement").html("<p>This is the new content.</p>"); $("#myElement").text("This is the new content.");

      //appends the HTML or text content of a specified element
      $("#myElement").append("<p>This is the new content.</p>"); $("p").append("<p>This is the new content.</p>");

      appendTo(), prepend(), prependTo(), before(), insertBefore(), after(), insertAfter()
  • Lavorare con gli eventi =>
    • $("a").click(function() {
        // do something here when any anchor is clicked
      });

      blur, focus, hover, keydown, load, mousemove, resize, scroll, submit, select
  • Mostrare/Nascondere elementi =>
    • //opzionalmente può essere impostata una funzione di callback
      //che viene eseguita dopo che l'elemento è mostrato/nascosto
      $("#myElement").hide("slow", function() { // do something once the element is hidden } $("#myElement").show("fast", function() { // do something once the element is shown }
      //1000milliseconds, velocità nel mostrare o nascondere l'elemento $("#myElement").toggle(1000, function() { // do something once the element is shown/hidden }
      $("#myElement").fadeOut("slow", function() {
        // do something when fade out finished
      }
      
      $("#myElement").fadeIn("fast", function() {
        // do something when fade in finished
      }
      $("#myElement").fadeTo(2000, 0.4, function() {
        // do something when fade is finished
      }
      //fare il fade di un elemento solo parzialmente
      //0.4 rappresenta l'opacità
      $("#myElement").fadeTo(2000, 0.4, function() { // do something when fade is finished }

RISORSE

  • Transpiler (Translator + compiler) => Convertitore da JS moderno a JS classico (https://babeljs.io)
    • 1- creare una nuova cartella /es6-tooling
      2- inizializzare un nuovo progetto node.js => cmd>npm init --yes (questo comando crea il file package-json)
      3- installare 3 pacchetti per avere Babel => cmd>npm i babel-cli@6.26.0 babel-core@6.26.0 babel-preset-env@1.6.1
      4- nella cartella /es6-tooling aggiungo un file index.js con il codice moderno da tradurre
      5- modifico il file package-json aggiungendo nel nodo "scripts"
      "babel": "babel --presets env index.js -o build/index.js"
      6- lancio la traduzione del file index.js in javascript classico => cmd>npm run babel
  • Bundler => crea 1 file js a partire da molti e minimizarli (https://webpack.js.org)
    • 1- installo webpack globalmente -> cmd>npm i -g webpack-cli@2.0.14
      2- nella cartella del progetto inizializzo webpack -> cmd>webpack-cli init
      3- inizializzare un nuovo progetto node.js => cmd>npm init --yes (questo comando crea il file package-json)
      4- modifico il file package-json aggiungendo nel nodo "scripts"
      "build": "webpack"
      5- lancio il bundle dei file che ho messo nella cartella "/src" e li trovo in "/dist" => cmd>npm run build