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

  • 相关阅读:
    Java输出错误信息与调试信息
    Java实现两个变量的互换(不借助第3个变量)
    Java用三元运算符判断奇数和偶数
    使用webpack-dev-server设置反向代理解决前端跨域问题
    springboot解决跨域问题(Cors)
    Spring boot集成swagger2
    Redis学习汇总
    【年终总结】2017年迟来的总结
    Springboot项目maven多模块拆分
    Maven实现多环境打包
  • 原文地址:https://www.cnblogs.com/coding4/p/5585453.html
Copyright © 2020-2023  润新知