es6关键词:

  • 块级作用域
  • 脱离顶层对象
  • 解构
  • 箭头函数
  • Set和Map
  • 异步编程更强大

还没仔细看的:

  • Promise
  • 正则
  • 数值
  • Symbol
  • Proxy
  • Reflect
  • Iterator

let命令

let命令类似var,声名变量

  • 暂时性死区

    let命令只在它所在的代码块内有效,它声明的变量一定要在声明后才能使用(不会发生变量提升问题,即脚本运行前,变量不存在)

      for(let i = 0 ; i < 10; i++) {
          console.log(i);
      }
    

    var所在文件中有效

    es6明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭的作用域。凡是在声明之前就使用这些变量,就会报错。

  • 不允许重复声明,所以在函数内部也不能重新声明参数

      //报错
      function(){
      	let a = 10;
          var a = 1;
      }
        
      //报错
      function(){
      	let a = 10;
          let a = 1;
      }
     		
      //报错
      	function func(name){
      	let name;
      }
    

const命令

const 声明一个只读的常量,一旦声明,常量的值就不能改变(意味着一旦声明,必须立即初始化)

  • 对于声明对象,const命令只保证变量名指向的地址不变,不会保证该地址的数据不变

      const foo = {};
      foo.prop = 123;
        
      foo.prop // 123
      foo = {} // TypeError: "foo" is read-only
    

Note:

  • var命令和function命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。(顶层对象=全局变量)

变量的解构赋值(提取json数据!!!)

数组的解构赋值

let [a,b,c] = [1,2,3]
  • 允许指定默认值

    let [a, b = 1] = [2,3]
    

对象的解构赋值

let {foo, bar} = {foo: 1, bar: 2}
  • 变量必须与属性同名

    let {foo, baa} = {foo: 1, bar: 2}
    >foo
    1
    >bar
    undefined  
    
  • 允许指定默认值

字符串的解构赋值

字符串转换类似数组的对象

const [a,b,c,d,e] = 'hello'
>a
'h'
>b
'e'
>c
'l'
>d
'l'
>e
'o'

函数参数解构赋值

function add([x,y]){
	return x + y;
}

add([1,2]);//3

函数

基本用法

  • 可为参数指定默认值,es5不支持

  • 参数变量是默认声明的,不能用let和const再次声明

  • 与解构赋值结合使用

参数默认值的位置

定义了默认值的参数,是没法省略的

function f(x=1, y){
	return [x,y];
}

console.log(f()) //[1, undefined]
console.log(f(2)) //[1, undefined]
f(,1) // 报错
console.log(f(undefined,1)) //[1, 1]

函数的length属性

函数的length返回没有指定默认值的参数个数,指定了默认值后,使用length将失真

作用域

  • 设置参数默认值时,会形成一个单独的作用域

      let i = 1 
      function f(y = i) {
          let i = 2;
          console.log(y);
      }
      f(); //1
    

应用

  • 利用参数默认值,可以指定某一个参数不能省略

      function throwIfMissing() {
      	throw new Error('Missiong Paramter');
      }
    
      function foo(name = throwIfMissing()) {
          return name;
      }
    
      foo();
    

name属性

函数的name属性,返回该函数的函数名

function foo() {}

foo.name // "foo"

箭头函数

var f = () => 5
//等同于
var f = function () { return 5 }

var sum = (n1,n2) => n1 + n2
//等同于
var sum = function(n1, n2) {
	return n1 + n2
}

//返回对象
var f = returnObj => ({name : "Tom", age : 20})

//和变量解构结合使用
var f = ({a,b}) => a + b   
  • 可用于回调函数
  • 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象

     function foo() {
       setTimeout(() => {
         console.log('id:', this.id);
       }, 100);
     }
    
     var id = 21; //全局对象
    
     foo.call({ id: 42 }); //函数定义时所在对象
     // id: 42
    
  • 尾调用优化,每次执行时,函数调用帧只有一项,大大节省内存

     function a() {
     	return b()
     }
    

数组

Array.from() : 将两类对象转为真正的数组

let arrayLike = {
'0' : 'Tom',
'1' : 20,
length : 2 //数组长度
}

let arr = Array.from(arrayLike)
console.log(arr);

Array.of() 将一组值转换为数组

Array.of(1,2,3) //[1,2,3]

set和map数据结构

1.Set结构

Set类似于数组,但是成员值都是唯一的,没有重复。

> const s1 = new Set([1,2,3,4])
> [...s1]
[ 1, 2, 3, 4 ]
> const s2 = new Set([1,2,3,4,5])
> s2.size
5

四个操作方法:

  • add(value): 添加某个值
  • delete(value): 删除某个值,返回布尔值
  • has(value): 返回布尔值
  • clear(): 清楚所有成员

遍历操作:

  • keys(): 返回键名的遍历器
  • values(): 返回键值的遍历器
  • entries(): 返回键值对的遍历器
  • forEach(): 返回回调函数遍历每个成员

2.Map结构

Object结构提供了”字符串-值”的对应,Map结构提供了”值-值”的对应,是一种更加完善的hash结构实现。

var map = new Map() //初始化map

属性

  • size: 返回map结构的成员总数

方法

  • set: 设置key所对应的值,返回整个Map结构,如果key已有值,则会更新键值。
  • get: 获取key对应的键值,如果找不到key,返回undefined。
  • has: 返回布尔值,表示某个键是否在map中。
  • delete: 删除某个键,成功返回true。
  • clear: 清楚所有成员,无返回值。

遍历方法

  • keys(): 返回键名的遍历器
  • values(): 返回键值的遍历器
  • entries(): 返回成员的遍历器
  • forEach(): 返回回调函数遍历每个成员

与其他数据结构转换

  1. Map => Array 扩展运算符 […map]
  2. Array => Map 将数组传入map构造函数
  3. Map => Object Map的键都是字符串时

     function strMapToObj(strMap) {
       let obj = Object.create(null);
       for (let [k,v] of strMap) {
         obj[k] = v;
       }
       return obj;
     }
    
     let myMap = new Map().set('yes', true).set('no', false);
     strMapToObj(myMap)
     // { yes: true, no: false }
    
  4. 对象转换为Map

     function objToStrMap(obj) {
       let strMap = new Map();
       for (let k of Object.keys(obj)) {
         strMap.set(k, obj[k]);
       }
       return strMap;
     }
    
     objToStrMap({yes: true, no: false})
     // [ [ 'yes', true ], [ 'no', false ] ]
    
  5. Map与Json的转换较为复杂,见 http://es6.ruanyifeng.com/#docs/set-map

Promise 异步编程

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,它是一个对象,从它可以获取异步操作的消息。

特点:

  • 对象状态不受外界影响
  • 一旦状态改变,就不会再变,任何时候都可以得到这个结果

    function timeout(ms) { return new Promise((resolve, reject) => { setTimeout(resolve, ms, ‘done’); }); }

    timeout(1000).then((value) => { console.log(value); });


Class

ES6中引入了Class(类)这个概念,作为对象的模版,通过class关键字,可以定义类。

class Point {
	constructor(x, y) {
    	this.x = x;
        this.y = y;
    }
    
    toString() {
    	return '(' + this.x + ',' + this.y + ')';
    }
}

var p = new Point();
p.toString(1,2);

Module

export命令

规定模块的对外接口

一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。希望外部获取某个变量,就必须使用exports关键字暴露该变量

const firstName = 'Michael';
const lastNmae = 'Jackson';
const year = 2000;

export {firstName, year};

import命令

输入其他模块提供的功能

import {firstName, lastName, year} from './profile';

function setName(element) {
  element.textContent = firstName + ' ' + lastName;
}

export default 命令

为模块指定默认输出

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

ES6模块加载的实质

js引擎对脚本静态分析的时候,遇到模块加载命令import, 就会生成一个只读引用,等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。换句话说,es6的import有点像unix系统的”符号连接”,原始值变了,import加载的值也会跟着变。因此,es6模块是动态引用,不会缓存值,模块里面的变量绑定其所在的模块。


编程风格

  • let 取代 var
  • let 和 const 之间,优先使用const
  • 静态字符串一律使用单引号或反引号,不使用双引号。动态字符串使用反引号
  • 对数组成员变量赋值时,优先解构赋值
  • 单行定义对象,最后一个成员不以逗号结尾;多行定义对象,最后一个成员以逗号结尾。

      const a = { k1: v1, k2: v2 };
      const b = {
        k1: v1,
        k2: v2,
      };
    
  • 对象尽量静态化,一旦定义,不得随意添加新的属性。如果添加属性不可避免,要使用Object.assign方法

  • 使用扩展运算符(…)拷贝数组

      const itemsCopt = [...items];
    
  • 立即执行的函数可以写成箭头函数的形式

      [1,2,3].map(x => x * x)
    
  • 只有模拟现实世界的实体对象时,使用Object,如果只需要key:value,使用map结构
  • 用import取代require, export取代module.exports
  • 一个模块输出一个函数,函数名首字母小写;输出对象,首字母大写。