- BabelJs 教程
- BabelJs - 主页
- BabelJs - 概述
- BabelJs - 环境设置
- BabelJs-CLI
- BabelJs - ES6 代码执行
- BabelJs - 使用 Babel 6 进行项目设置
- BabelJs - 使用 Babel 7 进行项目设置
- 将 ES6 功能转换为 ES5
- 将 ES6 模块转译为 ES5
- 将 ES7 功能转换为 ES5
- 将 ES8 功能转译为 ES5
- BabelJs - Babel 插件
- BabelJs - Babel Polyfill
- BabelJs - Babel CLI
- BabelJs - Babel 预设
- 使用 Babel 和 Webpack
- 使用 Babel 和 JSX
- 使用 Babel 和 Flow
- 使用 BabelJS 和 Gulp
- BabelJs - 示例
- BabelJs 有用的资源
- BabelJs - 快速指南
- BabelJs - 有用的资源
- BabelJs - 讨论
BabelJS - 将 ES6 功能转换为 ES5
在本章中,我们将看到 ES6 中添加的功能。我们还将学习如何使用 BabelJS 将功能编译为 ES5。
以下是我们将在本章中讨论的各种 ES6 功能 -
- 让 + 常量
- 箭头功能
- 课程
- 承诺
- 发电机
- 解构
- 迭代器
- 模板文字
- 增强对象
- 默认、剩余和传播属性
让 + 常量
Let 在 JavaScript 中声明一个块作用域局部变量。请考虑以下示例以了解 let 的用法。
例子
let a = 1; if (a == 1) { let a = 2; console.log(a); } console.log(a);
输出
2 1
第一个控制台打印 2 的原因是因为a再次使用let声明,并且仅在if块中可用。使用 let 声明的任何变量仅在声明的块中可用。我们使用let声明了变量a两次,但它并没有覆盖a的值。
这就是 var 和 let 关键字之间的区别。当您使用 var 声明变量时,该变量将在函数范围内可用,或者如果声明则将充当全局变量。
如果使用 let 声明变量,则该变量在块作用域内可用。如果在 if 语句内声明,则它仅在 if 块内可用。这同样适用于 switch、for 循环等。
我们现在将看到使用 babeljs 在 ES5 中进行代码转换。
让我们运行以下命令来转换代码 -
npx babel let.js --out-file let_es5.js
let 关键字从 es6 到 es5 的输出如下 -
让我们使用ES6
let a = 1; if (a == 1) { let a = 2; console.log(a); } console.log(a);
使用 babel 转译为 ES5
"use strict"; var a = 1; if (a == 1) { var _a = 2; console.log(_a); } console.log(a);
如果您看到 ES5 代码,let 关键字会被替换为var关键字。此外,if 块内的变量被重命名为_a,以具有与使用let关键字声明时相同的效果。
常量
在本节中,我们将了解 const 关键字在 ES6 和 ES5 中的工作原理。Const关键字在作用域内也可用;如果在外面,它会抛出错误。const 声明的变量的值一旦赋值就不能更改。让我们考虑以下示例来了解如何使用 const 关键字。
例子
let a =1; if (a == 1) { const age = 10; } console.log(age);
输出
Uncaught ReferenceError: age is not defined at:5:13
上面的输出会引发错误,因为 const Age 是在 if 块内定义的,并且在 if 块内可用。
我们将了解使用 BabelJS 到 ES5 的转换。
ES6
let a =1; if (a == 1) { const age = 10; } console.log(age);
命令
npx babel const.js --out-file const_es5.js
使用 BabelJS 转换为 ES6
"use strict"; var a = 1; if (a == 1) { var _age = 10; } console.log(age);
在 ES5 中,const 关键字被替换为 var 关键字,如上所示。
箭头功能
与变量表达式相比,箭头函数的语法更短。它也称为胖箭头函数或 lambda 函数。该函数没有自己的 this 属性。在这个函数中,省略了关键字function。
例子
var add = (x,y) => { return x+y; } var k = add(3,6); console.log(k);
输出
9
使用 BabelJS,我们将上面的代码转译为 ES5。
ES6 - 箭头函数
var add = (x,y) => { return x+y; } var k = add(3,6); console.log(k);
命令
npx babel arrowfunction.js --out-file arrowfunction_es5.js
BabelJS-ES5
使用 Babel 将箭头函数转换为变量表达式函数,如下所示。
"use strict"; var add = function add(x, y) { return x + y; }; var k = add(3, 6); console.log(k);
课程
ES6 附带了新的 Classes 功能。类类似于 ES5 中基于原型的继承。 class 关键字用于定义类。类就像特殊的函数,并且与函数表达式有相似之处。它有一个构造函数,在类内部调用。
例子
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;
输出
Siya-Kapoor
ES6 - 类
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;
命令
npx babel class.js --out-file class_es5.js
BabelJS-ES5
使用 babeljs 添加了额外的代码,以获得与 ES5 中相同的类功能。BabelJs 确保该功能与 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;
承诺
JavaScript Promise 用于管理代码中的异步请求。
当您管理来自具有依赖性的异步请求的多个回调时,它使生活变得更轻松并保持代码整洁。Promise 提供了一种更好的使用回调函数的方法。Promise 是 ES6 的一部分。默认情况下,当您创建 Promise 时,Promise 的状态为待处理。
承诺有三种状态 -
- 待定(初始状态)
- 已解决(成功完成)
- 被拒绝(失败)
new Promise()用于构造一个 Promise。Promise 构造函数有一个参数,即回调函数。回调函数有两个参数——resolve和reject;
这两个都是内部函数。您编写的异步代码,即Ajax调用、图像加载、定时函数将放在回调函数中。
如果回调函数中执行的任务成功,则调用resolve函数;否则,将使用错误详细信息调用拒绝函数。
以下代码行显示了 Promise 结构调用 -
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. });
ES6 Promise 示例
let timingpromise = new Promise((resolve, reject) => { setTimeout(function() { resolve("Promise is resolved!"); }, 1000); }); timingpromise.then((msg) => { console.log(msg); });
输出
Promise is resolved!
ES6 - 承诺
let timingpromise = new Promise((resolve, reject) => { setTimeout(function() { resolve("Promise is resolved!"); }, 1000); }); timingpromise.then((msg) => { console.log(msg); });
命令
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); });
对于 Promise,代码在转译时不会改变。我们需要使用 babel-polyfill 才能在旧版浏览器上工作。关于 babel-polyfills 的详细信息在 babel - poyfill 章节中有解释。
发电机
生成器函数就像普通函数一样。该函数具有特殊的语法 function*,其中 * 表示函数,并且在函数内部使用yield关键字。这是为了在需要时暂停或启动该功能。一旦开始执行,普通函数就不能在中间停止。它将执行完整的函数或在遇到 return 语句时停止。生成器在这里执行不同的操作,您可以使用yield关键字停止该函数,并在需要时通过再次调用生成器来启动它。
例子
function* generatorfunction(a) { yield a; yield a +1 ; } let g = generatorfunction(8); console.log(g.next()); console.log(g.next());
输出
{value: 8, done: false} {value: 9, done: false}
ES6 - 生成器
function* generatorfunction(a) { yield a; yield a +1 ; } let g = generatorfunction(8); console.log(g.next()); console.log(g.next());
命令
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());
迭代器
JavaScript 中的迭代器返回一个具有值的 JavaScript 对象。该对象还有一个名为“done”的标志,它具有 true/false 值。如果不是迭代器的末尾,则返回 false。让我们考虑一个例子,看看迭代器在数组上的工作原理。
例子
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());
在上面的示例中,我们使用了一个数字数组,并使用Symbol.iterator作为索引在该数组上调用了一个函数。
我们在数组上使用 next() 得到的输出如下 -
{value: 4, done: false} {value: 7, done: false} {value: 3, done: false} {value: 10, done: false} {value: undefined, done: true}
输出给出一个具有值的对象,并作为属性完成。每个next()方法调用都会给出数组中的下一个值,并以 false 完成。仅当数组中的元素完成时,done 的值才会为 true。我们可以用它来迭代数组。还有更多选项可用,例如for-of循环,其用法如下 -
例子
let numbers = [4, 7, 3, 10]; for (let n of numbers) { console.log(n); }
输出
4 7 3 10
当for-of 循环使用键时,它会给出数组值的详细信息,如上所示。我们将检查这两个组合,看看 babeljs 如何将它们转译为 es5。
例子
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); }
命令
npx babel iterator.js --out-file iterator_es5.js
输出
"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; } } }
es5 中添加了for-of循环的更改。但 iterator.next 保持原样。我们需要使用babel-polyfill来使其在旧浏览器中工作。Babel-polyfill 与 babel 一起安装,并且可以从 node_modules 中使用相同的内容,如下所示 -
例子
<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>
输出
解构
解构属性的Behave类似于 JavaScript 表达式,它从数组、对象中解压值。
以下示例将解释解构语法的工作原理。
例子
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);
输出
10 20 [30, 40, 50] 1 2
上面的代码行显示了如何将值从数组右侧分配给左侧的变量。带有...rem 的变量从数组中获取所有剩余的值。
我们还可以使用条件运算符分配左侧对象的值,如下所示 -
({ x, y } = (z) ? { x: 10, y: 20 } : { x: 1, y: 2 }); console.log(x); // 1 console.log(y); // 2
让我们使用 babeljs 将其转换为 ES5 -
命令
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);
模板文字
模板文字是一个字符串文字,允许在其中包含表达式。它使用反引号(``)而不是单引号或双引号。当我们说字符串内的表达式时,这意味着我们可以在字符串内使用变量、调用函数等。
例子
let a = 5; let b = 10; console.log(`Using Template literal : Value is ${a + b}.`); console.log("Using normal way : Value is " + (a + b));
输出
Using Template literal : Value is 15. Using normal way : Value is 15
ES6 - 模板文字
let a = 5; let b = 10; console.log(`Using Template literal : Value is ${a + b}.`); console.log("Using normal way : Value is " + (a + b));
命令
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));
增强的对象文字
在es6中,添加到对象字面量的新功能非常好且有用。我们将介绍 ES5 和 ES6 中对象字面量的几个示例 -
例子
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}
如果你看到上面的代码,ES5和ES6中的对象是不同的。在ES6中,如果变量名与键相同,我们就不必指定键值。
让我们看看使用 babel 编译到 ES5。
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"
命令
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"
默认、剩余和传播属性
在本节中,我们将讨论默认、剩余和扩展属性。
默认
使用 ES6,我们可以使用函数 params 的默认参数,如下所示 -
例子
let add = (a, b = 3) => { return a + b; } console.log(add(10, 20)); // 30 console.log(add(10)); // 13
让我们使用 babel 将上面的代码转译为 ES5。
命令
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));
休息
Rest 参数以三个点(...)开头,如下例所示 -
例子
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
在上面的函数中,我们将 n 个参数传递给函数 add。如果是在 ES5 中,要添加所有这些参数,我们必须依靠参数对象来获取参数的详细信息。在 ES6 中,rest有助于用三个点定义参数,如上所示,我们可以循环遍历它并获得数字的总和。
注意- 当使用三个点(即休息)时,我们不能使用附加参数。
例子
let add = (...args, value) => { //syntax error let sum = 0; args.forEach(function (n) { sum += n; }); return sum; };
上面的代码会出现语法错误。
es5 的编译如下 -
命令
npx babel rest.js --out-file rest_es5.js
通天塔-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));
传播
Spread属性也有像rest这样的三个点。以下是一个工作示例,展示了如何使用 spread 属性。
例子
let add = (a, b, c) => { return a + b + c; } let arr = [11, 23, 3]; console.log(add(...arr)); //37
现在让我们看看如何使用 babel 转译上面的代码 -
命令
npx babel spread.js --out-file spread_es5.js
巴别塔-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));
代理
代理是一个对象,您可以在其中定义属性查找、赋值、枚举、函数、调用等操作的自定义Behave。
句法
var a = new Proxy(target, handler);
目标和处理程序都是对象。
target是一个对象,也可以是另一个代理元素。
handler将是一个对象,其属性作为函数,在调用时将给出Behave。
让我们尝试借助示例来理解这些功能 -
例子
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);
我们在上面的示例中定义了目标和处理程序,并将其与代理一起使用。代理返回带有键值的对象。
输出
Siya Kapoor Mumbai invalid key
现在让我们看看如何使用 babel 将上述代码转译为 ES5 -
命令
npx babel proxy.js --out-file proxy_es5.js
巴别塔-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);