- 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 - 快速指南
BabelJS - 概述
BabelJS 是一个 JavaScript 转换器,它将新特性转换为旧标准。这样,这些特性就可以在旧版和新版浏览器上无缝运行。一位澳大利亚开发者 Sebastian McKenzie 启动了 BabelJS。
为什么选择 BabelJS?
JavaScript 是浏览器理解的语言。我们使用不同的浏览器来运行我们的应用程序 - Chrome、Firefox、Internet Explorer、Microsoft Edge、Opera、UC 浏览器等。ECMA Script 是 JavaScript 语言规范;ECMA Script 2015 ES6 是稳定的版本,在所有新旧浏览器中都能正常工作。
在 ES5 之后,我们有了 ES6、ES7 和 ES8。ES6 发布了许多新特性,并非所有浏览器都完全支持。ES7、ES8 和 ESNext(ECMA Script 的下一个版本)也是如此。目前尚不确定所有浏览器何时能够兼容所有发布的 ES 版本。
如果我们计划使用 ES6 或 ES7 或 ES8 特性来编写代码,由于缺乏对新更改的支持,它可能会在某些旧版浏览器中中断。因此,如果我们想在代码中使用 ECMA Script 的新特性,并希望它在所有可用的浏览器上运行,我们需要一个工具将我们的最终代码编译成 ES5。
Babel 做的就是这件事,它被称为转换器,可以将代码转换为我们想要的 ECMA Script 版本。它具有预设和插件等特性,可以配置我们需要转换代码的 ECMA 版本。使用 Babel,开发人员可以使用 JavaScript 中的新特性编写代码。用户可以使用 Babel 转换代码;这些代码随后可以在任何浏览器中使用,而不会出现任何问题。
下表列出了 ES6、ES7 和 ES8 中可用的特性 -
| 特性 | ECMA Script 版本 |
|---|---|
| Let + Const | ES6 |
| 箭头函数 | ES6 |
| 类 | ES6 |
| Promise | ES6 |
| 生成器 | ES6 |
| 迭代器 | ES6 |
| 模块 | ES6 |
| 解构 | ES6 |
| 模板字面量 | ES6 |
| 增强对象 | ES6 |
| 默认、剩余和扩展属性 | ES6 |
| Async - Await | ES7 |
| 指数运算符 | ES7 |
| Array.prototype.includes() | ES7 |
| 字符串填充 | ES8 |
BabelJS 管理以下两个部分 -
- 转换
- 填充
什么是 Babel-转换器?
Babel-转换器将现代 JavaScript 的语法转换为旧版浏览器可以轻松理解的形式。例如,箭头函数、const、let 类将转换为函数、var 等。这里语法,即箭头函数被转换为普通函数,在两种情况下功能相同。
什么是 Babel-填充?
JavaScript 中添加了一些新特性,例如 Promise、Map 和 includes。这些特性可以用于数组;同样,当使用 Babel 进行转换时,不会被转换。如果新特性是方法或对象,我们需要将 Babel-填充与转换一起使用才能使其在旧版浏览器上工作。
以下是 JavaScript 中可用的 ECMA Script 特性列表,可以进行转换和填充 -
- 类
- 装饰器
- Const
- 模块
- 解构
- 默认参数
- 计算属性名
- 对象剩余/扩展
- 异步函数
- 箭头函数
- 剩余参数
- 扩展
- 模板字面量
可以填充的 ECMA Script 特性 -
- Promise
- Map
- Set
- Symbol
- Weakmap
- Weakset
- includess
- Array.from、Array.of、Array#find、Array.buffer、Array#findIndex
- Object.assign、Object.entries、Object.values
BabelJS 的特性
在本节中,我们将了解 BabelJS 的不同特性。以下是 BabelJS 最重要的核心特性 -
Babel-插件
插件和预设是 Babel 转换代码的配置细节。Babel 支持许多插件,如果我们知道代码将在哪个环境中执行,则可以单独使用这些插件。
Babel-预设
Babel 预设是一组插件,即 babel-转换器的配置细节,指示 Babel 以特定模式进行转换。我们需要使用预设,其中包含我们希望代码转换为的环境。例如,es2015 预设会将代码转换为 es5。
Babel-填充
有些特性(例如方法和对象)无法转换。在这种情况下,我们可以使用 babel-填充来促进在任何浏览器中使用这些特性。让我们以 Promise 为例;为了使该特性在旧版浏览器中工作,我们需要使用填充。
Babel-填充
Babel-cli 带有一系列命令,可以使用这些命令轻松地在命令行上编译代码。它还具有插件和预设等特性,可以与命令一起使用,从而可以轻松地一次性转换代码。
使用 BabelJS 的优势
在本节中,我们将了解与使用 BabelJS 相关的不同优势 -
BabelJS 为添加到 JavaScript 的所有新特性提供向后兼容性,并且可以在任何浏览器中使用。
BabelJS 能够转换以获取 JavaScript 的下一个即将发布的版本 - ES6、ES7、ESNext 等。
BabelJS 可以与 gulp、webpack、flow、react、typescript 等一起使用,使其功能非常强大,并且可以用于大型项目,从而使开发人员的生活更轻松。
BabelJS 还与 react JSX 语法一起使用,并且可以编译成 JSX 形式。
BabelJS 支持插件、填充、babel-cli,这使得它易于处理大型项目。
使用 BabelJS 的缺点
在本节中,我们将了解使用 BabelJS 的不同缺点 -
BabelJS 代码在转换时会更改语法,这使得发布到生产环境后难以理解代码。
与原始代码相比,转换后的代码大小更大。
并非所有 ES6/7/8 或即将发布的新特性都可以转换,我们必须使用填充才能使其在旧版浏览器上工作。
这是 babeljs 的官方网站 https://babel.node.org.cn/。
BabelJS - 环境搭建
在本节中,我们将学习如何为 BabelJS 设置环境。
要使用 BabelJS,我们需要以下设置 -
- NodeJS
- Npm
- Babel-CLI
- Babel-Preset
- 用于编写代码的 IDE
NodeJS
要检查系统中是否安装了 nodejs,请在终端中键入node –v。这将帮助您查看当前安装在系统上的 nodejs 版本。
如果它没有打印任何内容,请在您的系统上安装 nodejs。要安装 nodejs,请访问 nodejs 的主页 https://node.org.cn/en/download/ 并根据您的操作系统安装软件包。
以下屏幕截图显示了 nodejs 的下载页面 -
根据您的操作系统,安装所需的软件包。安装 nodejs 后,npm 也会随之安装。要检查 npm 是否已安装,请在终端中键入npm –v。它应该显示 npm 的版本。
BabelJS - CLI
Babel 带有一个内置的命令行界面,可用于编译代码。
创建一个您将在其中工作的目录。在这里,我们创建了一个名为babelproject的目录。让我们利用 nodejs 创建项目详细信息。
我们使用npm init创建项目,如下所示 -
这是我们创建的项目结构。
现在要使用 Babel,我们需要安装 Babel cli、Babel 预设、Babel 核心,如下所示 -
babel-cli
执行以下命令以安装 babel-cli -
npm install --save-dev babel-cli
babel-preset
执行以下命令以安装 babel-preset -
npm install --save-dev babel-preset-env
babel-core
执行以下命令以安装 babel-core -
npm install --save-dev babel-core
安装后,以下是 package.json 中可用的详细信息 -
我们已将 babel 插件安装到项目的本地。这样做是为了我们可以根据项目需求以及 babeljs 的不同版本在项目中以不同的方式使用 babel。Package.json 提供了所用 babeljs 的版本详细信息。
为了在项目中使用 babel,我们需要在 package.json 中指定如下 -
Babel 主要用于编译 JavaScript 代码,这将具有向后兼容性。现在,我们将用 ES6 -> ES5 或 ES7 -> ES5 以及 ES7->ES6 等编写代码。
为了在执行时向 Babel 提供相同的说明,我们需要在根文件夹中创建一个名为 .babelrc 的文件。它包含一个具有预设详细信息的 json 对象,如下所示 -
我们将创建 JavaScript 文件 index.js 并使用 Babel 将其编译为 es2015。在此之前,我们需要安装 es2015 预设,如下所示 -
在 index.js 中,我们使用箭头函数创建了一个函数,这是 es6 中添加的新特性。使用 Babel,我们将代码编译为 es5。
要执行到 es2015,使用以下命令 -
npx babel index.js
输出
它显示了上面所示的 es5 中的 index.js 代码。
我们可以通过执行如下命令将输出存储到文件中:
npx babel index.js --out-file index_es5.js
输出
这是我们创建的文件,index_es5.js:
BabelJS - ES6 代码执行
BabelJS 是一个 JavaScript 编译器,它将添加到 JavaScript 中的新特性转换为 ES5 或 React,具体取决于给定的预设或插件。ES5 是 JavaScript 最古老的形式之一,并且可以无缝运行在新旧浏览器上。在本教程的大多数示例中,我们都将代码编译成了 ES5。
我们已经看到了 ES6、ES7 和 ES8 中添加了许多特性,例如箭头函数、类、Promise、生成器、异步函数等。当在旧浏览器中使用任何新添加的特性时,它都会抛出错误。BabelJS 有助于编译代码,使其向后兼容旧版浏览器。我们已经看到 ES5 在旧版浏览器上运行良好,没有任何问题。因此,考虑到项目环境的详细信息,如果需要在旧版浏览器上运行,我们可以在项目中使用任何新特性,并使用 babeljs 将代码编译成 ES5,然后在任何浏览器中使用它而不会出现任何问题。
让我们考虑以下示例来理解这一点。
示例
<!DOCTYPE html>
<html>
<head>
<title>BabelJs Testing</title>
</head>
<body>
<script type="text/javascript" src="index.js"></script>
</body>
</html>
index.js 文件
var _foo = () => {
return "Hello World"
};
alert(_foo());
输出
当我们在 Chrome 浏览器中运行以上 html 时,我们得到以下输出:
当 HTML 在 Firefox 中运行时,它会生成以下输出:
当相同的 HTML 在 Internet Explorer 中运行时,它会生成以下语法错误:
我们使用了 ES6 箭头函数;如上所示,它并不适用于所有浏览器。为了使其正常工作,我们使用 BabelJS 将代码编译为 ES5,并在所有浏览器中使用它。
将使用 babeljs 将 js 文件编译为 es5,并在浏览器中再次检查。
在 html 文件中,我们将使用 index_new.js,如下所示:
<!DOCTYPE html>
<html>
<head>
<title>BabelJs Testing</title>
</head>
<body>
<script type="text/javascript" src="index_new.js"></script>
</body>
</html>
index_new.js
"use strict";
var _foo = function _foo() {
return "Hello World";
};
alert(_foo());
Chrome 输出
Firefox 浏览器输出
IE 浏览器输出
BabelJS - 使用 Babel 6 进行项目设置
在本章中,我们将了解如何在项目中使用 babeljs。我们将使用 nodejs 创建一个项目,并使用 http 本地服务器来测试我们的项目。
创建项目设置
在本节中,我们将学习如何创建项目设置。
创建一个新目录并运行以下命令创建项目:
npm init
输出
执行后,上述命令会生成以下输出:
以下是创建的 package.json:
我们将安装开始使用 babeljs 所需的软件包。我们将执行以下命令来安装babel-cli、babel-core、babel-preset-es2015。
npm install babel-cli babel-core babel-preset-es2015 --save-dev
输出
执行后,上述命令会生成以下输出:
Package.json 更新如下:
我们需要 http 服务器来测试 js 文件。执行以下命令安装 http 服务器:
npm install lite-server --save-dev
我们在 package.json 中添加了以下详细信息:
在脚本中,Babel 负责将 src 文件夹中的 scripts.js 转换为 dev 文件夹中的 scripts.bundle.js。我们在 package.json 中添加了编译所需代码的完整命令。此外,添加了build,它将启动lite-server 来测试更改。
src/scripts.js 中的 JavaScript 如下所示:
class Student {
constructor(fname, lname, age, address) {
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
get fullname() {
return this.fname +"-"+this.lname;
}
}
我们在 index.html 中调用了转换后的脚本,如下所示:
<html>
lt;head></head>
<body>
<script type="text/javascript" src="dev/scripts.bundle.js?a=11"></script>
<h1 id="displayname"></h1>
<script type="text/javascript">
var a = new Student("Siya", "Kapoor", "15", "Mumbai");
var studentdet = a.fullname;
document.getElementById("displayname").innerHTML = studentdet;
</script>
</body>
</html>
我们需要运行以下命令,它将调用 babel 并编译代码。该命令将从 package.json 调用 Babel:
npm run babel
scripts.bundle.js 是在 dev 文件夹中创建的新 js 文件:
dev/scripts.bundle.js 的输出如下:
"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 Student = function () {
function Student(fname, lname, age, address) {
_classCallCheck(this, Student);
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
_createClass(Student, [{
key: "fullname",
get: function get() {
return this.fname + "-" + this.lname;
}
}]);
return Student;
}();
现在让我们运行以下命令来启动服务器:
npm run build
当命令运行时,它将在浏览器中打开 url:
输出
上述命令生成以下输出:
BabelJS - 使用 Babel 7 进行项目设置
Babel 的最新版本 7 发布了对现有软件包的更改。安装部分与 Babel 6 相同。Babel 7 中唯一的区别是所有软件包都需要使用@babel/安装,例如 @babel/core、@babel/preset-env、@babel/cli、@babel/polyfill 等。
这是一个使用 babel 7 创建的项目设置。
命令
执行以下命令启动项目设置:
npm init
安装以下软件包
npm install --save-dev @babel/core npm install --save-dev @babel/cli npm install --save-dev @babel/preset-env
以下是创建的 package.json:
现在将在根文件夹中创建一个.babelrc文件:
创建一个文件夹src/并在其中添加文件main.js,并将您的代码写入转换为 es5。
src/main.js
let add = (a,b) => {
return a+b;
}
转换命令
npx babel src/main.js --out-file main_es5.js
main_es5.js
"use strict";
var add = function add(a, b) {
return a + b;
};
Babel 7 的工作原理与 Babel 6 相同。唯一的区别是使用 @babel 安装软件包。
Babel 7 中有一些预设已弃用。列表如下:
- ES20xx 预设
- babel-preset-env
- babel-preset-latest
- Babel 中的阶段预设
此外,软件包中的年份也被删除 - @babel/plugin-transform-es2015-classes现在为@babel/plugin-transform-classes
我们将再举一个使用 typescript 并使用 typescript 预设和 babel 7 将其转换为 Es2015 JavaScript 的示例。
要使用 typescript,我们需要安装 typescript 软件包,如下所示:
npm install --save-dev @babel/preset-typescript
在src/文件夹中创建test.ts文件,并以 typescript 形式编写代码:
test.ts
let getName = (person: string) => {
return "Hello, " + person;
}
getName("Siya");
.babelrc
命令
npx babel src/test.ts --out-file test.js
test.js
"use strict";
var getName = function getName(person) {
return "Hello, " + person;
};
getName("Siya");
BabelJS - 将 ES6 特性转换为 ES5
在本章中,我们将了解添加到 ES6 中的特性。我们还将学习如何使用 BabelJS 将这些特性编译为 ES5。
以下是我们将在本章中讨论的各种 ES6 特性:
- Let + Const
- 箭头函数
- 类
- Promise
- 生成器
- 解构
- 迭代器
- 模板字面量
- 增强对象
- 默认、剩余和扩展属性
Let + Const
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
从 es6 到 es5 的 let 关键字的输出如下:
使用 ES6 的 Let
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 变量的值就不能更改。让我们考虑以下示例以了解 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 带来了新的类特性。类类似于 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;
Promise
JavaScript Promise 用于管理代码中的异步请求。
它使生活更轻松并使代码保持简洁,因为您管理来自具有依赖关系的异步请求的多个回调。Promise 提供了一种更好的处理回调函数的方法。Promise 是 ES6 的一部分。默认情况下,当您创建一个 Promise 时,Promise 的状态为 pending。
Promise 有三种状态:
- pending(初始状态)
- resolved(成功完成)
- rejected(失败)
new Promise()用于构造一个 Promise。Promise 构造函数有一个参数,它是一个回调函数。回调函数有两个参数 - resolve 和 reject;
这两个都是内部函数。您编写的异步代码,即 Ajax 调用、图像加载、定时函数将进入回调函数。
如果回调函数中执行的任务成功,则调用 resolve 函数;否则,将使用错误详细信息调用 reject 函数。
以下代码行显示了 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 - Promise
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。该函数具有特殊的语法 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}
输出给出一个具有 value 和 done 作为属性的对象。每次next()方法调用都会从数组中获取下一个值,并且 done 为 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>
输出
解构
解构属性的行为类似于 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,我们可以对函数参数使用默认参数,如下所示。
示例
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));
剩余
剩余参数以三个点(...)开头,如下面的示例所示。
示例
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
在以上函数中,我们向 add 函数传递了 n 个参数。如果在 ES5 中添加所有这些参数,则必须依赖 arguments 对象来获取参数的详细信息。使用 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
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));
扩展
扩展属性也像剩余参数一样使用三个点。以下是一个工作示例,展示了如何使用扩展属性。
示例
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
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));
代理
代理是一个对象,您可以在其中定义属性查找、赋值、枚举、函数、调用等操作的自定义行为。
语法
var a = new Proxy(target, handler);
目标 和 处理程序 都是对象。
目标 是一个对象,也可以是另一个代理元素。
处理程序 将是一个对象,其属性为函数,这些函数将在被调用时提供行为。
让我们尝试通过一个示例来理解这些特性。
示例
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
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);
BabelJS - 将 ES6 模块转换为 ES5
在本章中,我们将了解如何使用 Babel 将 ES6 模块转换为 ES5。
模块
考虑这样一种情况:需要重用 JavaScript 代码的部分内容。ES6 通过模块的概念来解决这个问题。
模块只不过是写在文件中的 JavaScript 代码块。除非模块文件导出它们,否则模块中的函数或变量不可用于使用。
简单来说,模块可以帮助您在模块中编写代码,并仅公开代码中其他部分应访问的部分。
让我们考虑一个示例,以了解如何使用模块以及如何导出它以便在代码中使用它。
示例
add.js
var add = (x,y) => {
return x+y;
}
module.exports=add;
multiply.js
var multiply = (x,y) => {
return x*y;
};
module.exports = multiply;
main.js
import add from './add';
import multiply from './multiply'
let a = add(10,20);
let b = multiply(40,10);
console.log("%c"+a,"font-size:30px;color:green;");
console.log("%c"+b,"font-size:30px;color:green;");
我有三个文件:add.js 用于添加两个给定数字,multiply.js 用于将两个给定数字相乘,以及 main.js,它调用 add 和 multiply 并输出控制台。
为了在 main.js 中使用 add.js 和 multiply.js,我们必须首先导出它们,如下所示。
module.exports = add; module.exports = multiply;
要在 main.js 中使用它们,我们需要导入它们,如下所示。
import add from './add'; import multiply from './multiply'
我们需要模块打包器来构建文件,以便我们可以在浏览器中执行它们。
我们可以这样做:
- 使用 Webpack
- 使用 Gulp
ES6 模块和 Webpack
在本节中,我们将了解 ES6 模块是什么。我们还将学习如何使用 webpack。
在开始之前,我们需要安装以下包。
npm install --save-dev webpack npm install --save-dev webpack-dev-server npm install --save-dev babel-core npm install --save-dev babel-loader npm install --save-dev babel-preset-env
Package.json
我们在脚本中添加了 pack 和 publish 任务,以便使用 npm 运行它们。以下是 webpack.config.js 文件,它将构建最终文件。
webpack.config.js
var path = require('path');
module.exports = {
entry: {
app: './src/main.js'
},
output: {
path: path.resolve(__dirname, 'dev'),
filename: 'main_bundle.js'
},
mode:'development',
module: {
rules: [
{
test: /\.js$/,
include: path.resolve(__dirname, 'src'),
loader: 'babel-loader',
query: {
presets: ['env']
}
}
]
}
};
运行命令 npm run pack 来构建文件。最终文件将存储在 dev/ 文件夹中。
命令
npm run pack
创建了 dev/main_bundle.js 通用文件。此文件将 add.js、multiply.js 和 main.js 组合在一起,并将其存储在 dev/main_bundle.js 中。
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string')
for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) {
return Object.prototype.hasOwnProperty.call(object, property);
};
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = "./src/main.js");
/******/ })
/************************************************************************/
/******/ ({
/***/ "./src/add.js":
/*!********************!*\
!*** ./src/add.js ***!
\********************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
eval(
"\n\nvar add = function add(x, y) {\n return x + y;\n};
\n\nmodule.exports = add;
\n\n//# sourceURL = webpack:///./src/add.js?"
);
/***/ }),
/***/ "./src/main.js":
/*!*********************!*\
!*** ./src/main.js ***!
\*********************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
eval(
"\n\nvar _add = __webpack_require__(/*! ./add */ \"./src/add.js\");
\n\nvar _add2 = _interopRequireDefault(_add);
\n\nvar _multiply = __webpack_require__(/*! ./multiply */ \"./src/multiply.js\");
\n\nvar _multiply2 = _interopRequireDefault(_multiply);
\n\nfunction _interopRequireDefault(obj) {
return obj >> obj.__esModule ? obj : { default: obj };
}
\n\nvar a = (0, _add2.default)(10, 20);
\nvar b = (0, _multiply2.default)(40, 10);
\n\nconsole.log(\"%c\" + a, \"font-size:30px;color:green;\");
\nconsole.log(\"%c\" + b, \"font-size:30px;color:green;\");
\n\n//# sourceURL = webpack:///./src/main.js?"
);
/***/ }),
/***/ "./src/multiply.js":
/*!*************************!*\
!*** ./src/multiply.js ***!
\*************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
eval(
"\n\nvar multiply = function multiply(x, y) {\n return x * y;\n};
\n\nmodule.exports = multiply;
\n\n//# sourceURL = webpack:///./src/multiply.js?"
);
/***/ })
/******/ });
命令
以下是在浏览器中测试输出的命令。
npm run publish
在您的项目中添加 index.html。它调用 dev/main_bundle.js。
<html>
<head></head>
<body>
<script type="text/javascript" src="dev/main_bundle.js"></script>
</body>
</html>
输出
ES6 模块和 Gulp
要使用 Gulp 将模块捆绑到一个文件中,我们将使用 browserify 和 babelify。首先,我们将创建项目设置并安装所需的包。
命令
npm init
在开始项目设置之前,我们需要安装以下包。
npm install --save-dev gulp npm install --save-dev babelify npm install --save-dev browserify npm install --save-dev babel-preset-env npm install --save-dev babel-core npm install --save-dev gulp-connect npm install --save-dev vinyl-buffer npm install --save-dev vinyl-source-stream
安装后的 package.json
现在让我们创建 gulpfile.js,它将帮助运行将模块捆绑在一起的任务。我们将使用上面与 webpack 一起使用的相同文件。
示例
add.js
var add = (x,y) => {
return x+y;
}
module.exports=add;
multiply.js
var multiply = (x,y) => {
return x*y;
};
module.exports = multiply;
main.js
import add from './add';
import multiply from './multiply'
let a = add(10,20);
let b = multiply(40,10);
console.log("%c"+a,"font-size:30px;color:green;");
console.log("%c"+b,"font-size:30px;color:green;");
此处创建了 gulpfile.js。用户将使用 browserify 并使用 transform 转换为 babelify。babel-preset-env 用于将代码转换为 es5。
Gulpfile.js
const gulp = require('gulp');
const babelify = require('babelify');
const browserify = require('browserify');
const connect = require("gulp-connect");
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
gulp.task('build', () => {
browserify('src/main.js')
.transform('babelify', {
presets: ['env']
})
.bundle()
.pipe(source('main.js'))
.pipe(buffer())
.pipe(gulp.dest('dev/'));
});
gulp.task('default', ['es6'],() => {
gulp.watch('src/app.js',['es6'])
});
gulp.task('watch', () => {
gulp.watch('./*.js', ['build']);
});
gulp.task("connect", function () {
connect.server({
root: ".",
livereload: true
});
});
gulp.task('start', ['build', 'watch', 'connect']);
我们使用 browserify 和 babelify 来处理模块导出和导入,并将它们组合到一个文件中,如下所示。
gulp.task('build', () => {
browserify('src/main.js')
.transform('babelify', {
presets: ['env']
})
.bundle()
.pipe(source('main.js'))
.pipe(buffer())
.pipe(gulp.dest('dev/'));
});
我们在 transform 中调用了带有 presets env 的 babelify。
将包含 main.js 的 src 文件夹提供给 browserify 并保存在 dev 文件夹中。
我们需要运行命令 gulp start 来编译文件。
命令
npm start
以下是 dev/ 文件夹中创建的最终文件。
(function() {
function r(e,n,t) {
function o(i,f) {
if(!n[i]) {
if(!e[i]) {
var c = "function"==typeof require&&require;
if(!f&&c)return c(i,!0);if(u)return u(i,!0);
var a = new Error("Cannot find module '"+i+"'");
throw a.code = "MODULE_NOT_FOUND",a
}
var p = n[i] = {exports:{}};
e[i][0].call(
p.exports,function(r) {
var n = e[i][1][r];
return o(n||r)
}
,p,p.exports,r,e,n,t)
}
return n[i].exports
}
for(var u="function"==typeof require>>require,i = 0;i<t.length;i++)o(t[i]);return o
}
return r
})()
({1:[function(require,module,exports) {
"use strict";
var add = function add(x, y) {
return x + y;
};
module.exports = add;
},{}],2:[function(require,module,exports) {
'use strict';
var _add = require('./add');
var _add2 = _interopRequireDefault(_add);
var _multiply = require('./multiply');
var _multiply2 = _interopRequireDefault(_multiply);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var a = (0, _add2.default)(10, 20);
var b = (0, _multiply2.default)(40, 10);
console.log("%c" + a, "font-size:30px;color:green;");
console.log("%c" + b, "font-size:30px;color:green;");
},
{"./add":1,"./multiply":3}],3:[function(require,module,exports) {
"use strict";
var multiply = function multiply(x, y) {
return x * y;
};
module.exports = multiply;
},{}]},{},[2]);
我们将它用于 index.html,并在浏览器中运行它以获取输出。
<html>
<head></head>
<body>
<h1>Modules using Gulp</h1>
<script type="text/javascript" src="dev/main.js"></script>
</body>
</html>
输出
BabelJS - 将 ES7 特性转换为 ES5
在本章中,我们将学习如何将 ES7 特性转换为 ES5。
ECMA Script 7 添加了以下新特性。
- 异步-等待
- 指数运算符
- Array.prototype.includes()
我们将使用 babeljs 将它们编译为 ES5。根据您的项目需求,还可以将代码编译为任何 ecma 版本,例如 ES7 到 ES6 或 ES7 到 ES5。由于 ES5 版本最稳定并且在所有现代和旧版浏览器上都能正常工作,因此我们将代码编译为 ES5。
异步-等待
Async 是一个异步函数,它返回一个隐式 Promise。Promise 要么被 fulfilled 要么被 rejected。异步函数与普通标准函数相同。该函数可以具有 await 表达式,该表达式会暂停执行,直到它返回一个 Promise,一旦获得 Promise,执行就会继续。只有当函数为异步函数时,await 才能工作。
以下是一个关于异步和等待的工作示例。
示例
let timer = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve("Promise resolved after 5 seconds");
}, 5000);
});
};
let out = async () => {
let msg = await timer();
console.log(msg);
console.log("hello after await");
};
out();
输出
Promise resolved after 5 seconds hello after await
在调用 timer 函数之前添加了 await 表达式。timer 函数将在 5 秒后返回 Promise。因此,await 将暂停执行,直到 timer 函数上的 Promise 被 fulfilled 或 rejected,然后继续执行。
现在让我们使用 babel 将以上代码转换为 ES5。
ES7 - 异步-等待
let timer = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve("Promise resolved after 5 seconds");
}, 5000);
});
};
let out = async () => {
let msg = await timer();
console.log(msg);
console.log("hello after await");
};
out();
命令
npx babel asyncawait.js --out-file asyncawait_es5.js
BabelJS - ES5
"use strict";
var timer = function timer() {
return new Promise(function (resolve) {
setTimeout(function () {
resolve("Promise resolved after 5 seconds");
}, 5000);
});
};
var out = async function out() {
var msg = await timer();
console.log(msg);
console.log("hello after await");
};
out();
Babeljs 不会编译对象或方法;因此,此处使用的 Promise 不会被转换,并将按原样显示。为了在旧版浏览器上支持 Promise,我们需要添加代码,这些代码将支持 Promise。现在,让我们安装 babel-polyfill,如下所示。
npm install --save babel-polyfill
它应该被保存为依赖项,而不是开发依赖项。
要在浏览器中运行代码,我们将使用 node_modules\babel-polyfill\dist\polyfill.min.js 中的 polyfill 文件,并使用 script 标签调用它,如下所示。
<!DOCTYPE html>
<html>
<head>
<title>BabelJs Testing</title>
</head>
<body>
<script src="node_modules\babel-polyfill\dist\polyfill.min.js" type="text/javascript"></script>
<script type="text/javascript" src="aynscawait_es5.js"></script>
</body>
</html>
当您运行以上测试页面时,您将在控制台中看到以下输出。
指数运算符
** 是 ES7 中用于幂运算的运算符。以下示例展示了 ES7 中其工作原理,以及使用 babeljs 转换的代码。
示例
let sqr = 9 ** 2; console.log(sqr);
输出
81
ES6 - 幂运算
let sqr = 9 ** 2; console.log(sqr);
要转换幂运算符,我们需要安装一个插件,如下所示。
命令
npm install --save-dev babel-plugin-transform-exponentiation-operator
将插件详细信息添加到 .babelrc 文件中,如下所示。
{
"presets":[
"es2015"
],
"plugins": ["transform-exponentiation-operator"]
}
命令
npx babel exponeniation.js --out-file exponeniation_es5.js
BabelJS - ES5
"use strict"; var sqr = Math.pow(9, 2); console.log(sqr);
Array.prototype.includes()
如果传递给它的元素存在于数组中,则此特性返回 true,否则返回 false。
示例
let arr1 = [10, 6, 3, 9, 17];
console.log(arr1.includes(9));
let names = ['Siya', 'Tom', 'Jerry', 'Bean', 'Ben'];
console.log(names.includes('Tom'));
console.log(names.includes('Be'));
输出
true true false
我们必须再次使用 babel-polyfill,因为 includes 是数组上的方法,它不会被转换。我们需要额外的步骤来包含 polyfill 以使其在旧版浏览器中工作。
ES6 - array.includes
let arr1 = [10, 6, 3, 9, 17];
console.log(arr1.includes(9));
let names = ['Siya', 'Tom', 'Jerry', 'Bean', 'Ben'];
console.log(names.includes('Tom'));
console.log(names.includes('Be'));
命令
npx babel array_include.js --out-file array_include_es5.js
Babel-ES5
'use strict';
var arr1 = [10, 6, 3, 9, 17];
console.log(arr1.includes(9));
var names = ['Siya', 'Tom', 'Jerry', 'Bean', 'Ben'];
console.log(names.includes('Tom'));
console.log(names.includes('Be'));
要在旧版浏览器中测试它,我们需要使用 polyfill,如下所示。
<!DOCTYPE html>
<html>
<head>
<title>BabelJs Testing</title>
</head>
<body>
<script src="node_modules\babel-polyfill\dist\polyfill.min.js" type="text/javascript"></script>
<script type="text/javascript" src="array_include_es5.js"></script>
</body>
</html>
输出
BabelJS - 将 ES8 特性转换为 ES5
字符串填充是添加到 javascript 中的新 ES8 特性。我们将研究一个简单的示例,该示例将使用 babel 将字符串填充转换为 ES5。
字符串填充
字符串填充根据指定的长度从左侧添加另一个字符串。字符串填充的语法如下所示。
语法
str.padStart(length, string); str.padEnd(length, string);
示例
const str = 'abc'; console.log(str.padStart(8, '_')); console.log(str.padEnd(8, '_'));
输出
_____abc abc_____
ES8 - 字符串填充
const str = 'abc'; console.log(str.padStart(8, '_')); console.log(str.padEnd(8, '_'));
命令
npx babel strpad.js --out-file strpad_es5.js
Babel - ES5
'use strict'; var str = 'abc'; console.log(str.padStart(8, '_')); console.log(str.padEnd(8, '_'));
js 必须与 babel-polyfill 一起使用,如下所示。
test.html
<!DOCTYPE html>
<html>
<head>
<title>BabelJs Testing</title>
</head>
<body>
<script src="node_modules\babel-polyfill\dist\polyfill.min.js" type="text/javascript"></script>
<script type="text/javascript" src="strpad_es5.js"></script>
</body>
</html>
BabelJS - Babel 插件
BabelJS 是一个 JavaScript 编译器,它根据可用的预设和插件更改给定代码的语法。Babel 编译流程涉及以下三个部分。
- 解析
- 转换
- 打印
传递给 Babel 的代码会原样返回,只是语法发生了改变。我们已经看到过将预设添加到 .babelrc 文件中,以将代码从 es6 编译到 es5 或反之亦然。预设只不过是一组插件。如果在编译期间未提供预设或插件的详细信息,Babel 不会进行任何更改。
现在让我们讨论以下插件 -
- transform-class-properties
- Transform-exponentiation-operator
- For-of
- 对象 rest 和扩展
- async/await
现在,我们将创建一个项目设置并使用一些插件进行操作,这将使我们对 Babel 中插件的需求有更清晰的了解。
命令
npm init
我们必须为 Babel 安装所需的包 - Babel CLI、Babel Core、Babel 预设等。
Babel 6 的包
npm install babel-cli babel-core babel-preset-es2015 --save-dev
Babel 7 的包
npm install @babel/cli @babel/core @babel/preset-env --save-dev
在你的项目中创建一个 js 文件并编写你的 js 代码。
类 - Transform-class-properties
为此,请观察以下给出的代码 -
示例
main.js
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;
目前,我们还没有向 Babel 提供任何预设或插件的详细信息。如果我们碰巧使用以下命令转换代码 -
npx babel main.js --out-file main_out.js
main_out.js
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;
我们将获得与代码相同的输出。现在让我们将预设添加到 .babelrc 文件中。
注意 - 在项目根目录下创建 .babelrc 文件。
.babelrc for babel 6
.babelrc for babel 7
{
"presets":["@babel/env"]
}
我们已经安装了预设;现在让我们再次运行命令 -
npx babel main.js --out-file main_out.js
main_out.js
"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;
在 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;
}
}
存在构造函数,并且类的所有属性都在其中定义。如果我们需要在类外部定义类属性,则无法这样做。
示例
class Person {
name = "Siya Kapoor";
fullname = () => {
return this.name;
}
}
var a = new Person();
var persondet = a.fullname();
console.log("%c"+persondet, "font-size:25px;color:red;");
如果我们碰巧编译上述代码,它将在 Babel 中抛出一个错误。这导致代码无法编译。
为了使其按我们想要的方式工作,我们可以使用名为 babel-plugin-transform-class-properties 的 Babel 插件。为了使其工作,我们需要先安装它,如下所示 -
Babel 6 的包
npm install --save-dev babel-plugin-transform-class-properties
Babel 7 的包
npm install --save-dev @babel/plugin-proposal-class-properties
将插件添加到 .babelrc 文件中以供 Babel 6 使用 -
.babelrc for babel 7
{
"plugins": ["@babel/plugin-proposal-class-properties"]
}
现在,我们将再次运行命令。
命令
npx babel main.js --out-file main_out.js
main.js
class Person {
name = "Siya Kapoor";
fullname = () => {
return this.name;
}
}
var a = new Person();
var persondet = a.fullname();
console.log("%c"+persondet, "font-size:25px;color:red;");
编译到 main_out.js
class Person {
constructor() {
this.name = "Siya Kapoor";
this.fullname = () => {
return this.name;
};
}
}
var a = new Person();
var persondet = a.fullname();
console.log("%c"+persondet, "font-size:25px;color:red;");
输出
以下是我们在浏览器中使用时获得的输出 -
指数运算符 - transform-exponentiation-operator
** 是 ES7 中用于指数运算的运算符。以下示例显示了 ES7 中相同运算符的工作原理。它还展示了如何使用 BabelJS 转换代码。
示例
let sqr = 9 ** 2;
console.log("%c"+sqr, "font-size:25px;color:red;");
要转换指数运算符,我们需要安装以下插件 -
Babel 6 的包
npm install --save-dev babel-plugin-transform-exponentiation-operator
Babel 7 的包
npm install --save-dev @babel/plugin-transform-exponentiation-operator
将插件详细信息添加到 .babelrc 文件中,如下所示,以供 Babel 6 使用 -
{
"plugins": ["transform-exponentiation-operator"]
}
.babelrc for babel 7
{
"plugins": ["@babel/plugin-transform-exponentiation-operator"]
}
命令
npx babel exponeniation.js --out-file exponeniation_out.js
exponeniation_out.js
let sqr = Math.pow(9, 2);
console.log("%c" + sqr, "font-size:25px;color:red;");
输出
For-of
Babel 6 和 7 中插件所需的包如下 -
Babel 6
npm install --save-dev babel-plugin-transform-es2015-for-of
Babel 7
npm install --save-dev @babel/plugin-transform-for-of
.babelrc for babel 6
{
"plugins": ["transform-es2015-for-of"]
}
.babelrc for babel 7
{
"plugins": ["@babel/plugin-transform-for-of"]
}
forof.js
let foo = ["PHP", "C++", "Mysql", "JAVA"];
for (var i of foo) {
console.log(i);
}
命令
npx babel forof.js --out-file forof_es5.js
Forof_es5.js
let foo = ["PHP", "C++", "Mysql", "JAVA"];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = foo[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var i = _step.value;
console.log(i);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
输出
对象 rest 和扩展
Babel 6 和 7 中插件所需的包如下 -
Babel 6
npm install --save-dev babel-plugin-transform-object-rest-spread
Babel 7
npm install --save-dev @babel/plugin-proposal-object-rest-spread
.babelrc for babel 6
{
"plugins": ["transform-object-rest-spread"]
}
.babelrc for babel 7
{
"plugins": ["@babel/plugin-proposal-object-rest-spread"]
}
o.js
let { x1, y1, ...z1 } = { x1: 11, y1: 12, a: 23, b: 24 };
console.log(x1);
console.log(y1);
console.log(z1);
let n = { x1, y1, ...z1};
console.log(n);
命令
npx babel o.js --out-file o_es5.js
o_es5.js
var _extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i]; for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
function _objectWithoutProperties(obj, keys) {
var target = {};
for (var i in obj) {
if (keys.indexOf(i) >= 0) continue;
if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
target[i] = obj[i];
}
return target;
}
let _x1$y1$a$b = { x1: 11, y1: 12, a: 23, b: 24 },
{ x1, y1 } = _x1$y1$a$b,
z1 = _objectWithoutProperties(_x1$y1$a$b, ["x1", "y1"]);
console.log(x1);
console.log(y1);
console.log(z1);
let n = _extends({ x1, y1 }, z1);
console.log(n);
输出
async/await
我们需要为 Babel 6 安装以下包 -
npm install --save-dev babel-plugin-transform-async-to-generator
Babel 7 的包
npm install --save-dev @babel/plugin-transform-async-to-generator
.babelrc for babel 6
{
"plugins": ["transform-async-to-generator"]
}
.babelrc for babel 7
{
"plugins": ["@babel/plugin-transform-async-to-generator"]
}
async.js
let timer = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve("Promise resolved after 5 seconds");
}, 5000);
});
};
let out = async () => {
let msg = await timer();
console.log(msg);
console.log("hello after await");
};
out();
命令
npx babel async.js --out-file async_es5.js
async_es5.js
function _asyncToGenerator(fn) {
return function () {
var gen = fn.apply(this, arguments);
return new Promise(function (resolve, reject) {
function step(key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
} if (info.done) {
resolve(value);
} else {
return Promise.resolve(value).then(function (value) {
step("next", value);
},
function (err) {
step("throw", err); });
}
} return step("next");
});
};
}
let timer = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve("Promise resolved after 5 seconds");
}, 5000);
});
};
let out = (() => {
var _ref = _asyncToGenerator(function* () {
let msg = yield timer();
console.log(msg);
console.log("hello after await");
});
return function out() {
return _ref.apply(this, arguments);
};
})();
out();
我们必须为此使用 polyfill,因为它在不支持 Promise 的浏览器中不起作用。
输出
BabelJS - Babel Polyfill
Babel Polyfill 为 Web 浏览器添加了对尚不可用功能的支持。Babel 将代码从最新的 Ecma 版本编译到我们想要的版本。它根据预设更改语法,但无法对使用的对象或方法执行任何操作。我们必须为这些功能使用 polyfill 以实现向后兼容性。
可以进行 polyfill 的功能
以下是当在旧版浏览器中使用时需要 polyfill 支持的功能列表 -
- Promise
- Map
- Set
- Symbol
- Weakmap
- Weakset
- Array.from、Array.includes、Array.of、Array#find、Array.buffer、Array#findIndex
- Object.assign、Object.entries、Object.values
我们将创建项目设置,并查看 Babel Polyfill 的工作原理。
命令
npm init
我们现在将安装 Babel 所需的包。
Babel 6 的包
npm install babel-cli babel-core babel-preset-es2015 --save-dev
Babel 7 的包
npm install @babel/cli @babel/core @babel/preset-env --save-dev
这是最终的 package.json -
我们还将 es2015 添加到预设中,因为我们希望将代码编译到 es5。
.babelrc for babel 6
.babelrc for babel 7
{
"presets":["@babel/env"]
}
我们将安装 lite-serve,以便我们可以在浏览器中测试代码 -
npm install --save-dev lite-server
让我们将 Babel 命令添加到 package.json 中以编译我们的代码 -
我们还添加了 build 命令,该命令调用 lite-server。
Babel-polyfill 与 babel-core 包一起安装。babel-polyfill 将在 node_modules 中可用,如下所示 -
我们将进一步研究 Promise 并与之一起使用 babel-polyfill。
ES6 - Promise
let timingpromise = new Promise((resolve, reject) => {
setTimeout(function() {
resolve("Promise is resolved!");
}, 1000);
});
timingpromise.then((msg) => {
console.log("%c"+msg, "font-size:25px;color:red;");
});
命令
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("%c"+msg, "font-size:25px;color:red;");
});
编译不需要更改任何内容。Promise 的代码已原样转换。但是,即使我们将代码编译到 es5,不支持 Promise 的浏览器也会抛出错误。
要解决此问题,我们需要在最终的 es5 编译代码中添加 polyfill。要在浏览器中运行代码,我们将从 node_modules 中获取 babel-polyfill 文件并将其添加到我们要使用 Promise 的 .html 文件中,如下所示 -
index.html
<html>
<head>
</head>
<body>
<h1>Babel Polyfill Testing</h1>
<script type="text/javascript" src="node_modules/babel-polyfill/dist/polyfill.min.js"></script>
<script type="text/javascript" src="promise_es5.js"></script>
</body>
</html>
输出
在 index.html 文件中,我们使用了来自 node_modules 的 polyfill.min.js 文件,然后是 promise_es5.js -
<script type="text/javascript" src="node_modules/babel-polyfill/dist/polyfill.min.js"></script> <script type="text/javascript" src="promise_es5.js"></script>
注意 - polyfill 文件必须在主 JavaScript 调用之前开始使用。
字符串填充
字符串填充根据指定的长度从左侧添加另一个字符串。字符串填充的语法如下所示。
语法
str.padStart(length, string); str.padEnd(length, string);
示例
const str = 'abc'; console.log(str.padStart(8, '_')); console.log(str.padEnd(8, '_'));
输出
_____abc abc_____
Babel - ES5
npx babel strpad.js --out-file strpad_es5.js
命令
'use strict'; var str = 'abc'; console.log(str.padStart(8, '_')); console.log(str.padEnd(8, '_'));
js 必须与 babel-polyfill 一起使用,如下所示。
test.html
<!DOCTYPE html>
<html>
<head>
<title>BabelJs Testing </title>
</head>
<body>
<script src="node_modules/babel-polyfill/dist/polyfill.min.js" type="text/javascript"></script>
<script type="text/javascript" src="strpad_es5.js"></script>
</body>
</html>
Map、Set、WeakSet、WeakMap
在本节中,我们将学习Map、Set、WeakSet、WeakMap。
Map 是一个具有键/值对的对象。
Set 也是一个对象,但具有唯一值。
WeakMap 和 WeakSet 也是具有键/值对的对象。
Map、Set、WeakMap 和 WeakSet 是添加到 ES6 中的新功能。要将其转换为在旧版浏览器中使用,我们需要使用 polyfill。我们将使用一个示例并使用 polyfill 编译代码。
示例
let m = new Map(); //map example
m.set("0","A");
m.set("1","B");
console.log(m);
let set = new Set(); //set example
set.add('A');
set.add('B');
set.add('A');
set.add('B');
console.log(set);
let ws = new WeakSet(); //weakset example
let x = {};
let y = {};
ws.add(x);
console.log(ws.has(x));
console.log(ws.has(y));
let wm = new WeakMap(); //weakmap example
let a = {};
wm.set(a, "hello");
console.log(wm.get(a));
输出
Map(2) {"0" => "A", "1" => "B"}
Set(2) {"A", "B"}
true
false
hello
命令
npx babel set.js --out-file set_es5.js
Babel-ES5
"use strict";
var m = new Map(); //map example
m.set("0", "A");
m.set("1", "B");
console.log(m);
var set = new Set(); //set example
set.add('A');
set.add('B');
set.add('A');
set.add('B');
console.log(set);
var ws = new WeakSet(); //weakset example
var x = {};
var y = {};
ws.add(x);
console.log(ws.has(x));
console.log(ws.has(y));
var wm = new WeakMap(); //weakmap example
var a = {};
wm.set(a, "hello");
console.log(wm.get(a));
js 必须与 babel-polyfill 一起使用,如下所示。
test.html
<!DOCTYPE html>
<html>
<head>
<title>BabelJs Testing</title>
</head>
<body>
<script src="node_modules/babel-polyfill/dist/polyfill.min.js" type="text/javascript"></script>
<script type="text/javascript" src="set_es5.js"></script>
</body>
</html>
输出
数组方法
可以在数组上使用许多属性和方法;例如,array.from、array.includes 等。
让我们考虑使用以下示例来更好地理解这一点。
示例
arraymethods.js
var arrNum = [1, 2, 3]; console.log(arrNum.includes(2)); console.log(Array.from([3, 4, 5], x => x + x));
输出
true [6, 8, 10]
命令
npx babel arraymethods.js --out-file arraymethods_es5.js
Babel-es5
"use strict";
var arrNum = [1, 2, 3];
console.log(arrNum.includes(2));
console.log(Array.from([3, 4, 5], function (x) {
return x + x;
}));
数组上使用的方法按原样打印。为了使其在旧版浏览器上工作,我们需要在开头添加 polyfill 文件,如下所示 -
index.html
<html>
<head></head>
<body>
<h1>Babel Polyfill Testing</h1>
<script type="text/javascript" src="node_modules/babel-polyfill/dist/polyfill.min.js"></script>
<script type="text/javascript" src="arraymethods_es5.js"></script>
</body>
</html>
输出
BabelJS - Babel CLI
BabelJS 带有一个内置的命令行界面,其中可以使用易于使用的命令轻松地将 JavaScript 代码编译到相应的 ECMA Script。我们将在本章中讨论这些命令的使用。
首先,我们将为我们的项目安装 babel-cli。我们将使用 babeljs 编译代码。
为你的项目创建一个文件夹以使用 babel-cli。
命令
npm init
显示
为上述项目创建的 Package.json -
让我们运行命令来安装 babel-cli。
Babel 6 的包
npm install --save-dev babel-cli
Babel 7 的包
npm install --save-dev @babel/cli
显示
我们已经安装了 babel-cli,这是更新后的 package.json -
此外,我们需要安装 babel-preset 和 babel-core。现在让我们看看安装命令。
Babel 6 的包
npm install --save-dev babel-preset-env npm install --save-dev babel-core
Babel 7 的包
npm install --save-dev @babel/core npm install --save-dev @babel/preset-env
这是上述命令的更新后的 package.json -
由于我们需要编译我们将要编写的 JavaScript 代码以具有向后兼容性,因此我们将将其编译为 ECMA Script 5。为此,我们需要指示 Babel 查找预设,即将在其中进行编译的 es 版本。我们需要在创建的项目根目录中创建一个 .babelrc> 文件,如下所示。
它包含一个具有以下预设详细信息的 json 对象 -
{ "presets": ["env"] }
对于 Babel 7,.babelrc 如下所示 -
{
"presets":["@babel/env"]
}
我们已将 Babel 本地安装到项目中。为了在我们的项目中使用 Babel,我们需要在 package.json 中指定它,如下所示 -
编译 JS 文件
现在我们准备编译我们的 JavaScript 文件了。在你的项目中创建一个名为 src 的文件夹;在这个文件夹中,创建一个名为 main.js 的文件并编写如下所示的 es6 javascript 代码 -
命令
npx babel src/main.js
输出
在上述情况下,来自 main.js 的代码在终端中以 es5 版本显示。来自 es6 的箭头函数转换为 es5,如上所示。我们将存储在不同的文件中,而不是在终端中显示编译后的代码,如下所示。
我们在项目中创建了一个名为 out 的文件夹,我们希望将编译后的文件存储在其中。以下命令将编译并将输出存储在我们想要的位置。
命令
npx babel src/main.js --out-file out/main_out.js
输出
命令中的 --out-file 选项帮助我们将输出存储在我们选择的文件夹位置。
如果我们希望每次更改主要文件时都更新文件,请将 --watch 或 -w 选项添加到命令中,如下所示。
命令
npx babel src/main.js --watch --out-file out/main_out.js
输出
你可以对主要文件进行更改;此更改将反映在编译后的文件中。
在上述情况下,我们更改了日志消息,并且 --watch 选项持续检查是否有任何更改,并在编译后的文件中添加了相同的更改。
编译后的文件
在我们之前的章节中,我们学习了如何编译单个文件。现在,我们将编译一个目录并将编译后的文件存储在另一个目录中。
在 src 文件夹中,我们将创建另一个 js 文件,名为 main1.js。目前,src 文件夹中有 2 个 javascript 文件 main.js 和 main1.js。
以下是文件中的代码 -
main.js
var arrowfunction = () => {
console.log("Added changes to the log message");
}
main1.js
var handler = () => {
console.log("Added one more file");
}
以下命令将编译来自 src 文件夹的代码并将其存储到 out/ 文件夹中。我们已从 out/ 文件夹中删除所有文件并将其清空。我们将运行该命令并检查 out/ 文件夹中的输出。
命令
npx babel src --out-dir out
我们在 out 文件夹中得到了 2 个文件 - main.js 和 main1.js
main.js
"use strict";
var arrowfunction = function arrowfunction() {
console.log("Added changes to the log message");
};
main1.js
"use strict";
var handler = function handler() {
console.log("Added one more file");
};
接下来,我们将执行以下命令以使用 babeljs 将这两个文件编译成一个文件。
命令
npx babel src --out-file out/all.js
输出
"use strict";
var arrowfunction = function arrowfunction() {
console.log("Added changes to the log message");
};
"use strict";
var handler = function handler() {
console.log("Added one more file");
};
如果我们希望忽略某些文件不被编译,我们可以使用 --ignore 选项,如下所示。
命令
npx babel src --out-file out/all.js --ignore src/main1.js
输出
all.js
"use strict";
var arrowfunction = function arrowfunction() {
console.log("Added changes to the log message");
};
我们可以使用插件选项在文件编译期间使用。要使用插件,我们需要安装它,如下所示。
命令
npm install --save-dev babel-plugin-transform-exponentiation-operator
expo.js
let sqr = 9 ** 2; console.log(sqr);
命令
npx babel expo.js --out-file expo_compiled.js --plugins=babel-plugin-transform-exponentiation-operator
输出
"use strict"; var sqr = Math.pow(9, 2); console.log(sqr);
我们也可以在命令中使用预设,如下所示。
命令
npx babel src/main.js --out-file main_es5.js --presets=es2015
为了测试上述情况,我们已从 .babelrc 中删除了预设选项。
main.js
var arrowfunction = () => {
console.log("Added changes to the log message");
}
main_es5.js
"use strict";
var arrowfunction = function arrowfunction() {
console.log("Added changes to the log message");
};
我们也可以从命令行忽略 .babelrc,如下所示 -
npx babel --no-babelrc src/main.js --out-file main_es5.js --presets=es2015
为了测试上述情况,我们已将预设添加回 .babelrc,并且由于我们在命令中添加了 --no-babelrc,因此它将被忽略。main_es5.js 文件的详细信息如下 -
main_es5.js
"use strict";
var arrowfunction = function arrowfunction() {
console.log("Added changes to the log message");
};
BabelJS - Babel 预设
Babel 预设是 Babel 转换器的配置详细信息,告诉它以指定的模式进行转换。以下是一些我们将在本章中讨论的最流行的预设 -
- ES2015
- Env
- React
我们需要使用包含我们希望代码转换到的环境的预设。例如,es2015 预设会将代码转换为 es5。值为 env 的预设也会转换为 es5。它还具有其他功能,即选项。如果您希望该功能在最新版本的浏览器上受支持,则 Babel 仅在这些浏览器不支持该功能时才会转换代码。使用 react 预设,Babel 会将代码转换为 React 代码。
要使用预设,我们需要在项目根文件夹中创建一个 .babelrc 文件。为了展示其工作原理,我们将创建一个如下所示的项目结构。
命令
npm init
我们必须按照如下方式安装所需的 Babel 预设,以及 Babel CLI、Babel Core 等。
Babel 6 包
npm install babel-cli babel-core babel-preset-es2015 --save-dev
Babel 7 包
npm install @babel/cli @babel/core @babel/preset-env --save-dev
注意 - babel-preset-es2015 从 Babel 7 开始已弃用。
es2015 或 @babel/env
在项目的根目录中创建 .babelrc 文件 (Babel 6) -
在 .babelrc 中,预设为 es2015。这表示我们希望 Babel 编译器将代码转换为 es2015。
对于 Babel 7,我们需要按如下方式使用预设 -
{
"presets":["@babel/env"]
}
以下是安装后的 package.json -
由于我们已在本地安装了 Babel,因此我们在 package.json 的 scripts 部分添加了 Babel 命令。
让我们做一个简单的示例来检查使用 es2015 预设进行转译。
示例
main.js
let arrow = () => {
return "this is es6 arrow function";
}
转译为 es5,如下所示。
命令
npx babel main.js --out-file main_es5.js
main_es5.js
"use strict";
var arrow = function arrow() {
return "this is es6 arrow function";
};
Env
使用 Env 预设,您可以指定您希望最终代码转译到的环境。
我们将使用上面创建的相同的项目结构,并将预设从 es2015 更改为 env,如下所示。
此外,我们需要安装 babel-preset-env。我们将执行以下命令来安装它。
命令
npm install babel-preset-env --save-dev
我们将再次编译 main.js 并查看输出。
main.js
let arrow = () => {
return "this is es6 arrow function";
}
命令
npx babel main.js --out-file main_env.js
main_env.js
"use strict";
var arrow = function arrow() {
return "this is es6 arrow function";
};
我们看到转译后的代码是 es5。如果我们知道代码将执行的环境,我们可以使用此预设来指定它。例如,如果我们将浏览器指定为 Chrome 和 Firefox 的最后 1 个版本,如下所示。
命令
npx babel main.js --out-file main_env.js
main_env.js
"use strict";
let arrow = () => {
return "this is es6 arrow function";
};
我们现在获得的箭头函数语法保持不变。它没有被转译成 ES5 语法。这是因为我们希望代码支持的环境已经支持箭头函数。
Babel 使用 babel-preset-env 处理基于环境的代码编译。我们还可以根据 Node.js 环境来指定编译目标,如下所示
代码的最终编译结果如下所示。
命令
npx babel main.js --out-file main_env.js
main_env.js
"use strict";
let arrow = () => {
return "this is es6 arrow function";
};
Babel 根据当前 Node.js 版本编译代码。
React 预设
当我们使用 React.js 时,可以使用 React 预设。我们将做一个简单的示例,并使用 React 预设查看输出。
要使用预设,我们需要安装 babel-preset-react (Babel 6),如下所示 -
npm install --save-dev babel-preset-react
对于 Babel 7,如下所示 -
npm install --save-dev @babel/preset-react
对于 Babel 6,.babelrc 的更改如下 -
对于 Babel 7
{
"presets": ["@babel/preset-react"]
}
main.js
<h1>Hello, world!</h1>
命令
npx babel main.js --out-file main_env.js
main_env.js
React.createElement( "h1", null, "Hello, world!" );
使用预设:react,main.js 中的代码被转换为 React.js 语法。
BabelJS - 使用 Babel 和 Webpack
Webpack 是一个模块打包器,它将所有模块及其依赖项(js、样式、图像等)打包成静态资源 .js、.css、.jpg、.png 等。Webpack 带有预设,有助于将代码编译成所需的格式。例如,React 预设有助于将最终输出转换为 React 格式,es2015 或 env 预设有助于将代码编译为 ES5 或 6 或 7 等。我们在项目设置中使用了 Babel 6。如果您想切换到 Babel 7,请使用 @babel/babel-package-name 安装 Babel 的所需包。
这里,我们将讨论使用 Babel 和 Webpack 的项目设置。创建一个名为 的文件夹,并在 Visual Studio IDE 中打开它。
要创建项目设置,请运行 npm init babel webpack,如下所示 -
以下是 npm init 创建后的 package.json -
现在,我们将安装使用 Babel 和 Webpack 所需的包。
npm install --save-dev webpack npm install --save-dev webpack-dev-server npm install --save-dev babel-core npm install --save-dev babel-loader npm install --save-dev babel-preset-env
以下是安装后的 Package.json -
现在,我们将创建一个 webpack.config.js 文件,其中包含打包 js 文件的所有详细信息。这些文件将使用 Babel 编译成 es5。
要使用服务器运行 Webpack,我们使用 webpack-server。以下是添加到其中的详细信息 -
我们添加了 publish 命令,它将启动 webpack-dev-server 并更新最终文件存储的路径。现在我们将用于更新最终文件的路径是 /dev 文件夹。
要使用 Webpack,我们需要运行以下命令 -
npm run publish
首先我们需要创建 webpack.config.js 文件。这些文件将包含 Webpack 工作的配置详细信息。
文件中的详细信息如下 -
var path = require('path');
module.exports = {
entry: {
app: './src/main.js'
},
output: {
path: path.resolve(__dirname, 'dev'),
filename: 'main_bundle.js'
},
mode:'development',
module: {
rules: [
{
test: /\.js$/,
include: path.resolve(__dirname, 'src'),
loader: 'babel-loader',
query: {
presets: ['env']
}
}
]
}
};
文件的结构如上所示。它以 path 开头,提供当前路径的详细信息。
var path = require('path'); //gives the current path
接下来是 module.exports 对象,它具有 entry、output 和 module 属性。entry 是起点。在这里,我们需要提供要编译的主要 js 文件。
entry: {
app: './src/main.js'
},
path.resolve(_dirname, ‘src/main.js’) -- 将在目录中查找 src 文件夹,并在该文件夹中查找 main.js。
输出
output: {
path: path.resolve(__dirname, 'dev'),
filename: 'main_bundle.js'
},
Output 是一个包含 path 和 filename 属性的对象。Path 将保存编译文件所在的文件夹,filename 将告诉您在 .html 文件中使用的最终文件名。
module
module: {
rules: [
{
test: /\.js$/,
include: path.resolve(__dirname, 'src'),
loader: 'babel-loader',
query: {
presets: ['env']
}
}
]
}
Module 是一个包含规则详细信息的对象。它具有以下属性 -
- test
- include
- loader
- query
Test 将保存所有以 .js 结尾的 js 文件的详细信息。它具有模式,将在给定的入口点中查找结尾处的 .js。
Include 指示要查看的文件使用的文件夹。
Loader 使用 babel-loader 来编译代码。
Query 具有 presets 属性,它是一个数组,其值为 env - es5 或 es6 或 es7。
创建 src 文件夹和 main.js 文件;在其中编写您的 ES6 代码。稍后,运行命令以查看它如何使用 Webpack 和 Babel 编译为 es5。
src/main.js
let add = (a,b) => {
return a+b;
};
let c = add(10, 20);
console.log(c);
运行以下命令 -
npm run pack
编译后的文件如下所示 -
dev/main_bundle.js
!function(e) {
var t = {};
function r(n) {
if(t[n])return t[n].exports;var o = t[n] = {i:n,l:!1,exports:{}};
return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports
}
r.m = e,r.c = t,r.d = function(e,t,n) {
r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})
},
r.r = function(e) {
"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})
},
r.t = function(e,t) {
if(1&t&&(e = r(e)),8&t)return e;
if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;
var n = Object.create(null);
if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t) {return e[t]}.bind(null,o));
return n
},
r.n = function(e) {
var t = e&&e.__esModule?function() {return e.default}:function() {return e};
return r.d(t,"a",t),t
},
r.o = function(e,t) {return Object.prototype.hasOwnProperty.call(e,t)},
r.p = "",r(r.s = 0)
}([function(e,t,r) {"use strict";var n = function(e,t) {return e+t}(10,20);console.log(n)}]);
!function(e) {
var t = {};
function r(n) {
if(t[n])return t[n].exports;
var o = t[n] = {i:n,l:!1,exports:{}};
return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports
}
r.m = e,r.c = t,r.d = function(e,t,n) {
r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})
},
r.r = function(e) {
"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})
},
r.t = function(e,t) {
if(1&t&&(e=r(e)),
8&t)return e;
if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;
var n = Object.create(null);
if(
r.r(n),
Object.defineProperty(n,"default",{enumerable:!0,value:e}),
2&t&&"string"!=typeof e
)
for(var o in e)r.d(n,o,function(t) {return e[t]}.bind(null,o));
return n
},
r.n = function(e) {
var t = e&&e.__esModule?function() {return e.default}:function() {return e};
return r.d(t,"a",t),t
},
r.o = function(e,t) {
return Object.prototype.hasOwnProperty.call(e,t)
},
r.p = "",r(r.s = 0)
}([function(e,t,r) {
"use strict";
var n = function(e,t) {return e+t}(10,20);
console.log(n)
}]);
代码如上所示编译。Webpack 添加了一些内部所需的代码,并且 main.js 中的代码位于末尾。我们已经像上面那样控制台输出了值。
在 .html 文件中添加最终的 js 文件,如下所示 -
<html>
<head></head>
<body>
<script type="text/javascript" src="dev/main_bundle.js"></script>
</body>
</html>
运行以下命令 -
npm run publish
要检查输出,我们可以在以下地址打开文件 -
https://:8080/
我们得到如上所示的控制台值。现在让我们尝试使用 Webpack 和 Babel 将代码编译成单个文件。
我们将使用 Webpack 将多个 js 文件捆绑到一个文件中。Babel 将用于将 es6 代码编译为 es5。
现在,我们在 src/ 文件夹中有 2 个 js 文件 - main.js 和 Person.js,如下所示 -
person.js
export 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;
}
}
我们使用了 export 来使用 Person 类的详细信息。
main.js
import {Person} from './person'
var a = new Person("Siya", "Kapoor", "15", "Mumbai");
var persondet = a.fullname;
console.log(persondet);
在 main.js 中,我们从文件路径导入了 Person。
注意 - 我们不必包含 person.js,只需文件名即可。我们创建了一个 Person 类的对象,并如上所示控制台输出了详细信息。
Webpack 将合并 person.js 和 main.js,并在 dev/main_bundle.js 中更新为一个文件。运行命令 npm run publish 以在浏览器中检查输出 -
BabelJS - 使用 Babel 和 JSX
在本章中,我们将了解使用 JSX 和 Babel 的方法。在深入了解细节之前,让我们先了解什么是 JSX。
什么是 JSX?
JSX 是一种 JavaScript 代码,其中包含 XML 语法。JSX 标签具有标签名称、属性和子元素,使其看起来像 XML。
React 使用 JSX 进行模板化,而不是普通的 JavaScript。这不是必须的,但是,以下是一些随之而来的优点。
它更快,因为它在将代码编译为 JavaScript 时执行优化。
它也是类型安全的,大多数错误可以在编译时被捕获。
如果您熟悉 HTML,它使编写模板变得更容易和更快。
我们在项目设置中使用了 Babel 6。如果您想切换到 Babel 7,请使用 @babel/babel-package-name 安装 Babel 的所需包。
我们将创建项目设置并使用 Webpack 将 JSX 与 React 编译成正常的 JavaScript,使用 Babel。
要启动项目设置,请运行以下命令以安装 Babel、React 和 Webpack。
命令
npm init
现在,我们将安装使用 Babel、Webpack 和 JSX 所需的包 -
npm install --save-dev webpack npm install --save-dev webpack-cli npm install --save-dev webpack-dev-server npm install --save-dev babel-core npm install --save-dev babel-loader npm install --save-dev babel-preset-es2015 npm install --save-dev babel-preset-react npm install --save-dev react npm install --save-dev react-dom
以下是安装后的 package.json -
现在将创建一个 webpack.config.js 文件,其中包含打包 js 文件的所有详细信息,并使用 Babel 将其编译成 es5。
要使用服务器运行 Webpack,有一个名为 webpack-server 的工具。我们添加了一个名为 publish 的命令;此命令将启动 webpack-dev-server 并更新最终文件存储的路径。现在我们将用于更新最终文件的路径是 /dev 文件夹。
要使用 Webpack,我们需要运行以下命令 -
npm run publish
我们将创建 webpack.config.js 文件,其中包含 Webpack 工作的配置详细信息。
文件中的详细信息如下 -
var path = require('path');
module.exports = {
entry: {
app: './src/main.js'
},
output: {
path: path.resolve(__dirname, 'dev'),
filename: 'main_bundle.js'
},
mode:'development',
module: {
rules: [
{
test:/\.(js|jsx)$/,
include: path.resolve(__dirname, 'src'),
loader: 'babel-loader',
query: {
presets: ['es2015','react']
}
}
]
}
};
文件的结构如上所示。它以 path 开头,提供当前路径的详细信息。
var path = require('path'); //gives the current path
接下来是 module.exports 对象,它具有 entry、output 和 module 属性。
Entry 是起点。在这里,我们需要提供要编译的主要 js 文件。
entry: {
app: './src/main.js'
},
path.resolve(_dirname, ‘src/main.js’) -- 将在目录中查找 src 文件夹,并在该文件夹中查找 main.js。
输出
output: {
path: path.resolve(__dirname, 'dev'),
filename: 'main_bundle.js'
},
Output 是一个包含 path 和 filename 属性的对象。Path 将保存编译文件所在的文件夹,filename 将告诉您在 .html 文件中使用的最终文件名。
module
module: {
rules: [
{
test:/\.(js|jsx)$/,
include: path.resolve(__dirname, 'src'),
loader: 'babel-loader',
query: {
presets: ['es2015','react']
}
}
]
}
模块是一个包含规则细节的对象,它具有属性,例如 test、include、loader 和 query。
Test 将保存所有以 .js 和 .jsx 结尾的 js 文件的详细信息。它具有一个模式,将在给定的入口点中查找结尾处的 .js 和 .jsx。
Include 指示用于查找文件的文件夹。
Loader 使用 babel-loader 来编译代码。
Query 具有属性 presets,它是一个数组,其值为 env – es5 或 es6 或 es7。我们使用了 es2015 和 react 作为预设。
创建文件夹 src/。在其中添加 main.js 和 App.jsx。
App.jsx
import React from 'react';
class App extends React.Component {
render() {
var style = {
color: 'red',
fontSize: 50
};
return (
<div style={style}>
Hello World!!!
</div>
);
}
}
export default App;
main.js
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.jsx'; ReactDOM.render(, document.getElementById('app'));
运行以下命令来打包 .js 文件并使用预设 es2015 和 react 进行转换。
命令
npm run pack
将 dev 文件夹中的 main_bundle.js 添加到 index.html 中 -
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<title>React App</title>
</head>
<body>
<div id = "app"></div>
<script src = "dev/main_bundle.js"></script>
</body>
</html>
命令
npm run publish
输出
BabelJS - 使用 Babel 和 Flow
Flow 是 JavaScript 的静态类型检查器。要使用 Flow 和 Babel,我们将首先创建一个项目设置。我们在项目设置中使用了 Babel 6。如果您想切换到 Babel 7,请使用 @babel/babel-package-name 安装 Babel 的必需包。
命令
npm init
安装 Flow 和 Babel 的必需包 -
npm install --save-dev babel-core babel-cli babel-preset-flow flow-bin babel-plugin-transform-flow-strip-types
这是安装后的最终 package.json。还添加了 Babel 和 Flow 命令,以便在命令行中执行代码。
在项目设置内创建 .babelrc,并添加如下所示的预设
创建一个 main.js 文件,并使用 Flow 编写您的 JavaScript 代码 -
main.js
/* @flow */
function concat(a: string, b: string) {
return a + b;
}
let a = concat("A", "B");
console.log(a);
使用 Babel 命令编译代码,使用预设:将 Flow 转换为普通 JavaScript
npx babel main.js --out-file main_flow.js
main_flow.js
function concat(a, b) {
return a + b;
}
let a = concat("A", "B");
console.log(a);
我们还可以使用名为 babel-plugin-transform-flow-strip-types 的插件来代替预设,如下所示 -
在 .babelrc 中,添加如下所示的插件 -
main.js
/* @flow */
function concat(a: string, b: string) {
return a + b;
}
let a = concat("A", "B");
console.log(a);
命令
npx babel main.js --out-file main_flow.js
main_flow.js
function concat(a, b) {
return a + b;
}
let a = concat("A", "B");
console.log(a);
BabelJS - 使用 BabelJS 和 Gulp
在本章中,我们将使用 Babel 和 Gulp 创建项目设置。Gulp 是一个使用 Node.js 作为平台的任务运行器。Gulp 将运行将 JavaScript 文件从 es6 转换为 es5 的任务,完成后将启动服务器以测试更改。我们在项目设置中使用了 Babel 6。如果您想切换到 Babel 7,请使用 @babel/babel-package-name 安装 Babel 的必需包。
我们将首先使用 npm 命令创建项目,并安装所需的包以开始。
命令
npm init
我们创建了一个名为 gulpbabel 的文件夹。接下来,我们将安装 Gulp 和其他必需的依赖项。
命令
npm install gulp --save-dev npm install gulp-babel --save-dev npm install gulp-connect --save-dev npm install babel-preset-env --save-dev npm install babel-core --save-dev
我们将如下所示将预设环境详细信息添加到 .babelrc 文件中
gulpfile.js
var gulp =require('gulp');
var babel =require('gulp-babel');
var connect = require("gulp-connect");
gulp.task('build', () => {
gulp.src('src/./*.js')
.pipe(babel())
.pipe(gulp.dest('./dev'))
});
gulp.task('watch', () => {
gulp.watch('./*.js', ['build']);
});
gulp.task("connect", function () {
connect.server({
root: ".",
livereload: true
});
});
gulp.task('start', ['build', 'watch', 'connect']);
我们在 Gulp 中创建了三个任务:[‘build’,’watch’,’connect’]。src 文件夹中所有可用的 js 文件将使用 Babel 转换为 es5,如下所示 -
gulp.task('build', () => {
gulp.src('src/./*.js')
.pipe(babel())
.pipe(gulp.dest('./dev'))
});
最终更改存储在 dev 文件夹中。Babel 使用 .babelrc 中的预设详细信息。如果您想更改为其他预设,可以在 .babelrc 文件中更改详细信息。
现在,我们将使用 es6 javascript 在 src 文件夹中创建一个 .js 文件,并运行 gulp start 命令来执行更改。
src/main.js
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;
}
}
命令:gulp start
dev/main.js
这是使用 Babel 转换的 -
"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;
}();
Index.html
这是使用 转换后的 dev/main.js 完成的 -
<html>
<head></head>
<body>
<script type="text/javascript" src="dev/main.js"></script>
<h1 id="displayname"></h1>
<script type="text/javascript">
var a = new Student("Siya", "Kapoor", "15", "Mumbai");
var studentdet = a.fullname;
document.getElementById("displayname").innerHTML = studentdet;
</script>
</body>
</html>
输出
BabelJS - 示例
我们将使用 ES6 功能并创建一个简单的项目。Babeljs 将用于将代码编译为 ES5。该项目将包含一组图像,这些图像将在固定时间间隔后自动滑动。我们将使用 ES6 类来处理它。我们在项目设置中使用了 Babel 6。如果您想切换到 Babel 7,请使用 @babel/babel-package-name 安装 Babel 的必需包。
自动滑动图像
我们将使用 Gulp 来构建项目。首先,我们将创建如下所示的项目设置
命令
npm init
我们创建了一个名为 babelexample 的文件夹。接下来,我们将安装 Gulp 和其他必需的依赖项。
命令
npm install gulp --save-dev npm install gulp-babel --save-dev npm install gulp-connect --save-dev npm install babel-preset-env --save-dev
以下是安装后的 Package.json -
我们将如下所示将预设环境详细信息添加到 .babelrc 文件中 -
由于我们需要 Gulp 任务来构建最终文件,因此我们将创建包含所需任务的 gulpfile.js
gulpfile.js
var gulp = require('gulp');
var babel = require('gulp-babel');
var connect = require("gulp-connect");
gulp.task('build', () => {
gulp.src('src/./*.js')
.pipe(babel())
.pipe(gulp.dest('./dev'))
});
gulp.task('watch', () => {
gulp.watch('./*.js', ['build']);
});
gulp.task("connect", function () {
connect.server({
root: ".",
livereload: true
});
});
gulp.task('start', ['build', 'watch', 'connect']);
我们在 Gulp 中创建了三个任务,[‘build’,’watch’,’connect’]。src 文件夹中所有可用的 js 文件将使用 Babel 转换为 es5,如下所示
gulp.task('build', () => {
gulp.src('src/./*.js')
.pipe(babel())
.pipe(gulp.dest('./dev'))
});
最终更改存储在 dev 文件夹中。Babel 使用 .babelrc 中的预设详细信息。如果您想更改为其他预设,可以在 .babelrc 文件中更改详细信息。
现在,我们将使用 es6 JavaScript 在 src 文件夹中创建一个 .js 文件,并运行 gulp start 命令来执行更改。
项目结构如下所示 -
src/slidingimage.js
class SlidingImage {
constructor(width, height, imgcounter, timer) {
this.counter = 0;
this.imagecontainerwidth = width;
this.imagecontainerheight = height;
this.slidercounter = imgcounter;
this.slidetimer = timer;
this.startindex = 1;
this.css = this.applycss();
this.maincontainer = this.createContainter();
this.childcontainer = this.imagecontainer();
this.autoslide();
}
createContainter() {
let maindiv = document.createElement('div');
maindiv.id = "maincontainer";
maindiv.class = "maincontainer";
document.body.appendChild(maindiv);
return maindiv;
}
applycss() {
let slidercss = ".maincontainer{ position : relative; margin :auto;}.left,
.right {
cursor: pointer; position: absolute;" +
"top: 50%; width: auto; padding: 16px; margin-top: -22px; color: white; font-weight: bold; " +
"font-size: 18px; transition: 0.6s ease; border-radius: 0 3px 3px 0;
}.right { right: 0; border-radius: 3px 0 0 3px;}" +
".left:hover, .right:hover { background-color: rgba(0,0,0,0.8);}";
let style = document.createElement('style');
style.id = "slidercss";
style.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(style);
let styleall = style;
if (styleall.styleSheet) {
styleall.styleSheet.cssText = slidercss;
} else {
let text = document.createTextNode(slidercss);
style.appendChild(text);
}
}
imagecontainer() {
let childdiv = [];
let imgcont = [];
for (let a = 1; a >= this.slidercounter; a++) {
childdiv[a] = document.createElement('div');
childdiv[a].id = "childdiv" + a;
childdiv[a].style.width = this.imagecontainerwidth + "px";
childdiv[a].style.height = this.imagecontainerheight + "px";
if (a > 1) {
childdiv[a].style.display = "none";
}
imgcont[a] = document.createElement('img');
imgcont[a].src = "src/img/img" + a + ".jpg";
imgcont[a].style.width = "100%";
imgcont[a].style.height = "100%";
childdiv[a].appendChild(imgcont[a]);
this.maincontainer.appendChild(childdiv[a]);
}
}
autoslide() {
console.log(this.startindex);
let previousimg = this.startindex;
this.startindex++;
if (this.startindex > 5) {
this.startindex = 1;
}
setTimeout(() => {
document.getElementById("childdiv" + this.startindex).style.display = "";
document.getElementById("childdiv" + previousimg).style.display = "none";
this.autoslide();
}, this.slidetimer);
}
}
let a = new SlidingImage(300, 250, 5, 5000);
我们将创建 src/ 中的 img/ 文件夹,因为我们需要显示图像;这些图像需要每 5 秒旋转一次。dev/ 文件夹将存储编译后的代码。运行 gulp start 以构建最终文件。
最终项目结构如下所示 -
在 slidingimage.js 中,我们创建了一个名为 SlidingImage 的类,该类具有诸如 createcontainer、imagecontainer 和 autoslide 等方法,这些方法创建主容器并将图像添加到其中。autoslide 方法有助于在指定的时间间隔后更改图像。
let a = new SlidingImage(300, 250, 5, 5000);
在此阶段,将调用该类。我们将传递 宽度、高度、图像数量和旋转图像的秒数。
命令
gulp start
dev/slidingimage.js
"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 SlidingImage = function () {
function SlidingImage(width, height, imgcounter, timer) {
_classCallCheck(this, SlidingImage);
this.counter = 0;
this.imagecontainerwidth = width;
this.imagecontainerheight = height;
this.slidercounter = imgcounter;
this.slidetimer = timer;
this.startindex = 1;
this.css = this.applycss();
this.maincontainer = this.createContainter();
this.childcontainer = this.imagecontainer();
this.autoslide();
}
_createClass(SlidingImage, [{
key: "createContainter",
value: function createContainter() {
var maindiv = document.createElement('div');
maindiv.id = "maincontainer";
maindiv.class = "maincontainer";
document.body.appendChild(maindiv);
return maindiv;
}
}, {
key: "applycss",
value: function applycss() {
var slidercss = ".maincontainer{ position : relative; margin :auto;}.left, .right {
cursor: pointer; position: absolute;" + "top: 50%;
width: auto;
padding: 16px;
margin-top: -22px;
color: white;
font-weight: bold;
" + "font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
}
.right { right: 0; border-radius: 3px 0 0 3px;}" +
".left:hover, .right:hover { background-color: rgba(0,0,0,0.8);}";
var style = document.createElement('style');
style.id = "slidercss";
style.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(style);
var styleall = style;
if (styleall.styleSheet) {
styleall.styleSheet.cssText = slidercss;
} else {
var text = document.createTextNode(slidercss);
style.appendChild(text);
}
}
}, {
key: "imagecontainer",
value: function imagecontainer() {
var childdiv = [];
var imgcont = [];
for (var _a = 1; _a <= this.slidercounter; _a++) {
childdiv[_a] = document.createElement('div');
childdiv[_a].id = "childdiv" + _a;
childdiv[_a].style.width = this.imagecontainerwidth + "px";
childdiv[_a].style.height = this.imagecontainerheight + "px";
if (_a > 1) {
childdiv[_a].style.display = "none";
}
imgcont[_a] = document.createElement('img');
imgcont[_a].src = "src/img/img" + _a + ".jpg";
imgcont[_a].style.width = "100%";
imgcont[_a].style.height = "100%";
childdiv[_a].appendChild(imgcont[_a]);
this.maincontainer.appendChild(childdiv[_a]);
}
}
}, {
key: "autoslide",
value: function autoslide() {
var _this = this;
console.log(this.startindex);
var previousimg = this.startindex;
this.startindex++;
if (this.startindex > 5) {
this.startindex = 1;
}
setTimeout(function () {
document.getElementById("childdiv" + _this.startindex).style.display = "";
document.getElementById("childdiv" + previousimg).style.display = "none";
_this.autoslide();
}, this.slidetimer);
}
}]);
return SlidingImage;
}();
var a = new SlidingImage(300, 250, 5, 5000);
我们将如下所示在浏览器中测试代码行 -
index.html
<html>
<head></head>
<body>
<script type="text/javascript" src="dev/slidingimage.js"></script>
<h1>Sliding Image Demo</h1>
</body>
</html>
我们在 index.html 中使用了 dev 文件夹中的编译文件。命令 gulp start 启动服务器,我们可以在其中测试输出。
在 Chrome 中
在 Firefox 中
在 Internet Explorer 中
编译后的代码在所有浏览器中都能正常工作。