精华内容
下载资源
问答
  • ES6 新特性

    千次阅读 多人点赞 2019-08-11 20:31:12
    现在使用主流的前端框架中,如ReactJS、Vue.js、angularjs等,都会使用到ES6新特性,作为一名高级工程师而言,ES6也就成为了必修课,所以本套课程先以ES6新特性开始。 1.1、了解ES6 ES6,是ECMAScript 6的简称,...

    1 、ES6 新特性

    现在使用主流的前端框架中,如ReactJS、Vue.js、angularjs等,都会使用到ES6的新特性,作为一名高级工程师而言,ES6也就成为了必修课,所以本套课程先以ES6的新特性开始。

    1.1、了解ES6

    ES6,是ECMAScript 6的简称,它是 JavaScript 语言的下一代标准,己于 2015 年 6 月正式发 布。
    它的目标是使 JavaScript语言可以用于编写复杂的大型应用程序,成为企业级开发语言。

    1.1.1.什么是ECMAScript?

    来看下前端的发展历程:

    • web1.0时代:

      最初的网页以 HTML为主,是纯静态的网页。网页是只读的,信息流只能从服务的到客户端单向流通。开发人员
      也只关心页面的样式和内容即可。

    • web2.0时代:

      1995 年,网景工程师Brendan Eich 花了10天时间设计了JavaScript语言。
      1996 年,微软发布了JScript,其实是JavaScript的逆向工程实现。
      1997 年,为了统一各种不同script脚本语言,ECMA(欧洲计算机制造商协会)以JavaScript为基础,制定了
      ECMAscript 标准规范。JavaScript和JScript都是 ECMAScript 的标准实现者,随后各大浏览器厂商纷纷实现了
      ECMAScript 标准。

    所以,ECMAScript是浏览器脚本语言的规范,而各种我们熟知的js语言,如JavaScript则是规范的具体实现。

    1.1.2.ECMAScript的快速发展

    而后,ECMAScript就进入了快速发展期。

    • 1998 年6月,ECMAScript 2.0 发布。

    • 1999 年12月,ECMAScript 3.0 发布。这时,ECMAScript 规范本身也相对比较完善和稳定了,但是接下来的事情,就比较悲剧了。

    • 2007 年10月。。。。ECMAScript 4.0 草案发布。
      这次的新规范,历时颇久,规范的新内容也有了很多争议。在制定ES4的时候,是分成了两个工作组同时工作的。

      一边是以 Adobe, Mozilla, Opera 和 Google为主的 ECMAScript 4 工作组。
      一边是以 Microsoft 和 Yahoo 为主的 ECMAScript 3.1 工作组。

    ECMAScript 4 的很多主张比较激进,改动较大。而 ECMAScript 3.1 则主张小幅更新。最终经过 TC39 的会
    议,决定将一部分不那么激进的改动保留发布为 ECMAScript 3.1,而ES4的内容,则延续到了后来的
    ECMAScript5和6版本中

    • 2009 年12月,ECMAScript 5 发布。
    • 2011 年6月,ECMAScript 5.1 发布。
    • 2015 年6月,ECMAScript 6,也就是 ECMAScript 2015 发布了。 并且从 ECMAScript 6 开始,开始采用年号来做版本。即 ECMAScript 2015,就是ECMAScript6。
    • 2016 年 6月,小幅修订的《ECMAScript 2016标准》 (简称 ES2016)如期发布, 这个版本可以看作是 ES6.1版,因为两者的差异非常小(只新增了数组实例的 includes 方法 和指数运算符),基本上可以认为是同 一个标准 。
    • 2017 年 6 月发布了ES2017 标准。

    因此, ES6 既是一个历史名词,也是一个泛指,含义是 5.1 版本以后的 JavaScript 的下一代 标准,涵盖了 ES2015、ES2016、 ES2017 等,而 ES2015 则是正式名称,特指当年发布的正式 版本的语言标准

    1.2、let 和 const 命令

    • var
      之前,我们写js定义变量的时候,只有一个关键字: var
      var 有一个问题,就是定义的变量有时会莫名奇妙的成为全局变量。
      例如这样的一段代码:
    for (var i = 0; i < 5; i++){
      console.log(i);
    }
    console.log("循环外:" + i)
    

    运行打印的结果是如下:
    在这里插入图片描述
    可以看出,在循环外部也可以获取到变量 i的值,显然变量i的作用域范围太大了,在做复杂页面时,会带来很大的问题。

    • let
      let 所声明的变量,只在 let 命令所在的代码块内有效。
      我们把刚才的 var 改成 let 试试:
    for (let i = 0; i < 5; i++){
      console.log(i);
    }
    console.log("循环外:" + i)
    

    结果:
    在这里插入图片描述这样,就把变量的 i的作用域控制在了循环内部。

    • const
      const 声明的变量是常量,不能被修改,类似于java中final关键字。
      const a = 1;
      console.log("a = ", a);
      //给a重新赋值
      a = 2;
      console.log("a = ", a);
    

    在这里插入图片描述
    可以看到,变量 a的值是不能修改的。

    1.3、字符串扩展

    在ES6中,为字符串扩展了几个新的API:
    includes() :返回布尔值,表示是否找到了参数字符串。
    startsWith() :返回布尔值,表示参数字符串是否在原字符串的头部。
    endsWith() :返回布尔值,表示参数字符串是否在原字符串的尾部。
    实验一下:

    < script>
      let str = "hello heima";
      console.log(str, " 中是否包含了heima => ", str.includes("heima"));
      console.log(str, " 中是否包含了baima => ", str.includes("baima"));
      console.log(str, " 中是否以h开头 => ", str.startsWith("h"));
      console.log(str, " 中是否以a开头 => ", str.startsWith("a"));
      console.log(str, " 中是否以a结束 => ", str.endsWith("a"));
      console.log(str, " 中是否以h结束 => ", str.endsWith("h"));
    </script>
    

    在这里插入图片描述

    • 字符串模板
      ES6中提供了`来作为字符串模板标记。我们可以这么玩:
    < script>
      let str = `
      hello
      itheima
      itcast
      `;
      console.log(str);
    </script>
    
    

    在这里插入图片描述
    在两个 `之间的部分都会被作为字符串的值,可以任意换行。

    1.3 、解构表达式

    什么是解构? – ES6中允许按照一定模式从数组和对象中提取值,然后对变量进行赋值,这被称为解构 (
    Destructuring)。

    1.3.1、数组解构

    比如有一个数组:

    let arr = [1,2,3] 
    

    之前,我想获取其中的值,只能通过角标。ES6可以这样:

       let arr = [1,2,3]
      const [x,y,z] = arr;// x,y,z将与arr中的每个位置对应来取值
      // 然后打印
      console.log(x,y,z);
      const [a] = arr; //只匹配1个参数
      console.log(a);
    

    结果:
    在这里插入图片描述

    1.3.2、对象解构

    例如有个person对象:

    const person = {
      name:"jack",
      age:21,
      language: ['java','js','css']
    }
    

    我们可以这么做:

    //  解构表达式获取值
    const {name,age,language} = person;
    // 打印
    console.log(name);
    console.log(age);
    console.log(language);
    

    结果:
    在这里插入图片描述
    如过想要用其它变量接收,需要额外指定别名:
    在这里插入图片描述

    {name:n} :name是person中的属性名,冒号后面的n是解构后要赋值给的变量。
    

    1.4、函数优化

    在ES6中,对函数的操作做了优化,使得我们在操作函数时更加的便捷。

    1.4.1、函数参数默认值

    在ES6以前,我们无法给一个函数参数设置默认值,只能采用变通写法:

     function add(a , b) {
        // 判断b是否为空,为空就给默认值1
        b = b || 1;
        return a + b;
     }
      // 传一个参数
      console.log(add(10));
    

    现在可以这么写:

    function add(a , b = 1) {
      return a + b;
    }
    // 传一个参数
    console.log(add(10));
    

    1.4.2、箭头函数

    ES6中定义函数的简写方式:
    一个参数时:

    var print = function (obj) {
      console.log(obj);
    }
    // 简写为:
    var print2 = obj => console.log(obj);
    

    多个参数:

    //  两个参数的情况:
    var sum = function (a , b) {
      return a + b;
    }
    // 简写为:
    var sum2 = (a,b) => a+b;
    

    // 没有参数时,需要通过()进行占位,代表参数部分

    let sayHello = () => console.log("hello!");
    sayHello();
    

    代码不止一行,可以用 {} 括起来。

    var sum3 = (a,b) => {
      return a + b;
    }
    // 多行,没有返回值
    let sayHello = () => {
      console.log("hello!");
      console.log("world!");
    }
    sayHello();
    

    1.4.3、对象的函数属性简写

    比如一个Person对象,里面有eat方法:

    let person = {
      name: "jack",
      // 以前:
      eat: function (food) {
        console.log(this.name + "在吃" + food);
     },
      // 箭头函数版:
      eat2: food => console.log(person.name + "在吃" + food),// 这里拿不到this
      // 简写版:
      eat3(food){
        console.log(this.name + "在吃" + food);
     }
    }
    

    1.4.4、箭头函数结合解构表达式

    比如有一个函数:

    const person = {
      name:"jack",
      age:21,
      language: ['java','js','css']
    }
    function hello(person) {
      console.log("hello," + person.name)
    }
    

    如果用箭头函数和解构表达式

    var hi = ({name}) =>  console.log("hello," + name);
    hi(person)
    

    1.5、map和reduce

    ES6中,数组新增了map和reduce方法。

    1.5.1、map

    map() :接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回。
    举例:有一个字符串数组,我们希望转为int数组

    let arr = ['1','20','-5','3'];
    console.log(arr)
    let newArr = arr.map(s => parseInt(s));
    console.log(newArr)
    

    在这里插入图片描述

    1.5.1、reduce

    reduce() :接收一个函数(必须)和一个初始值(可选),该函数接收两个参数:

    • 第一个参数是上一次 reduce处理的结果
    • 第二个参数是数组中要处理的下一个元素

    reduce() 会从左到右依次把数组中的元素用reduce处理,并把处理的结果作为下次reduce的第一个参数。如果是
    第一次,会把前两个元素作为计算参数,或者把用户指定的初始值作为起始参数
    举例:

    const arr = [1,20,-5,3] 
    

    没有初始值:
    在这里插入图片描述
    指定初始值:
    在这里插入图片描述

    1.6 、扩展运算符

    扩展运算符(spread)是三个点(…), 将一个数组转为用逗号分隔的参数序列 。
    用法:

      console.log (...[1, 2, 3]); //1 2 3
      console.log(1, ...[2, 3, 4], 5); // 1 2 3 4 5
      function add(x, y) {
        return x + y;
     }
      var numbers = [1, 2];
      console.log(add(...numbers)); // 3
      // 数组合并
      let arr = [...[1,2,3],...[4,5,6]];
      console.log(arr); //[1, 2, 3, 4, 5, 6]
      // 与解构表达式结合
      const [first, ...rest] = [1, 2, 3, 4, 5];
      console.log(first, rest) //1  [2, 3, 4, 5]
      //将字符串转成数组
      console.log([...'hello']) //["h", "e", "l", "l", "o"]
    

    1.7、Promise

    所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法
    上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样
    的方法进行处理。
    我们可以通过Promise的构造函数来创建Promise对象,并在内部封装一个异步执行的结果。
    语法:

    const promise = new Promise(function(resolve, reject) {
     // ... 执行异步操作
     if (/* 异步操作成功 */){
      resolve(value);// 调用resolve,代表Promise将返回成功的结果
    } else {
      reject(error);// 调用reject,代表Promise会返回失败结果
    }
    });
    

    这样,在promise中就封装了一段异步执行的结果。
    如果我们想要等待异步执行完成,做一些事情,我们可以通过 promise的then方法来实现,语法:

    promise .then(function(value){
      // 异步执行成功后的回调
    });
    

    如果想要处理promise异步执行失败的事件,还可以跟上catch:

    promise .then(function(value){
      // 异步执行成功后的回调
    }).catch(function(error){
      // 异步执行失败后的回调
    })
    

    示例:

    const p = new Promise(function (resolve, reject) {
      // 这里我们用定时任务模拟异步
      setTimeout(() => {
        const num = Math.random();
        // 随机返回成功或失败
        if (num < 0.5) {
          resolve("成功!num:" + num)
       } else {
          reject("出错了!num:" + num)
       }
     }, 300)
    })
    // 调用promise
    p.then(function (msg) {
      console.log(msg);
    }).catch(function (msg) {
      console.log(msg);
    })
    

    结果:
    在这里插入图片描述
    在这里插入图片描述

    1.8 、set和map

    ES6提供了Set和Map的数据结构。
    Set,本质与数组类似。不同在于Set中只能保存不同元素,如果元素相同会被忽略。和java中的Set集合非常相似。
    构造函数:

    // Set 构造函数可以接收一个数组或空
    let set = new Set();
    set.add(1);// [1]
    // 接收数组
    let set2 = new Set([2,3,4,5,5]);// 得到[2,3,4,5]
    

    方法:

    *set.add(1);//  添加
    set.clear();// 清空
    set.delete(2);// 删除指定元素
    set.has(2); // 判断是否存在
    set.forEach(function(){})//遍历元素
    set.size; // 元素个数。是属性,不是方法。*
    

    map,本质是与Object类似的结构。不同在于,Object强制规定key只能是字符串。而Map结构的key可以是任意对象。即:
    object 是 <string,object>集合
    map 是<object,object>集合
    构造函数:

    // map 接收一个数组,数组中的元素是键值对数组
    const map = new Map([
     ['key1','value1'],
     ['key2','value2'],
    ])
    // 或者接收一个set
    const set = new Set([
     ['key1','value1'],
     ['key2','value2'],
    ])
    const map2 = new Map(set)
    // 或者其它map
    const map3 = new Map(map);
    

    方法:

    map .set(key, value);// 添加
    map.clear();// 清空
    map.delete(key);// 删除指定元素
    map.has(key); // 判断是否存在
    map.forEach(function(key,value){})//遍历元素
    map.size; // 元素个数。是属性,不是方法
    map.values() //获取value的迭代器
    map.keys() //获取key的迭代器
    map.entries() //获取entry的迭代器
    用法:
    for (let key of map.keys()) {
    console.log(key);
    }
    或:
    console.log(...map.values()); //通过扩展运算符进行展开
    

    1.9、class(类)的基本语法

    JavaScript 语言的传统方法是通过构造函数定义井生成新对象。ES6中引入了class的概念,通过class关键字自定义
    类。
    基本用法:

    < script>
      class User{
        constructor(name, age = 20){ // 构造方法
          this.name = name; // 添加属性并且赋值
          this.age = age;
       }
        sayHello(){ // 定义方法
          return "hello";
       }
        static isAdult(age){ //静态方法
          if(age >= 18){
            return "成年人";
         }
          return "未成年人";
       }
     }
      let user = new User("张三");
      // 测试
      console.log(user); // User {name: "张三", age: 20}
      console.log(user.sayHello()); // hello
      console.log(User.isAdult(20)); // 成年人
    </script>
    

    类的继承:

    < script>
      class User{
        constructor(name, age = 20){ // 构造方法
          this.name = name; // 添加属性并且赋值
          this.age = age;
       }
        sayHello(){
          return "hello"; // 定义方法
       }
        static isAdult(age){ //静态方法
          if(age >= 18){
            return "成年人";
         }
          return "未成年人";
       }
     }
      class ZhangSan extends User{
        constructor(){
          super("张三", 30); //如果父类中的构造方法有参数,那么子类必须通过super调用父类的构造
    方法
          this.address = "上海";//设置子类中的属性,位置必须处于super下面
       }
     }
      // 测试
      let zs = new ZhangSan();
      console.log(zs.name, zs.address);
      console.log(zs.sayHello());
      console.log(ZhangSan.isAdult(20));
      < /script>
    

    1.10、Generator函数

    Generator 函数是 ES6 提供的 一种异步编程解决方案,语法行为与传统函数完全不同 。
    Generator函数有两个特征: 一是 function命令与函数名 之间有一个星号: 二是 函数体内部使用 yield吾句定义不同的
    内部状态。
    用法:

    < script>
      function* hello () {
        yield "hello";
        yield "world";
        return "done";
     }
      let h = hello();
     
      console.log(h.next()); //{value: "hello", done: false}
      console.log(h.next()); //{value: "world", done: false}
      console.log(h.next()); //{value: "done", done: true}
      console.log(h.next()); //{value: undefined, done: true}
    </script>
    

    可以看到,通过hello()返回的h对象,每调用一次next()方法返回一个对象,该对象包含了value值和done状态。直到遇到return关键字或者函数执行完毕,这个时候返回的状态为ture,表示已经执行结束了。

    1.10.1、for…of循环

    通过for…of可以循环遍历Generator函数返回的迭代器。
    用法:

    < script>
      function* hello () {
        yield "hello";
        yield "world";
        return "done";
     }
      let h = hello();
      for (let obj of h) {
        console.log(obj);
     }
     < /script>
    // 输出:
    hello
    world
    

    1.11、修饰器(Decorator)

    修饰器(Decorator)是一个函数, 用来修改类的行为。 ES2017 引入了这项功能, 目前 Babel 转码器己经支持。
    使用:

    < script>
      @T //通过@符号进行引用该方法,类似java中的注解
      class User {
        constructor(name, age = 20){
          this.name = name;
          this.age = age;
       }
     }
     
      function T(target) { //定义一个普通的方法
        console.log(target); //target对象为修饰的目标对象,这里是User对象
        target.country = "中国"; //为User类添加一个静态属性country
     }
      console.log(User.country); //打印出country属性值
    </script>
    

    运行报错:
    在这里插入图片描述
    原因是,在 ES6中,并没有支持该用法,在ES2017中才有,所以我们不能直接运行了,需要进行编码后再运行。
    转码的意思是:将ES6或ES2017转为ES5执行。类似这样:

    // 转码前
    input .map(item =>item + 1);
    //转码后
    input.map(function (item) {
      return item + 1;
    })
    
    展开全文
  • ES6新特性

    千次阅读 2020-03-02 14:57:01
    ES6新特性 ES6的常用新特性简介,全部特性可参阅 Ecma-International MDN ES6入门 ES6 教程 ES6全称ECMAScript 6.0,是JavaScript的下一个版本标准,2015.06发版。ECMAScript和 JavaScript的关系是,前者是后者的...

    ES6新特性

    ES6的常用新特性简介,全部特性可参阅 Ecma-International
    MDN
    ES6入门
    ES6 教程

    ES6全称ECMAScript 6.0,是JavaScript的下一个版本标准,2015.06发版。ECMAScriptJavaScript的关系是,前者是后者的规格,后者是前者的一种实现。

    let 与 const

    ES2015(ES6)新增加了两个重要的JavaScript关键字: letconst
    ES6明确规定,代码块内如果存在let或者 const,代码块会对这些命令声明的变量从块的开始就形成一个封闭作用域。代码块内,在声明变量之前使用它会报错,称为暂时性死区
    ES6的块级作用域必须有大括号,如果没有大括号,JavaScript引擎就认为不存在块级作用域。

    • for循环计数器很适合用let
    • letconst只能声明一次,var可以声明多次。
    • var会变量提升,letconst也存在变量提升但有所不同。
    • const声明一个只读的常量,一旦声明,常量的值就不能改变。
    • constlet在全局作用域中声明的变量不会挂载到window上。
    • letconst声明的变量只在其声明所在的代码块内有效,形成块级作用域。
    • const其实保证的不是变量的值不变,而是保证变量指向的内存地址所保存的数据不允许改动。对于基本数据类型numberstringboolean等,值就保存在变量指向的那个内存地址,因此const 声明的简单类型变量等同于常量。而引用类型objectarrayfunction等,变量指向的内存地址其实是保存了一个指向实际数据的指针,所以const只能保证指针是固定的,至于指针指向的数据结构变不变就无法控制了。

    解构赋值

    ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。

    let [a, b, c] = [1, 2, 3]; // 基本
    let [a, [[b], c]] = [1, [[2], 3]]; //嵌套
    let [a, , b] = [1, 2, 3]; // 可忽略
    let [a = 1, b] = []; // a = 1, b = undefined // 不完全解构
    let [a, ...b] = [1, 2, 3]; // 剩余运算符
    let [a, b, c, d, e] = 'hello'; // 字符串等
    let { a, b } = { a: 'aaa', b: 'bbb' }; // 对象模型的解构 前后两个kay需对应
    

    Symbol

    ES6引入了一种新的原始数据类型Symbol,表示独一无二的值,最大的用法是用来定义对象的唯一属性名。
    ES6数据类型除了NumberStringBooleanObjectnullundefined,还新增了 Symbol

    let s1 = Symbol("s");
    let s2 = Symbol("s");
    console.log(s1 === s2); //false
    

    Spread / Rest 操作符

    Spread用于将数组作为参数直接传入函数。

    var s = ['1', '2', '3'];
    function f(s1,s2,s3){
        console.log(`Hello ${s1},${s2},${s3}`); //ES6新增字符串中加入变量和表达式
    }
    f(...s); //Hello 1,2,3
    

    Rest用于函数传参传递数组。

    function f(...args){
        console.log(args);
    }
    f(1,2,3,4,5); //[1, 2, 3, 4, 5]
    

    箭头函数

    ES6中,箭头函数就是函数的一种简写形式,使用括号包裹参数,跟随一个 =>,紧接着是函数体,特别需要注意的是箭头函数是继承当前上下文的this关键字。

    var add = (a, b) => a + b;
    var show = a => console.log(a);
    var test = (a,b,c) => {console.log(a,b,c);return a+b+c;}
    add(1,1); //2
    show(1); //1
    test(1,1,1); //1 1 1
    

    参数默认值

    function f(a = 1){
        console.log(a);
    }
    f(); //1
    f(11); //11
    

    字符串拓展

    ES6之前判断字符串是否包含子串,用indexOf方法,ES6新增了子串的识别方法。

    • includes() 返回布尔值,判断是否找到参数字符串。
    • startsWith() 返回布尔值,判断参数字符串是否在原字符串的头部。
    • endsWith() 返回布尔值,判断参数字符串是否在原字符串的尾部。
    • repeat() 返回新的字符串,表示将字符串重复指定次数返回。
    • padStart() 返回新的字符串,表示用参数字符串从头部补全原字符串。
    • padEnd() 返回新的字符串,表示用参数字符串从尾部(右侧)补全原字符串。

    数值拓展

    • 二进制表示法新写法 前缀0b0B,例如console.log(0B11 === 3); //true
    • 八进制表示法新写法 前缀0o0O,例如console.log(0O11 === 9); //true
    • 常量Number.EPSILON,表示1与大于1的最小浮点数之间的差,值接近于 2.2204460492503130808472633361816E-16
    • Number.MAX_SAFE_INTEGER 表示在JavaScript中能够精确表示的最大安全整数。
    • Number.isFinite() 用于检查一个数值是否为有限的finite,即不是Infinity
    • Number.parseInt() 逐步减少全局方法,用于全局变量的模块化,方法的行为没有发生改变。

    数组拓展

    • Array.of() 将参数中所有值作为元素形成数组。
    • Array.from() 将类数组对象或可迭代对象转化为数组。
    • find() 查找数组中符合条件的元素,若有多个符合条件的元素,则返回第一个元素。
    • findIndex() 查找数组中符合条件的元素索引,若有多个符合条件的元素,则返回第一个元素索引。
    • fill() 将一定范围索引的数组元素内容填充为单个指定的值。
    • copyWithin() 将一定范围索引的数组元素修改为此数组另一指定范围索引的元素。
    • entries() 遍历键值对。
    • keys() 遍历键名。
    • values() 遍历键值。
    • includes() 数组是否包含指定值。
    • flat() 嵌套数组转一维数组。
    • flatMap() 先对数组中每个元素进行了处理,再对数组执行flat()方法。

    迭代器

    • Symbol.iterator 一个统一的接口,它的作用是使各种数据结构可被便捷的访问。
    • for of 是 ES6 新引入的循环,用于替代 for..inforEach()

    ES6提供了更接近传统语言的写法,引入了class这个概念,作为对象的模板。通过class关键字,可以定义类,与多数传统语言类似。不过,ES6class不是新的对象继承模型,它只是原型链的语法糖表现形式。

    class Me {
      constructor() {
        console.log("constructor");
      }
      study() {
        console.log('study');
      }
    }
    
    console.log(typeof Me); //function
    let me = new Me(); //constructor
    me.study(); //study
    

    Promise 对象

    Promise是异步编程的一种解决方案。
    从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。
    Promise异步操作有三种状态:pendingfulfilledrejected。除了异步操作的结果,任何其他操作都无法改变这个状态。
    then方法接收两个函数作为参数,第一个参数是Promise执行成功时的回调,第二个参数是 Promise执行失败时的回调,两个函数只会有一个被调用。

    const p1 = new Promise(function(resolve,reject){
        resolve('resolve');
    }); 
    const p2 = new Promise(function(resolve,reject){
        reject('reject');
    });
    p1.then(function(v){  
        console.log(v); //resolve
    });
    p2.then(function(v){ 
        console.log(v);
    },
    function(v){
        console.log(v); //reject
    });
    
    展开全文
  • es6 新特性

    2019-10-08 11:32:32
    title: es6 新特性 preview: imgs/preview/es6_1.jpg preview_text: es6 新特性 主要包含“类、模块化、箭头函数、函数参数默认值、模板字符串、解构赋值、延展操作符、对象属性简写、Promise、let与const” tags: -...

    title: es6 新特性
    preview: imgs/preview/es6_1.jpg
    preview_text: es6 新特性 主要包含“类、模块化、箭头函数、函数参数默认值、模板字符串、解构赋值、延展操作符、对象属性简写、Promise、let与const”
    tags:
    - javascript
    ---

    1. 类(class)

    这三个特性涉及了ES5中最令人头疼的的几个部分:原型、构造函数,继承...ES6提供了更接近传统语言的写法,引入了Class(类)这个概念。新的class写法让对象原型的写法更加清晰、更像面向对象编程的语法,也更加通俗易懂。

    class Animal {
      constructor(name, color) {  // 构造函数
        this.name = name;
        this.color = color;
      }
    
      toString() { // toString方法
          console.log(`name: ${this.name}, color: ${this.color}`);
      }
    
      getName() {  // 取值
        return this.name;
      }
      setName(value) { // 存值
        this.name = value;
      }
    
      getColor() {  // 取值
        return this.color;
      }
      setColor(value) { // 存值
        this.color = value;
      }
    }
    
    let animal = new Animal("cat", "white");
    animal.toString(); // name: cat, color: white
    
    console.log(animal.hasOwnProperty('name')) // true
    console.log(animal.hasOwnProperty('toString')) // false
    console.log(animal.__proto__.hasOwnProperty('toString')) // true

    2. super 和 extends

    使用新的super和extends关键字扩展类

    class Cat extends Animal {
      constructor(action = "catch thing",name, color) {
        super("cat", "black"); // super用作函数, 必须在this使用前调用
        this.action = action; // Cat 类本身属性
      }
    
      toString() {
        super.toString();// super用作对象
      }
    
      getAction() {
        return this.action;
      }
    
      setAction(value) {
          this.action = value;
      }
    }
    
    let cat = new Cat("eat fish");
    cat.toString(); // name: cat, color: white
    console.log(cat instanceOf Cat) // true
    console.log(cat instanceOf Animal) // true

    使用ES5编写同样功能的类

    function Animal(name, color) {
      this.name = name || "cat";
      this.color = color || "orange";
    }
    
    Animal.prototype.toString = function() {
      console.log(`name: ${this.name}, color: ${this.color}`);
    }
    
    function Cat (action, name, color) {
      Animal.call(this, name, color);
      this.action = action || "catch thing";
    }
    
    Cat.prototype = Object.create(Animal.prototype);
    Cat.prototype.constructor = Cat;
    
    Cat.prototype.toString = function() {
      Tree.prototype.toString.call(this);
    }
    
    Cat.prototype.setAction = function(value) {
      this.action = value;
    }

    3. 模块化(Module)

    es5不支持原生的模块化,在es6模块作为重要的组成部分被添加进来。模块的共能主要由export和import组成。每一个模块都有自己的单独的作用域,模块之间的调用是通过export来规定模块对外暴露的接口,通过import来引用其他模块提供的接口。同时模块还创造了命名空间,防止函数的命名冲突。

    导出(export)

    ES6允许在一个模块中使用export来导出多个变量和函数。

    导出变量
    export let varible = "test variable exprot";
    export default varible;
    let name = "cat";
    let color = "yellow";
    export {name, color}
    导出常量
    export const NUMBER_LENGTH = 20
    导出函数
    export function myModuleFn(somParams) {
        return somParams
    }

    导入(import)

    定义好模块的输出,就可以在另一个模块通过import导入

    import varible from "test.js"
    import {myModuleFn} from "myModuleFn";
    import {name, color} from "./path/to/test.js";

    4. 箭头函数(Arrow Function)

    =>不只是function的简写,它还带来了其他好处。箭头函数与包围它的代码共享同一个this,能够帮你解决this的指向问题。有经验的javaScript开发者都熟悉var self = this或var that = this这种引用外围的this的模式。但=>就不需要这种模式了。

    不论是箭头函数还是bind,每次被执行都返回的是一个新的函数引用,因此如果你还需要函数的引用去做别的一些事(如卸载监听器),那么你必须保存这个引用。

    箭头函数与普通函数的区别

    • 箭头函数是匿名函数,不能作为构造函数,不能使用new
    • 箭头函数不绑定arguments,取而代之用rest参数...解决
    • 箭头函数不绑定this,会捕获其所在的上下文的this值,作为自己的this值
    • 箭头函数通过 call() 或 apply() 方法调用一个函数时,只传入了一个参数,对 this 并没有影响。
    • 箭头函数没有原型属性
    • 箭头函数不能当做Generator函数,不能使用yield关键字
    • 箭头函数的 this 永远指向其上下文的 this ,任何方法都改变不了其指向,如 call() , bind() , apply()
      普通函数的this指向调用它的那个对象

    5. 模板字符串

    ES6支持模板字符串,使得字符串的拼接更加简洁、直观。

    • 不使用模板字符串
    var name = 'your name is ' + first + ' ' + last;
    • 使用模板字符串
    var name = `your name is ${first}  ${last}`;

    在ES6中通过${}就可以完成字符串拼接,只需要将变量放在大括号中。

    7. 解构赋值

    解构赋值语法是Javascript的一种表达式,可以方便的从数组或对象中快速提取值赋给定义的变量。

    获取数组的值

    从数据中获取值并赋值到的变量中,变量的顺序与数组中对象顺序对应

    var foo = [{"a": "one"}, "two", "three", "four"];
    var [one,  two, three] = foo;
    console.log(one, two, three)
    // 如果你要忽略某些值, 你可以按照下面的写法获取你想要的值
    var [first, , , last] = foo;
    console.log(first, last)
    
    var [a, b] = [1, 2]
    console.log(a, b)

    如果没有从数组中获取到值,可以为变量设置一个默认值。

    var a ,b;
    [a= 3, b=7]=[1]

    获取对象的值

    const student = {
      name: "Nyan",
      age: 27,
      city: "ShenZhen"
    }
    const {name, age, city} = student;
    console.log(name, age, city)

    8. 延展操作符(Spread operator)

    延展操作符...可以在函数调用/数组构造时,将数组表达式或者string在语法层面展开;还可以在构造对象时,将对象表达式按key-value方式展开。

    语法

    • 函数调用
    myFunction(...iterableObj)
    • 数组构造或字符串
    [...iterableObj, '4', ...'hello', 6]
    • 构造对象时,进行克隆或属性拷贝(ES2018)新增特性:
    let objClone = {...obj};

    应用场景

    • 在函数调用时使用延展操作符
    function (x, y, z) {
      return x + y + z;
    }
    const numbers= [1, 2, 3];
    console.log(sum.apply(null, numbers))
    console.log(sum(...numbers))
    • 构造数组
      没有延展操作符的时候,只能通过使用push, splice, concat等方法,来将已有的数组元素变成新数组的一部分。有了延展操作符,构造数组更加简单,优雅。
    const students = ["Jack", "Tom"];
    const persons = ["Jony", ...students, "Kin", "Anny"]
    console.log(persons)

    和参数列表的展开类似,...在构造数组时,可以任意位置多次使用。

    • 数组拷贝
    var arr = [1, 2, 4];
    var arr2 = [...arr]
    arr2.push(5)
    console.log(arr2)

    展开语法,与object.assign()行为一致,执行的是都是浅拷贝(只遍历一层)

    • 连接多个数组
    var arr3 = [...arr1, ...arr3]
    // 等同与
    var arr4 = arr1.concat(arr2)

    在ES2018中延展操作符增加了对对象的支持

    var obj1 = {foo: "baz", x: 12};
    var obj2 = {foo: "bar", y: 34};
    var cloneObj = {...obj1};
    var mergeObj = {...obj, ...obj2};
    console.log(obj1, obj2)
    • 在React中使用
      通常我们在封装一个组件时,会对外公开一些props用于实现功能。大部分情况下在外部使用都应显示传递的props.但是当传递大量的props时,会非常繁琐,这时我们可以使用...延展操作符,用于取出参数对象的所有可遍历属性,来进行传递
    • 一般情况下,我们这样传递
    <CustomComponent name="Nyan" age={27} />
    • 使用...,等同于上面的写法
    const params = {
      name: "name",
      age: 27
    }
    <CustomComponent {...params} />
    • 配合解构赋值避免传入一些不需要的参数
    const params = {
      name: "name",
      age: 27,
      type: "type Name"
      }
      var {type, ...other} = params;
    <CustomComponent {...other} />

    9. 对象属性的简写

    在ES6中允许我们在设置一个对象的属性的时候不指定属性名

    • 不使用es6
    const name= "name", age = 27
    const student = {name: name,age: age, getName: function(){}}

    对象必须包含属性和值,显得非常冗余

    • 使用Es6
    const name= "name", age = 27
    const student = {name,age, function getName(){}}

    10. Promise

    Promise是异步编程的一种解决方案,比传统的解决方案callback更加优雅。它最早由社区提出与实现,ES6将其写进了语言标准,统一了写法,原生提供了Promise对象。

    • 不使用ES6
    setTimeout(function(){
      console.log("promise test")
      setTimeout(function(){
      console.log("promise test 1")
      }, 1000)
    }, 1000)
    • 使用ES6
    var waitSecond = new Promise(function(resolve, reject){
      setTimeout(resolve, 1000)
    });
    waitSeccond
    .then(function(){
      console.log("promise test")
      return waitSecond
    }).then(function(){
      console.log("promise test 1")
    })

    转载于:https://www.cnblogs.com/Nyan-Workflow-FC/p/11291020.html

    展开全文
  • Es6新特性

    千次阅读 2021-01-02 18:54:51
    Es6新特性 模板字符串 传统字符串用法 const str = ‘hello world this is a string’ 模板字符串 const str = hello world this is a \string`console.log(str)//hello world this is astring` const str = hello ...

    Es6新特性

    模板字符串

    传统字符串用法

    const str = 'hello world this is a string'
    

    模板字符串

    const str = `hello world this is a \`string\``
    console.log(str)//hello world this is a `string`
    
    const str = `hello world
     this is a \`string\``
    console.log(str )
    //输出 hello world
     this is a \`string\`
     
    const name = 'tony'
    constr str = ` hey,${name}`
    console.log(str)//hey,tony
    

    带标签的模板字符串

    let data = console.log`hello world`
    console.log(data)//["hello world"]
    
    const name = 'tom'
    const gender = true
    function dealData(strings){
    	console.log(strings)//['hey ,', ' is a', '.']//用嵌入的表达式作为分隔符
    }
     dealData`hey , ${name} is a ${gender} .`
    
    const name = 'tom'
    const gender = true
    function dealData(strings,name,gender){
    	console.log(strings)//['hey ,', ' is a', '.']//用嵌入的表达式作为分隔符
    	console.log(name,gender)//tom true
    }
    const result = dealData`hey , ${name} is a ${gender} .`
    console.log(result)
    
    const name = 'tom'
    const gender = true
    function dealData(strings,name,gender){
    	//return '1243'
    	const sex = gender ? 'man' : 'woman'
    	return strings[0] + name + strings[1] + sex+ strings[2]
    	//目的是对模板字符串进行加工,让返回的结果更适合用户的阅读
    	// hey ,tom is a true.
    }
    const result = dealData`hey , ${name} is a ${gender} .`
    console.log(result)//1243
    

    字符串扩展方法

    includes  startwith endwith
    const msg ='Error foo is not defined .' 
    console.log(msg.includes('foo'))
    console.log(msg.startwith('error'))
    console.log(msg.endwith('.'))
    

    参数默认值

    //在形参的后面加一个等于号设置默认值
    function foo(fo,bar = true) {//如果参数较多的情况下,只能放在最后一位
    	console.log(false)//false 以为传入的实参是false,不是undefined或者没有传递
    }
    foo(false)//没有传递实参,或者实参是undefined才会被使用
    

    剩余参数

    function foo(...args){
    	console.log(args)//[1,2,3,4]
    }
    foo(1,2,3,4)
    
    function foo(first,...args){
    	console.log(args)//[2,3,4]
    }
    foo(1,2,3,4)
    

    展开数组

    const arr = ['foo','bar','styring']
    console.log(...arr)//foo bar styring
    

    对象字面量

    var bar = '124'
    var obj = {
    	name:'toney',
    	bar //bar:bar
    }
    console.log(obj.bar)
    
    var obj1 = {
    	name:'toney',
    	bar ,//bar:bar
    	//method:functiion(){
    	//	console.log(this)
    	//},
    	method(){
    		console.log(this)
    	}
    }
    console.log(obj1.method())
    

    Object.assign

    将源对象的属性赋值到目标对象中去

    var target = {
    	a:'121',
    	b:'212'
    }
    var source= {
    	a:'1211',
    	c:'111'
    }
    var source1= {
    	a:'1212',
    	d:'111'
    }
    var result = Object.assign(target , source, source1)
    console.log(result )
    //{
    //	a:'1212',
    //	b:'212',
    //	c:'111',
    //	d:'111'
    //}
    console.log(result  == target )//true
    

    Object.is

    console.log(Object.is(+0,-0))//false
    console.log(Object.is(Nan,Nan))//true
    

    Proxy

    代理对象
    监视某个对象中的属性读写
    可以使用ES5的Object.defineProperty为对象添加属性,Vue使用这个实现数据相应,从而实现数据的双向绑定
    Proxy专门为了给对象设置访问代理器的
    
    	var person = {
    		name:'tony',
    		age:20
    	}
    	//第一个参数是代理的处理对象,
    	const personProxy = new Proxy(person,{
    		//第一个参数代表目标对象,第二个是访问的属性名
    		get(target, property){//监视属性的访问
    			//console.log(target, property)
    			//return 100
    			return property in target ? target[property ] : 'default'
    		},
    		//第一个参数代表目标对象,第二个是写入的属性名称,第三个地表写入的值
    		set(target, property, value){//监视属性设置
    			//{name:'tony',age:20} gender true
    			//console.log(target, property, value)
    			if(property == 'age'){
    				if(!Number.isInteger(value)){/如果value不是Number类型报错
    					throw new Error (`${value} is not a int`)
    				}
    			}
    			target[property ] = value//给代理目标设置专门的属性
    		}
    	})
    	personProxy.gender = true
    	//{name:'tony',age:20} name
    	console.log(personProxy.name)//100
    

    Proxy与Object.defineProperty的区别

    Proxy的功能更为强大
    Object.defineProperty只能监听对象属性的读写,而Proxy不仅能监听对象的读写
    还能监听到更多对象操作,例如delete操作或者对象中方法的调用等

    var person ={
    	name:'ceshi',
    	age:20
    }
    const proxy = new Proxy(person, {
    	deleteProperty(person, property){
    		console.log(person,property)
    		delete person[property]
    	}
    })
    delete proxy.name
    console.log(person )
    

    在这里插入图片描述

    Proxy 更好支持数组对象的监视
    let list = []
    const listProxy = new Proxy(list,{
    	set(target, property, value){
    		console.log(target, property, value)
    		target[property] = value
    		return true
    	}
    }) 
    listProxy.push(100)
    // [] "0" 100
    // [100] "length" 1
    //get方法走了两边,set方法走了两边。因为push方法其实做了两步,第一是再length出加上push的值,第二是把length加一,所以走了两边。
    

    Proxy是以非侵入的方式监管对象的读写
    已经定义好的对象,不需要对对象做任何的操作就可以实现监听

    var person ={}
    Object.defineProperty(person,'name',{
    	get(){
    		console.log('name被访问')
    		return person._name
    	},
    	set(value){
    		console.log('name被设置')
    		person._name = value
    	}
    })
    Object.defineProperty(person,'age',{
    	get(){
    		console.log('age被访问')
    		return person._age
    	},
    	set(value){
    		console.log('age被设置')
    		person._age = value
    	}
    })
    person.name = 'jack'
    console.log(person)
    

    Relect

    ES6提供的一个静态类,是一个内置对象,统一对象操作Api
    不能通过new构建一个实例对象,只能调用静态类里的静态方法Relect.get()去调用
    内部封装了一系列对对象的底层操作(13个静态方法)

    内部成员方法是Proxy处理对象的默认实现

    const person = {
    	name:'tony',
    	age:20
    }
    const personProxy = new Proxy(person, {
    	get(target, property){
    		return Reflect.get(target, property)
    	}
    })
    console.log(personProxy.name)
    
    const person = {
    	name:'tony',
    	age:20
    }
    console.log('name' in person)
    console.log(Reflect.has(person,'name'))
    
    console.log(delete person['name'])
    console.log(Reflect.deletePorperty(person,'name'))
    
    consoe.log(Obejct.keys(person))
    consoe.log(Reflect.ownKeys(person))
    

    class

    function Person(name){
    	this.name = name
    }
    Person.prototype.say = function(){
    	console.log(`this is a name called ${this.name}`)
    }
    
    class Person{
    	constuctor(name){
    		this.name = name
    	}
    	say(){
    		console.log(`this is a name called ${this.name}`)
    	}
    }
    const p = new Person('tony')
    console.log(p.say())
    

    静态方法

    class Person{
    	constuctor(name){
    		this.name = name
    	}
    	say(){
    		console.log(`this is a name called ${this.name}`)
    	},
    	static create(name){
    		return new Person(name)
    	}
    }
    const p = new Person('tony')
    const tom  = Person.create('tom')
    //静态方法是挂载到类型上的,所以this不会指向实例对象,而是当前的类型
    console.log(p.say())
    console.log(tom.say())
    

    继承 extends

    可以集成对象中相似属性
    
    class Person{
    	constuctor(name){
    		this.name = name
    	}
    	say(){
    		console.log(`this is a name called ${this.name}`)
    	}
    }
    class Student extends Person{
    	constuctor(name,number){
    		super(name)
    		this.number = number
    	}
    	hello(){
    		super()
    		console.log(`this is a age called ${this.number}`)
    	}
    }
    const p = new Student ('tony',21)
    console.log(p.hello())//连同person一起被打印
    

    set数据集合

    类数组,没有重复的数据
    
    	const set = new Set()
    	set.add(1).add(2).add(3).add(2)
    	console.log(set)//Set {1, 2, 3}
    	set.forEach(i => console.log(i))//1 2 3
    	for(var i  of set){
    		 console.log(i)
    	}
    	console.log(set.size)
    	console.log(set.has(100))
    	console.log(set.delete(3))
    	set.clear()
    	const arr = [1,2,4,5,6,3,1]
    	const s = new Set(arr)
    	Array.from(s)
    	[...s]
    

    map

    类对象,和传统的对象一样,都是键值对集合,但是传统对象 键只能是字符串
    let obj = {}
    obj[true] = 'val1'
    obj[1243] = 'val2'
    obj[{a:1}] = 'val3'
    console.log(Object.keys(obj))//['1243','true','object object']
    console.log(obj['object object'])//val3
    
    const m = new Map()
    const tom = {tn : 90}
    m.set(tom, 200)
    console.log(m)
    console.log(m.get({tn : 90}))
    console.log(m.has({tn : 90}))
    console.log(m.delete({tn : 90}))
    m.clear()
    m.forEach((val, key) => {
    	console.log(val, key)
    })
    与对象最大的区别是可以用任意类型作为键
    

    Symbol

    一种全新的数据类型
    之前之前的字符串可以重复,从而导致冲突

    const obj = {}
    //a.js
    obj['foo'] = Math.random()
    //b.js
    obj['foo'] = '123'
    console.log(obj)
    
    //表示独一无二的值
    const s = Symbol()
    console.log(s)//Symbol()
    console.log(typeof s)//Symbol
    console.log(Symbol() === Symbol() )//false
    
    console.log(Symbol('foo'))
    console.log(Symbol('bar'))
    console.log(Symbol('baz'))
    
    const obj1= {}
    obj1[Symbol()] = '123'
    obj1[Symbol()] = '456'
    console.log(obj1)
    
    const obj2= {
    	[Symbol()] : '789'
    }
    console.log(obj2)
    
    const name = Symbol()
    const obj3 ={
    	[name]:'012',
    	say(){
    		console.log(this[name])
    	}
    }
    console.log(obj3.say())
    
    //主要用处是为对象添加一个独一无二的属性值
    
    如果要实现相同的Symbol,可以使用提供的静态方法实现 for
    const s1 = Symbol.for('foo')
    const s2 = Symbol.for('foo')
    console.log(s1===s2)
    但是这个方法内部维护的是字符串和Symbol的对应方式,传入的不是字符串方法内容会自动转换为字符串
    Symbole.for(true) = Symbole.for('true') 
    
    const obj = {
    	[Symbol.toStringTag] = 'XObject'
    }
    console.log(obj.toString()//[object XObject]
    Symbol类型的属性名,通过常规的方法无法获取
    const obj = {
    	[Symbol()]:'symbol value',
    	foo:'normal value'
    }
    for(var key in obj ){
    	console.log(obj[key])//foo
    }
    console.log(Object.keys(obj ))//foo
    console.log(JSON.stringify(obj ))//{'foo':'normal value'}
    可以用它作为私有属性
    console.log(Object.getOwnPropertySymbol(obj))
    

    for of循环

    const arr = [1, 2, 3, 4]
    for(const item of arr ){
    	console.log(item )
    }
    for(const item of arr ){
    	console.log(item )
    	if(item>2){
    		break;//可以随时终止循环
    	}
    }
    //除了数组还可以用来遍历类数组类对象的数据
    const newArr = new Set(['foo', 'bar'])
    for(const item of newArr ){
    	console.log(item)//'foo' 'bar'
    }
    const m = new Map()
    m.set('foo', '123')
    m.set('bar', '456')
    for(const [key, val] in m){
    	console.log(key, val)//foo 123  bar 456
    }
    const newM = {foo:'123',bar:'456'}
    for(const item of newM ){
    	console.log(item)//普通的对象会报错不可迭代
    }
    

    可迭代接口

    实现可迭代接口是for of 使用的前提
    数组,类数组,类对象,他们都有共同的属性,可以通过展开内部的原型对象看到
    const arr = [1, 2, 3, 4]
    const it = arr[Symbol.iterator]()
    //内部有一个数据指针,我们每调用一次,指针就会向后面移一位
    console.log(it.next())//{value:1,done:false}不断的去遍历 done代表是否遍历结束
    console.log(it.next())//{value:2,done:false}
    console.log(it.next())//{value:3,done:false}
    console.log(it.next())//{value:4,done:false}
    console.log(it.next())//{value:undefined,done:true}
    console.log(it.next())//{value:undefined,done:true}
    

    实现可迭代接口

    const obj = {
    	[Symbol.iterator]:function(){//实现可迭代接口,iterable可迭代接口约定内部必须有定义一个返回iterator的接口
    		return {
    			next:function(){//实现了迭代器接口iterator接口,约定了内部必须有个next方法
    				return{//返回的对象,叫做iterationResult
    					value:'foo',
    					done:true
    				}
    			}
    		}
    	}
    }
    for(const item of obj ){
    	console.log('循环体')
    ]
    
    const obj = {
    	store:[1, 2, 3, 4],
    	[Symbol.iterator]:function(){//实现可迭代接口,iterable可迭代接口约定内部必须有定义一个返回iterator的接口
    	let index = 0;
    	let _this = this
    		return {
    			next:function(){//实现了迭代器接口iterator接口,约定了内部必须有个next方法
    				let result = {//返回的对象,叫做iterationResult
    					value:_this.store[index],
    					done:index>= _this.store.length
    				}
    				index++
    				return result 
    			}
    		}
    	}
    }
    for(const item of obj ){
    	console.log(item )
    ]
    

    iterator 迭代器模式

    const obj = {
    	learn:["语文","数学","英语"],
    	life:["吃饭","睡觉","学习"],
    	each:function(callback){
    		let arr = [].concat(this.learn,this.life)
    		for(const item of arr){
    			callback(item)
    		}
    	},
    	[Symbol.iterator]:function(){
    	let index = 0;
    	let _this = this
    	let arr = [...this.learn,...this.life]
    		return {
    			next:function(){
    				return {
    					value:arr [index],
    					done:index++ >= arr .length
    				} 
    			}
    		}
    	}	
    }
    obj.each(function(item){
    	console.log(item)
    })
    console.log("---------")
    //迭代器模式,是向外部提供一个统一遍历接口,让外部不用去关系内部数据的结构
    for(const item of obj){
    	console.log(item )
    }
    

    生成器 Generator

    避免异步回调编程中嵌套太深
    提供更好的异步编程解决方案
    生成器函数,在function后面添加一个*function * fun(){
    	console.log("111")
    	return 100
    }
    const g = fun()
    console.log(g)//输出了生成器对象,对象的原型上有一个next方法
    console.log(g.next())//111 {value:100.done:true}
    
    function * foo(){
    	console.log("111")
    	yield 100
    	console.log("222")
    	yield 200
    	console.log("333")
    	yield 300
    }
    const f = fun()
    console.log(f.next())//111 {value:100.done:false}
    console.log(f.next())//222 {value:200.done:false}
    console.log(f.next())//333 {value:300.done:false}
    console.log(f.next())//undefined {value:undefined.done:true}
    
    生成器使用
    function * createId (){
    	let id = 1
    	while(true){
    		yield id ++ 
    	}
    }
    const c = createId ()
    console.log(c.next().value)
    console.log(c.next().value)
    console.log(c.next().value)
    console.log(c.next().value)
    

    ES2016

    inclues

    传统寻找数组是否函数某个元素使用indexOf
    includes
    const arr = [1,"string",NaN,undefined,null,Symbol(),true]
    console.log(arr.indexOf(1))//但是不能用于NaN
    console.log(arr.includes(NaN))//true 
    

    指数运算符

    const num = Math.pow(2,10)
    console.log(num)//2的10次方
    
    console.log(2 ** 10)//2的10次方
    

    ES2017

    Object.values()

    获取value 和 Object.keys()对应

    Object.entries()

    //有点类似于这个功能
    const m = new Map()
    m.set(‘foo’, ‘123’)
    m.set(‘bar’, ‘456’)
    for(const [key, val] in m){
    console.log(key, val)//foo 123 bar 456
    }

    const obj = {
    name:‘tony’,
    age:20
    }
    for(const [key, val] in Object.entries(obj ){
    console.log(key, val)//foo 123 bar 456
    }

    Async Await

    展开全文
  • es6新特性

    2020-09-25 10:55:20
    es6新特性let关键字const关键字结构赋值Symbol数据类型Proxy代理for...of遍历Set结构Map结构Promise对象Class类定义类 let关键字 用于声明只在块级作用域起作用的变量。 const关键字 用于声明一个常量。 结构赋值 一...
  • 前端学习之路 --ES6新特性

    万次阅读 2020-04-19 17:39:52
    #前言 这篇博客是我在b站进行学习es6课程...1.1 ES6新特性 1. 变量 2. 函数 3. 数组 4. 字符串 5. 面向对象 6. Promise 7. generator //类似于Promise 8. 模块化 1.2 变量 1.2.1 let、var、const和作用域 知识点:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,865
精华内容 3,146
关键字:

es6新特性