首选呐,你得了解一下javascript和ECMAScript的关系:javascript
编程语言JavaScript是ECMAScript的实现和扩展,由ECMA(一个相似W3C的标准组织)参与进行标准化。ECMAScript定义了:css
语言语法——语法解析规则、关键字、语句、声明、运算符等。html
类型——布尔型、数字、字符串、对象等。java
原型和继承node
内建对象和函数的标准库-json、Math、数组方法、对象自省方法等。es6
ecmascript不定义html和css的相关功能,也不定义相似DOM的api,这些都在独立的标准中定义。ecmascript涵盖了各类环境中js的应用场景,不管是浏览器环境仍是相似nodejs的非浏览器环境。编程
总结而言嘛(我的理解):javascript=ECMAScript+Bom+Dom;json
下面给你们介绍一下ECMAScript6新标准里面新增长的几项重要的内容:api
Default parameters(默认参数) in es6
还记得咱们之前不得不经过下面方式来定义默认参数:数组
var link = function (height, color, url) { var height = height || 50; var color = color || 'red'; var url = url || 'http://azat.co'; ... }
但在ES6,咱们直接能够把默认值放在函数声明里:
var link = function(height = 50, color = 'red', url = 'http://azat.co') { ... }
Template Literals(模板对象)in es6
在其余语言中,使用模板和插入值是在字符串里面输出变量的一种方式,所以,在es5能够这样组合一个字符串。
var name = 'Your name is ' + first + ' ' + last + '.'; var url = 'http://localhost:3000/api/messages/' + id;
可是在ES6中,咱们可使用使用新的语法$(NAME):
var name = `Your name is ${first} ${last}. `; var url = `http://localhost:3000/api/messages/${id}`;
Multi-line Strings (多行字符串)in ES6
ES6的多行字符串是一个很是实用的功能。在ES5中,咱们不得不使用如下方法来表示多行字符串:
var roadPoem = 'Then took the other, as just as fair,nt' + 'And having perhaps the better claimnt' + 'Because it was grassy and wanted wear,nt' + 'Though as for that the passing therent' + 'Had worn them really about the same,nt'; var fourAgreements = 'You have the right to be you.n You can only be you when you do your best.';
可是在ES6中,咱们能够用反引号表示:
var roadPoem = `Then took the other, as just as fair, And having perhaps the better claim Because it was grassy and wanted wear, Though as for that the passing there Had worn them really about the same,`; var fourAgreements = `You have the right to be you. You can only be you when you do your best.`;
Destructuring Assignment (解构赋值)in ES6
解构多是一个比较难以掌握的概念。先从一个简单的赋值讲起,其中house 和 mouse是key,同时house 和mouse也是一个变量,在ES5中是这样:
var data = $('body').data(), // data has properties house and mouse house = data.house, mouse = data.mouse;
以及在node.js中用ES5是这样:
var jsonMiddleware = require('body-parser').jsonMiddleware ; var body = req.body, // body has username and password username = body.username,
password = body.password;
在ES6,咱们可使用这些语句代替上面的ES5代码:
var jsonMiddleware = require('body-parser').jsonMiddleware ; var body = req.body, // body has username and password username = body.username, password = body.password;
这个一样也适用于数组,很是赞的用法:
var [col1, col2] = $('.column'), [line1, line2, line3, , line5] = file.split('n');
Enhanced Object Literals (加强的对象字面量)in ES6
Arrow Functions in(箭头函数) ES6 之前咱们使用闭包,this老是预期以外地产生改变,而箭头函数的迷人之处在于,如今你的this能够按照你的预期使用了,身处箭头函数里面,this仍是原来的this。
有了箭头函数在ES6中, 咱们就没必要用that = this或 self = this 或 _this = this 或.bind(this)。例如,下面的代码用ES5就不是很优雅:
var _this = this; $('.btn').click(function(event){ _this.sendData(); })
在ES6中就不须要用 _this = this:
$('.btn').click((event) =>{ this.sendData(); })
下面这是一个另外的例子,咱们经过call传递文本给logUpperCase() 函数在ES5中:
var logUpperCase = function() { var _this = this; this.string = this.string.toUpperCase(); return function () { return console.log(_this.string); } } logUpperCase.call({ string: 'ES6 rocks' })();
而在ES6,咱们并不须要用_this浪费时间:
var logUpperCase = function() { this.string = this.string.toUpperCase(); return () => console.log(this.string); } logUpperCase.call({ string: 'ES6 rocks' })();
请注意,只要你愿意,在ES6中=>能够混合和匹配老的函数一块儿使用。当在一行代码中用了箭头函数,它就变成了一个表达式。它将暗地里返回单个语句的结果。若是你超过了一行,将须要明确使用return。
这是用ES5代码建立一个消息数组:
var ids = ['5632953c4e345e145fdf2df8','563295464e345e145fdf2df9']; var messages = ids.map(function (value) { return "ID is " + value; // explicit return });
用ES6是这样:
var ids = ['5632953c4e345e145fdf2df8','563295464e345e145fdf2df9']; var messages = ids.map(value => `ID is ${value}`); // implicit return
这里使用到了咱们上文提到过的字符串模板。
在箭头函数中,对于单个参数,括号()是可选的,但当你超过一个参数的时候你就须要他们。
在ES5代码有明确的返回功能:
var messages = ids.map(function (value, index, list) { return 'ID of ' + index + ' element is ' + value + ' '; // explicit return });
在ES6中有更加严谨的版本,参数须要被包含在括号里而且它是隐式的返回:
var ids = ['5632953c4e345e145fdf2df8','563295464e345e145fdf2df9']; var messages = ids.map((value, index, list) => `ID of ${index} element is ${value} `); // implicit return
Promise in ES6
主要是用来解决异步回调黑洞的问题。
例如在ES5中若是咱们有不少的嵌套逻辑在setTimeout()回调函数中,
setTimeout(function(){ console.log('Yay!'); setTimeout(function(){ console.log('Wheeyee!'); }, 1000) }, 1000);
看起来是否是特别的头疼,可是在ES6中,咱们利用promise范式就能够很好地解决这个问题:
var wait1000 = ()=> new Promise((resolve, reject)=> {setTimeout(resolve, 1000)}); wait1000() .then(function() { console.log('Yay!') return wait1000() }) .then(function() { console.log('Wheeyee!') });
在ES6代码中,你可能已经看到那熟悉的身影let。在ES6里let并非一个花俏的特性,它是更复杂的。Let是一种新的变量申明方式,它容许你把变量做用域控制在块级里面。咱们用大括号定义代码块,在ES5中,块级做用域起不了任何做用:
function calculateTotalAmount (vip) { var amount = 0; if (vip) { var amount = 1; } { // more crazy blocks! var amount = 100; { var amount = 1000; } } return amount; } console.log(calculateTotalAmount(true));
结果将返回1000,这真是一个bug。在ES6中,咱们用let限制块级做用域。而var是限制函数做用域。
function calculateTotalAmount (vip) { var amount = 0; // probably should also be let, but you can mix var and let if (vip) { let amount = 1; // first amount is still 0 } { // more crazy blocks! let amount = 100; // first amount is still 0 { let amount = 1000; // first amount is still 0 } } return amount; } console.log(calculateTotalAmount(true));
这个结果将会是0,由于块做用域中有了let。若是(amount=1).那么这个表达式将返回1。谈到const,就更加容易了;它就是一个不变量,也是块级做用域就像let同样。下面是一个演示,这里有一堆常量,它们互不影响,由于它们属于不一样的块级做用域:
function calculateTotalAmount (vip) { const amount = 0; if (vip) { const amount = 1; } { // more crazy blocks! const amount = 100 ; { const amount = 1000; } } return amount; } console.log(calculateTotalAmount(true));
类的建立和使用真是一件使人头疼的事情在过去的ES5中,由于没有一个关键字class (它被保留,可是什么也不能作)。
用ES5写一个类,有不少种方法,这里就先不说了。如今就来看看如何用ES6写一个类吧。ES6没有用函数, 而是使用原型实现类。咱们建立一个类baseModel ,而且在这个类里定义了一个constructor 和一个 getName()方法:
class baseModel { constructor(options, data) { // class constructor,node.js 5.6暂时不支持options = {}, data = []这样传参 this.name = 'Base'; this.url = 'http://azat.co/api'; this.data = data; this.options = options; } getName() { // class method console.log(`Class name: ${this.name}`); } }
注意咱们对options 和data使用了默认参数值。此外方法名也不须要加function关键字,并且冒号(:)也不须要了。另一个大的区别就是你不须要分配属性this。如今设置一个属性的值,只需简单的在构造函数中分配。
AccountModel 从类baseModel 中继承而来:
class AccountModel extends baseModel { constructor(options, data) {
为了调用父级构造函数,能够绝不费力的唤起super()用参数传递:
super({private: true}, ['32113123123', '524214691']); //call the parent method with super this.name = 'Account Model'; this.url +='/accounts/'; }
众所周知,在ES6之前JavaScript并不支持本地的模块。人们想出了AMD,RequireJS,CommonJS以及其它解决方法。如今ES6中能够用模块import 和export 操做了。
在ES5中,你能够在<script>中直接写能够运行的代码(简称IIFE),或者一些库像AMD。然而在ES6中,你能够用export导入你的类。下面举个例子,在ES5中,module.js有port变量和getAccounts 方法:
module.exports = { port: 3000, getAccounts: function() { ... }}
在ES5中,main.js须要依赖require(‘module’) 导入module.js:
var service = require('module.js');console.log(service.port); // 3000
但在ES6中,咱们将用export and import。例如,这是咱们用ES6 写的module.js文件库:
export var port = 3000;export function getAccounts(url) { ...}
若是用ES6来导入到文件main.js中,咱们需用import {name} from ‘my-module’语法,例如:
import {port, getAccounts} from 'module';console.log(port); // 3000
或者咱们能够在main.js中把整个模块导入, 并命名为 service:
import * as service from 'module';console.log(service.port); // 3000