ES6标准以及颁布两年了,可是,好像尚未彻底走进咱们的平常开发。这篇文章从ES6的基本类型扩展入手,逐步展开对ES6的介绍。编程
JavaScript是由Netscape创造的,该公司1996年11月将JavaScript语言提交国际标准化组织ECMA。因而ECMA次年就发布了ECMAScript 1.0版本。之因此不采用JavaScript命名,缘由有两个,一个是版权问题,另外一个也是想经过ECMAScript代表制定者是ECMA而非Netscape。固然,这不是咱们关注的重点。数组
1998年,发布了ECMAScript 2.0,1999年发布了ECMAScript 3.0。这是ECMAScript自颁布以来最广为支持的版本,咱们如今所使用的JavaScript语法和规定大部分都来源于这个版本。它是一个通用标准,奠基了JavaScript的基本语法。2000年后,4.0开始提上日程,可是因为各方分歧很大,致使4.0草案流产,只在最后发布了一个小的改进版本,即ES 3.1,不久后改名为ECMAScript 5.0。函数
2011年,ECMAScript 5.1版发布后,就开始制定6.0版了。2015年6月发布了ES6的第一个版本,正式名称就是《ECMAScript 2015标准》(简称 ES2015)。2016年6月,小幅修订的《ECMAScript 2016标准》(简称 ES2016)如期发布,这个版本能够看做是 ES6.1 版,由于二者的差别很是小,基本上是同一个标准。根据计划,2017年6月发布 ES2017 标准。所以,ES6 既是一个历史名词,也是一个泛指,含义是5.1版之后的 JavaScript 的下一代标准,涵盖了ES201五、ES201六、ES2017等等,而ES2015 则是正式名称,特指该年发布的正式版本的语言标准。编码
在ES6以前,JavaScript的做用域只有两种:全局做用域和函数做用域。而在这两个做用域里,存在一种奇怪的现象--变量提高。MDN上的介绍是 在编译阶段将变量和函数声明放入内存中,但仍然保留在编码中键入的位置。rest
function(){ console.log(a); var a= 'hello'; } function(){ var a = undefined; console.log(a); a= 'hello'; }
上面的两段代码是等价的,也说明了变量提高的本质。在函数做用域内,函数或者变量的声明会被放到做用域顶部,而其余操做仍然保留在原来的键入位置。code
ES6中引入块级做用域的概念,和Java或者C语言中的局部变量做用域很像。所以,ES6中的块级做用域存在如下特色:暂时性死区、不可重复命名、不存在变量提高。经过关键字let和const声明的变量只在块级做用域内有效。对象
{ let i = 1; } console.log(i);//Error
上面的代码块解释了ES6中的块级做用域的概念,一个{}即为一个块级做用域,做用域内的变量在做用域外没法被访问。ip
块级做用域首先带来的问题就是暂时性死区。从做用域开始到变量被声明以前的空间内是该变量的死区,在这个空间内不能对该变量进行任何操做。例如:内存
{ //死区开始 i = 2;//Error console.log(i);//Error let i = 1;//死区结束 }
这个很容易理解,var声明的变量能够重复命名,后来的命名能够把以前的覆盖掉,可是let声明的变量若是出现重复命名的状况,会直接报错。作用域
const用来声明常量,一旦声明,值就不可改变。所以,const一旦声明,就必须当即初始化。这一点和Java或者C语言很像。
可是对于复合型变量,变量名不是指向数据,而是指向数据所在的地址。所以,const定义的复合型变量,只能保证变量名指向的地址不变,并不能确保改地址的内存储的数据不变。
const foo = {}; foo.a = 1; foo = {}//Error const b = []; b.length = 1; b = [];//Error
上面的一段代码中,分别用const声明了一个对象和一个数组。咱们能够给对象或者数组的一个属性赋值,可是不能直接给对象或者数组总体赋值。
结构赋值是ES6引入的一种新的变量赋值方式, MDN上的解释是:解构赋值语法是一个Javascript表达式,这使得能够将值从数组或属性从对象提取到不一样的变量中。
let [a, b, c] = [1, 2, 3]; console.log(a,b,c);//1 2 3 let [foo, [[bar], baz]] = [1, [[2], 3]]; console.log(foo, bar, baz);//1 2 3
上面的代码是两种数组解构赋值,只要等号左边的变量在右边的数组中可以找到对应的位置,就能够进行解构赋值。
对象的结构赋值和数组略有不一样。let { key:name } = obj。等价于 let name = obj[key]。
let obj = { first: 'hello', second: 'world' }; let { first: f, second: s } = obj; console.log(f, s);//hello world console.log(first, second);//Error let { foo, bar } = { foo: "aaa", bar: "bbb" }; console.log(foo, bar);// aaa bbb let { bar, foo } = { foo: "aaa", bar: "bbb" }; console.log(foo, bar);// aaa bbb
后两段代码是对象属性名和值相同时的简洁写法。从后两段代码咱们能够了解到对象解构赋值的本质:先在对象内部找到和变量名相同的属性,而后再把属性值赋给变量。对象的解构赋值自己是一次变量赋值运算。
解构赋值也能够设置默认值,当结构失败时,直接取默认值。例如:
var {x = 3} = {}; console.log(x); //3 var {x, y = 5} = {x: 1}; console.log(x, y) // 1 5
[x, y] = [y, x];
[x, y] = func();
let a={x:1,y:2,z:3,w:4}; let {x,y}=a; let b={x,y};
import {getOS} from '../utils';
ES6中为函数加入了添加默认值的功能。
function log(x, y = 'World') { console.log(x, y); } log('Hello');//Hello World
下边的代码有点意思,是函数解构参数的默认值写法。
// 写法一 function m1({x = 0, y = 0} = {}) { return [x, y]; } // 写法二 function m2({x, y} = { x: 0, y: 0 }) { return [x, y]; } m1({x: 3}); m2({x: 3});
两种写法略有不一样,所表达的意思也不同。首先,函数的解构参数的写法是这样的:
function add({x, y}){ return x + y; }
固然,这里也能够是数组解构,上面的代码拿对象解构作事例。
写法一,两个大括号相等,表达的意思是函数参数拥有默认值,当m1函数被调用时没有传递参数时,区默认值即{}。以后,进行解构赋值。方法一里的解构赋值是带有默认值的解构赋值,所以,当解构失败时,x和y分别取默认值0。因此m1({x: 3})的执行结果是[3,0]。
写法二,两个大括号相等,一样表达的意思是函数参数拥有默认值,当m2函数被调用时没有传递参数时,区默认值即{ x: 0, y: 0}。方法二里的解构赋值没有默认值,所以,当解构失败时,x和y的值都是undefined。因此,m2()的值是[0,0],可是m2({x: 3})的则是[3,undefined]。
函数的解构参数最大的意义在于,我能够不用关心传递过来的数组或者对象内部的解构,只要内部有我想要的属性值就够了,这样在必定程度上下降了逻辑函数之间的耦合。例如:
let obj = { name: 'hello', age: 18, address: 'BeiJing', mobile: '123123123', timestamp: '1496940548319' } function getName({name}){ return name; } getName(obj);
ES6为函数参数引入rest写法。也就是咱们偶尔会在ES6代码里见到的 ...
function add(...values) { let sum = 0; for (let val of values) { sum += val; } return sum; }
rest参数用于获取函数的多余参数,相似于arguments对象。与之不一样的是,rest参数是一个数组,也就意味着咱们能够对rest参数使用数组的全部方法。
ES6的函数扩展里,最引人注意的应该就是箭头函数了。一个最简单的箭头函数:let f = v => v
等价于
let f = function(v){ return v }
当箭头函数没有参数或者有多个参数时,使用圆括号把参数括起来。当箭头函数的函数体多于一行代码时,就采用花括号把函数体括起来,并使用return语句返回值。
箭头函数的出现,主要是为了简化函数的书写。对于开发而言,最大的好处是简单易读,同时匿名函数写起来也更加舒服天然。
ES6的基本扩展还有一些没有在这里详细介绍。整体感受,ES6作了一些语法的丰富,使得JavaScript写起来更加舒服了,特别是结构赋值和箭头函数的引入,用习惯了之后,彻底是另一种编程体验。