BabelJS - Funzionalità Transpile ES6 in ES5

In questo capitolo vedremo le funzionalità aggiunte a ES6. Impareremo anche come compilare le funzionalità per ES5 usando BabelJS.

Di seguito sono riportate le varie funzionalità di ES6 che discuteremo in questo capitolo:

  • Lasciate + Cost
  • Funzioni freccia
  • Classes
  • Promises
  • Generators
  • Destructuring
  • Iterators
  • Modello Literalst
  • Oggetto migliorato
  • Proprietà predefinite, di riposo e di diffusione

Lasciate + Cost

Let dichiara una variabile locale con ambito di blocco in JavaScript. Considera il seguente esempio per comprendere l'uso di let.

Esempio

let a = 1;
if (a == 1) {
   let a = 2;
   console.log(a);
}
console.log(a);

Produzione

2
1

Il motivo per cui la prima console stampa 2 è perché a viene dichiarato nuovamente utilizzando let e sarà disponibile solo in ifbloccare. Qualsiasi variabile dichiarata utilizzando let è disponibile solo all'interno del blocco dichiarato. Abbiamo dichiarato la variabile a due volte usando let, ma non sovrascrive il valore di a.

Questa è la differenza tra le parole chiave var e let. Quando dichiari una variabile utilizzando var, la variabile sarà disponibile nell'ambito della funzione o, se dichiarata, agirà come una variabile globale.

Nel caso in cui una variabile venga dichiarata con let, la variabile è disponibile nell'ambito del blocco. Se dichiarato all'interno dell'istruzione if, sarà disponibile solo all'interno del blocco if. Lo stesso vale per switch, for-loop, ecc.

Ora vedremo la conversione del codice in ES5 usando babeljs.

Eseguiamo il seguente comando per convertire il codice:

npx babel let.js --out-file let_es5.js

L'output da es6 a es5 per la parola chiave let è il seguente:

Lascia usando ES6

let a = 1;
if (a == 1) {
   let a = 2;
   console.log(a);
}
console.log(a);

Transpiled usando babel in ES5

"use strict";

var a = 1;
if (a == 1) {
   var _a = 2;
   console.log(_a);
}
console.log(a);

Se vedi il codice ES5, la parola chiave let viene sostituita con varparola chiave. Anche la variabile all'interno del blocco if viene rinominata_a avere lo stesso effetto di quando dichiarato con il let parola chiave.

Const

In questa sezione, impareremo il funzionamento della parola chiave const in ES6 e ES5. La parola chiave Const è disponibile anche nell'ambito; e se all'esterno, genererà un errore. Il valore della variabile dichiarata const non può essere modificato una volta assegnato. Consideriamo il seguente esempio per capire come viene utilizzata la parola chiave const.

Esempio

let a =1;
if (a == 1) {
   const age = 10;
}
console.log(age);

Produzione

Uncaught ReferenceError: age is not defined at 
      
       :5:13 
      

L'output di cui sopra genera un errore poiché la const age è definita all'interno del blocco if ed è disponibile all'interno del blocco if.

Comprenderemo la conversione in ES5 utilizzando BabelJS.

ES6

let a =1;
if (a == 1) {
   const age = 10;
}
console.log(age);

Comando

npx babel const.js --out-file const_es5.js

Transpiled in ES6 utilizzando BabelJS

"use strict";

var a = 1;
if (a == 1) {
   var _age = 10;
}
console.log(age);

In caso di ES5, la parola chiave const viene sostituita con la parola chiave var come mostrato sopra.

Funzioni freccia

Una funzione Arrow ha una sintassi più breve rispetto all'espressione variabile. è anche chiamata funzione freccia grassa o funzione lambda. La funzione non ha una sua proprietà. In questa funzione, la funzione parola chiave viene omessa.

Esempio

var add = (x,y) => {
   return x+y;
}

var k = add(3,6);
console.log(k);

Produzione

9

Utilizzando BabelJS, trasferiremo il codice sopra in ES5.

ES6 - Funzione freccia

var add = (x,y) => {
   return x+y;
}

var k = add(3,6);
console.log(k);

Comando

npx babel arrowfunction.js --out-file arrowfunction_es5.js

BabelJS - ES5

Utilizzando Babel, la funzione freccia viene convertita in funzione di espressione variabile come mostrato di seguito.

"use strict";

var add = function add(x, y) {
   return x + y;
};

var k = add(3, 6);
console.log(k);

Classi

ES6 viene fornito con la nuova funzionalità Classi. Le classi sono simili all'ereditarietà basata su prototipi disponibile in ES5. La parola chiave class viene utilizzata per definire la classe. Le classi sono come funzioni speciali e hanno somiglianze come l'espressione di funzioni. Ha un costruttore, che viene chiamato all'interno della classe.

Esempio

class Person {
   constructor(fname, lname, age, address) {
      this.fname = fname;
      this.lname = lname;
      this.age = age;
      this.address = address;
   }

   get fullname() {
      return this.fname +"-"+this.lname;
   }
}
var a = new Person("Siya", "Kapoor", "15", "Mumbai");
var persondet = a.fullname;

Produzione

Siya-Kapoor

ES6 - Classi

class Person {
   constructor(fname, lname, age, address) {
      this.fname = fname;
      this.lname = lname;
      this.age = age;
      this.address = address;
   }

   get fullname() {
      return this.fname +"-"+this.lname;
   }
}
var a = new Person("Siya", "Kapoor", "15", "Mumbai");
var persondet = a.fullname;

Comando

npx babel class.js --out-file class_es5.js

BabelJS - ES5

C'è del codice extra aggiunto usando babeljs per far funzionare la funzionalità per le classi come in ES5. BabelJs si assicura che la funzionalità funzioni come avrebbe fatto in ES6.

"use strict";

var _createClass = function () {
   function defineProperties(target, props) {
      for (var i = 0; i < props.length; i++) {
         var descriptor = props[i];
         descriptor.enumerable = descriptor.enumerable || false;
         descriptor.configurable = true;
         if ("value" in descriptor) descriptor.writable = true;
         Object.defineProperty(target, descriptor.key, descriptor);
      }
   }
   return function (Constructor, protoProps, staticProps) {
      if (protoProps) defineProperties(Constructor.prototype, protoProps);
      if (staticProps) defineProperties(Constructor, staticProps);
      return Constructor;
   };
}();

function _classCallCheck(instance, Constructor) {
   if (!(instance instanceof Constructor)) {
      throw new TypeError("Cannot call a class as a function");
   }
}

var Person = function () {
   function Person(fname, lname, age, address) {
      _classCallCheck(this, Person);

      this.fname = fname;
      this.lname = lname;
      this.age = age;
      this.address = address;
   }

   _createClass(Person, [{
      key: "fullname",
      get: function get() {
         return this.fname + "-" + this.lname;
      }
   }]);

   return Person;
}();

var a = new Person("Siya", "Kapoor", "15", "Mumbai");
var persondet = a.fullname;

Promesse

Le promesse JavaScript vengono utilizzate per gestire le richieste asincrone nel codice.

Rende la vita più facile e mantiene pulito il codice mentre gestisci più callback da richieste asincrone, che hanno dipendenza. Le promesse forniscono un modo migliore per lavorare con le funzioni di callback. Le promesse fanno parte di ES6. Per impostazione predefinita, quando crei una promessa, lo stato della promessa è in sospeso.

Le promesse arrivano in tre stati:

  • in sospeso (stato iniziale)
  • risolto (completato con successo)
  • rejected(failed)

new Promise()è usato per costruire una promessa. Il costruttore Promise ha un argomento, che è una funzione di callback. La funzione di callback ha due argomenti: risolvere e rifiutare;

entrambe queste sono funzioni interne. Il codice asincrono che scrivi, cioè la chiamata Ajax, il caricamento dell'immagine, le funzioni di temporizzazione andrà nella funzione di callback.

Se l'attività eseguita nella funzione di callback ha esito positivo, viene chiamata la funzione di risoluzione; in caso contrario, la funzione di rifiuto viene chiamata con i dettagli dell'errore.

La seguente riga di codice mostra una chiamata alla struttura della promessa -

var _promise = new Promise (function(resolve, reject) {
   var success = true;
   if (success) {
      resolve("success");
   } else {
      reject("failure");
   }
});
_promise.then(function(value) {
   //once function resolve gets called it comes over here with the value passed in resolve
   console.log(value); //success
}).catch(function(value) {
   //once function reject gets called it comes over here with the value passed in reject
   console.log(value); // failure.
});

Esempio di promessa ES6

let timingpromise = new Promise((resolve, reject) => {
   setTimeout(function() {
      resolve("Promise is resolved!");
   }, 1000);
});

timingpromise.then((msg) => {
   console.log(msg);
});

Produzione

Promise is resolved!

ES6 - Promesse

let timingpromise = new Promise((resolve, reject) => {
   setTimeout(function() {
      resolve("Promise is resolved!");
   }, 1000);
});

timingpromise.then((msg) => {
   console.log(msg);
});

Comando

npx babel promise.js --out-file promise_es5.js

BabelJS - ES5

"use strict";

var timingpromise = new Promise(function (resolve, reject) {
   setTimeout(function () {
      resolve("Promise is resolved!");
   }, 1000);
});

timingpromise.then(function (msg) {
   console.log(msg);
});

Per le promesse, il codice non cambia quando viene traspilato. Abbiamo bisogno di usare babel-polyfill perché funzioni sui browser più vecchi. I dettagli su babel-polyfill sono spiegati nel capitolo babel - poyfill.

Generatori

La funzione del generatore è normale function. La funzione ha una funzione di sintassi speciale * con * per la funzione e la parola chiave yield da utilizzare all'interno della funzione. Questo ha lo scopo di mettere in pausa o avviare la funzione quando richiesto. Le normali funzioni non possono essere interrotte nel frattempo una volta avviata l'esecuzione. Eseguirà la funzione completa o si fermerà quando incontra l'istruzione return. Generator funziona in modo diverso qui, puoi interrompere la funzione con la parola chiave yield e avviarla richiamando nuovamente il generatore ogni volta che è necessario.

Esempio

function* generatorfunction(a) {
   yield a;
   yield a +1 ;
}

let g = generatorfunction(8);
console.log(g.next());
console.log(g.next());

Produzione

{value: 8, done: false}
{value: 9, done: false}

ES6 - Generatore

function* generatorfunction(a) {
   yield a;
   yield a +1 ;
}

let g = generatorfunction(8);
console.log(g.next());
console.log(g.next());

Comando

npx babel generator.js --out-file generator_es5.js

BabelJS - ES5

"use strict";

var _marked = /*#__PURE__*/regeneratorRuntime.mark(generatorfunction);

function generatorfunction(a) {
   return regeneratorRuntime.wrap(function generatorfunction$(_context) {
      while (1) {
         switch (_context.prev = _context.next) {
            case 0:
               _context.next = 2;
               return a;

            case 2:
               _context.next = 4;
               return a + 1;
               
            case 4:
            case "end":
               return _context.stop();
         }
      }
   }, _marked, this);
}

var g = generatorfunction(8);
console.log(g.next());
console.log(g.next());

Iteratori

L'iteratore in JavaScript restituisce un oggetto JavaScript, che ha valore. L'oggetto ha anche un flag chiamato fatto, che ha un valore vero / falso. Fornisce false se non è la fine dell'iteratore. Consideriamo un esempio e vediamo il funzionamento dell'iteratore su un array.

Esempio

let numbers = [4, 7, 3, 10];
let a = numbers[Symbol.iterator]();
console.log(a.next());
console.log(a.next());
console.log(a.next());
console.log(a.next());
console.log(a.next());

Nell'esempio sopra, abbiamo usato un array di numeri e chiamato una funzione sull'array usando Symbol.iterator come indice.

L'output che otteniamo utilizzando next () sull'array è il seguente:

{value: 4, done: false}
{value: 7, done: false}
{value: 3, done: false}
{value: 10, done: false}
{value: undefined, done: true}

L'output fornisce un oggetto con valore e viene eseguito come proprietà. Ogninext()la chiamata al metodo fornisce il valore successivo dall'array e viene eseguita come false. Il valore di done sarà vero solo quando gli elementi dell'array saranno completati. Possiamo usarlo per iterare su array. Sono disponibili più opzioni come ilfor-of loop che viene utilizzato come segue -

Esempio

let numbers = [4, 7, 3, 10];
for (let n of numbers) {
   console.log(n);
}

Produzione

4
7
3
10

Quando il for-of loopusa la chiave, fornisce i dettagli dei valori dell'array come mostrato sopra. Controlleremo entrambe le combinazioni e vedremo come babeljs le trasporta in es5.

Esempio

let numbers = [4, 7, 3, 10];
let a = numbers[Symbol.iterator]();
console.log(a.next());
console.log(a.next());
console.log(a.next());
console.log(a.next());
console.log(a.next());

let _array = [4, 7, 3, 10];
for (let n of _array) {
   console.log(n);
}

comando

npx babel iterator.js --out-file iterator_es5.js

Produzione

"use strict";

var numbers = [4, 7, 3, 10];
var a = numbers[Symbol.iterator]();
console.log(a.next());
console.log(a.next());
console.log(a.next());
console.log(a.next());
console.log(a.next());

var _array = [4, 7, 3, 10];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;

try {
   for (var _iterator = _array[Symbol.iterator](),
      _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done);
      _iteratorNormalCompletion = true) {
      var n = _step.value;

      console.log(n);
   }
} catch (err) {
   _didIteratorError = true;
   _iteratorError = err;
} finally {
   try {
      if (!_iteratorNormalCompletion && _iterator.return) {
         _iterator.return();
      }
   } finally {
      if (_didIteratorError) {
         throw _iteratorError;
      }
   }
}

Sono state aggiunte modifiche for-ofloop in es5. Ma iterator.next viene lasciato così com'è. Dobbiamo usarebabel-polyfillper farlo funzionare nei vecchi browser. Babel-polyfill viene installato insieme a babel e lo stesso può essere utilizzato da node_modules come mostrato di seguito -

Esempio

<html>
   <head>
      <script type="text/javascript" src="node_modules/babel-polyfill/dist/polyfill.min.js"></script>
      <script type="text/javascript" src="iterator_es5.js"></script>
   </head>
   <body>
      <h1>Iterators</h1>
   </body>
</html>

Produzione

Destrutturante

La proprietà Destructuring si comporta come un'espressione JavaScript che decomprime i valori da array, oggetti.

L'esempio seguente spiegherà il funzionamento della sintassi destrutturante.

Esempio

let x, y, rem;
[x, y] = [10, 20];

console.log(x);
console.log(y);
[x, y, ...rem] = [10, 20, 30, 40, 50];
console.log(rem);

let z = 0;
({ x, y } = (z) ? { x: 10, y: 20 } : { x: 1, y: 2 });
console.log(x);
console.log(y);

Produzione

10
20
[30, 40, 50]
1
2

La riga di codice sopra mostra come i valori vengono assegnati dal lato destro della matrice alle variabili sul lato sinistro. La variabile con...rem ottiene tutti i valori rimanenti dall'array.

Possiamo anche assegnare i valori dall'oggetto sul lato sinistro usando l'operatore condizionale come mostrato di seguito -

({ x, y } = (z) ? { x: 10, y: 20 } : { x: 1, y: 2 });
console.log(x); // 1
console.log(y); // 2

Convertiamo lo stesso in ES5 usando babeljs -

comando

npx babel destructm.js --out-file destruct_es5.js

destruct_es5.js

"use strict";

var x = void 0,
   y = void 0,
   rem = void 0;
x = 10;
y = 20;

console.log(x);
console.log(y);
x = 10;
y = 20;
rem = [30, 40, 50];

console.log(rem);

var z = 0;

var _ref = z ? { x: 10, y: 20 } : { x: 1, y: 2 };

x = _ref.x;
y = _ref.y;

console.log(x);
console.log(y);

Letterali modello

Il letterale modello è un valore letterale stringa che consente espressioni al suo interno. Utilizza il backtick (``) invece di virgolette singole o doppie. Quando diciamo espressione all'interno di una stringa, significa che possiamo usare variabili, chiamare una funzione, ecc. All'interno della stringa.

Esempio

let a = 5;
let b = 10;
console.log(`Using Template literal : Value is ${a + b}.`);
console.log("Using normal way : Value is " + (a + b));

Produzione

Using Template literal : Value is 15.
Using normal way : Value is 15

ES6 - Modello letterale

let a = 5;
let b = 10;
console.log(`Using Template literal : Value is ${a + b}.`);
console.log("Using normal way : Value is " + (a + b));

comando

npx babel templateliteral.js --out-file templateliteral_es5.js

BabelJS - ES5

"use strict";

var a = 5;
var b = 10;
console.log("Using Template literal : Value is " + (a + b) + ".");

console.log("Using normal way : Value is " + (a + b));

Valori letterali oggetto migliorati

In es6, le nuove funzionalità aggiunte ai letterali oggetto sono molto buone e utili. Esamineremo alcuni esempi di oggetto letterale in ES5 ed ES6 -

Esempio

ES5
var red = 1, green = 2, blue = 3;
var rgbes5 = {
   red: red,
   green: green,
   blue: blue
};
console.log(rgbes5); // {red: 1, green: 2, blue: 3}

ES6
let rgbes6 = {
   red,
   green,
   blue
};
console.log(rgbes6); // {red: 1, green: 2, blue: 3}

Se vedi il codice sopra, l'oggetto in ES5 e ES6 è diverso. In ES6, non è necessario specificare il valore della chiave se i nomi delle variabili sono gli stessi della chiave.

Vediamo la compilation per ES5 usando babel.

Valore letterale oggetto avanzato da ES6

const red = 1, green = 2, blue = 3;
let rgbes5 = {
   red: red,
   green: green,
   blue: blue
};
console.log(rgbes5);

let rgbes6 = {
   red,
   green,
   blue
};
console.log(rgbes6);

let brand = "carbrand";
const cars = {
   [brand]: "BMW"
}
console.log(cars.carbrand);  //"BMW"

comando

npx babel enhancedobjliteral.js --out-file enhancedobjliteral_es5.js

BabelJS - ES5

"use strict";

function _defineProperty(obj, key, value) {
   if (key in obj) {
      Object.defineProperty(obj, key, {
         value: value, enumerable: true, configurable: true, writable: true
      });
   } else { obj[key] = value; } return obj;
}

var red = 1,
   green = 2,
   blue = 3;
var rgbes5 = {
   red: red,
   green: green,
   blue: blue
};
console.log(rgbes5);

var rgbes6 = {
   red: red,
   green: green,
   blue: blue
};
console.log(rgbes6);

var brand = "carbrand";
var cars = _defineProperty({}, brand, "BMW");

console.log(cars.carbrand); //"BMW"

Proprietà predefinite, di riposo e di diffusione

In questa sezione, discuteremo le proprietà di default, rest e spread.

Predefinito

Con ES6, possiamo utilizzare i parametri predefiniti per i parametri della funzione come segue:

Esempio

let add = (a, b = 3) => {
   return a + b;
}

console.log(add(10, 20));  // 30
console.log(add(10));      // 13

Traspiliamo il codice sopra in ES5 usando babel.

comando

npx babel default.js --out-file default_es5.js

BabelJS - ES5

"use strict";

var add = function add(a) {
   var b = arguments.length > 1 >> arguments[1] !== undefined ? arguments[1] : 3;
   return a + b;
};

console.log(add(10, 20));
console.log(add(10));

riposo

Il parametro Rest inizia con tre punti (...) come mostrato nell'esempio seguente -

Esempio

let add = (...args) => {
   let sum = 0;
   args.forEach(function (n) {
      sum += n;
   });
   return sum;
};

console.log(add(1, 2));    // 3
console.log(add(1, 2, 5, 6, 6, 7));   //27

Nella funzione sopra stiamo passando n numero di parametri alla funzione add. Per aggiungere tutti quei parametri se fosse in ES5, dobbiamo fare affidamento sull'oggetto arguments per ottenere i dettagli degli argomenti. Con ES6,rest it aiuta a definire gli argomenti con tre punti come mostrato sopra e possiamo scorrerli e ottenere la somma dei numeri.

Note - Non è possibile utilizzare argomenti aggiuntivi quando si utilizzano tre punti, ovvero riposo.

Esempio

let add = (...args, value) => {    //syntax error
   let sum = 0;
   args.forEach(function (n) {
      sum += n;
   });
   return sum;
};

Il codice sopra darà un errore di sintassi.

La compilation per es5 è la seguente:

comando

npx babel rest.js --out-file rest_es5.js

Babel -ES5

"use strict";

var add = function add() {
   for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
   }

   var sum = 0;
   args.forEach(function (n) {
      sum += n;
   });
   return sum;
};

console.log(add(1, 2));
console.log(add(1, 2, 5, 6, 6, 7));

Diffusione

La proprietà Spread ha anche i tre punti come resto. Di seguito è riportato un esempio funzionante, che mostra come utilizzare la proprietà spread.

Esempio

let add = (a, b, c) => {
   return a + b + c;
}
let arr = [11, 23, 3];
console.log(add(...arr));   //37

Vediamo ora come il codice sopra viene traspilato usando babel -

comando

npx babel spread.js --out-file spread_es5.js

Babel-ES5

"use strict";

var add = function add(a, b, c) {
   return a + b + c;
};
var arr = [11, 23, 3];
console.log(add.apply(undefined, arr));

Proxy

Proxy è un oggetto in cui è possibile definire un comportamento personalizzato per operazioni come ricerca di proprietà, assegnazione, enumerazione, funzione, invocazione, ecc.

Sintassi

var a = new Proxy(target, handler);

Sia il target che il gestore sono oggetti.

  • target è un oggetto o può essere un altro elemento proxy.

  • handler sarà un oggetto con le sue proprietà come funzioni che daranno il comportamento quando chiamato.

Cerchiamo di capire queste caratteristiche con l'aiuto di un esempio:

Esempio

let handler = {
   get: function (target, name) {
      return name in target ? target[name] : "invalid key";
   }
};

let o = {
   name: 'Siya Kapoor',
   addr: 'Mumbai'
}

let a = new Proxy(o, handler);
console.log(a.name);
console.log(a.addr);
console.log(a.age);

Abbiamo definito target e handler nell'esempio precedente e li abbiamo usati con proxy. Il proxy restituisce l'oggetto con valori-chiave.

Produzione

Siya Kapoor
Mumbai
invalid key

Vediamo ora come trasferire il codice sopra in ES5 usando babel -

comando

npx babel proxy.js --out-file proxy_es5.js

Babel-ES5

'use strict';

var handler = {
   get: function get(target, name) {
      return name in target ? target[name] : "invalid key";
   }
};

var o = {
   name: 'Siya Kapoor',
   addr: 'Mumbai'
};

var a = new Proxy(o, handler);
console.log(a.name);
console.log(a.addr);
console.log(a.age);