为了账号安全,请及时绑定邮箱和手机立即绑定

深入ES6 第一章 历史与简介

第一章 历史与简介

ES6于2015年6月正式发布,其目标是使JS原因呢可用于编写大型的应用程序,成为企业级的开发语言。这篇文章主要介绍:

  1. ECMAScript的版本历史
  2. 使用babel对ES6代码进行转码
  3. 配合gulp搭建ES6开发环境
  4. ES6最常用的特性
1.1 ES6与ES2015

标准的制定者计划,以后每年发布一次标准,使用年份作为版本号。ES6是在2015年发布的,所以又称为ES2015。但ES6其实多用于泛指ES5.1版本后的下一代JS标准,它涵盖在ES2015版本上稍作改动的ES2016。

1.2 ECMAScript与Javascript

1996年11月,javascript的创造者网景公司将JS提交给国际化标准组织ECMA(European computer manufactures association,欧洲计算机制造联合会),希望这种语言能够成为国际标准。次年,ECMA发布了规定浏览器脚本语言的标准,即ECMAScript。该标准一开始就是针对JS语言制定的,之所以不使用Javascript这个名号,一是因为商标使用权的冲突,二则是想体现这门语言的制定者是ECMA而并非网景,这样有利于这门语言的开放和中立。

因此,可以这么说,ECMAScript是标准与规格,Javascript是对它的实现。此外,像Flash的ActionScript也遵循ECMAScript的规范,所以其基本语法看起来和javascript几乎一模一样。二者的主要区别则在于对页面元素的操作。使用JS可以轻松的对页面的元素进行操作,与浏览器进行交互,所以很多人又把javascript看成是ECMAScript+DOM(文档对象模型)+BOM(浏览器对象模型)的组合。

1.3 ECMAScript的历史
  1. 1997年 ECMAScript 1.0 诞生
  2. 1999年12月 ECMAScript 3.0诞生,它 是一个巨大的成功,在业界得到了广泛的支持,它奠定了JS的基本语法,被其后版本完全继承。直到今天,我们一开始学习JS,其实就是在学3.0版的语法。
  3. 2000年的ECMAScript4.0是当下ES6的前身,但由于这个版本太过激烈,对ES3做了彻底升级,所以暂时被“和谐”了。
  4. 2009年12月,ECMAScript5.0版正式发布。ECMA专家组预计ECMAScript的第五个版本会在2013年中期到2018年作为主流的开发标准。2011年6月,ES5.1版发布,并且成为ISO国际标准。
  5. 2013年,ES6草案冻结,不再添加新的功能,新的功能将被放到ES7中;2015年6月,ES6正式通过,成为国际标准。
1.4 转码

ES6强大的语法能够大大的加快我们的开发效率,但缺点在于老旧的环境对它的支持并不理想。我们可以使用转码技术将ES6代码转为被浏览器普遍支持的ES5代码,以保证浏览器的支持。Babel是当下最流行的转码器。

babel的名字取自“巴别塔”,据《圣经·旧约·创世记》第11章记载,是当时人类联合起来兴建,希望能通往天堂的高塔。为了阻止人类的计划,上帝让人类说不同的语言,使人类相互之间不能沟通,计划因此失败,人类自此各散东西,向世界各地迁移。

babel命令行工具

babel的命令行通过下面代码来安装

npm install babel-cli -g
npm install babel-preset-es2015 --save

然后再根目录创建名为.babelrc的配置文件。

{
    "presets" : ["es2015"]
}

babel提供下面几种处理ES6代码的方式:

babel-node运行ES6代码

以REPL的方式直接运行ES6代码

babel-node
> var a = 10;console.log((a=>a*a)(a));
> 100

也可以直接运行ES6脚本。比如现在我们有两个ES6模块m1.js和m2.js,m1.js的内容如下:

import myInfo from './m2.js';
myInfo();

m2.js的内容为:

export default function () {
    console.log('default')
};

运行

babel-node m1.js

输出:default。可见两个ES6文件都被正确的解析执行了。

Babel转换ES6代码

使用babel命令可以直接把ES6代码转化成ES5代码,但默认只是把转换后的代码输出到控制台,我们可以加上-o命令将转换后的代码重定向至文件。

babel foo.js -o bar.js

-d参数可以转换整个目录,注意资源目录和构建目录的顺序

babel -d build-dir sourse-dir

如果希望生成sourse-map,需要加上-s参数

babel foo.js -o bar.js -s

Babel在浏览器环境

首先在浏览器引入browser.js,然后在type="text/babel"的script元素中编写你的代码就可以了。可以使用下面的命令从npm上获取browser.js

npm install babel-core@5

文件在node_modules/babel-core子目录下。因为从babel6.0开始,不再直接提供浏览器的版本,所以我们通过安装第5个版本获取。

显然,这种做法对浏览器性能会有很坏的影响,而且本质上讲,这没有什么用。在开发时,最新版本的chrome可以实现大部分的ES6特性(除了模块的特性),在上线时,则可以使用已经经过转码的版本。

Babel在Nodejs环境

首先需要安装核心模块

npm install babel-core
npm install babel-preset-es2015 --save

然后再根目录创建名为.babelrc的配置文件。

{
    "presets" : ["es2015"]
}

然后在应用的脚本入口(比如express的app.js)加上如下语句:

require("babel-core/register")

这样,后面所有通过require命令加载后缀名为.es6.js.jsx.es的脚本,都会通过babel先转码,再加载。

Babel不会转换Iterator、Generator、Set、Map等全局对象以及一些定义在全局对象上的方法,如果用到了这些功能,你的环境却不支持,就需要安装使用babel-polyfill模块。

npm install babel-polyfill --save

然后在所有脚本头部加上

require('babel-polyfill');

还可以使用babel-core模块以编码的形式进行转码,这可能会调用到nodejs的文件系统。我们一般使用gulp等构建工具取完成这个功能。

1.5 使用gulp搭建ES6环境

开发中,我们常常配合gulp来搭建ES6开发环境。

下载依赖模块

  "devDependencies": {
    "babel-preset-es2015": "^6.24.0",
    "gulp": "^3.9.1",
    "gulp-babel": "^6.1.2",
    "gulp-plumber": "^1.1.0",
    "gulp-rename": "^1.2.2",
    "gulp-sequence": "^0.4.6",
    "gulp-watch": "^4.3.11"
  }

需要babel-preset-es2015和gulp-babel转换ES6代码为ES5。

gulp-plumber的作用是在出现错误时重新启动gulp(gulp的设计使得gulp非常容易由于你想不到的原因挂掉,比如你使用let重复命名了变量)。

gulp-rename重命名产生的ES5文件,在后面加上“-es5”后缀。

gulp-watch用来检测文件变化,与gulp.watch()不同,gulp-watch可以监听文件的增加与删除。gulp-sequence与gulp-watch联合使用,它的作用是顺序触发一些任务。当watch监听到文件变化时(改变或增加),可以使用它触发任务。

配置文件

glupfile.js如下所示:

"use strict";

let gulp = require('gulp');
let babel = require("gulp-babel");
let rename = require("gulp-rename");
let plumber = require("gulp-plumber");
let watch = require("gulp-watch");
let gulpSequence  = require("gulp-sequence");
let del = require('del');

gulp.task("es6", function () {
    return gulp.src(['./project/**/*.js', '!./project/**/*-es5.js'])
    .pipe(plumber())
    .pipe(babel({
        presets: ['es2015'],
        compact: false
    }))
    .pipe(rename({
        suffix: "-es5",
        extname: ".js"
    }))
    .pipe(gulp.dest("./project"));
});

gulp.task('default', ['es6'], function () {
    watch('./project/**/*.js', function () {
        gulpSequence('es6')(function (err) {
            if (err) console.log(err)
        })
    });

    watch('./project/**/*.js', {events:['unlink']}, function (vinyl) {
        let filename = vinyl.path.replace('.js','-es5.js');
        del(filename)
    });
});

这里我新加了一个功能,如果删除了es6文件,其生产的es5文件也对应被删除。如果不想这样,把上面这部分代码(del watch unlink那部分)注释掉就可以了。
还有一个比较坑的地方,就是在配置src路径的时候,如果不指定一个初始文件夹,比如./project,只写成./这样,就会报一些很奇怪的错误,回来有机会在解决。

1.6 ES6常用语法简介

这一节我们将会对接下来的教程中,我们将用到的取代ES5中的传统编码方法的高效ES6方法进行简要的介绍。

let与const

使用let代替var,let较var而言,支持块级作用域,不存在代码提升,同一作用域内不允许出现相同名称的变量。const与let特性基本相同,我们使用const声明常量,一旦声明必须立即赋值,并且不可更改。

箭头函数与函数默认值

使用箭头函数可以简化简单逻辑函数的编码,例如:

var foo = function(a){
    a = a||1; // a的默认值为1
    return a*a
}

可以用箭头函数+参数默认值表示为:

let foo = (a=1)=>a*a
//更完全的形式为
let foo = (a=1)=>{return a*a}

模板字符串

使用模板字符串可以轻松的在字符串中进行变量的替换。注意使用模板时,最外层为``号(反引号),变量使用${}包裹。

let name = 'Kyle';
let bar ='学生'+name+'正在学习ES6';
// 等价于
let foo = `学生${name}正在学习ES6`;

解构赋值

解构赋值可以帮助我们快速的把对象里的值转移到局部变量中,比如:

let {c, d} = {c:'c',d:'d',e:'e'};
console.log(c); // c
console.log(d); // d

let [d,b,c] = [1,2,3];
console.log(d); // 1
console.log(b); //2
console.log(c); //3

模块化

ES6提供了模块化的原生支持

// 引入模块
import {readFile, writeFile} from 'fs'
readFile('./a.txt', ()=>{
    // do something
});
// 导出模块
export function foo(){
    console.log('foo');
}

其它

ES6还提供了其它非常有用的语法与特性,比如:class作为传进对象的语法糖,promise提供异步调用的解决方案,Set,Map数据结构等等。在接下来的几天内我们将一点点深入学习。

点击查看更多内容
5人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消