在项目中80%的时间用到的ES6语法只占其20%,所以我们暂时先集中精力把这20%学好,那就差不多够用了,剩下的可以看书或是查文档,现学现用。
重要提示:教程的示例代码请前往es6-demo,下载后可以结合这个讲义进行学习操作。
1.let && const
let和const的出现让js有了块级作用域,这个块级作用域是个神器,由于之前没有块级作用域的存在,以及var关键字的变量提升,导致我们调试的时候会出现一些莫名其妙的问题,同时也是很长一段时间面试的常问问题之一。
下面看两个简单的demo理解。
// demo 1 function f1() { let n = 5; if (true) { let n = 10; } console.log(n); // 5 } // demo 2 const PI = 3.1415; console.log(PI); // 3.1415 PI = 3; console.log(PI); // TypeError: "PI" is read-only
2.destructuring
destructuring是解构的意思,ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。来两个例子看看大家就明白了。
'use strict'; // 数组的解构赋值 let [foo, [[bar], baz]] = [1, [[2], 3]]; console.log(foo); // 1 console.log(bar); // 2 console.log(baz); // 3 // 对象的解构赋值 var { foo, bar } = { foo: "aaa", bar: "bbb" }; console.log(foo); // "aaa" console.log(bar ); // "bbb" // 字符串的解构赋值 const [a, b, c, d, e] = 'hello'; console.log(a + b + c + e); // 'hello'
3.template string
let name = 'guoyongfeng'; let age = 18; console.log(`${name} want to drink ${age}`)
4.arrow function
arrow function译名即为箭头函数,这早已不是一个新名词,下面简单看一下它的写法
class Animal { constructor(name){ this.name = name; } // type = 'water'这里的意思是当type未传值的时候默认是'water' drink(type = 'water'){ // 使用了箭头函数 setInterval( () => { // 模板字符串 console.log(`${this.name} want to drink ${type}`) }, 1000) } } let pig = new Animal('pig'); console.log(pig.drink('milk')); export default Animal;
5.rest
我们知道JS函数内部有个arguments对象,可以拿到全部实参。现在ES6给我们带来了一个新的对象,可以拿到除开始参数外的参数,即剩余参数,听起来好屌的样子,我们来段代码。
// rest function restFunc(a, ...rest) { console.log(a) console.log(rest) } restFunc(1); restFunc(1, 2, 3, 4);
6.spread
spread为扩展操作符,来一个有点无聊的例子。
var args = ["a", "b", "c"]; console.log(...args); // "a" "b" "c"
就是这样无聊的例子,如果没有spread语法的支持,我们还得来个遍历,ES6委员会真是程序员的小棉袄。
7.class, extends, super
回想之前,如果我们需要模拟一个js的类,一般会采用构造函数加原型的方式。
function Point(x,y){ this.x = x; this.y = y; } Point.prototype.toString = function () { return '(' + this.x + ', ' + this.y + ')'; }
而现在我们可以使用class来定义一个类 代码清单:class.js
'use strcit'; export default class Point { // constructor方法是类的默认方法 constructor(x, y) { this.x = x; this.y = y; } // 这里定义的都是类的公共方法 // 等同于Point.prototype.toString toString() { return '(' + this.x + ', ' + this.y + ')'; } } var point = new Point(2, 3); console.log(point.toString()); console.log(point.hasOwnProperty('x')) console.log(point.hasOwnProperty('y')) console.log(point.hasOwnProperty('toString')) console.log(point.__proto__.hasOwnProperty('toString'))
在moduleB中来import这个文件进行运行。 代码清单:moduleB.js
'use strict'; // import moduleA from './moduleA'; import Point from './class.js';
8.Object.assign
Object.assign用于对象的合并,ES6对object做了很多扩展,assign是最值得点评的。想必你很熟悉jquery提供的extend接口,那么ES6的Object.assign就从语法层面做了这件事情,是不是很nice。
var target = { a: 1 }; var source1 = { b: 2 }; var source2 = { c: 3 }; Object.assign(target, source1, source2); console.log(target); // {a:1, b:2, c:3}
9.Decorator
修饰器(Decorator)是一个表达式,用来修改类的行为。这是ES7的一个提案,目前Babel(babel-plugin-transform-decorators-legacy)转码器已经支持。
不知道大家有没有使用过java的spring mvc,其中的注解就跟这个比较相似,学习React的话可以重点关注下这个语法,因为后面使用redux类库的时候会频繁的用到decorator。
首先说下如何配置babel的插件来进行decorator的解析。
// 官网提供了babel-plugin-transform-decorators这个插件来解析,但是我发现不work,就找了下面这个 $ npm install babel-plugin-transform-decorators-legacy --save-dev
配置.babelrc的plugins字段。
{ "presets": ["es2015", "react", "stage-0"], "plugins": ["transform-decorators-legacy"] }
ok,接下来来段使用decorator的示例代码
function testable(target) { target.isTestable = true; } @testable class MyTestableClass {} console.log(MyTestableClass.isTestable) // true
10.promise
Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了Promise对象。
下面摘抄一个《ECMASCRIPT 6入门》书上的例子,使用promise模拟一个ajax方法的demo用于大家理解
var getJSON = function(url) { var promise = new Promise(function(resolve, reject){ var client = new XMLHttpRequest(); client.open("GET", url); client.onreadystatechange = handler; client.responseType = "json"; client.setRequestHeader("Accept", "application/json"); client.send(); function handler() { if ( this.readyState !== 4 ) { return; } if (this.status === 200) { resolve(this.response); } else { reject(new Error(this.statusText)); } }; }); return promise; }; getJSON("/posts.json").then(function(json) { console.log('Contents: ' + json); }, function(error) { console.error('出错了', error); });
11.export, import
以前我们学习AMD和CMD规范,讨论用什么样的模块化规范比较合适,更有甚者,不得不使用UMD规范来做全兼容,现在好了,ES6在语言层面推出了模块化的写法。
新建两个模块
$ touch moduleA.js moduleB.js
代码清单:moduleA.js
'use strict'; export default function foo(x, y) { return x * y; } // 另外几种导出的方式 // function foo() { // console.log('foo'); // } // export { foo as default }; // export var a = 1; // export const PI = 3.14;
代码清单:moduleB.js
'use strict'; import moduleA from './moduleA'; console.log( moduleA(2, 3) );
代码清单:index.js
'use strict'; import moduleB from './util/moduleB ';
最终运行打印出结果:6;
结语
多的不在赘述,以上的一些知识可以当成学习ES6的一个快餐,不成体系,但是快速掌握常用的一些语法,有时间有精力建议最好买本书通读一遍。