ES6学习笔记 【第一课:ES发展历史】 【第二课:let,const】 【第三课:解构赋值】 【第五课:函数默认参数、箭头函数、剩余参数】 【第六课:数组循环】 【第七课:数组新增特性】 【第十二课:Symbol&generator】 【第十三课:async,await】 【第十五课:Map和WeakMap】 【第十六课:数字的变化及Math新增对象】 【第十七课:ES2018新增对象】 【第十八课:Proxy的使用】

*******************************************************************************

*******************************************************************************

ES -> ECMA标准

ES6 -> 2015年6月    ES6.0

ESnext ->下一代js语言

标准委员会(TC39)要求更改语言标准

提案->标准

         Stage 0  展示阶段

         Stage 1  征求意见阶段

         Stage 2  草案阶段

         Stage 3  候选阶段

         Stage 4  定案阶段(标准)

【第二课:let,const】

*******************************************************************************

*******************************************************************************

定义(声明)变量

ES5 作用域>>>>>函数作用域:

<script>

        function fn() {

            for (var i = 0; i < 10; i++) {

                console.log(i)

            }

        }

        fn();      

    </script>

ES5 作用域>>>>>全局用域:

<script>

        for (var i = 0; i < 10; i++) {

            //console.log(i)

        }

        console.log(i);

    </script>

特性>>>>>预解析,变量提升

<script>

        console.log(i);

        var i = 1;

    </script>

打印:undefined(语法未出现错误)

特性>>>>>同一作用域里面可以定义相同变量

<script>      

        var i = 1;

        var i = 2;

        console.log(i);

    </script>

打印:2;赋值被重写掉。

ES6 作用域>>>>>块级作用域 {}

特性>>>>>没有预解析,不存在变量提升;先定义后使用

<script>      

       let i= 1;

       console.log(i);

    </script>

特性>>>>>统一作用域里面只能定义一次变量,不能重复定义变量    

<script>

        let i = 1;

        let i = 2;

        console.log(i);

    </script>

Uncaught SyntaxError: Identifier 'i' has already been declared

特性>>>>>for循环时类似于一个父级作用域  

  <script>

        for (let i = 0; i < 10; i++) {

            console.log(i);

        }

 

        {

            let i = 100;

            console.log(i);

            {

                console.log(i);

                {

                    let i = 111;

                    console.log(i);

                }

            }

        }

    </script>

Const 定义变量特性和let一致,但定义的变量不可修改。   

 <script>

       const arr = ["a","b", "c"];

       arr = ["a"];

       console.log(arr);

    </script>

ES6.html:11 Uncaught TypeError: Assignment to constant variable.

但满足对象的基本特性:  

  <script>

       const arr = ["a","b", "c"];

       arr.push("d");

       console.log(arr);

    </script>

(4) ["a", "b", "c", "d"]

【第三课:解构赋值】

*******************************************************************************

*******************************************************************************

常规应用解构赋值

  

  <script>

        {

            let [a, b, c] = ["a", "b", "c"];

            console.log(a, b, c);

            //a b c

        }

        {

            let [a, b, c] = ["a", "b"];

            console.log(a, b, c);

            //a b undefined

        }

        {

            let [a, [b, c]] = ["a", ["b"]];

            console.log(a, b, c);

            //a b undefined

        }

        {

            //交换位置

            // let a = "a";

            // let b = "b";

            let [a, b] = ["a", "b"];

            [a, b] = [b, a]

            console.log(a, b);

            //b a

        }

        {

            //json解构赋值

            let json = {

                age: 12,

                name: "姓名",

                sex: "男"

            };

            let { name, age, sex } = json;//注意为花括号,两边对象格式一致

            console.log(age, name, sex);

            //12 "姓名" "男"

        }

        //解构赋值重命名

        {

            let json = {

                age: 12,

                name: "姓名",

                sex: "男"

            };

            let { name: name_a, age: age_b, sex: sex_c } = json;//注意为花括号,两边对象格式一致

            console.log(name_a, age_b, sex_c);

            //姓名 12 男

        }

        //解构赋值初始值(默认值undefined)

        {

            let json = {

                age: 12,

                name: "姓名",

                //sex : undefined            

            };

            let { name: name_a, age: age_b, sex: sex_c = "暂无性别" } = json;//注意为花括号,两边对象格式一致 默认值只针对于undefined情况

            console.log(name_a, age_b, sex_c);

            //姓名 12 暂无性别

        }

        //解构赋值初始值(默认值null)

        {

            let json = {

                age: 12,

                name: "姓名",

                sex: null

            };

            let { name: name_a, age: age_b, sex: sex_c = "暂无性别" } = json;//注意为花括号,两边对象格式一致

            console.log(name_a, age_b, sex_c);

            //姓名 12 null

        }

    </script>

函数应用:

    <script>

        {

            function fn() {

                return { a: 1, b: 2 };

            }

            let { a, b } = fn();

            console.log(a, b);

            //1 2

        }

        {

            function fn() {

                return { a: 1 };

            }

            let { a, b: temp_b = "暂无数据" } = fn();

            console.log(a, temp_b);

            //1 "暂无数据"

        }

        {

            function fn({ a, b }) {

                console.log(a, b);

            }

            fn({ a: 1, b: 2 });

            //1 2

        }

        {

            function fn({ a, b ="暂无数据" }) {

                console.log(a, b);

            }

            fn({ a: 1 });

            //1 "暂无数据"

        }

        {

            function fn({ a="a暂无数据", b ="b暂无数据" }) {

                console.log(a, b);

            }

            fn({ });

            //a暂无数据 b暂无数据

        }

        {

            function fn({ a="a暂无数据", b ="b暂无数据" }={}) {

                console.log(a, b);

            }

            fn();

            //a暂无数据 b暂无数据

        }

    </script>

【第四课:字符串模板及新增函数】

*******************************************************************************

*******************************************************************************

字符串模板:波浪线反飘符号。``

    

<script>

        {

            let [title, count] = ["ES6学习案例", 100];

            let str = `标题${title};浏览次数${count};`;

            console.log(str);

            //标题ES6学习案例;浏览次数100;

        }

        {

            //新增字符串函数

            let str = "apple orange pear panda";

            let str1 = "123";

            console.log(str.includes("app"));

            //true

            console.log(str.startsWith("app"));

            //true

            console.log(str.endsWith("app"));

            //false

            console.log(str1.padStart(10, "x"));

            //xxxxxxx123

            console.log(str1.padStart(10, "xa"));

            //xaxaxax123

            console.log(str1.padEnd(10, "x"));

            //123xxxxxxx

            console.log(str1.padEnd(10, "xa"));

            //123xaxaxax

        }

    </script>

【第五课:函数默认参数、箭头函数、剩余参数】

*******************************************************************************

*******************************************************************************

函数默认参数    

<script>

        {

            function fn() {

                return { a: 1, b: 2 };

            }

            let { a, b } = fn();

            console.log(a, b);

            //1 2

        }

        {

            function fn() {

                return { a: 1 };

            }

            let { a, b: temp_b = "暂无数据" } = fn();

            console.log(a, temp_b);

            //1 "暂无数据"

        }

        {

            function fn({ a, b }) {

                console.log(a, b);

            }

            fn({ a: 1, b: 2 });

            //1 2

        }

        {

            function fn({ a, b = "暂无数据" }) {

                console.log(a, b);

            }

            fn({ a: 1 });

            //1 "暂无数据"

        }

        {

            function fn({ a = "a暂无数据", b = "b暂无数据" }) {

                console.log(a, b);

            }

            fn({});

            //a暂无数据 b暂无数据

        }

        {

            function fn({ a = "a暂无数据", b = "b暂无数据" } = {}) {

                console.log(a, b);

            }

            fn();

            //a暂无数据 b暂无数据

        }

        {

            //函数参数默认已经定义,不可再次使用let,const声明定义

            function fn(a = 1) {

                let a = 2;

                console.log(a);

            }

            //Uncaught SyntaxError: Identifier 'a' has already been declared

        }

    </script>

…及剩余参数

<script>

       {

           function fn(a){

               console.log(...a);//将数组展开

           }

           fn([1,2,3,4,5]);

           //1 2 3 4 5

       }

       {

           function fn(...a){

               console.log(a);//将散数合并成数组

           }

           fn(1,2,3,4,5);

           //[1 2 3 4 5]

       }

       {

           function fn(a,b,...c){

               console.log(c);//将散数合并成数组

           }

           fn(1,2,3,4,5); //...c表示剩余参数,只能放在最后一个参数位置

           //[3 4 5]

       }

    </script>

箭头函数     

<script>

        {

            let fn = () => { return 1 }

            console.log(fn());

            //1

        }

        {

            let fn = (a,b) => { return a+b }

            console.log(fn(2,3));

            //5

        }

        {

            let fn = (a,b) => { return `标题${a};浏览次数${b}。`; }

            console.log(fn("ES学习案例",30));

            //标题ES学习案例;浏览次数30。

        }

        {

            // this问题, 定义函数所在的对象,不在是运行时所在的对象

            let json = {

                id : 1,

                fn :function(){

                    setTimeout(() => {

                        console.log(this.id);

                    }, 2000);

                }

            }

            json.fn();

        }

    </script>

Ps注意事项:

1. this问题, 定义函数所在的对象,不在是运行时所在的对象

2. 箭头函数里面没有arguments, 用  ‘...’

3. 箭头函数不能当构造函数

【第六课:数组循环】

*******************************************************************************

*******************************************************************************  

  <script>

        {

            //for循环、

            let arr = [1, 2, 3, 4, 5];

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

                console.log(arr[i])

            }

        }

        {

            //forEach 代替普通for,无返回值不需要return

            let arr = [1, 2, 3, 4, 5];

            arr.forEach(function (value, idnex, arr) { console.log(value) });

        }

        {

            //forEach 代替普通for,无返回值不需要return

            let arr = [1, 2, 3, 4, 5];

            arr.forEach((value, idnex, arr) => { console.log(value) });

        }

        {

            //map

            //非常有用,做数据交互  "映射"

            //正常情况下,需要配合return,返回是一个新的数组

            //若是没有return,相当于forEach

            //注意:平时只要用map,一定是要有return

            let arr = [{ title: "title1", hot: 10 }, { title: "title2", hot: 20 }, { title: "title3", hot: 30 }];

            let newArr = arr.map((val, idnex, arr) => { return val.hot > 10 });

            //重新整理数据结构

            let newArr1 = arr.map((val, idnex, arr) => { return `主题为${val.title};热度为${val.hot}。` });

            console.log(newArr);

            console.log(newArr1);

            // [false, true, true]

            //["主题为title1;热度为10。", "主题为title2;热度为20。", "主题为title3;热度为30。"]

        }

        {

            //filter 过滤,过滤一些不合格“元素”, 如果回调函数返回true,就留下来

            let arr = [{ title: "title1", hot: 10 }, { title: "title2", hot: 20 }, { title: "title3", hot: 30 }];

            let newArr = arr.filter((val, idnex, arr) => { return val.hot > 10 });

            console.log(newArr);

            //0: { title: "title2", hot: 20 }

            //1: { title: "title3", hot: 30 }

        }

        {

            //arr.some(): 类似查找,  数组里面某一个元素符合条件,返回true

            let arr = [1, 3, 5, 7, 9, 10];

            let res = arr.some((val, index, arr) => { return val % 2 == 0 });

            console.log(res);

            //true

        }

        {

            //arr.every(): 类似查找,  数组里面某一个元素符合条件,返回true

            let arr = [1, 3, 5, 7, 9, 10];

            let res = arr.every((val, index, arr) => { return val % 2 == 0 });

            console.log(res);

            //false

        }

        {

            //arr.reduce()  从左往右  求数组的和、阶乘

            let arr = [2, 2, 3];

            let res = arr.reduce((prev, cur, index, arr) => { return prev * cur });

            let res1 = arr.reduce((prev, cur, index, arr) => { return prev ** cur });//幂运算

            console.log(res);

            console.log(res1);

            //12

            //64

        }

        {

            //arr.reduce()  从右往左  求数组的和、阶乘

            let arr = [2, 2, 3];

            let res = arr.reduceRight((prev, cur, index, arr) => { return prev * cur });

            let res1 = arr.reduceRight((prev, cur, index, arr) => { return prev ** cur });

            console.log(res);

            console.log(res1);

            //12

            //81

        }

        {

            //for...of...类似于普通for

            //但新增了arr.keys()    数组下标

            //       arr.entries()  数组某一项

            let arr = [2, 2, 3];

            for (let val of arr) {

                console.log(val);

            }

            for (let val of arr.keys()) {

                console.log(val);

            }

            for (let [key,val] of arr.entries()) {

                console.log(key,val);

            }

        }

</script>

【第七课:数组新增特性】

*******************************************************************************

*******************************************************************************   

 <script>

        {

            //扩展运算符...

            let arr1 = [1, 2, 3];

            let arr2 = [...arr1];

            console.log(arr2);

            //(3) [1, 2, 3]

        }

        {

            //Array.from();

            //作用: 把类数组(获取一组元素、arguments...) 对象转成数组

            //个人观点: 具备 length这个东西,就靠谱

            let arr1 = [1, 2, 3];

            let arr2 = Array.from(arr1);

            console.log(arr2);

            //[1, 2, 3]

            let str = "123";

            console.log(Array.from(str));

            //["1", "2", "3"]

            let json = {

                0: "name1",

                1: "男",

                2: 18,

                length: 3

            };

            console.log(Array.from(json))//json key比较特殊

            // ["name1", "男", 18]

            let json1 = {

                0: "name1",

                1: "男",

                2: 18,

                length: 2

            };

            console.log(Array.from(json1))//json key比较特殊

            // ["name1", "男"]

        }

        {

            //Array.of():  把一组值,转成数组

            let arr = Array.of("1", "2", "3");

            console.log(arr);

            //["1", "2", "3"]

        }

        {

            //arr.find():  查找,找出第一个符合条件的数组成员,如果没有找到,返回undefined

            let arr = [10, 20, 30];

            console.log(arr.find((val, index, arr) => { return val > 10 }));

        }

        {

            //arr.findIndex():  找的是第一个符合条件位置, 没找到返回-1

            let arr = [10, 20, 30];

            console.log(arr.findIndex((val, index, arr) => { return val > 10 }));

        }

        {

            //arr.fill()    填充

            //arr.fill(填充的东西, 开始位置, 结束位置);

            let arr = [10, 20, 30];          

            arr.fill([1, 2, 3, 4], 1);

            console.log(arr);

        }

        {

           //在ES2016里面新增:

           //arr.indexOf()

           //arr.includes()

            let arr = [10, 20, 30];   

            let res = arr.includes(20);

            console.log(res);

            //true

        }

    </script>

【第八课:对象简洁语法及对象新增】

*******************************************************************************

*******************************************************************************

对象简洁语法   

 <script>

        {

            let name = "name1";

            let sex = "男";

            let age = 18

            let json1 = {

                name: name,

                sex: sex,

                age: age

            }

            console.log(json1);

            let json2 ={

                name,

                sex,

                age

            };

            console.log(json2);

            //json2 为json1 的简介语法

            //Object age: 18name: "name1"sex: "男"

            //Object age: 18name: "name1"sex: "男"

        }

    </script> 

对象新增特性

两个对象是否相等Object.is()新增 

   <script>

        {

           //判断两个对象是否相等Object.is()新增对NaN以及+0,-0的处理

           console.log(NaN == NaN);

           //false

           console.log(NaN===NaN);

           //false

           console.log(Number.isNaN(NaN));

           //true

           console.log(Object.is(NaN,NaN));

           //true

           console.log(Object.is(+0,-0));

           //false

           console.log(+0==-0);

           //true

           console.log(+0===-0);

           //true

        }

    </script>

Object.assign():合并对象

let 新的对象 = Object.assign(目标对象, source1, srouce2....)

    <script>

        {

            let json1 = { a: 1 };

            let json2 = { b: 2 };

            let json3 = { c: 3 };

            let json4 = { d: 4, a: 4 };

            let newJson1 = Object.assign({}, json1, json2, json3);

            let newJson2 = Object.assign({}, json1, json2, json3, json4);

            console.log(newJson1);

            //{a: 1, b: 2, c: 3}

            console.log(newJson2);

            //{a: 4, b: 2, c: 3, d: 4} //a变成4,覆盖前面的值

        }

    </script>

对象新增函数属性 

   <script>

        {

            //对象新增属性

            //ES2017引入:

            //Object.keys()

            //Object.entries();

            //Object.values();

            var json = { a: 1, b: 2, c: 3 };

            for (let key of Object.keys(json)) {

                console.log(key);

            }

            //a

            //b

            //c

            for (let val of Object.values(json)) {

                console.log(val);

            }

            //1

            //2

            //3

            for (let item of Object.entries(json)) {

                console.log(item);

            }

            //(2) ["a", 1]

            //(2) ["b", 2]

            //(2) ["c", 3]

            for (let [key, val] of Object.entries(json)) {

                console.log(key, val);

            }

            //a 1

            //b 2

            //c 3

            //对象的扩展函数... 拷贝json对象

            let json1 = {...json};

            console.log(json1);

            //{a: 1, b: 2, c: 3}

        }

    </script>

【第九课:Promise】

*******************************************************************************

*******************************************************************************

  

  <script>

        //Promise

        //承诺,许诺 作用:  解决异步回调问题

        //语法:

        //let promise = new Promise(function(resolve, reject){

        //    //resolve,   成功调用

        //    //reject     失败调用

        //});

        //promise.then(res=>{

        //

        //}, err=>{

        //  

        //})

        //promise.catch(err => { })

 

        {

            let status = 2

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

                if (status == 1) {

                    resolve("成功了");

                } else {

                    reject("失败了");

                }

            })

            promise.then(res => {

                console.log(res);

            },err=>{

                console.log(err);

            })

            //promise.catch(err=>{console.log(err)});

        }

        //简洁用法

        //new Promise().then(res=>{

        //}).catch(err=>{

        //})

        {

            let status = 1;

            new Promise(function (resolve, reject) {

                if (status == 1) {

                    resolve("成功了");

                } else {

                    reject("失败了");

                }

            }).then(res=>{console.log(res)}).catch(err=>{console.log(err)});

        }

        //Promise.resolve('aa') :  将现有的东西,转成一个promise对象, resolve状态,成功状态

        //等价于:

        //new Promise(resolve =>{

        //    resolve('aaa')

        //});

        {

            Promise.resolve("111").then(res=>{console.log(res)}).catch(err=>{console.log(err)});;

            new Promise((resolve,reject)=>{

                resolve("111");

            }).then(res=>{console.log(res)}).catch(err=>{console.log(err)});

        }

        //Promise.reject('aaa'):   将现有的东西,转成一个promise对象,reject状态,失败状态

        //等价于:

        //new Promise((resolve, reject) =>{

        //    reject('aaa')

        //});

        {

            Promise.reject("222").then(res=>{console.log(res)}).catch(err=>{console.log(err)});;

            new Promise((resolve,reject)=>{

                reject("222");

            }).then(res=>{console.log(res)}).catch(err=>{console.log(err)});

        }

        //Promise.all([p1, p2, p3]):  把promise打包,扔到一个数组里面,打包完还是一个promise对象

        //必须确保,所有的promise对象,都是resolve状态,都是成功状态

        //Promise.race([p1, p2, p3]): 只要有一个成功,就返回

    </script>

【第十课:模块化】

*******************************************************************************   

 <script type="module">

        //模块化:

        //  注意: 需要放到服务器环境

        //  a). 如何定义模块?

        //      export  东西

        //      export const a =12;

        //      export{

        //          a as aaa,

        //          b as banana

        //      }

        //  b). 如何使用?

        //      import

        //      import './modules/1.js';

        //      import {a as a, banana, c} from './modules/2.js'

        //      import * as modTwo from './modules/2.js';

        //使用模块:

        //  <script type="module"><?script>

 

        //1.js

        //console.log("模块1加载")

        //export default  "默认值";

        //export const a = "a的值";

        //export const b = "b值";

        import dVal, { a as apple, b } from './modules/1.js'; //模块里面是默认值(export default  "默认值"; );外部接受时不使用{}。

        console.log(dVal, apple, b);

        ///模块1加载

        ///默认值 a的值 b值

 

        //import:  特点

        //  a). import 可以是相对路径,也可以是绝对路径

        //      import 'https://code.jquery.com/jquery-3.3.1.js';

        //  b). import模块只会导入一次,无论你引入多少次

        //  c). import './modules/1.js';  如果这么用,相当于引入文件

        //  d). 有提升效果,import会自动提升到顶部,首先执行

        //  e). 导出去模块内容,如果里面有定时器更改,外面也会改动,不想Common规范缓存

        // import()  类似node里面require, 可以动态引入, 默认import语法不能写到if之类里面

        //  返回值,是个promise对象

        //  import('./modules/1.js').then(res=>{

        //      console.log(res.a+res.b);

        //  });

        //动态引入

        import('./modules/1.js').then(res => {

            console.log(res.default + res.a + res.b);

        });

        //默认值a的值b值

        

        //  优点:

        //      1. 按需加载

        //      2. 可以写if中

        //      3. 路径也可以动态

        //  Promise.all([])

    </script>

【第十一课:类和继承】

*******************************************************************************

*******************************************************************************

    

<script type="module">

        let aaa = "test"; //定义变量作为方法名

        let bbb = "t111";

        class Person {

            constructor(name, age) {

                console.log(`传入参数name${name};age${age};`);

                this.name = name;

                this.age = age;

            }

            showName() {

                console.log(this.name);

            }

            showAge() {

                console.log(this.age);

            }

 

            //方法名拼接

            [aaa]() { // 调用方法名变量

                console.log("test");

            }

            [bbb]() { // 调用方法名变量

                console.log("t111");

            }

            [aaa + bbb]() { // 调用方法名变量

                console.log("testt111");

            }

            //静态方法

            static sfn() {

                console.log("调用静态函数sfn");

            }

        }

 

        class Student extends Person {

            constructor(name, age, skill) {

                super(name, age);

                this.skill = skill;

            }

            showName() {

                super.showName();

                console.log("子类");

            }

            showSkill() {

                console.log(this.skill);

            }

        }

        let person = new Person("张三", 18);

        //传入参数name张三;age18;

        console.log(person.name);

        // 张三

        console.log(person.age);

        //18

        person.showName();

        //张三

        person.showAge();

        ///////////////////////////////////方法名拼接

        //18

        person.test();

        //test

        person[aaa]();

        //test

        person.t111();

        //t111

        person[bbb]();

        //t111

        person.testt111();

        //testt111

        person[aaa + bbb]();

        //testt111

        Person.sfn();

        //调用静态函数sfn

        let stu = new Student("学生张", 18, "逃学");

        stu.showName();

        //传入参数name学生张; age18;

        //学生张

        //子类

    </script>

【第十二课:Symbol&generator】

*******************************************************************************

*******************************************************************************

Symbol   

 <script>

        //数据类型:number、string、boolean、Object、undefined、function、symbol(ES6新增数据类型)

        //      symbol  使用情况一般

        //

        //定义:

        //  let syml = Symbol('aaa');

        //

        //注意:

        //  1. Symbol 不能new

        //  2. Symbol() 返回是一个唯一值

        //      坊间传说, 做一个key,定义一些唯一或者私有一些东

        //  3. symbol是一个单独数据类型,就叫 symbol, 基本类型

        //

        //  4. 如果symbol作为key,用for in循环,出不来

        let syml = Symbol('aaa');

        console.log(syml);

        //Symbol(aaa)

    </script>

Generator

    <script>

        //generator     解决异步深度嵌套的问题, async

        //定义:

        function* gen() {

            yield 'welcome';

            yield 'to';

            return '牧码人';

        }

        //调用:

        let g1 = gen();

        g1.next();  // {value:'welcome', done:false}

        //console.log(g1.next());

        g1.next();  // {value:'to', done:false}

        g1.next();  // {value:'牧码人', done:true}

 

        // for .. of  自动遍历 generator

        // return的东西,它不会遍历

    </script>

异步: 不连续,上一个操作没有执行完,下一个操作照样开始

同步: 连续执行,上一个操作没有执行完,下一个没法开始 

关于异步,解决方案:

         a). 回调函数

         b). 事件监听

         c). 发布/订阅

         d). Promise对象

    e).generator,

【第十三课:async,await】

*******************************************************************************

*******************************************************************************

   

 <script>

        //ES2017,规定 async

        //nodeJs

        //读取文件  fs.readFile

        //1. promise

        //2. genrator

        //3. async

        const fn = function (status) {

            return new Promise(function (resolve, reject) {

                if (status % 2 == 1) {

                    resolve(status);

                } else {

                    throw new Error("出错了")

                }

            }).then(res => { console.log(res) }).catch(err => { console.log(err) });

 

        }

        //async function fn(){  //表示异步,这个函数里面有异步任务

        //let result = await  xxx   //表示后面结果需要等待

        //}

        async function test() {

            let t1 = await fn(1);

            let t2 = await fn(2);

            let t3 = await fn(3);

        }

        test();

        //async特点:

        //  1. await只能放到async函数中

        //  2. 相比genrator语义化更强

        //  3. await后面可以是promise对象,也可以数字、字符串、布尔

        //  4. async函数返回是一个promise对象

        //  5. 只要await语句后面Promise状态变成 reject, 那么整个async函数会中断执行

        //如何解决async函数中抛出错误,影响后续代码:

        //  a).

        //      try{

        //

        //      }catch(e){

        //          

        //      }

        //  b). promise本身catch

        //个人建议大家:

        //  try{

        //      let f1 = await readFile('data/a.txt');

        //      let f3 = await readFile('data/c.txt');

        //      let f2 = await readFile('data/b.txt');

        //  }catch(e){}

    </script>

【第十四课:Set和WeakSet】

*******************************************************************************

*******************************************************************************

Set    

<script>

        //数据结构

        //数组

        //json, 二叉树....

        //

        //set数据结构:

        //类似数组,但是里面不能有重复值

        //let setArr = new Set("a", "c", "a", "b");

        let setArr = new Set();

        setArr.add("a").add("c").add("a").add("b");

        console.log(setArr);

        setArr.delete("a");

        console.log(setArr);

        let isHas = setArr.has("a");

        console.log(isHas);

        console.log(setArr.size);

        setArr.forEach((val, index) => {

            console.log(val, index);

        });

setArr.clear();

    </script>

WeakSet

new Set([]);      存储数组, 这种写法对

new WeakSet({})       存储json,这种写法不靠谱

WeakSet没有size,也没有clear()

有, add(), has(), delete()

确认,初始往里面添加东西,是不行的。最好用add添加

【第十五课:Map和WeakMap】

*******************************************************************************

*******************************************************************************

map:

         类似 json, 但是json的键(key)只能是字符串 

         map的key可以是任意类型 

使用:

         let map = new Map(); 

         map.set(key,value);    设置一个值 

         map.get(key)   获取一个值 

         map.delete(key)       删除一项        

         map.has(key)   判断有没有 

         map.clear()      清空 

循环:

         for(let [key,value] of map){} 

         for(let key of map.keys()){} 

         for(let value of map.values()){} 

         for(let [k,v] of map.entries()){} 

         map.forEach((value, key) =>{

             console.log(value, key);

         }) 

WeakMap():  key只能是对象 

Set   里面是数组,不重复,没有key,没有get方法

Map 对json功能增强,key可以是任意类型值

【第十六课:数字的变化及Math新增对象】

*******************************************************************************

*******************************************************************************

数字(数值)变化:

         二进制:  (Binary)

                   let a = 0b010101;

         八进制: (Octal)

                   let a = 0o666;        

         十六进制:

                   #ccc

         Nunber()、parseInt()、 parseFloat()

         Number.isNaN(NaN)        -> true 

         Number.isFinite(a)   判断是不是数字         

         Number.isInteger(a)  判断数字是不是整数        

         Number.parseInt();

         Number.parseFloat();

安全整数:

         2**3 

         安全整数:    -(2^53-1) 到 (2^53-1),   包含-(2^53-1) 和(2^53-1) 

         Number.isSafeInteger(a); 

         Number.MAX_SAFE_INTEGER         最大安全整数

         Number.MIN_SAFE_INTEGER 最小安全整数

Math:

         Math.abs()

         Math.sqrt()

         Math.sin() 

         Math.trunc()    截取,只保留整数部分

                   Math.trunc(4.5)  ->  4

                   Math.trunc(4.9)  ->  4 

         Math.sign(-5)   判断一个数到底是正数、负数、0

                   Math.sign(-5)  ->  -1

                   Math.sign(5)  -> 1

                   Math.sign(0)    ->  0

                   Math.sign(-0)  ->  -0

                   其他值,返回 NaN        

         Math.cbrt()      计算一个数立方根 

                   Math.cbrt(27)  ->  3 

【第十七课:ES2018新增对象】

*******************************************************************************

*******************************************************************************

ES2018(ES9):

         1. 命名捕获

                   语法:  (?<名字>) 

                   let str = '2018-03-20';

                   let reg = /(?<year>d{4})-(?<month>d{2})-(?<day>d{2})/;

                   let {year, month ,day} = str.match(reg).groups;

                   console.log(year, month, day);

         反向引用:

                   1  2     $1  $2

         反向引用命名捕获:

                   语法:  k<名字> 

                   let reg = /^(?<Strive>welcome)-k<Strive>$/; 

                   匹配: ‘welcome-welcome’ 

                   let reg = /^(?<Strive>welcome)-k<Strive>-1$/; 

                   匹配: 'welcome-welcome-welcome' 

         替换:

                   $<名字> 

                   let reg = /(?<year>d{4})-(?<month>d{2})-(?<day>d{2})/;

                   str = str.replace(reg,'$<day>/$<month>/$<year>');

                   console.log(str);

                   str = str.replace(reg, (...args)=>{

                            //console.log(args)

                            let {year, month, day} = args[args.length-1]; 

                            return `${day}/${month}/${year}`;

                   }); 

                   console.log(str); 

         2.   dotAll 模式    s 

                   之前 '.' 在正则里表示匹配任意东西, 但是不包括         

            let reg = /w+/gims; 

         3. 标签函数

                   function fn(){ 

                   } 

                   fn()  //这样调用就是普通函数 

                   fn`aaa`  //标签函数使用

                   function fn(args){

                            return args[0].toUpperCase();

                   } 

                   console.log(fn`welcome`);

【第十八课:Proxy的使用】

*******************************************************************************

*******************************************************************************

   

 <script>

        let obj = {

            name: "name1",

            age: 18

        };

        let newObj = new Proxy(obj, {

            get(target, property) {

                console.log(target, property);

                if (property == "age") {

                    console.log(`您访问了${property}属性。禁止访问年龄属性`);

                    return undefined;

                } else {

                    console.log(`您访问了${property}属性。`);

                    return target[property];

                }

 

            }

        })

        console.log(newObj.name);

        console.log(newObj.age);

        //语法:

        //  new Proxy(target, handler);

        //  let obj = new Proxy(被代理的对象,对代理的对象做什么操作)

        //

        //  handler:

        //

        //  {

        //      set(){},  //设置的时候干的事情 设置,拦截:设置一个年龄,保证是整数,且范围不能超过200

        //      get(){},  //获取干的事情 获取拦截

        //      deleteProperty(){},  //删除 删除,拦截:

        //      has(){}  //问你有没有这个东西  ‘xxx’ in obj 检测有没有

        //      apply()  //调用函数处理 拦截方法

        //      .....

        //  }

        //

        //实现一个,访问一个对象身上属性,默认不存在的时候给了undefined,希望如果不存在错误(警告)信息:

    </script>

【第十九课:Reflect的使用】

*******************************************************************************

*******************************************************************************

Reflect.apply(调用的函数,this指向,参数数组); 

fn.call()

fn.apply()  类似 

Reflect: 反射

         Object.xxx  语言内部方法

                   Object.defineProperty 

         放到Reflect对象身上 

         通过Reflect对象身上直接拿到语言内部东西 

         'assign' in Object    ->   Reflect.has(Object, 'assign')

         delete json.a        ->   Reflect.deleteProperty(json, 'a');   

 <script>

        function sum(a, b) {

            return a + b;

        }

        let newSum = new Proxy(sum, {

            apply(target, context, args) {

                return Reflect.apply(...arguments) ** 2;

            }

        });

        console.log(newSum(2,3));

        console.log(Reflect.apply(sum,"aaa",[2,3]));

        let json = {

            a:1,

            b:2

        };

        Reflect.deleteProperty(json, 'a');

        console.log(json);

    </script>