• ECMAScript 6 学习总结


    1.什么是ES6?

          简单的说 ES6 的第一个版本,在2015年6月发布了,正式名称就是《ECMAScript 2015标准》(简称 ES2015)在2016年6月,小幅修订的《ECMAScript 2016标准》(简称 ES2016)如期发布,2017年6月发布的新版本就是ES7。ES6 既是一个历史名词,也是一个泛指,含义是5.1版以后的 JavaScript 的下一代标准,涵盖了ES2015、ES2016、ES2017等等。

    2.箭头函数 =>

    会解析为 function(){}

    eg. input.map(item => item+1);  解析完:

          input.map(function(item){

              item = item + 1;

          });

    箭头函数的特征:

    • 代码简写
    • 箭头函数会捕获上下文的this对象,本身没有this对象
    • 箭头函数是匿名函数
    function MyFun(){
    
    this.a = 1;
    
    setInterval(function growUp(){
    
    //此处的this,growUp函数定义的内部的this, 不同于构造函数MyFun函数中的this
    
    this.a ++; 
    
    },1000);
    
    }
    
    var fun = new MyFun();
    
    //要修改的话,我们往往会将构造函数的this指定到一个新增的变量中
    
    //如果使用箭头函数,就会很方便:
    
    function MyFun(){
    
    this.a = 1;
    
    setInterval(() => {
    
    //此处的this正确的指向了构造函数MyFun
    
      this.a++;
    
    },1000);
    
    }
    var fun = new MyFun();

    3.let 和const命令

    let定义的变量只在let命令所在的代码块内有效.

    let不允许在相同作用域内重复声明,允许在块级作用域内声明函数, 声明类似于var,即会提升到全局作用域或函数作用域的头部。同时,函数声明还会提升到所在的块级作用域的头部。

    {
      let a = 10;
      var b = 1;
    }
    console.log(a);  // ReferenceError: a is not defined.
    console.log(b); // 1
    
    for循环,就很适合使用let命令
    for(let i = 0; i < 10; i++){}
        console.log(i);// ReferenceError: i is not defined
    //循环的语句定义和循环体可以作为两个不同的作用域
    for(let i = 0; i < 10; i++){
        let i = “abc”;
        console.log(i);
    }
    //所以会打印3个”abc”

    const用来定义不可变的常量,不可变的常量名一般全大写。一旦声明,常量的值就不能改变。

    eg. const PI = 3.14;

    对于const来说,只声明不赋值,就会报错。const的作用域与let命令相同:只在声明所在的块级作用域内有效。

    4.ES6 的解构赋值

    (1)数组的解构赋值——右边如果不是数组则报错,并且在严格模式中,变量不能重复定义,否则会报异常。

    let [x, y, z] = [1, 2, 3];
    let [a, …b] = [1, 2, 3, 4];  ==> a = 1; b = [2, 3, 4];
    let [x1, [y1, [z1, r]]] = [1, [2, [3]]]; r = undefined;  //对应不上的变量值为undefined
    
    //解构赋值可以添加默认值,如果右边赋值不严格(===)等于undefined, 则默认值将不会生效。
    let [h=1] = [undefined]; //h = 1;
    let [h1=1] = [null]; //h1 = null;
    
    //如果默认值是一个表达式,会懒赋值,就是在需要的时候才会去执行结果
    function myFun(){
    console.log(“come in”);
    }
    let [f = myFun()] = [1];

    (2)对象的解构赋值

    对象赋值可数组赋值的区别是:数组是按位置取值,值由位置来决定

    而对象不一定顺序一致,只要变量名和属性名相同,便可以取值。

    var {bar, liz} = {bar: ‘barValue’, liz1: ‘liz1Value’}; 
    console.log(bar);//barValue
    console.log(liz);//undefined   属性名不一致
    
    var obj = {first:'hello',last:'world'};
    var {first:fi,last:la} = obj;
    console.log(fi);//hello
    console.log(la);//world
    
    //默认赋值,必须严格等于(===)undefined,默认值才会生效.如果解构失败,变量的值就等于undefined
    var {lib = 1} = {lib: undefined};
    var {lib1 = 2} = {lib1: null};
    console.log(lib); //1
    console.log(lib1); //null

    (3)字符串的解构赋值 —其赋值规则类似于数组

    const [a0, b0, c0, d0, e0] = “hello”;
    console.log(a0);//h
    console.log(b0);//e
    console.log(c0);//l
    console.log(d0);//l
    console.log(e0);//o
    
    //字符串有个属性length
    const {length: len} = “hello”;
    console.log(len); //5

    (4)数值和布尔类型的解构赋值——等号右边不是对象,而是数值或者布尔值,则先转换为对象。

    let {toString: x0} = 123;
    console.log(x0);//[function:toString]
    x0 === Number.prototype.toString;
    let {toString:y0} = true;
    console.log(y0);//[function:toString]
    y0 === Boolean.prototype.toString;
    
    //因为undefined和null不能转换为对象,所以会报异常
    let {toString:z0} = undefined /null;
    console.log(z0); //var z0 = undefined.toString;TypeError: Cannot read property 'toString' of undefined

    (5)函数的参数解构赋值

    function add([x, y]){
        return x+y;
    }
    console.log(add([1,2])); //3
    console.log([[1,2],[3,4]].map(([a,b]) => a+b));//[3,7]
    
    //函数参数默认值结构赋值,也是===undefined时,默认值有效
    function myFun([x=1,y=2]){
      return x+y;
    }
    console.log(myFun([4,5]));//9
    console.log(myFun({}));//error
    console.log(myFun([5]));//7
    console.log(myFun([null,null]));//0

    变量解构赋值用处:

    (1)交换值

    eg. let [myx,myy] = [myy,myx];

    (2)函数可以返回多个值(good)

    eg. function mytest(){

            return [1,2,3];

          }

         let [m1,m2,m3] = mytest();

    (3)函数可以返回多个对象

    eg.  function mytest2(){

            return ({

               foo:1,

               foo1:2,

             })

          }

          let {foo, foo1} = mytest2();

          console.log(foo); //1

          console.log(foo1); //2

    5.ES6的算术方法

    ES6的二进制(0b/0B)和八进制(0o/0O)表示

    Number(); //方法将其转换为10进制数值
    console.log(Number(0b111));
    console.log(Number(0o111));
    NUmber.isFinite();//判断是否是非无穷
    Number.isNaN();//检查是否是NaN
    Number.parseInt();
    Number.parseFloat();
    Number.isInterger();
    
    console.log(Number.isInterger(3));
    console.log(Number.isInterger(3.0));
    
    Number.EPSILON;//表示一个极小的变量 2.220446049250313e-16
    //起作用来进行浮点数计算的误差判断,误差<Number.EPSILON 则计算结果正确
    // js表示整数的范围是 -2^53 ~ 2^53
    //ES6引入了Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER这两个常量,用来表示这个范围的上下限。
    Number.MAX_SAFE_INTEGER;
    Number.MIN_SAFE_INTEGER;
    isSafeInterger()//方法就是判断某个整数值是否落在上面的安全范围之间
    Number.isSafeInterger();
    
    //获取整数部分,对于空值和无法截取整数的值,返回NaN。
    Math.trunc(4.1);//4
    Math.trunc(4.9);//4
    Math.trunc(-4.1);//-4
    Math.trunc('NaN');//NaN
    //来返回一个函数是正数(1),负数(-1),还是0(0),-0(-0),其他返回NaN
    Math.sign(5);//1
    Math.sign(-5);//-1
    Math.sign(0);//0
    Math.sign(-0);//-0
    Math.sign("NaN");//NaN
    //用来计算一个数的立方根
    Math.cbrt();
    //将一个整数用32位二进制来表示
    Math.clz32();
    //Math.imul方法返回两个数以32位带符号整数形式相乘的结果,返回的也是一个32位的带符号整数。
    Math.imul(a,b);
    //返回一个数的单精度浮点数形式
    Math.fround();
    //Math.hypot方法返回所有参数的平方和的平方根。
    Math.hypot();
    
    ES6新增了6个三角函数方法。
    Math.sinh(x) //返回x的双曲正弦(hyperbolic sine)
    Math.cosh(x) //返回x的双曲余弦(hyperbolic cosine)
    Math.tanh(x) //返回x的双曲正切(hyperbolic tangent)
    Math.asinh(x) //返回x的反双曲正弦(inverse hyperbolic sine)
    Math.acosh(x) //返回x的反双曲余弦(inverse hyperbolic cosine)
    Math.atanh(x) //返回x的反双曲正切(inverse hyperbolic tangent)
    
    ES7新增了一个指数运算符(**)
    b **= 3;//等同于 b = b * b * b;

     6.ES6数组方法

        Array.from();   ——将类似于数组的对象和可遍历的对象(明显特征就是有length属性)转为数组

    let obj = {
      "0":"dtl",
      "1":18,
      "2":1234,
      length:5
    }
    var arr = Array.from(obj);
    console.log(arr);  //["dtl",18,1234,undefined,undefined]

       Array.of();  ——将一组数转为数组,如果没有参数,返回一个空数组

      console.log(Array.of(3));//[1]

      

      copyWith(); ——方法用于将目标元素拷贝到指定位置,将代替指定位置target的元素

         Array.prototype.copyWithin(target,[start],[end]);  //target 必需元素,从start位置开始拷贝 :默认为0

    //复制几个就从指定位置替换几个元素
    console.log([1,2,3,4,5].copyWithin(0,3));//[4,5,3,4,5]
    console.log([1,2,3,4,5].copyWithin(0,2));//[3,4,5,4,5]
    console.log([1,2,3,4,5].copyWithin(0));//[1,2,3,4,5]

      find(); ——用于找回第一个符合条件的数组成员,回调函数的三个参数:1表示当前的值,2表示当前的位置,3表示当前的数组

      findIndex(); ——返回第一个符合条件的数组成员的位置

    let b = [1,2,5,8,9].find(function(value,index,arr){
      return value > 7;
    });
    console.log(b);//8
    
    
    let c = [1,2,5,8,9].findIndex(function(value,index,arr){
      return value > 7;
    });
    console.log(c);//3

      fill(value,start,end); ——使用给定值来填充一个数组 ,常用于数组的初始化。value表示填充的值,start填充的起始位置,end填充的结束位置(但不包括结束位置)

    let myArr = new Array(3).fill(7, 0, 2);
    console.log(myArr); //[7, 7, ]

      entries(),keys(),values(); ——来遍历数组

    for (let index of ['a', 'b'].keys()) {
      console.log(index);
    }
    0
    1
    
    for (let elem of ['a', 'b'].values()) {
      console.log(elem);
    }
    'a'
    'b'
    
    for (let [index, elem] of ['a', 'b'].entries()) {
      console.log(index, elem);
    }
    0 "a"
    1 "b"

      includes(); ——返回数组是否包含某个值,true/false。没有includes之前我们通过indexOf()来判断,它有两个弊端:使用===判断,对NaN判断不准确,还有表达语义不够直观

     Es6明确将空位转为undefined。

    copyWith()//会连空位一起拷贝

    fill()//会将空位当正常数组对待

    for...of //循环会遍历空位

    entires(),keys(),values(),find(),findIndex()//都会将空处理成undefined

    7.ES6 函数

    函数参数赋默认值

    //原来的方式给函数赋默认值
    function add(x,y){
      y=y||'world';
    console.log(x+' '+y);
    }
    add('hello',);
    add('hello','china');
    add('hello','');//hello world 将“”变成了默认值,所以给y赋值时先要判断又是否有值,因此原来的方式很麻烦
    
    //新的方式给函数参数赋默认值
    function newAdd(x,y = 'world'){
      console.log(x+' '+y);
    }
    newAdd('hello',);
    newAdd('hello','');//hello

    后续ES6 学习总结:

    1.块级作用域和let ,const

    let和const不会提升变量的声明

    同名的变量或者常量在同一个作用域不能重复定义

    在作用域内,在声明前操作let或const定义的变量或者常量,会抛出异常。 (临时死区 TDZ)

    在循环中使用let和const每次迭代会创建新绑定(产生一个副本),所以可以获取到每次迭代的值

    块级作用域绑定的最佳实践: 默认使用const 定义,除非需要修改变量值时,使用let, 这样在很大程度上就实现了代码的不可变,防止错误的产生。

     

    2.String.codePointAt() 获取字符占用的编码单元数量

       String.fromCodePoint() 根据指定的码位生成一个字符串

       normalize() 字符串比较之前,现将其按照同一规则进行转换

       includes(), startWith(), endsWith()  返回结果为true/false, 都可以传入两个参数,第一个表示要搜索的字符,第二个参数可选表示开始检索的其实位置

       endsWith() 从字符串的末尾开始向前匹配

       repeat() 传入number类型的参数,表示字符串重复的次数

       正则表达式的flags属性会返回所有应用于但钱正则表达式的修饰字符串,source属性获取正则表达式的文本部分

       ES5中一直缺乏许多特性,如多行字符串、字符串格式化、HTML转义等。ES6通过模板字面量的方式进行了填补。模板字面量:用反撇号(``)替代单双引号,如果要在字符串中使用反撇号,用反斜杠()将其转义即可。字符串占位符${} 符号组合,中间可以包含任意的JavaScript表达式,可以是变量,运算式,函数等,也可以在模板字       面量里面嵌套另外一个。创建标签模板,标签函数接受模板字面量每个部分组成的参数数组,通过这些数据来组装出一个适合的字符串值。String.raw`Multiline string` 获取原生字串-> Multiline\nstring

     

    3.ECMAScript 6 的函数

    默认参数值arguments,在ECMAScript 5里非严格模式和严格模式不同:

    function(first, second){

    console.log(first === arguments[0]);

    console.log(second === arguments[1]);

    first = ‘c’;

    second = ‘d’;

    console.log(first === arguments[0]);

    console.log(second === arguments[1]);

    }

    返回的结果为:

    true

    true

    true

    true

    非严格模式下,参数的改变会同步到arguments对象中

     

    下面再看下严格模式:

    function(first, second){

    “use strict”;

    console.log(first === arguments[0]);

    console.log(second === arguments[1]);

    first = ‘c’;

    second = ‘d’;

    console.log(first === arguments[0]);

    console.log(second === arguments[1]);

    }

    返回的结果为:

    true 

    true

    false

    false

    严格模式下,无论参数如何变化,arguments 对象不再随之改变

    ECMAScript 6 的函数,如果使用了默认值,则无论是否显式的定义了严格模式,arguments都保持和ECMAScript 5严格模式下保持一致

    function(first, second=‘5’){

    console.log(arguments.length);

    console.log(first === arguments[0]);

    console.log(second === arguments[1]);

    first = ‘c’;

    second = ‘d’;

    console.log(first === arguments[0]);

    console.log(second === arguments[1]);

    }

    返回结果为:

    1

    true

    false

    false

    false

    arguments.length的值为1,arguments[1]的值为undefined

     

    函数的不定参数:在函数的命名参数前添加三个点(…)就表明这是一个不定参数,该参数为一个数组,包含自它传入后的所有参数。arguments 是返回了所有的参数,不定参数可以放心直接遍历。如果函数声明了不定参数,arguements对象包含了所有传入函数的参数。

    函数的length 属性统计的是函数命名参数的数量,不算不定参数,所以不定参数的引入不会影响函数的length值。还有不定参数必须放在函数参数的末尾,否则会语法错误。    

     

    展开运算符: 简化使用数组传参的过程。

    let values = [10, 9, 0,5,6,20];

    console.log(Math.max.apply(Math, values)); //ES5 通过apply实现

    console.log(Math.max(…values));  //ES6中展开运算符很大程度可以代替apply 

     

    Es6引入了new.target原属性,如果通过new 函数调用则new.target !== undefined,比如通过call,或者apply调用。

    ES6引入了块级函数,来解决在ES6之前版本函数声明在不同浏览器下的不兼容性。

    “use strict”;

    if(s){

     console.log(typeof doSomething); // function

    console.log(typeof doSomething1); // undefined

      function doSomething(){

     } //Es6的严格模式下,块级函数的声明会被提升到块级顶部

      let doSomething1 = function(){} // let定义的函数声明不会被提升

    }

    console.log(typeof doSomething); // undefined   在非严格模式下会提升至全局作用域

    增加了name 属性,来返回函数的名称。

    箭头函数

    1.没有this,super, arguments, new.target的绑定,这些值由外围最近一层的非箭头函数决定。

    2.不能通过new关键字调用

    3.没有原型

    4.不可改变this的绑定

    5.不支持arguments对象

    6.不支持重复的命名参数

     

    let reflect = value => value;

    let sum = (sum1, sum2) => sum1 + sum2;

    let sum2 = (num1, num2) => {

    return num1 + num2;

    }

    let getName = () => 'dtl';

    let myFun = () => {} ; // 创建一个空函数

    let getObj = id => ({id: id, name:'dd'}); //在函数外返回一个对象字面量,用小括号将字面量包裹起来

     

    let person = ((name) => {

    return {

        getName: function(){

            return name;

            }

        };

    })('dtl'); //创建立即执行函数,小括号将箭头函数包裹,不包裹传参部分。

     

    尾调用优化可以帮助函数保持一个更小的调用栈,从而减少内存的使用,避免栈溢出错误。在函数尾部,直接return 函数调用结果。引擎进行的自动优化。

    function factorial(n, p = 1){

    if(n <= 1){

    return 1*p;

    }else{

    let result = n*p;

    return factorial(n -1, result);  // 优于 return n*factorial(n -1);

    }

    }

     

    4.扩展对象的功能性

    对象字面量:

    function createPerson(id, name){

    return {  //当属性名与值名字相同,可以不用写冒号

        id,

            name,

        }

    }

    var person = {

    id: '123',

      sayName(){   //消除了冒号和function关键字

        console.log(this.name);

        }

    }

    let lastName = "last name";

    let person = {

    "first name" : 'taoli',

        [lastName]: 'du', // 在对象字面量中使用[],表示该属性名是可以计算的,它的内容被求值并转换为一个字符串。

    }

     

    ES6 在全局Object上引入了新方法:

    Object.is() 弥补全等运算符的不准确计算 +0 === -0 //true Object.is(+0, -0)//false   NaN === NaN //false Object.is(NaN, NaN) // true  除了这两个特例,剩下的基本和 === 返回结果一致

    Object.assign() 接受一个接收对象和任意淑玲的源对象,最终返回接收对象。可以代替ES5中的maxin() 方法

    ES6 清晰的定义了枚举类型的枚举顺序,先数字升序,再字母,按照插入的先后顺序排列。

    Object.getPrototypeOf()

    Object.setPrototypeOf(a, b) //改变a 的原型为 b 对象创建后,用此方法修改它的原型

     

    super 便捷地访问原型对象原型  super 就是 Object.getPrototypeof(this)的值,使用super时,此时的this会被自动设置为当前作用域的this值。

     

    5.解构:使数据访问更便捷

    对象解构:根据对象字面量,读取相应的属性名称。注意,使用 var,let或const 解构声明变量时,必须提供初始化值。如果不适用解构赋值,只有const定义必须初始化。

    数组解构:按顺序对应赋值,eg, let a =1;b=2; [a, b] = [b, a];实现两个数的交换。嵌套数组解构,不定元素解构,不定元素必须是数组的最后一个条目。

    解构的混合应用: 对象解构和数组解构嵌套混合使用赋值。

    在对象和解构赋值中,都可以为值为null/undefined的对象数组或数组元素指定默认值。

    let node = {

    type : 'identifier',

      name: 'foo',

      loc: {

        start: {

            line: 1,

              column: 1

            },

          end:{

          line: 1,

              column: 4

          }

        },

      range: [0, 3]

    }

     

    let {

    loc: { start },

        range: [ startIndex ]

    } = node;

     

    console.log(start.line); //1

    console.log(start.column); //1

    console.log(startIndex);//0

     

    6.Symbol和Symbol属性

    ES6 为 JavaScript 引入了一种新的基本类型:Symbol,它由全局 Symbol() 函数创建,每次调用 Symbol()函数,都会返回一个唯一的 Symbol

    所有可以计算属性名的地方都可以用Symbol。

    Symbol 是 JavaScript 中的新原始类型。console.log(typeof symbol) //Symbol

    let uid = Symbol.for(‘uid’);//Symbol.for() 创建之前会去全局Symbol注册表中搜索,如果有,就是用已建的,没有就创建新的Symbol

    Symbol.keyFor(‘uid’) //‘uid’ /undefined Symbol.keyFor() 在Symbol全局注册表中检索与Symbol有关的键

    Symbol不能和其他类型进行转换/强制转换,会报错

    Object.getOwnProperty-Symbol() 来检索Symbol属性

    Object.getOwnPropertySymbol() 返回Symbol自有属性数组

    well-known Symbol定义了一些语言内部可用的功能,eg. Symbol.hasInstance 属性,需要再去查阅。

     

    7.Set集合和Map集合

    一般来说,Set集合常被用于检查对象中是否存在某个键名,而Map集合常被用于获取已存信息。

    ES6中的Set集合: 是一种有序列表,其中含有一些相互独立的非重复值

    let set = new Set();

    set.add(5);

    set.add(‘5’);

    console.log(set.size); //2

    set.add(5); //重复add的值,实际调用会被忽略

    let set = new Set([1,2,3,4,5,5,5,5]); console.log(set.size);// 5  重复add的值,实际调用会被忽略

    不会对所存值进行强制类型转换

    let set = new Set(),

    key1 = {},

    key2 = {};

    set.add(key1);

    set.add(key2);

    cosole.log(set.size); //2  ES6 中不会key1,key2强转为字符串,因此在set集合中是两个独立的元素,而在ES5中会被转换,则两者的值“[object object]”,实际是同一个属性值

    set.has(5); // true  has()方法检测set集合中是否存在某个值

    set.delete(5); //delete()方法移除Set集合中的某个元素

    set.clear(); //clear()方法清除Set集合中的元素

    Set集合和数组之间的转换:

    let set = new Set([1,2,3,3,4,4,5]), //去掉了重复了值

    array = […set]; //用展开运算符,很容易将set转换为array

    console.log(array); //[1,2,3,4,5]

    Weak set: 解决清除了对初始对象的引用,但Set集合缺保留着引用,而引起的一些内存泄漏问题。

    创建Weak Set 集合:

    let set = new WeakSet(),

    key = {};

    set.add(key);

    key = null;

    //console.log(set.has(key));// false

    WeakSet 和Set的一些区别:

    . 在weakSet的实例中,如果向 add(), has()和delete()这三个方法传入非对象参数都会导致程序出错。

    .Weak Set 集合不可迭代,所以不能被用于for-of循环

    .没有keys(),values()等任何迭代器,所以无法通过程序本身来检测其中的内容。

    .不支持forEach()方法

    .不支持size()属性

    Map集合的初始化方法

    let map = new Map([[‘name’, ‘dtl’], [‘age’, 18]]);

    同样:map.set(key,value);

      map.delete(key);

    map.clear(); //清除所有键值对

    也可以用对象作为Map的key, 在对象中,是不能用对象作为对象的属性名。

    let set = new Set([1, 2]);

    forEach 方法都支持传入三个参数:

    set.forEach(function(value, key, ownerset){  //set中的 value === key

      console.log(key + ' ' + value);

      console.log(ownerSet === set);

    });

     

    let map = new Map([['name', 'dtl'], ['age', 18]]);

    map.forEach(function(value, key, ownerMap){

      console.log(key + ' ' + value);

      console.log(ownerMap === map);

    });

    WeakMap集合  支持 has(key), 和delete(key)方法判断和移除key,value.

    如果只用对象作为key, WeakMap集合将是最好的选择,当数组再也不可访问后集合中存储的相关引用和数据会被自动回收。但是WeakMap不支持forEach(),size,clear()来管理元素,对用户的能见度较低。

    如果使用费对象的kay,那就选择Map集合。   

    Set 集合的值和Map集合的key 的等价性都是通过Object.is()来判断。如果相同,会高滤掉重复的值。

     

    8.  ES6中的迭代器(Iterator)和生成器(Generator)

    迭代器(Iterator): 迭代器是一种特殊对象,它具有一些专门为迭代过程设计的专有接口,所有的迭代器对象都有一个next()方法,每次调用都返回一个结果对象。结果对象有两个属性:一个是value,表示下一个将要返回的值;另一个是done,它是一个布尔类型的值,当没有更多可返回数据时返回true,如果没有相关数据则返回undefined 。迭代器还会保存一个内部指针,用来指向当前集合中值的位置,每调用一次next()方法,都会返回下一个可用的值。

    生成器(Generator): 是来返回迭代器的函数。

    function关键字后的星号(*)来表示,函数中会用到新的关键字yield。星号可以紧挨着function关键字,也可以在中间添加一个空格。

    function *createGenerator(){

        yield 1;

        yield 2;

        yield 3;

    }

    // 生成器能像正规函数那样被调用,但会返回一个迭代器

    let iterator = createIterator();

    console.log(iterator.next().value); // 1

    console.log(iterator.next().value); // 2

    console.log(iterator.next().value); // 3

    只会在调用迭代器的next()方法时,返回yield的值。并且yield只能在迭代器的主函数中有效,不能嵌套在语句里,会报错。(yield关键字只可在生成器内部使用,在其他地方使用会导致程序抛出错误)

    生成器函数表达式,function与次奥括号之间添加一个* 号。

    let createIterator = function *(items) {

        for (let i = 0; i < items.length; i++) {

            yield items[i];

        }

    };

    生成器对象方法:

    var o = {

        *createIterator(items) {

                for (let i = 0; i < items.length; i++) {

                    yield items[i];

                }

            }

    };

    let iterator = o.createIterator([1, 2, 3]);

     

    可迭代对象具有Symbol.iterator属性,是一种与迭代器密切相关的对象。在ES6中,所有的集合对象(数组、Set集合及Map集合)和字符串都是可迭代对象,这些对象中都有默认的迭代器。

    let values = [1, 2, 3];

    let iterator = values[Symbol.iterator]();

    console.log(iterator.next()); // "{ value: 1, done: false }"

    console.log(iterator.next()); // "{ value: 2, done: false }"

    console.log(iterator.next()); // "{ value: 3, done: false }"

    console.log(iterator.next()); // "{ value: undefined, done: true }"

    创建可迭代对象:

    默认情况下,开发者定义的对象都是不可迭代对象,但如果给Symbol.iterator属性添加一个生成器,则可以将其变为可迭代对象。

    let collection = {

        items: [],

        *[Symbol.iterator]() {

            for (let item of this.items) {

                yield item;

            }

        }

    };

    collection.items.push(1);

    collection.items.push(2);

    collection.items.push(3);

    for (let x of collection) {

        //1

        //2

        //3

        console.log(x);

    }

    在数组字面量对此使用展开运算符,将可迭代对象的多个元素依次插入新数组中,替换原先展开运算符所在的位置。

    let smallNumbers = [1, 2, 3],

    bigNumbers = [100, 101, 102],

    allNumbers = [0, ...smallNumbers, ...bigNumbers];

    console.log(allNumbers.length); // 7

    console.log(allNumbers); // [0, 1, 2, 3, 100, 101, 102]

     内建迭代器:

    1.集合对象迭代器: 数组,Map集合,Set集合

    内建了三种迭代器:

    entries() 返回一个迭代器,其值为对个键值对

    values() 返回一个迭代器,其值为集合的值

    keys() 返回一个迭代器,其值为集合中的所有键名

    let colors = [ "red", "green", "blue" ];

    let tracking = new Set([1234, 5678, 9012]);

    let data = new Map();

    data.set("title", "Understanding ES6");

    data.set("format", "ebook");

    for (let entry of colors.entries()) {  

        console.log(entry);  //[0, red][1, green],[2,blue]

    }

    for (let entry of tracking.entries()) {

        console.log(entry); //[1234,1234] [5678, 5678] [9012, 9012]

    }

    for (let entry of data.entries()) {

        console.log(entry); //[“title”, “Understanding ES6”] [“format”,”ebook”]

    }

    for (let entry of colors.values()) {  

        console.log(entry);  //“red” “green” “blue”

    }

    for (let entry of tracking.values()) {

        console.log(entry); //“1234” “5678” “9012”

    }

    for (let entry of data.values()) {

        console.log(entry); //“Understanding ES6” ”ebook”

    }

    for (let entry of colors.keys()) {  

        console.log(entry);  //0 1 2

    }

    for (let entry of tracking.keys()) {

        console.log(entry); //1234 5678 9012

    }

    for (let entry of data.keys()) {

        console.log(entry); //“title” “format”

    }

    2.字符串迭代器 for of 循环输出正确的内容

    3.NodeList迭代器 for of 循环输出正确的内容

     

    9.类的访问器属性

    let propertyName = “html”;

    class CustomHtmlElement {

    constructor(element) {

    this.element = element;

    }

    get [propertyName] () { //用[] 包裹起来,就是可计算名称

    return this.element.innerHTML;

    }

    set [propertyName] () {

    return this.element.innerHTML = value;

    }

    }

     

    类中的所有方法和访问器属性都可以添加static,除了构造函数之外。

    不可在实例中访问静态成员,必须要在类中访问静态成员。

    继承和派生类:

    class Rectangle

    class Square extends  Rectangle 

    使用super()可访问基类的构造函数,需注意以下几点:

    1.只可在派生类(extends 声明的类)的构造函数中使用super()

    2.在构造函数访问this之前一定要调用super()

    3.如果不想调用super(),则唯一的方法就是让类的构造函数返回一个对象

     

    10.改进的数组功能

    ES6 增加了Array.of() 和Array.from() 方法

    查找数组中匹配的元素:

    find() 返回查到的值

    findIndex() 返回查到值的索引

    查找与某个值匹配的元素:

    indexOf()和lastIndexOf()

    fill()用指定的值填充数组中一到多个元素

    eg.  let number = [1,2,3,4];

    number.fill(1);

    Console.log(numbers.toString()); //1,1,1,1

    let number = [1,2,3,4];

    number.fill(1,2);

    Console.log(number.toString());//1,2,1,1  从索引2开始填充元素,到number.length结束

    number.fill(0,1,3);

    console.log(numbers.toString()); //1,0,0,1  索引1和2的元素填充0

    copyWithin(a, b, [c]) 方法 a:开始填充值的索引位置 b:开始复制值的索引位置 [c]:到该索引停止赋值

    eg. Let numbers = [1, 2, 3, 4]; numbers.copyWithin(2, 0); console.log(numbers.toString());// 1,2,1,2

    numbers.copyWithin(2, 0, 1); //1,2,1,4 

    了解定型数组

     

    11.Promise 与异步编程

    promise的生命周期: pending(进行中), fulfilled(已完成),rejected(已拒绝)

    Promise.resolve() 

    Promise.reject()

    Promise 链操作,并且传递返回值给下一个promise, 看下面的例子:

    let p1 = new Promise(function(resolve, reject){

    resolve(42);

    });

    p1.then(function(value){

    console.log(value);// 42

    return value+1;

    }).then(function(value){

    console.log(value); //43

    })

     

    也可以返回promise对象,在一个promise执行成功后,创建另一个promise,然后调用

    let p1 = new Promise(function(resolve,reject){

    resolve(42);

    });

     

    P1.then(function(value){

    console.log(value); //42

     

    let p2 = new Promise(function(resolve, reject){

    resolve(43);

    })

    return p2;

    }).then(function(value){

    console.log(value);//43

    })

     

    直到p2处理完成后,才处理第二个处理程序

     

    响应多个Promise

    Promise.all() 方法 只接受一个参数,并且返回一个Promise,该参数是一个含有多个受监视的promise可迭代对象,只有可迭代对象中的promise全部处理完成,最后的promise才会执行

    let p1 = new promise(function(resolve,reject){

    resolve(42);

    });

     

    Let p2 = new Promise(function(resolve,reject){

    resolve(43);

    });

     

    Let p3 = new Promise(function(resolve.reject){

    resolve(44);

    });

     

    Let p4 = Promise.all([p1,p2,p3]);

    P4.then(function(value){

    console.log(Array.isArray(value)); //true

    console.log(value[0]);//42

    console.log(value[1]);//43

    console.log(value[2]);//44

    });

     

    Promise迭代对象中只要有一个被拒绝,不等其他执行完成,都全部拒绝。

     

    let p1 = new promise(function(resolve,reject){

    resolve(42);

    });

     

    Let p2 = new Promise(function(resolve,reject){

    reject(43);

    });

     

    Let p3 = new Promise(function(resolve.reject){

    resolve(44);

    });

     

    Let p4 = Promise.all([p1,p2,p3]);

    P4.then(function(value){

    console.log(Array.isArray(value)); //false

    console.log(value);//42

    });

     

     

    Promise.race() 方法和promise.all()的区别就是,只要promise迭代对象中有一个解决,那么无需等待其他promise解决,就返回,会竞选,如果p2先完成,则返回拒绝的promise,如果跑先完成,返回已完成的promise.

     

    let p1 = new promise(function(resolve,reject){

    resolve(42);

    });

     

    Let p2 = new Promise(function(resolve,reject){

    reject(43);

    });

     

    Let p3 = new Promise(function(resolve.reject){

    resolve(44);

    });

     

    Let p4 = Promise.race([p1,p2,p3]);

    P4.then(function(value){

    console.log(value);//42

    });

     

     

     

     

  • 相关阅读:
    lnmp yum源的安装自己总结。
    bootstrap 表单validator与ajax验证!!!!
    laravel5.4 安装
    学习进度条
    作业8:单元测试练习(个人练习)
    作业7: 用户体验设计案例分析
    学生成绩录入系统设计与实现(1)
    作业5:需求分析
    结对项目—— 词频统计
    结对项目—— 词频统计
  • 原文地址:https://www.cnblogs.com/torri/p/6894382.html
Copyright © 2020-2023  润新知