写一些,自己认为应该记住的es6的东西。不常用的就不说了。

1.let,const参见阮一峰老师的。记住有let,const,class,import这6种生命的方法。import用来代替require.

2.​​解构赋值​​赋值,我们可以了解数组,对象,字符串的赋值就行。

3.数组的扩展。

Array.from()用于将两类对象为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括ES6新增的数据结构Set和Map

ES6_数组

​Array.from​​​还可以接受第二个参数,作用类似于数组的​​map​​方法,用来对每个元素进行处理,将处理后的值放入返回的数组。

ES6_数组_02

第二个参数的实用的例子:

ES6_数据结构_03

​Array.of​​方法用于将一组值,换为数组

​Array​​​方法没有参数、一个参数、三个参数时,返回结果都不一样。只有当参数个数不少于2个时,​​Array()​​才会返回由参数组成的新数组。参数个数只有一个时,实际上是指定数组的长度。

 ES6_javascript_04

ES6_数组_05

ES6_数据结构_06

ES6_数据结构_07

ES6_javascript_08


 ES6_javascript_09


数组实例的​​find​​​方法,用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为​​true​​​的成员,然后返回该成员。如果没有符合条件的成员,则返回​​undefined​​。

而findIndex返回的是坐标 。

ES6_javascript_10

​fill​​方法使用给定值,填充一个数组。

['a', 'b', 'c'].fill(7)
// [7, 7, 7]

new Array(3).fill(7)
// [7, 7, 7]
['a', 'b', 'c'].fill(7, 1, 2)
// ['a', 7, 'c']

上面代码表示,fill方法从1号位开始,向原数组填充7,到2号位之前结束。
ES6提供三个新的方法——entries()
,keys()
和values()
——用于遍历数组。它们都返回一个遍历器对象(详见《Iterator》一章),可以用for...of
循环进行遍历,唯一的区别是keys()
是对键名的遍历、values()
是对键值的遍历,entries()
是对键值对的遍历。

ES6_javascript_11

如果不使用​​for...of​​​循环,可以手动调用遍历器对象的​​next​​方法,进行遍历。

let letter = ['a', 'b', 'c'];
let entries = letter.entries();
console.log(entries.next().value); // [0, 'a']
console.log(entries.next().value); // [1, 'b']
console.log(entries.next().value); // [2, 'c']

includes

该方法的第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为-4,但数组长度为3),则会重置为从0开始。


​indexOf​​​方法有两个缺点,一是不够语义化,它的含义是找到参数值的第一个出现位置,所以要去比较是否不等于-1,表达起来不够直观。二是,它内部使用严格相当运算符(===)进行判断,这会导致对​​NaN​​的误判。

[NaN].indexOf(NaN)
// -1

​includes​​使用的是不一样的判断算法,就没有这个问题。

[NaN].includes(NaN)
// true
[1, 2, 3].includes(2);     // true
[1, 2, 3].includes(4); // false
[1, 2, NaN].includes(NaN); // true
备注;

Map和Set数据结构有一个​​has​​​方法,需要注意与​​includes​​区分。


  • Map结构的​​has​​​方法,是用来查找键名的,比如​​Map.prototype.has(key)​​​、​​WeakMap.prototype.has(key)​​​、​​Reflect.has(target, propertyKey)​​。
  • Set结构的​​has​​​方法,是用来查找值的,比如​​Set.prototype.has(value)​​​、​​WeakSet.prototype.has(value)​

数组的空位指,数组的某一个位置没有任何值。比如,Array构造函数返回的数组都是空位。
我们要避免空位。

 4.函数的扩展。

(1) 默认值。

ES6_数据结构_12

(2)函数的.length属性。参数的个数,如果参数有默认值则不算,或者有默认值的参数放在第一个的话,length也是0.

 (3)rest函数。

ES6_javascript_13


ES6_数据结构_14

(4) 扩展运算符(spread)是三个点(​​...​​)。它好比 rest 参数的逆运算,将一个数组为用逗号分隔的参数序列。

ES6_javascript_15

应用代替apply:

ES6_javascript_16


ES6_数组_17

ES6_javascript_18

1)合并数组

扩展运算符提供了数组合并的新写法。

(2)与解构赋值结合

扩展运算符可以与解构赋值结合起来,用于生成数组。

(3)函数的返回值

JavaScript的函数只能返回一个值,如果需要返回多个值,只能返回数组或对象。扩展运算符提供了解决这个问题的一种变通方法。

(4)字符串

扩展运算符还可以将字符串为真正的数组

(5)实现了Iterator接口的对象

任何Iterator接口的对象,都可以用扩展运算符为真正的数组。

(6)Map和Set结构,Generator函数

扩展运算符内部调用的是数据结构的Iterator接口,因此只要具有Iterator接口的对象,都可以使用扩展运算符,比如Map结构。

​5.name​​属性

ES6_javascript_19

ES6_数据结构_20

ES6_数据结构_21

6.箭头函数。

ES6允许使用“箭头”(​​=>​​)定义函数。

ES6_数组_22

ES6_数组_23

ES6_javascript_24


7.set

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

上面代码通过​​add​​方法向 Set 结构加入成员,结果表明 Set 结构不会添加重复的值。

Set 函数可以接受一个数组(或类似数组的对象)作为参数,用来初始化。

ES6_javascript_25

上面代码中,也展示了一种去除数组重复成员的方法。

// 去除数组的重复成员
[...new Set(array)]

ES6_javascript_26


let set = new Set();

set.add({});
set.size // 1

set.add({});
set.size // 2

上面代码表示,由于两个空对象不相等,所以它们被视为两个值


  • ​add(value)​​:添加某个值,返回Set结构本身。
  • ​delete(value)​​:删除某个值,返回一个布尔值,表示删除是否成功。
  • ​has(value)​​​:返回一个布尔值,表示该值是否为​​Set​​的成员。
  • ​clear()​​:清除所有成员,没有返回值。


s.add(1).add(2).add(2);
// 注意2被加入了两次

s.size // 2

s.has(1) // true
s.has(2) // true
s.has(3) // false

s.delete(2);
s.has(2) // false

ES6_数据结构_27


ES6_数组_28

keys()​values()​​entries()​

ES6_数组_29

Set结构的实例默认可遍历,它的默认遍历器生成函数就是它的​​values​​方法。

ES6_javascript_30


forEach()

let set = new Set([1, 2, 3]);
set.forEach((value, key) => console.log(value * 2) )
// 2
// 4
// 6

 8.map

ES6_数据结构_31

ES6_javascript_32

map的size属性,set(key, value),get(key),has(key),delete(key),clear() 


  • ​keys()​​:返回键名的遍历器。
  • ​values()​​:返回键值的遍历器。
  • ​entries()​​:返回所有成员的遍历器。
  • ​forEach()​​:遍历Map的所有成员

 上面代码最后的那个例子,表示Map结构的默认遍历器接口(​​Symbol.iterator​​​属性),就是​​entries​​方法。

ES6_数据结构_33

ES6_数组_34

ES6_数据结构_35

9.Class

ES6_javascript_36

ES6_数据结构_37

ES6_javascript_38

这个是以为b.__proto__ ==  B.prototype

如果构造器有return并且返回的不是this的话,那么需要小心了。

ES6_javascript_39


ES6_数据结构_40

ES6_javascript_41


私有方法。

ES6_数组_42

ES6_数据结构_43

ES6_数组_44

this的指向。

ES6_javascript_45

ES6_数组_46

ES6_数组_47

ES6_javascript_48

Class的继承

ES6_数组_49


类的prototype属性和__proto__属性

大多数浏览器的ES5实现之中,每一个对象都有​​__proto__​​​属性,指向对应的构造函数的prototype属性。Class作为构造函数的语法糖,同时有prototype属性和​​__proto__​​属性,因此同时存在两条继承链。

 ES6_数组_50

ES6_数组_51

原生构造函数的继承。

ES6_数据结构_52


以前,这些原生构造函数是无法继承的,比如,不能自己定义一个​​Array​​的子类

 ES6_数组_53

中间超出的那一行:

this.splice(0, this.length, ...this.history[this.history.length - 1]);

Class的取值函数(getter)和存值函数(setter)

ES6_javascript_54

ES6_数据结构_55

ES6_javascript_56



Class的静态属性和实例属性

Class内部只有静态方法,没有静态属性。

这么写是有效的。

ES6_数组_57

除此之外,还有一种写法,虽然es6不支持,但是babel已经支持了。

ES6_javascript_58

ES6_数组_59

ES6_数据结构_60

ES6_javascript_61


 ES6_数据结构_62

ES6_数组_63


10.Symbol

ES6_数组_64

ES6_数据结构_65


ymbol 作为属性名,该属性不会出现在​​for...in​​​、​​for...of​​​循环中,也不会被​​Object.keys()​​​、​​Object.getOwnPropertyNames()​​​、​​JSON.stringify()​​​返回。但是,它也不是私有属性,有一个​​Object.getOwnPropertySymbols​​方法,可以获取指定对象的所有 Symbol 属性名。

​Object.getOwnPropertySymbols​​方法返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。


ES6_javascript_66

Symbol.for(),Symbol.keyFor()

有时,我们希望重新使用同一个Symbol值,​​Symbol.for​​方法可以做到这一点。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的Symbol值。如果有,就返回这个Symbol值,否则就新建并返回一个以该字符串为名称的Symbol值。

ES6_数组_67


ES6_数组_68

单利模式:

ES6_数组_69

Symbol.hasInstance

对象的​​Symbol.isConcatSpreadable​​​属性等于一个布尔值,表示该对象使用​​Array.prototype.concat()​​时,是否可以展开。

对象的​​Symbol.species​​属性,指向当前对象的构造函数。创造实例时,默认会调用这个方法,即使用这个属性返回的函数当作构造函数,来创造新的实例对象

对象的​​Symbol.match​​​属性,指向一个函数。当执行​​str.match(myObject)​​时,如果该属性存在,会调用它,返回该方法的返回值。

对象的​​Symbol.replace​​​属性,指向一个方法,当该对象被​​String.prototype.replace​​方法调用时,会返回该方法的返回值。

对象的​​Symbol.search​​​属性,指向一个方法,当该对象被​​String.prototype.search​​方法调用时,会返回该方法的返回值。

对象的​​Symbol.split​​​属性,指向一个方法,当该对象被​​String.prototype.split​​方法调用时,会返回该方法的返回值。 



下面的coolcao的笔记。以后再精简吧。 

## es6分享


### es6新的内容可简单归纳为几个部分:


* 新的语法定义

    * let,const

    * class,extend

    * 模板字符串

    * 不定参数和默认参数

    * 解构

    * 箭头函数

* 新的数据结构及类型

    * Set,Map

    * Symbols

    * 迭代器,生成器,Promise

    * 代理 Proxy Reflect

    * 模块系统 Modules

* es5已有的对象的拓展

    * 字符串的拓展

    * 正则的拓展

    * 数值的拓展

    * 数组的拓展

    * 对象的拓展

    * 函数的拓展


### 推荐重点研究的新特性

* Promise

* Iterator for of循环

* Generator函数

* classextend 对继承的拓展

* 箭头函数


### 稍微看一下文档,平时练习用即可,难度不大

* let,const

* 模板字符串

* 不定参数和默认参数

* 解构(nodejs 6.0后才开始支持解构)

* Symbols(平时用的不多)

* 代理Proxy 反射 Reflect

* 模块系统 nodejs一直用的自己的模块系统,和es6的模块系统差别不大,只是语法上有点区别)

* 各种拓展



### Promise

promise三种状态:初始等待状态pending,完成状态resolved,拒绝状态rejected


#### 异常捕捉

异步的js回调,没法使用try catch去捕捉异常,只能约定在回调函数的第一个参数传err,第二个参数传结果

但是使用promise可以将异常统一catch

promise链的最后都要用catch去捕捉异常,这样链条上任何promise出了错误或是被拒绝都会被catch到。


```javascript

MongoClient.connect('mongodb://localhost:27017',function(err,db){

    var collection = db.collection('simple_query');

    collection.find({},function (err,result) {

        console.log(result);

    });

});

```

改写成promise形式:

```js

MongoClient.connect('mongodb://localhost:27017').then(function (db) {

    return db.collection('simple_query');

}).then(function (coll) {

    return coll.find();

}).then(function (result) {

    console.log(result);

}).catch();

```

promise形成一个链,在处理流程时逻辑更清晰。


整个promise的概念,很容易理解。无非就是如下的示意图流程:

```javascript

                 ------fulfilled(resolved)-----then(value)方法调用

                 |

     pending ----

                 |

                 ------rejected---------catch(error)方法调用

```

但是在实际使用的时候,如果对其概念理解不深,会跳入很多坑,分享一下自己遇到的一些。


#### 遇到的坑,值得注意的问题


##### then()方法的参数,永远传递函数

then()方法有两个参数,onSuccess()处理成功时的函数,onFail()处理失败时的函数,但是一般如果在最后的链添加了catch方法,则只需要传一个处理成功的函数即可。

* 但如果传两个参数,而且最后还添加了catch会如何?

```javascript

var p = new Promise(function (resolved,rejected) {

    setTimeout(function () {

        let a = false;

        if(a){

            resolved(true);

        }else{

            rejected(false);

        }

    },1000);

});


p.then(function onSuccess(result) {

    console.log(result);

},function onFail(err) {

    console.log('onFail');

    console.log(err);

}).catch(function (err) {

    console.log('catch err');

    console.log(err);

});

```

结果:

```

onFail

false

```


#### then()方法的返回

前面一直提promise链,也没说Promise是怎么成链的,其实是通过then()方法的返回promise形成的一个链。

```javascript

var r = p.then(function onSuccess(result) {

    console.log(result);

},function onFail(err) {

    console.log('onFail');

    console.log(err);

}).catch(function (err) {

    console.log('catch err');

    console.log(err);

});

console.log(r);    //Promise { <pending> }

```

then()方法返回的是一个Promise,处于初始状态,在then()方法的成功函数中,return 的值会相应的改变r的状态。

处理函数return 有三种类型:

* return 一个Promise

* return 一个同步的值

* throw 一个异常

前两种方法都会相应的将promise的状态改为resolved.throw一个异常会改变其状态为rejected.

然后就可以使用r.then().catch()进行相应的处理。

这样的代码会比较凌乱,一般都是如下面这样链式的写法,形成promise链:

```javascript

p.then(function onSuccess(result) {

    console.log(result);

    return 'abc';

},function onFail(err) {

    console.log('onFail');

    console.log(err);

}).then(function (result) {

    console.log(result);    //abc

    return 'def';

}).then(function (result) {

    console.log(result);    //def

}).catch(function (err) {

    console.log('catch err');

    console.log(err);

});

```


#### promise的金字塔问题

```javascript

remotedb.allDocs({

  include_docs: true,

  attachments: true

}).then(function (result) {

  var docs = result.rows;

  docs.forEach(function(element) {

    localdb.put(element.doc).then(function(response) {

      alert("Pulled doc with id " + element.doc._id + " and added to local db.");

    }).catch(function (err) {

      if (err.status == 409) {

        localdb.get(element.doc._id).then(function (resp) {

          localdb.remove(resp._id, resp._rev).then(function (resp) {

// et cetera...


```

这样的代码,只是用了promise的写法,并没有使用promise的链式写法,原因是没有正确上面then()方法的返回值。这样,导致逻辑混乱,结构不清晰,还不如直接用回调来的清晰。

```javascript

remotedb.allDocs(...).then(function (resultOfAllDocs) {

  return localdb.put(...);

}).then(function (resultOfPut) {

  return localdb.get(...);

}).then(function (resultOfGet) {

  return localdb.put(...);

}).catch(function (err) {

  console.log(err);

});

```


#### promise中使用循环

例如有这样一个简单的场景,从数据库中查询出所有状态为0的商品,然后将所有的商品删除。

```javascript

coll.find({status:0}).then(function (docs) {

    docs.forEach(function (doc) {

        return doc.remove();

    });

}).then(function () {

    console.log('全部删除');

});

```

这样写是不对的,因为,假设有100个状态为0的文档,在使用forEach循环时,如果第一个文档删除成功了,return 回去后,整个promise的状态就改变了,那么即使后面的99个删除失败,也不会再抛出错误,导致操作失败。


正确的应该是,使用promise.all()

```javascript

coll.find({status:0}).then(function (docs) {

    return Promise.all(docs.forEach(doc){

        return doc.remove();

    });

})

```

100个文档遍历,返回100个删除操作的promise,然后Promise.all()传递一个100promise的数组。最后当这100promse都成功时,才算最终的成功。


#### catch()then(,...)并非完全等价

上面说过,异常的处理,可以用catch也可以在then传第二个参数异常处理函数处理,但这并不完全等价。

```javascript

somePromise().then(function () {

  return someOtherPromise();

}).catch(function (err) {

  // handle error

});


somePromise().then(function () {

  return someOtherPromise();

}, function (err) {

  // handle error

});

```

比如上面的代码,如果在someOtherPromise()这个函数里报错了,第一个是可以正常catch到的,因为在promise链里的任何异常都可以被catch捕捉到。

但是第二个,却没法捕捉到,因为then()方法第二个参数只能处理调用then()方法的promise的异常,这里是somePromise()的异常。


**promise链的最后一定要加catch()**


### Iterator for of

Iterator遍历器,类似java的遍历器

遍历器不断调用next()方式遍历所有数据

next方法必须返回一个包含valuedone两个属性的对象。value属性是当前遍历的位置的值,而done属性是一个布尔值,用来表示遍历是否结束。

遍历器是一种数据遍历机制,任何对象,只要实现了这种机制,都可以使用同种方式,也就是for of进行遍历。

Iterator的遍历过程是这样的。


1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。


2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。


3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。


4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。


js中默认实现了遍历器接口的有数组,Set,Map,字符串等,也可以自行实现,然后使用for of 循环遍历。

ES6规定,默认的Iterator接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是可遍历的iterable)。调用Symbol.iterator方法,就会得到当前数据结构默认的遍历器生成函数。Symbol.iterator本身是一个表达式,返回Symbol对象的iterator属性,这是一个预定义好的、类型为Symbol的特殊值,所以要放在方括号内(请参考Symbol一章)。

```javascript

let arr = ['a', 'b', 'c'];

let iter = arr[Symbol.iterator]();


iter.next() // { value: 'a', done: false }

iter.next() // { value: 'b', done: false }

iter.next() // { value: 'c', done: false }

iter.next() // { value: undefined, done: true }


```

自行实现iterable接口:

```javascript

class RangeIterator {

  constructor(start, stop) {

    this.value = start;

    this.stop = stop;

  }


  [Symbol.iterator]() { return this; }


  next() {

    var value = this.value;

    if (value < this.stop) {

      this.value++;

      return {done: false, value: value};

    } else {

      return {done: true, value: undefined};

    }

  }

}


function range(start, stop) {

  return new RangeIterator(start, stop);

}


for (var value of range(0, 3)) {

  console.log(value);

}

```


### Generator函数,yield

生成器函数内部实现了遍历器接口iterable,使用next()方法调用值。

```javascript

function* helloWorldGenerator() {

  yield 'hello';

  yield 'world';

  return 'ending';

}


var hw = helloWorldGenerator();     //生成一个遍历器对象

hw.next();      //{ value: 'hello', done: false }

hw.next();      //{ value: 'world', done: false }

hw.next();      //{ value: 'ending', done: true }

hw.next();      //{ value: undefined, done: true }

```

由于Generator函数返回的遍历器对象,只有调用next方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。yield语句就是暂停标志。

遍历器对象的next方法的运行逻辑如下。


1)遇到yield语句,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。


2)下一次调用next方法时,再继续往下执行,直到遇到下一个yield语句。


3)如果没有再遇到新的yield语句,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。


4)如果该函数没有return语句,则返回的对象的value属性值为undefined


#### 生成器函数有什么用

TJ大神将Promise,Generator的思想揉在一起,写了一个co模块,异步流程控制模块。

```javascript

co(function *(){

  // resolve multiple promises in parallel

  var a = Promise.resolve(1);

  var b = Promise.resolve(2);

  var c = Promise.resolve(3);

  var res = yield [a, b, c];

  console.log(res);

  // => [1, 2, 3]

}).catch(onerror);

```

co模块实质是一个生成器执行器,不用我们自己调用next()方法,也不用我们自己调用promisethen()方法。co模块给执行的。

原理就是,当生成器函数遇到yield时,会停下当前执行状态,返回一个promise,这时候可以调用promisethen()方法获取值。

所以不论同步异步,在代码感官上都一样,都好像是同步的。


目前(es7还未出来之前),生成器函数+co模块+promise方式控制异步流程的方式被大家所推崇。出了莫名其妙的加了一层co之外,这种方式也没什么不好。

但是有一个前提是,co模块yield后面必须跟的是promise,不能是其他的值。

所以promise还是万物的基础。


#### 解决异步流程方式比较

##### 单纯的promise

可以使用promise链的方式,这种方式逻辑简单明了,但是如果开发人员对promise理解不深,很容易出bug

##### co+生成器函数

比较受大家推崇的一种方式,但是需要额外引入co模块,还需要理解生成器函数,写出的代码很容易不受控制。但是在代码层面,可以用同步的代码解决异步流程

##### es7asyncawait

```javascript

var asyncReadFile = async function (){

  var f1 = await readFile('/etc/fstab');

  var f2 = await readFile('/etc/shells');

  console.log(f1.toString());

  console.log(f2.toString());

};

```

async函数就是将Generator函数的星号(*)替换成async,将yield替换成await

* 内置执行器

* 更好的语义

* 更广的适用性 使用coyield后面只能跟promisethunk函数,但是await后面可以跟proise或是基本类型的值

* 返回值是Promise Generator返回的是一个遍历器,而async返回的是promise


可以说,es7asyncawait才是解决异步流程问题的终极大招



### classextend的实现

js的继承使用的是原型链的方式,代码写起来太复杂,凌乱。es6引入了class关键字去定义一个构造函数,extend关键字实现继承

但其本质上,继承关系还是通过原型链的方式实现的。

```javascript

//定义类

class Point {

  constructor(x, y) {

    this.x = x;

    this.y = y;

  }


  toString() {

    return '(' + this.x + ', ' + this.y + ')';

  }

  static print(){

      console.log('(' + this.x + ', ' + this.y + ')');

  }

}

let point = new Point(3,4);

```

classextend简化了js中对象的继承,在逻辑上也更清晰明了。但也不是非常完美的,目前es6class里可以定义静态方法,但是不能定义静态属性,如果想要在某个class上定义一个静态属性,那么只能通过原始的方式进行了,例如:

```javascript

Point.sql = {

    insert:'insert into points (x,y) values (?,?)'

}

```

### 箭头函数

借鉴的coffeescript的箭头函数,当然并不只是形式上的简便,在实现上也有改进:

1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。


```javascript

var obj = {

    name: 'coolcao',

    say: function() {

        return {

            name: 'world',

            say: function() {

                console.log(this.name);

            }

        }

    }

};


var obj2 = {

    name: 'coolcao',

    say: function() {

        return {

            name: 'world',

            say: () => {

                console.log(this.name);

            }

        }

    }

};


obj.say().say();

obj2.say().say();

```


2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。


3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。


4)不可以使用yield命令,因此箭头函数不能用作Generator函数。


```javascript

let sayHi = (name) = > {

    console.log('hi ' + name);

}

```






ES6 *

* let,const

* class,extend

*

* *

*

* * Set,Map

* Symbols

* Promise

* Proxy Reflect * Modules










*

* Promise

* Iterator for of

* Generator

* class extend *










var queryByPage = function (page,limit) {page = page || 1;

limit = limit || 5; console.log({page:page,limit:limit});

}

es6

var queryByPage = function (page = 1,limit = 5) { console.log({page:page,limit:limit});

}










js arguments es6 arguments

function containsAll(array) {

for (var i = 1; i < arguments.length; i++) {

var item = arguments[i];

if (haystack.indexOf(item) === -1) {

return false; }

}

return true; }

var containsAll = function containsAll(array,...items) { for (let item of items) {

if(array.indexOf(item) === -1){ return false;

} }

return true; }

1. arguments array , arguments 1

2.







Iterator for of Iterator

ES6 Iterator 1




2 3 4







var it = makeIterator(['a', 'b']);




it.next() // { value: "a", done: false }
it.next() // { value: "b", done: false }




it.next() // { value: undefined, done: true }




function makeIterator(array) {




var nextIndex = 0;




return {




next: function() {




return nextIndex < array.length ?




{value: array[nextIndex++], done: false} :




{value: undefined, done: true};




}




};




}




next next




next






ES6 Iterator





let arr = ['a', 'b', 'c'];




for-of

es6 set,map,




for...of




Symbol.iterator




let iter = arr[Symbol.iterator]();




iter.next() // { value: 'a', done: false }
iter.next() // { value: 'b', done: false }
iter.next() // { value: 'c', done: false }




iter.next() // { value: undefined, done: true }




let obj = {




data: [ 'hello', 'world' ],




[Symbol.iterator]() {




const self = this;




let index = 0;




return {




next() {




if (index < self.data.length) {




return {




value: self.data[index++],




done: false




};




}




} else {




}




return { value: undefined, done: true };




};




}




};







function* helloWorldGenerator() { yield 'hello';

yield 'world';

return 'ending';

}

var hw = helloWorldGenerator(); hw.next()

// { value: 'hello', done: false } hw.next()

// { value: 'world', done: false } hw.next()

// { value: 'ending', done: true } hw.next()

// { value: undefined, done: true }

Generator Generator Generator










co co

var loadUser = function () {

return new Promise(function (resolve,reject) {

setTimeout(function () { resolve('coolcao');

},1000); });

}

var findBooksByUser = function (user) {

return new Promise(function (resolve,reject) { setTimeout(function () {

resolve('js '); },1000);

}); }

co(function *() {

var user = yield loadUser(); console.log(user);

var book = yield findBooksByUser(user); console.log(book);

});









class

class User { constructor(name,age) {

this.name = name;

this.age = age; }

toString(){

return `User[name:${this.name},age:${this.age}]`;

} valueOf(){

return this.age; }

// User.sayHi()

static sayHi(){ console.log(‘hi’);

} }

var u = new User(‘coolcao’,23);









class class prototype js Java

class 1.

var u = new User(); class User{}

2.class new 3.class

User.sql = {}









class extends

class Men extends User { constructor(name,age) {

super(name,age);

this.gender = 'm'; }

}





var m = new Men('coolcao',23);console.log(m);

console.log(m instanceof User);





//true class









coffeescript

1 this

2 new

3 arguments Rest

4 yield Generator









```javascript var obj = {

name: 'coolcao', say: function() {

return {

name: 'world', say: function() {

console.log(this.name); }

} }

};

var obj2 = {

name: 'coolcao', say: function() {

return {

name: 'world', say: () => {

console.log(this.name); }

} }

};

obj.say().say(); obj2.say().say(); ```









Promise promise pending, resolved, rejected

js try catch err, promise catch promise catch promise catch

```javascript MongoClient.connect('mongodb://localhost:27017',function(err,db){

var collection = db.collection('simple_query'); collection.find({},function (err,result) {

console.log(result); });

}); ```

promise : ```js

MongoClient.connect('mongodb://localhost:27017').then(function (db) { return db.collection(‘simple_query');

return Promise.resolve(db.collection(‘simple_query');); }).then(function (coll) {

return coll.find(); }).then(function (result) {

console.log(result); }).catch();

```









------fulfilled(resolved)-----then(value)

| pending --- |

———rejected---------catch(error)

箭头函数有几个使用注意点。

(1)函数体内的​​this​​对象,就是定义时所在的对象,而不是使用时所在的对象。

(2)不可以当作构造函数,也就是说,不可以使用​​new​​命令,否则会抛出一个错误。

(3)不可以使用​​arguments​​对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。

(4)不可以使用​​yield​​命令,因此箭头函数不能用作Generator函数。

上面四点中,第一点尤其值得注意。​​this​​对象的指向是可变的,但是在箭头函数中,它是固定的。

ES6_数组_70