BabelJS - Transpile las características de ES6 a ES5
En este capítulo, veremos las características agregadas a ES6. También aprenderemos a compilar las características en ES5 usando BabelJS.
A continuación se muestran las diversas características de ES6 que analizaremos en este capítulo:
- Let + Const
- Funciones de flecha
- Classes
- Promises
- Generators
- Destructuring
- Iterators
- Plantilla Literalst
- Objeto mejorado
- Propiedades predeterminadas, de descanso y propagación
Let + Const
Let declara una variable local de alcance de bloque en JavaScript. Considere el siguiente ejemplo para comprender el uso de let.
Ejemplo
let a = 1;
if (a == 1) {
let a = 2;
console.log(a);
}
console.log(a);
Salida
2
1
La razón por la que la primera consola imprime 2 es porque a se declara de nuevo usando let y estará disponible solo en el ifbloquear. Cualquier variable declarada usando let solo está disponible dentro del bloque declarado. Hemos declarado la variable a dos veces usando let, pero no sobrescribe el valor de a.
Esta es la diferencia entre las palabras clave var y let. Cuando declaras una variable usando var, la variable estará disponible dentro del alcance de la función o si se declara actuará como una variable global.
En caso de que una variable se declare con let, la variable está disponible dentro del alcance del bloque. Si se declara dentro de la instrucción if, solo estará disponible dentro del bloque if. Lo mismo se aplica a switch, for-loop, etc.
Ahora veremos la conversión de código en ES5 usando babeljs.
Ejecutemos el siguiente comando para convertir el código:
npx babel let.js --out-file let_es5.js
La salida de es6 a es5 para la palabra clave let es la siguiente:
Deje que use ES6
let a = 1;
if (a == 1) {
let a = 2;
console.log(a);
}
console.log(a);
Transpilado usando babel a ES5
"use strict";
var a = 1;
if (a == 1) {
var _a = 2;
console.log(_a);
}
console.log(a);
Si ve el código ES5, la palabra clave let se reemplaza por la varpalabra clave. Además, la variable dentro del bloque if se renombra a_a tener el mismo efecto que cuando se declara con el let palabra clave.
Const
En esta sección, aprenderemos sobre el funcionamiento de la palabra clave const en ES6 y ES5. La palabra clave Const también está disponible dentro del alcance; y si está afuera, arrojará un error. El valor de la variable declarada const no se puede cambiar una vez asignado. Consideremos el siguiente ejemplo para entender cómo se usa la palabra clave const.
Ejemplo
let a =1;
if (a == 1) {
const age = 10;
}
console.log(age);
Salida
Uncaught ReferenceError: age is not defined at :5:13
La salida anterior arroja un error ya que la constante se define dentro del bloque if y está disponible dentro del bloque if.
Entenderemos la conversión a ES5 usando BabelJS.
ES6
let a =1;
if (a == 1) {
const age = 10;
}
console.log(age);
Mando
npx babel const.js --out-file const_es5.js
Transpilado a ES6 usando BabelJS
"use strict";
var a = 1;
if (a == 1) {
var _age = 10;
}
console.log(age);
En el caso de ES5, la palabra clave const se reemplaza con la palabra clave var como se muestra arriba.
Funciones de flecha
Una función de flecha tiene una sintaxis más corta en comparación con la expresión de variable. también se denomina función de flecha grasa o función lambda. La función no tiene esta propiedad propia. En esta función, se omite la función de palabra clave.
Ejemplo
var add = (x,y) => {
return x+y;
}
var k = add(3,6);
console.log(k);
Salida
9
Usando BabelJS, transpilaremos el código anterior a ES5.
ES6 - Función de flecha
var add = (x,y) => {
return x+y;
}
var k = add(3,6);
console.log(k);
Mando
npx babel arrowfunction.js --out-file arrowfunction_es5.js
BabelJS - ES5
Usando Babel, la función de flecha se convierte en función de expresión variable como se muestra a continuación.
"use strict";
var add = function add(x, y) {
return x + y;
};
var k = add(3, 6);
console.log(k);
Clases
ES6 viene con la nueva función Clases. Las clases son similares a la herencia basada en prototipos disponible en ES5. La palabra clave class se usa para definir la clase. Las clases son como funciones especiales y tienen similitudes como expresión de función. Tiene un constructor, que se llama dentro de la clase.
Ejemplo
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;
Salida
Siya-Kapoor
ES6 - Clases
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;
Mando
npx babel class.js --out-file class_es5.js
BabelJS - ES5
Se agrega código adicional usando babeljs para que la funcionalidad funcione para las clases igual que en ES5. BabelJs se asegura de que la funcionalidad funcione igual que en 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;
Promesas
Las promesas de JavaScript se utilizan para administrar solicitudes asincrónicas en su código.
Facilita la vida y mantiene el código limpio a medida que administra múltiples devoluciones de llamada de solicitudes asíncronas, que tienen dependencia. Las promesas proporcionan una mejor forma de trabajar con funciones de devolución de llamada. Las promesas son parte de ES6. De forma predeterminada, cuando crea una promesa, el estado de la promesa está pendiente.
Las promesas vienen en tres estados:
- pendiente (estado inicial)
- resuelto (completado con éxito)
- rejected(failed)
new Promise()se utiliza para construir una promesa. El constructor de promesas tiene un argumento, que es una función de devolución de llamada. La función de devolución de llamada tiene dos argumentos: resolver y rechazar;
ambas son funciones internas. El código asincrónico que escriba, es decir, la llamada Ajax, la carga de imágenes, las funciones de sincronización irán a la función de devolución de llamada.
Si la tarea realizada en la función de devolución de llamada es un éxito, se llama a la función de resolución; de lo contrario, se llama a la función de rechazo con los detalles del error.
La siguiente línea de código muestra una llamada a la estructura de promesa:
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.
});
Ejemplo de promesa ES6
let timingpromise = new Promise((resolve, reject) => {
setTimeout(function() {
resolve("Promise is resolved!");
}, 1000);
});
timingpromise.then((msg) => {
console.log(msg);
});
Salida
Promise is resolved!
ES6 - Promesas
let timingpromise = new Promise((resolve, reject) => {
setTimeout(function() {
resolve("Promise is resolved!");
}, 1000);
});
timingpromise.then((msg) => {
console.log(msg);
});
Mando
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);
});
Para las promesas, el código no cambia cuando se transpila. Necesitamos usar babel-polyfill para que funcione en navegadores más antiguos. Los detalles sobre babel-polyfills se explican en el capítulo babel - poyfill.
Generadores
La función del generador es normal function. La función tiene una función de sintaxis especial * con * para la función y la palabra clave de rendimiento que se utilizará dentro de la función. Esto está destinado a pausar o iniciar la función cuando sea necesario. Las funciones normales no se pueden detener entre una vez que comienza la ejecución. Ejecutará la función completa o se detendrá cuando encuentre la declaración de retorno. El generador funciona de manera diferente aquí, puede detener la función con la palabra clave yield e iniciarla llamando al generador nuevamente cuando sea necesario.
Ejemplo
function* generatorfunction(a) {
yield a;
yield a +1 ;
}
let g = generatorfunction(8);
console.log(g.next());
console.log(g.next());
Salida
{value: 8, done: false}
{value: 9, done: false}
ES6 - Generador
function* generatorfunction(a) {
yield a;
yield a +1 ;
}
let g = generatorfunction(8);
console.log(g.next());
console.log(g.next());
Mando
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());
Iteradores
Iterator en JavaScript devuelve un objeto JavaScript, que tiene valor. El objeto también tiene un indicador llamado hecho, que tiene un valor verdadero / falso. Da falso si no es el final del iterador. Consideremos un ejemplo y veamos el funcionamiento del iterador en una matriz.
Ejemplo
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());
En el ejemplo anterior, hemos usado una matriz de números y hemos llamado a una función en la matriz usando Symbol.iterator como el índice.
La salida que obtenemos usando next () en la matriz es la siguiente:
{value: 4, done: false}
{value: 7, done: false}
{value: 3, done: false}
{value: 10, done: false}
{value: undefined, done: true}
La salida da un objeto con valor y se realiza como propiedades. Cadanext()La llamada al método da el siguiente valor de la matriz y se hace como falso. El valor de done será verdadero solo cuando los elementos de la matriz estén listos. Podemos usar esto para iterar sobre matrices. Hay más opciones disponibles comofor-of bucle que se utiliza de la siguiente manera:
Ejemplo
let numbers = [4, 7, 3, 10];
for (let n of numbers) {
console.log(n);
}
Salida
4
7
3
10
Cuando el for-of loopusa la clave, da detalles de los valores de la matriz como se muestra arriba. Comprobaremos ambas combinaciones y veremos cómo babeljs las transpila a es5.
Ejemplo
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);
}
mando
npx babel iterator.js --out-file iterator_es5.js
Salida
"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;
}
}
}
Hay cambios agregados for-ofbucle en es5. Pero iterator.next se deja como está. Necesitamos usarbabel-polyfillpara que funcione en navegadores antiguos. Babel-polyfill se instala junto con babel y lo mismo se puede usar desde node_modules como se muestra a continuación:
Ejemplo
<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>
Salida
Desestructurando
La propiedad de desestructuración se comporta como una expresión de JavaScript que descomprime valores de matrices, objetos.
El siguiente ejemplo explicará el funcionamiento de la sintaxis de desestructuración.
Ejemplo
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);
Salida
10
20
[30, 40, 50]
1
2
La línea de código anterior muestra cómo se asignan los valores del lado derecho de la matriz a las variables del lado izquierdo. La variable con...rem obtiene todos los valores restantes de la matriz.
También podemos asignar los valores del objeto en el lado izquierdo usando el operador condicional como se muestra a continuación:
({ x, y } = (z) ? { x: 10, y: 20 } : { x: 1, y: 2 });
console.log(x); // 1
console.log(y); // 2
Convirtamos lo mismo a ES5 usando babeljs -
mando
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);
Literales de plantilla
El literal de plantilla es un literal de cadena que permite expresiones dentro de él. Utiliza comillas inversas (``) en lugar de comillas simples o dobles. Cuando decimos expresión dentro de una cadena, significa que podemos usar variables, llamar a una función, etc.dentro de la cadena.
Ejemplo
let a = 5;
let b = 10;
console.log(`Using Template literal : Value is ${a + b}.`);
console.log("Using normal way : Value is " + (a + b));
Salida
Using Template literal : Value is 15.
Using normal way : Value is 15
ES6 - Literal de plantilla
let a = 5;
let b = 10;
console.log(`Using Template literal : Value is ${a + b}.`);
console.log("Using normal way : Value is " + (a + b));
mando
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));
Literales de objetos mejorados
En es6, las nuevas características agregadas a los objetos literales son muy buenas y útiles. Veremos algunos ejemplos de objetos literales en ES5 y ES6:
Ejemplo
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}
Si ve el código anterior, el objeto en ES5 y ES6 es diferente. En ES6, no tenemos que especificar el valor de la clave si los nombres de las variables son los mismos que los de la clave.
Veamos la compilación a ES5 usando babel.
Literal de objeto mejorado de 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"
mando
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"
Propiedades predeterminadas, de descanso y propagación
En esta sección, discutiremos las propiedades predeterminadas, de descanso y de propagación.
Defecto
Con ES6, podemos usar parámetros predeterminados para los parámetros de la función de la siguiente manera:
Ejemplo
let add = (a, b = 3) => {
return a + b;
}
console.log(add(10, 20)); // 30
console.log(add(10)); // 13
Transpilemos el código anterior a ES5 usando babel.
mando
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));
Descanso
El parámetro de descanso comienza con tres puntos (...) como se muestra en el siguiente ejemplo:
Ejemplo
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
En la función anterior, estamos pasando n número de parámetros a la función add. Para agregar todos esos parámetros si estaba en ES5, tenemos que confiar en el objeto de argumentos para obtener los detalles de los argumentos. Con ES6,rest it ayuda a definir los argumentos con tres puntos como se muestra arriba y podemos recorrerlos y obtener la suma de los números.
Note - No podemos usar argumentos adicionales cuando usamos tres puntos, es decir, resto.
Ejemplo
let add = (...args, value) => { //syntax error
let sum = 0;
args.forEach(function (n) {
sum += n;
});
return sum;
};
El código anterior dará error de sintaxis.
La compilación de es5 tiene el siguiente aspecto:
mando
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));
Propagar
La propiedad Spread también tiene los tres puntos como resto. A continuación se muestra un ejemplo práctico, que muestra cómo utilizar la propiedad spread.
Ejemplo
let add = (a, b, c) => {
return a + b + c;
}
let arr = [11, 23, 3];
console.log(add(...arr)); //37
Veamos ahora cómo se transpila el código anterior usando babel -
mando
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));
Proxies
Proxy es un objeto en el que puede definir un comportamiento personalizado para operaciones como búsqueda de propiedad, asignación, enumeración, función, invocación, etc.
Sintaxis
var a = new Proxy(target, handler);
Tanto el objetivo como el controlador son objetos.
target es un objeto o puede ser otro elemento proxy.
handler será un objeto con sus propiedades como funciones que darán el comportamiento cuando sea llamado.
Intentemos comprender estas características con la ayuda de un ejemplo:
Ejemplo
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);
Hemos definido target y handler en el ejemplo anterior y lo usamos con proxy. Proxy devuelve el objeto con pares clave-valor.
Salida
Siya Kapoor
Mumbai
invalid key
Veamos ahora cómo transpilar el código anterior a ES5 usando babel -
mando
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);