本文为 ES6 系列的第一篇。旨在给新同砚一些指引,带大家走近 ES6 新特征。
扼要引见:
什么是 ES6
它有哪些“明星”特征
它能够运转在哪些环境
What’s ES6
ES6 or ECMAScript 2015 ?
ECMAScript 6(以下简称ES6)是JavaScript言语的下一代规范,已在2015年6月正式宣布了。
ECMA-262 规范 第6版。设计今后每一年宣布一次规范,运用年份作为规范的版本。由于当前版本是在2015年宣布的,所以又称ECMAScript 2015。ECMA 的全称是 European Computer Manufacturers Association(欧洲计算机制造商协会)。ECMA-262 被 ISO 国际规范化构造采用为 ISO/IEC 16262:2011
一样平常议论的 JavaScript 一般还包括 DOM(文档对象模子)、BOM(浏览器对象模子),而 ES6 不包括这些。
ES6 近况
主流框架周全转向 ES6
Angular 2
ReactJs
koa
兼容性 对照表格
Well-known Features
本节引见一些广为人知的 ES6 “明星”特征,也就是议论 ES6 时常常说起的一些新特征。固然 ES6 并不仅限于这些,还包括很多其他有效的特征,会在本系列的其他文章中引见。
let and const
let 敕令
本来的 javascript 中没有块级作用域,只要函数级作用域。ES6 中新增了 let 敕令,运用 let 敕令替代 var 敕令声明变量,具有块级作用域。
函数级作用域
function test() {
var hello = 'world';
console.log(hello);
}
test(); // 'world'
console.log(hello); // Error: hello is not defined
块级作用域
var
敕令
if(true) {
var hello = 'world';
console.log(hello); // 'world'
}
console.log(hello); // 'world'
let
敕令
if(true) {
let hello = 'world';
console.log(hello); // 'world'
}
console.log(hello); // Error: hello is not defined
const 敕令
运用 const 敕令声明常量
const STATUS_NOT_FOUND = 404;
常量的值为只读,不能修正
STATUS_NOT_FOUND = 200;
// SyntaxError: "STATUS_NOT_FOUND" is read-only
Template String
传统的字符串
var name = 'es6';
var sayhello = 'hello, \
my name is ' + name + '.';
console.log(sayhello);
输出:
hello, my name is es6.
ES6 模板字符串
var name = 'es6';
var sayhello = `hello,
my name is ${name}.`;
console.log(sayhello);
输出:
hello,
my name is es6.
空格和换行都邑被保留
Arrow Function
许可运用 =>
定义函数,箭头函数自动绑定当前上下文 this。
x => x+1
等同于匿名函数
function (x) {
return x + 1;
}
多个参数:
(a,b) => a+b
等同于
function (a, b) {
return a + b;
}
多行函数体:
(a,b) => {
console.log(a + b);
return a + b;
}
等同于
function (a, b) {
console.log(a + b);
return a + b;
}
Promise
原生的 Promise 完成,不再须要 bluebird
或 Q+
。
Generator
Generator 天生器许可你经由历程写一个能够保留自身状况的的简朴函数来定义一个迭代算法。和 Generator 一同涌现的一般另有 yield。
Generator 是一种能够住手并在以后从新进入的函数。天生器的环境(绑定的变量)会在每次实行后被保留,下次进入时可继承运用。generator 字面上是“天生器”的意义,在 ES6 里是迭代器天生器,用于天生一个迭代器对象。
function *gen() {
yield 'hello';
yield 'world';
return true;
}
以上代码定义了一个简朴的 generator,看起来就像一个一般的函数,区别是function症结字背面有个*号,函数体内能够运用yield语句举行流程掌握。
var iter = gen();
var a = iter.next();
console.log(a); // {value:'hello', done:false}
var b = iter.next();
console.log(b); // {value:'world', done:false}
var c = iter.next();
console.log(c); // {value:true, done:true}
当实行gen()的时刻,并不实行 generator 函数体,而是返回一个迭代器 Iterator。迭代用具有 next() 要领,每次挪用 next() 要领,函数就实行到yield语句的处所。next() 要领返回一个对象,个中value属性示意 yield 症结词背面表达式的值,done 属性示意是不是遍历终了。generator 天生器经由历程 next 和 yield 的合营完成流程掌握,上面的代码实行了三次 next() ,generator 函数体才实行终了。
Class
在 JavaScript 中引入 OO 面向对象。实际上是语法糖,只是看上去更面向对象罢了。也有看法尽力阻挡 Class,以为 Class 隐蔽了 JavaScript 自身原型链的言语特征,使其更难明白。
一半以上库是按 OO/class 体式格局写的,除了jQuery以外,险些每一个“庄重”的JS基本库都有一个Class完成,东西、IDE 更轻易辨认,JavaScript 引擎机能优化。—- johnhax
ES5
function Point(x,y){
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')';
}
ES6
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '('+this.x+', '+this.y+')';
}
}
Module
很多JS框架都邑完成一套自身的 module/loader 机制。重复造轮子这也就罢了,更大的问题在于,这些轮子相互都是不兼容的。效果就造成了JS社区的分化和内讧,障碍了JS库和组件在较细粒度上的合作和生长,JS框架和库的切换成了强制开发者做出非此即彼的挑选。缺少言语级别的 module,其恶果就是既没有充足的规范库,也很难像其他言语一样经由历程森林轨则生长出事实规范库。 —- johnhax
社区主流解决方案有 CommonJS 和 AMD,离别用于服务器端和浏览器端,浏览器端另有 seajs 遵照的 CMD。
CommonJS
exports.firstName = 'mei';
exports.lastName = 'qingguang';
exports.year = 1988;
// or
module.exports = {
firstName: 'mei',
lastName: 'qingguang',
year: 1988
}
// or
module.exports = function() {
// do something
}
AMD
define(['./a', './b'], function(a, b) { // 依靠必需一开始就写好
a.doSomething()
// 此处略去 100 行
b.doSomething()
// ...
exports.action = function() {};
})
CMD
define(function(require, exports, module) {
var a = require('./a')
a.doSomething()
// 此处略去 100 行
var b = require('./b') // 依靠能够就近誊写
b.doSomething()
// ...
exports.action = function() {};
})
ES6 Module
export 敕令 和 import 敕令
export var firstName = 'mei';
export var lastName = 'qingguang';
export var year = 1988;
import {firstName, lastName, year} from './profile'
console.log(firstName, lastName, year)
模块团体输出
var firstName = 'mei';
var lastName = 'qingguang';
var year = 1988;
export {firstName, lastName, year};
import * as Profile from './profile'
console.log(Profile.firstName, Profile.lastName, Profile.year)
export default 团体输出
export default function() {
console.log('My name is mei qingguang');
};
import sayMyName from './profile'
console.log(sayMyName())
Node.js 运转环境
能够在 Node.js 和 io.js 中运用部份 ES6 特征。Node.js 和 io.js 都是运用 V8 引擎作为 JavaScript 运转环境,io.js 集成了更高版本的 V8 引擎,因而能够比 Node.js 支撑更多的 ES6 特征。
在 Node.js 中,须要运用 --harmony
参数开启 ES6 特征,包括一切已完成、待完成和订正中的特征。为了防止用到那些烧毁的特征,能够经由历程加相似 --harmony_generators
参数开启特定的特征。
而在 io.js 中,一切已完成的稳固 ES6 特征都已默许开启,不须要加任何运转时参数。而待完成和订正中的特征也能够经由历程特定的参数开启。
io.js 默许开启了以下 ES6 特征:
block scoping
let
const
function-in-blocks
Classes
Collections
Map
WeakMap
Set
WeakSet
Generators
Binary and Octal literals
Object literal extensions
Promises
New String methods
Symbols
Template strings
编译器
有两个有名的编译器,能将 ES6 代码编译成 ES5 代码,本节只引见 Babel。
Babel
Traceur
Babel
Babel 从根本上讲是一个平台,这是它与 compile-to-JS 言语 CoffeeScript 和 TypeScript 最大的差别。Babel 的插件体系许可开发者自定义代码转换器并插进去到编译历程。Babel 还能提拔 JavaScript 的实行速率,在编译时举行机能优化。
babel 敕令
编译单个文件
babel script.js --out-file script-compiled.js
监听文件变化
babel script.js --watch --out-file script-compiled.js
编译全部文件夹
babel src --out-dir lib
运用 source map,轻易调试
babel script.js --out-file script-compiled.js --source-maps
babel-node 敕令
运用 babel-node
敕令替代 node
敕令,及时编译并实行 ES6 代码。不要在临盆环境运用 babel-node
敕令,它异常耗内存,并且会拖慢运用的机能。
node app.js
babel-node app.js
require hook
运用 require 钩子,能够让你的运用 require 模块时自动编译 ES6 代码。比方:
run.js
require('babel/register')
require('./app.js')
将 run.js
作为全部运用的进口,就能够在 app.js
和其他营业代码中编写 ES6 代码,当代码被 require
进来时,自动编译成 ES5 代码。