ES6

 

 

 

http://es6.ruanyifeng.com/#docs/intro

这里有个es的笔记可以看看:http://www.cnblogs.com/yang-11/p/6053556.html

0001关于  Object.assign()痛点 http://blog.csdn.net/waiterwaiter/article/details/50267787  这个只是一个1级的拷贝,使用的时候需要注意点。

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

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

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

3.数组的扩展。

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

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

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

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

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

 

 

 

 

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

而findIndex返回的是坐标 。

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()是对键值对的遍历。

如果不使用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) 默认值。

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

 (3)rest函数。

 

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

应用代替apply:

 

1)合并数组

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

(2)与解构赋值结合

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

(3)函数的返回值

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

(4)字符串

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

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

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

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

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

5.name属性

6.箭头函数。

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

 

7.set

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

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

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

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

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

 

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

 

keys()values()entries()

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

 

forEach()

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

 8.map

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

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

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

9.Class

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

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

 

 

私有方法。

this的指向。

Class的继承

 

类的prototype属性和__proto__属性

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

 

原生构造函数的继承。

 

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

 

中间超出的那一行:

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

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

 

 

Class的静态属性和实例属性

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

这么写是有效的。

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

 

 

 

10.Symbol

 

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

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

 

Symbol.for(),Symbol.keyFor()

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

 

单利模式:

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方法调用时,会返回该方法的返回值。 

 11.关于es6的class

http://blog.csdn.net/pcaxb/article/details/53759637

12.三个点拓展符的多个用法。

https://www.cnblogs.com/mingjiezhang/p/5903026.html

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

下面的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对象的指向是可变的,但是在箭头函数中,它是固定的。

 

 

posted @ 2016-06-14 21:00  飘然离去  阅读(212)  评论(0编辑  收藏  举报