ES6-ES11新特性

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>ES6-ES11新特性</title>
    </head>
    <body>
        <script type="text/javascript">
            // promise、新增数据结构【基础数据类型 引用数据类型判断方法,事件循环、同步异步】
            // ES2015-ES6(第6版)
            // 参考文档:https://es6.ruanyifeng.com/#docs/intro 涵盖齐全

            // ES2016-ES7(第7版)
            /*
                1.Array.prototype.includes()
                    includes() 方法用来判断一个数组是否包含一个指定的值,包含则返回 true,否则返回false
                2.指数操作符(**) 与Math.pow(..)具有同样的效果
            */
            const arr = [1, 2, 3];
            console.log(arr.includes(2)); // true
            console.log(arr.includes(4)); // false

            console.log(2 ** 10) // 1024
            console.log(Math.pow(2, 10)) // 1024

            // ES2017-ES8(第8版)
            /*
                1.async await async和await可以像编写同步代码一样编写异步代码 解决回调地狱的问题 【await一定要在async中使用】
                2.Object.values() 返回一个给定对象的所有可枚举属性值的数组
                3.Object.entries() 返回一个给定对象自身可遍历属性 [key,value] 的数组
                4.Object.getOwnPropertyDescriptors() 返回指定对象所有自身属性的描述对象
                5.SharedArrayBuffer对象:SharedArrayBuffer 对象用来表示一个通用的,固定长度的原始二进制数据缓冲区,
                    类似于 ArrayBuffer 对象,它们都可以用来在共享内存(shared memory)上创建视图。
                    与 ArrayBuffer 不同的是,SharedArrayBuffer 不能被分离
                    语法:new SharedArrayBuffer(length)  length:所创建的数组缓冲区的大小,以字节(byte)为单位
                6.Atomics对象 提供了一组静态方法对 SharedArrayBuffer 和 ArrayBuffer 对象进行原子操作
                    使用文档参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Atomics
                7.String padding:
                    padEnd()方法会用一个字符串填充当前字符串(如果需要的话则重复填充),返回填充后达到指定长度的字符串。从当前字符串的末尾(右侧)开始填充
                    语法:str.padEnd(targetLength [, padString])
                    targetLength:当前字符串需要填充到的目标长度。如果这个数值小于当前字符串的长度,则返回当前字符串本身。
                    padString 可选
                    填充字符串。如果字符串太长,使填充后的字符串长度超过了目标长度,则只保留最左侧的部分,其他部分会被截断。此参数的缺省值为 " "(U+0020)
                    
                    padStart() 方法用另一个字符串填充当前字符串(如果需要的话,会重复多次),以便产生的字符串达到给定的长度。从当前字符串的左侧开始填充。
                    语法:str.padStart(targetLength [, padString])
                    targetLength:当前字符串需要填充到的目标长度。如果这个数值小于当前字符串的长度,则返回当前字符串本身。
                    padString 可选
                    填充字符串。如果字符串太长,使填充后的字符串长度超过了目标长度,则只保留最左侧的部分,其他部分会被截断。此参数的默认值为 " "(U+0020)。
            */
           // 随着Promise的大规模使用,当.then()过多后,就也会出现类似于回调地狱的情况 --> 解决回调地狱的问题
            (async () => {
                let time = await a1();
                time = await a2(time);
                await a3(time);
                b1();
                b2();
                b3();
            })();
            
            const obj = {
                name: 'test',
                desc: '测试下语法效果',
                cities: ['北京', '上海', '广州', '深圳'],
                course: ['web', 'java', 'node', 'vue', 'react']
            }
            console.log(Object.keys(obj)) // ["name", "desc", "cities", "course"]
            console.log(Object.values(obj)) // ["test", "测试下语法效果", Array(4), Array(5)]
            console.log(Object.entries(obj)) // [Array(2), Array(2), Array(2), Array(2)] 
            // 0: (2) ["name", "test"]
            // 1: (2) ["desc", "测试下语法效果"]
            // 2: (2) ["cities", Array(4)]
            // 3: (2) ["course", Array(5)]
            console.log(Object.getOwnPropertyDescriptors(obj))
            // cities: {value: Array(4), writable: true, enumerable: true, configurable: true}
            // course: {value: Array(5), writable: true, enumerable: true, configurable: true}
            // desc: {value: "测试下语法效果", writable: true, enumerable: true, configurable: true}
            // name: {value: "test", writable: true, enumerable: true, configurable: true}
            const buffer = new SharedArrayBuffer(6);
            console.log(buffer.byteLength); // 6

            const str1 = '测试下填充到一定长度';
            console.log(str1.padEnd(25, '')); // 测试下填充到一定长度哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
            const str2 = '测试下填充';
            console.log(str2.padEnd(8)); // "测试下填充   "

            const str3 = '66';
            console.log(str3.padStart(3, '0')); // 066
            const str4 = '2111119211';
            const str5 = str4.slice(-4);
            const numStr = str5.padStart(str4.length, '*');
            console.log(numStr) // ******9211

            // ES2018-ES9(第9版)
            /*
                1.对象展开:在以前,...只能用来展开数组,但是现在可以用来展开对象了
                2.Promise.prototype.finally():在Promise中,如果有不管成功还是失败都需要执行的语句
                3.正则表达式 (1)命名捕获组 (2)反向断言 (3)dotAll模式
            */
            let man1 = {
                name: "张三",
                sex: ""
            };
            let man2 = {
                name: "小花",
                sex: "",
                age: 22
            };

            let people = {
                ...man1,
                ...man2
            };
            // 注意:属性名相同后面的属性名会覆盖前面的属性名
            console.log(people); // {name: "小花", sex: "女", age: 22}

            const str =
                `<p>百度</p>
               <p>www.baidu.com</p>
             `;
            let reg = /<p>(?<name>.*)<\/p>\s*<p>(?<url>.*)<\/p>/g;
            const result = reg.exec(str);
            console.log(result, 'result');
            console.log(result.groups.name); // 百度
            console.log(result.groups.url); // www.baidu.com

            const date = '2021-02-25'.match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/)
            console.log(date) // 分组 年 月 日

            const strTest = 'JS5211314你知道么555啦啦啦';
            // 正向断言
            const reg1 = /\d+(?=啦)/;
            const result1 = reg1.exec(strTest);
            console.log(result1);
            // 反向断言
            const reg2 = /(?<=么)\d+/;
            const result2 = reg2.exec(strTest);
            console.log(result2);

            // 正则表达式 dotAll 模式
            const r = /foo.bar/s
            // 判断是否启用dotAll模式  
            console.log(r.dotAll) // true
            console.log(/foo.bar/.test('foo\nbar')); // false
            console.log(/foo.bar/.test('fooabar')); // true
            // 使用 dotAll模式匹配 正则表达式中,(.)可以匹配任意字符,但是4个字节的 utf16 和\n \r 换行、回车终止符不能用(.)匹配
            console.log(/foo.bar/s.test('foo\nbar')); // true

            // ES2019-ES10(第10版)
            /*
                1.Object.fromEntries(): 把键值对列表转换为一个对象 Object.fromEntries()方法是Object.entries()的逆操作
                2.trimStart()和trimEnd()
                    ES5中有 trim方法用来清除字符串两边的空白字符
                    trimStart() 方法从字符串的开头删除空格。trimLeft() 是此方法的别名。
                    trimEnd()方法从一个字符串的末端移除空白字符。trimRight() 是这个方法的别名
                3.Array.prototype.flat(): 默认只会“拉平”一层, 用于将嵌套的数组“拉平”,变成一维的数组。该方法返回一个新数组,对原数据没有影响;
                4.Array.prototype.flatMap(): 对原数组的每个成员执行一个函数(相当于执行Array.prototype.map())
                    然后对返回值组成的数组执行flat()方法。该方法返回一个新数组,不改变原数组
                5.Function.prototype.toString(): toString() 方法返回一个表示当前函数源代码的字符串 [次要]
                6.String.prototype.matchAll(): matchAll() 方法返回一个包含所有匹配正则表达式的结果及分组捕获组的迭代器
                7.Symbol.prototype.description: description 是一个只读属性,它会返回 Symbol 对象的可选描述的字符串
            */
            const peopleInfo1 = Object.fromEntries([
                ['name', 'bob'],
                ['age', 42]
            ])
            console.log(peopleInfo1) // {name: "bob", age: 42}

            // 特别适合将 Map 结构转为对象
            const entries = new Map([
                ['name', 'sob'],
                ['age', 29]
            ]);
            const peopleInfo2 = Object.fromEntries(entries)
            console.log(peopleInfo2) // {name: "sob", age: 29}
            const map = new Map().set('name', 'bala').set('sex', '');
            const peopleInfo3 = Object.fromEntries(map)
            console.log(peopleInfo3) // {name: "bala", sex: "男"}

            const emptyStr = '  abc  ';
            console.log("" + emptyStr.trim() + "") // "好abc看" ES5 
            console.log("" + emptyStr.trimStart() + "") // "好abc  看"  清除左侧空白字符,保留右侧空白字符
            console.log("" + emptyStr.trimEnd() + "") // "好  abc看"    清除右侧空白字符,保留左侧空白字符

            const arr1 = [1, 2, [3, 4]].flat()
            console.log(arr1, 'arr1') // [1, 2, 3, 4] "arr1"
            const arr2 = [1, 2, [3, [4, 5]]].flat(2) // [1, 2, 3, 4, 5]  "arr2"

            const arr3 = [1, 2, 3].flatMap((x) => [x, x * 2])
            console.log(arr3, 'arr3') // [1, 2, 2, 4, 3, 6]  "arr3"
            const arr4 = [1, 2, 3, 4].flatMap(x => [
                [x * 2]
            ])
            console.log(arr4, 'arr4') // [[2], [4], [6], [8]]   "arr4"

            const regexp = /t(e)(st(\d?))/g;
            const rStr = 'test1test2';
            const resStr = [...rStr.matchAll(regexp)];
            console.log(resStr[0]); //  ["test1", "e", "st1", "1", index: 0, input: "test1test2", groups: undefined]
            console.log(resStr[1]); //  ["test2", "e", "st2", "2", index: 5, input: "test1test2", groups: undefined]

            console.log(arr2, 'arr2')
            let sy = Symbol('Symbol数据')
            console.log(sy.description) // -> Symbol数据

            // ES2020-ES11(第11版)
            /*
                1.私有属性
                2.Promise.allSettled()
                3.import(): 支持动态加载模块
                4.BigInt(): BigInt 类型的数据必须添加后缀n,BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示
                5.globalThis: 全局属性 globalThis 包含全局的 this 值,类似于全局对象(global object)
                6.可选链操作符(?.)
                7.空值合并运算符(??)
            */

            // 私有属性和私有方法前面,也可以加上static关键字,表示这是一个静态的私有属性或私有方法
            class Person {
                name; // 公有属性
                #
                job; // 私有属性, 私有属性,只能在类的内部使用
                constructor(name, job) {
                    this.name = name
                    this.#job = job // 符号'#'带上
                }
                // #getPrviteFun(){
                //     console.log('私有方法只能内部调用')
                // }
                info() {
                    console.log(this.name)
                    console.log(this.#job) // 在内的内部正常访问私有属性
                    // this.getPrviteFun()
                }
            }
            const person = new Person('隔壁老王', '无业游民')
            console.log(person) // 正常访问  Person {#job: "无业游民", name: "隔壁老王"}
            console.log(person.info())
            // console.log(person.#job)    // 在类的外部无法访问私有属性 报错: Private field '#job' must be declared in an enclosing class

            // Promise.allSettled()方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例
            // 只有等到所有这些参数实例都返回结果,不管是fulfilled还是rejected,包装实例才会结束
            const prmise1 = Promise.resolve(1);
            const prmise2 = Promise.reject(-1);
            const allSettledPromise = Promise.allSettled([prmise1, prmise2]);
            allSettledPromise.then(res => {
                console.log(res); // [{ status: 'fulfilled', value: 1 },{ status: 'rejected', reason: -1 }]
            });

            // Promise.all()全部成功,才返回成功,有一个失败就返回失败
            const allPromise = Promise.all([prmise1, prmise2]);
            allPromise.then(res => {
                console.log(res); // 报错
            });
            // 总结: Promise.all【无法确定所有操作都结束】和 Promise.allSettled 不关心异步操作的结果,只关心这些操作有没有结束】常用于批量异步任务;

            // import()也可以用在 async 函数之中
            // 注意: 请不要滥用动态导入(只有在必要情况下采用)。静态框架能更好的初始化依赖,而且更有利于静态分析工具和 tree shaking 发挥作用
            // import('./xx.js').then(module=>{        // import返回promise对象,module就是导入的对象
            //     module.fn() // fn() xx.js中一个方法
            // })

            // typeof运算符对于 BigInt 类型的数据返回bigint BigInt 与普通整数是两种值,它们之间并不相等
            // 参考具体api: https://es6.ruanyifeng.com/#docs/number#BigInt-%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B
            // 超过 53 个二进制位的数值,无法保持精度
            console.log(Math.pow(2, 53) === Math.pow(2, 53) + 1) // true
            // 超过 2 的 1024 次方的数值,无法表示
            console.log(Math.pow(2, 1024)) // Infinity
            const a = 1236589966n;
            const b = 568965255n;
            // 普通整数无法保持精度
            console.log(Number(a) * Number(b)) // 703576725335631400
            // BigInt 可以保持精度
            console.log(a * b) // 703576725335631330n

            console.log(globalThis, typeof globalThis) // Window对象  object

            // 可选链(?.)如果要通过ajax动态获取数据,但是并不知道后端返回来的数据是否是空值 【最新版谷歌浏览器】
            const adventurer = {
                name: 'pig',
                cat: {
                    name: 'xiaohua'
                }
            }
            const animalName = adventurer.dog ? .name;
            console.log(animalName); // undefined

            // 空值合并运算符(??)在JavaScript中很多情况比如空字符串"",0,等等情况,如果用在条件判断中,都会被认为是false
            // 可能导致一个问题,就是在使用||运算符时,只需要在左边的值为 undefined 或者 null 的时候,才返回右边的值
            let aa = 0;
            let bb = aa || "aaa";
            let cc = aa ? ? "aaa";
            console.log("bb的值是 " + bb); // bb的值是 aaa
            console.log("cc的值是 " + cc); // cc的值是 0
        </script>
    </body>
</html>

 自己整理,请勿随意转载!!!!

posted @ 2021-03-05 18:39  鱼樱前端  阅读(569)  评论(0编辑  收藏  举报