ES6新特性,ES6详解

ES6新特性,ES6详解

文章目录

  • ES6新特性,ES6详解
    • 1:前言
    • 2:let与const
        • 2.1:let、const
        • 2.2:let与const的不同
    • 3:Promise 异步操作
        • 3.1:`Promise` 状态:
        • 3.2:`Promise` 实例方法:
        • 3.3:`Promise` 链式调用:
        • 3.4:`Promise` 同步执行异步函数:
    • 4:Class 类
        • 4.1:constructor 构造器
        • 4.2:super
    • 5:箭头函数
        • 5.1:没有自己的 this
        • 5.2:不可以使用 `new` 命令
        • 5.3:没有 `arguments` 对象
        • 5.4:不能用做 `Generator` 函数
    • 6:函数默认值
    • 7:模版字符串
    • 8:解构赋值
        • 8.1:解构对象
          • 8.1.1 设置别名:
          • 8.1.2 动态名称:
        • 8.2:解构对象使用/例子
        • 8.3:解构数组赋值
          • 8.3.1:解构数组指定位置
        • 8.4:解构数组
    • 9:展开语法
        • 9.1:函数传值
        • 9.2:函数接收值
        • 9.3:连接多个数组
    • 10:对象属性缩写
    • 11:模块化
        • 11.1:import 引入
          • 11.1.1:解构取值
          • 11.1.2:设置别名
          • 11.1.3:赋值对象
        • 11.2:export 导出
          • 11.2.1:export
          • 11.2.2:export default
          • 11.2.3:export 和 export default 的区别
    • 12:includes
    • 13:指数运算符
    • 14:async/await
        • 14.1:误区——使用就会同步执行异步代码
        • 14.2:一旦使用了 await ,await 之后的代码(包括同步)都会异步执行
    • 15:Object对象遍历
        • 15.1:Object.values()
        • 15.2:Object.keys()
        • 15.3:Object.entries()
    • 16:Object.getOwnPropertyDescriptors()
    • 17:padStart()/padEnd()
        • 17.1:padStart()
        • 17.1:padEnd()
    • 18:ShareArrayBuffer
    • 19:Atomics
    • 20:尾后逗号
    • 21:for await 异步迭代
    • 22:关于《带标签的模板字符串》非法转义序列的修订
        • 22.1:什么是带标签的模板字符串
        • 22.2:带标签的模版字面量及转义序列
        • 22.3:为什么修订非法转义序列
    • 23:正则拓展
        • 23.1:具名组匹配
        • 23.2:引入
    • 24:JSON.stringify 增强编码问题(转义字符串)
    • 25:flat
    • 25:flatMap
    • 26:trimStart/trimEnd 去除空格
    • 27:Object.fromEntries()
    • 28:Symbol.prototype.description

ES6新特性,ES6详解_第1张图片

1:前言

ES6 内容包含了 ES7ES8ES9ES10ES11 的特性。我们通常会使用 ES6 来统一概括这些新特性。

2:let与const

2.1:let、const
  1. 块级作用域
        {
            let a = 888;
        }
        /**
         * Uncaught ReferenceError: a is not defined
        */
        console.log(a);
  1. 不会变量提升
        /**
         * Uncaught ReferenceError: a is not defined
        */
        console.log(a);
        {
            let a = 888;
        }
  1. 同一作用域不可以重复声明
        {
            let a = 888;
            /**
             * Uncaught SyntaxError: Identifier 'a' has already been declared
            */
            let a = 666;
        }
2.2:let与const的不同

大部分特性相同,不同点:

const 设置的变量不可以再修改(对象类型除外)。

        const a = 888;
        /**
         * Uncaught TypeError: Assignment to constant variable.
        */
        a = 999;
        const a = {};
        /**
         * 成功
        */
        a.name = 'anny';

3:Promise 异步操作

3.1:Promise 状态:
  1. 待定(pending):初始状态。
  2. 已完成(fulfilled):操作成功完成。
  3. 已拒绝(rejected):操作失败。
3.2:Promise 实例方法:
  • then():完成
        new Promise((resolve,reject)=>{
            resolve(888)
        })
        .then(res=>{
            console.log(res)
        })
  • catch():失败
        new Promise((resolve,reject)=>{
            reject(888)
        })
        .catch(err=>{
            console.log(err)
        })
  • finally():无论成功/失败都执行
        let num = 100;
        new Promise((resolve,reject)=>{
            if(num==100){
                resolve(888)
            }else{
                reject(999)
            }
        })
        .then(res=>{
            console.log(res)
        })
        .catch(err=>{
            console.log(err)
        })
        .finally(info=>{
            console.log('finally!')
        })
3.3:Promise 链式调用:
        new Promise((resolve,reject)=>{
           resolve()
        })
        .then(res=>{
            console.log(888)
        })
        .then(res=>{
            console.log(999)
        })
        .then(res=>{
            console.log(666)
        })
3.4:Promise 同步执行异步函数:

实现同步执行异步函数,只需要在每个回调中返回一个 Promise 对象即可。

        function asyncMeth_one(){
            return new Promise(resolve=>{
                setTimeout(() => {
                    console.log('run 800!');
                    resolve()
                }, 800);
            })
        }
        function asyncMeth_two(){
            return new Promise(resolve=>{
                setTimeout(() => {
                    console.log('run 500!')
                    resolve()
                }, 500);
            })
        }
        new Promise((resolve,reject)=>{
           resolve()
        })
        .then(res=>{
            return asyncMeth_one();
        })
        .then(res=>{
            return asyncMeth_two();
        })

4:Class 类

4.1:constructor 构造器

当使用 new 关键词调用 时,会自动调用 constructor

        class People{
            constructor(){
                console.log('被 new 了');
            }
        }
        new People();
4.2:super

当继承时,如果子类使用了 constructor 构造器,则必须使用 super 关键词。

        class Earth {
            constructor(name){
               this.name = name;
            }
        }
        class People extends Earth{
            constructor(){
                super('anny');
                console.log(this.name);
            }
        }
        new People();

5:箭头函数

5.1:没有自己的 this

箭头函数的 this 指向作用域链的上一层。

        function test(){
            this.name = 'anny';
            let arrow = ()=>{
                console.log(this.name);
            }
            arrow();
        }
        test();
5.2:不可以使用 new 命令

因为箭头函数没有自己的 this ,所以不可以用做 构造函数

5.3:没有 arguments 对象
5.4:不能用做 Generator 函数

6:函数默认值

函数参数可以设置默认值:

        function test(a,b=100){
            return a+b;
        }
        console.log(test(80));

注意:函数默认值不会更改函数 arguments 的值。

7:模版字符串

通常,我们需要非常复杂的连接字符串。

        function test(){
            let name = 'anny';
            let age = 22;
            return "My name is " + name + "; age is "+ age;
        }
        console.log(test());

但是我们可以通过使用模板字符串来大大简化这一点。

        function test(){
            let name = 'anny';
            let age = 22;
            return `My name is ${name}; age is ${age}`;
        }
        console.log(test());

8:解构赋值

8.1:解构对象
        let obj = {
            name:'anny',
            age:22
        }
        let {age} = obj;
        console.log(age);
8.1.1 设置别名:
        let obj = {
            name:'anny',
            age:22
        }
        let {age:Myage} = obj;
        console.log(Myage);
8.1.2 动态名称:
        let key = 'age';
        let obj = {
            name:'anny',
            age:22
        }
        let {[key]:Myage} = obj;
        console.log(Myage);
8.2:解构对象使用/例子

我们这里拿 console 为例:

        let {log} = console;
        log(888);
8.3:解构数组赋值
        let [a] = [1,2,3,4,5,6];
        console.log(a);
8.3.1:解构数组指定位置

只使用部分位置下标值,可以使用 逗号 分割。

        let [,,,a] = [1,2,3,4,5,6];
        console.log(a);

这里输出 4

8.4:解构数组
        let a = [1,2,3,4,5,6];
        console.log(...a);

9:展开语法

9.1:函数传值
        function test(a, b, c) {
            console.log(`a:${a},b:${b},c:${c}.`)
        }
        let arr = [1,2,3];
        test(...arr); //a:1,b:2,c:3.
9.2:函数接收值
        function test(...a) {
            console.log(a)
        }
        let arr = [1, 2, 3];
        test(...arr); //[1,2,3]
9.3:连接多个数组
        let arr1 = [4, 5, 6];
        let arr2 = [1, 2, 3, ...arr1];
        console.log(arr2); //[1,2,3,4,5,6]

10:对象属性缩写

对象属性名变量/函数 名称相同时就可以进行缩写。

比如:

        let age = 20;
        let obj = {
            age: age
        }

        /**
         * 缩写
        */
        let obj1 = {
            age
        }
        let obj = {
            speak: function speak() {
                console.log('speak')
            }
        }

        /**
         * 缩写
        */
        let obj1 = {
            speak() {
                console.log('speak')
            }
        }

11:模块化

注意:script 标签使用模块化需要设置 type="module" 属性。另外,本地运行,会有跨域提醒。需要搭建一个服务器解决。

11.1:import 引入
11.1.1:解构取值
import {name} from './test.js'
11.1.2:设置别名
import {name as names} from './test.js'
11.1.3:赋值对象
import * as names from './test.js'
console.log(names.name)
11.2:export 导出
11.2.1:export
export const name = 'anny';
export const age = 22;
11.2.2:export default
export default {
    name:'anny',
    age:20
}
11.2.3:export 和 export default 的区别
  1. import引入大部分相同,export default支持单独使用一个变量引入:
import name from './test.js'
  1. export 支持多次导出,而 export default 只可导出一次:

12:includes

includes用于判断数组中是否包含指定的值。

返回值:true/false

let arr = [1,2,3];
console.log(arr.includes(2))

可以指定查找 起始位置

let arr = [1,2,3];
console.log(arr.includes(2,1))

13:指数运算符

console.log(2**3) //8

等同于:2*2*2

14:async/await

用于同步执行异步函数:

14.1:误区——使用就会同步执行异步代码
async function test() {

    await setTimeout(() => {
        console.log(8888)
    }, 2000);

    console.log(999)
}

test(); //999 8888

其实 await 渴望接收一个 Promise 期约:

function asyncMeth(){
    return new Promise(resolve=>{
        setTimeout(()=>{
            console.log(8888)
            resolve();
        },1000)
    })
}
async function test() {

    await asyncMeth();

    console.log(999)
}

test(); // 8888 999
14.2:一旦使用了 await ,await 之后的代码(包括同步)都会异步执行
async function test() {

    await console.log(888);

    console.log(999)
}

test();
console.log(666)

输出:888 666 999

15:Object对象遍历

15.1:Object.values()

返回一个包含对象所有 属性值 的数组。

for in 的区别,for in会遍历原型链。

let obj = {
    name:'anny',
    age:20
}

console.log(Object.values(obj));

输出:['anny', 20]

15.2:Object.keys()

返回一个包含对象所有 属性名 的数组。

let obj = {
    name:'anny',
    age:20
}

console.log(Object.keys(obj));

输出:['name', 'age']

15.3:Object.entries()

返回一个包含对象自身可枚举属性的键值对数组。

let obj = {
    name:'anny',
    age:20
}

console.log(Object.entries(obj));

输出:[['name', 'anny'] , ['age', 20]]

16:Object.getOwnPropertyDescriptors()

Object.getOwnPropertyDescriptors() 方法用来获取一个对象的所有自身属性的描述符

对象属性描述符:

  1. configurable:属性描述符是否可以被改变/删除(默认false)
  2. enumerable:是否可以被枚举(默认false)
  3. value:属性对应的值(默认undefined)
  4. writable:属性值 value 是否可以被改变(默认false)

17:padStart()/padEnd()

padStart()/padEnd() 都属于填充字符串,只是填充开始位置不同。

17.1:padStart()
let str = '7878'
console.log(str.padStart(10,"*"))

输出:******7878

17.1:padEnd()
let str = '7878'
console.log(str.padEnd(10,"*"))

输出:7878******

18:ShareArrayBuffer

JavaScript 是单线程的,如果要使用多线程,可以使用 Workers 对象:
主线程用于与用户交互,Worker 线程用于承担计算任务

var myWorker = new Worker('test.js');

SharedArrayBuffer 的大部分作用是创建一块公共内存,供 主线程Workers 线程共同读写。

19:Atomics

Atomics 作用是提供一组静态方法对 SharedArrayBufferArrayBuffer 对象进行原子操作。

什么是原子操作?

原子操作:多个共享内存的线程能够同时读写同一位置上的数据。原子操作会确保正在读或写的数据的值是符合预期的,即下一个原子操作一定会在上一个原子操作结束后才会开始,其操作过程不会中断。

20:尾后逗号

let arr = [
    1,
    2,
    3
]

如果想要在数组中再添加一条数据(第 5 行),需要先在第 4 行添加一个 逗号,然后再添加数据。但在 版本比较 中会提醒第 4 行发生了改变。

为了方便 比较(diff),提案了 尾后逗号

它看起来就像这样:

let arr = [
    1,
    2,
    3,
]

21:for await 异步迭代

for await 可异步迭代 实现异步迭代器协议的对象

function * asyncMeth(){
    yield import('./test.js')
    yield import('./test3.js')
}

for await (let aa of asyncMeth()) {
    console.log(aa);
}

22:关于《带标签的模板字符串》非法转义序列的修订

22.1:什么是带标签的模板字符串
function test(msg) {
    console.log(msg)
}
test`this is anny`
22.2:带标签的模版字面量及转义序列
  1. Unicode 字符以"\u"开头,例如\u00A9
  2. Unicode 码位用"\u{}"表示,例如\u{2F804}
  3. 十六进制以"\x"开头,例如\xA9
  4. 八进制以""和数字开头,例如\251
22.3:为什么修订非法转义序列

就像看到的关于22.2:《带标签的模版字面量及转义序列》,解析器转义都是根据那些规则去查找有效的转义序列。

但提议者认为带标签的模版字符串应该 允许嵌套支持常见转义序列 的语言。

如:

function test(msg) {
    console.log(msg)
}
test`\unicode`

如果根据 22.2:《带标签的模版字面量及转义序列》 规则,该功能不能运行。

总的概括来说,就是允许更广泛的自定义写法,可以使用 undefined 代替解析不了的值,使用 raw 返回原始传入的字符串,而不是无法运行的 报错

23:正则拓展

这里只列出了一部分,更多详情请到搜索引擎查询。

23.1:具名组匹配

首先看一下 组匹配

let rep= /(\w{5})-(\w{8})/;
console.log(rep.exec("China-ShanDong"))

输出:

	0: "China-ShanDong"
	1: "China"
	2: "ShanDong"
	groups: undefined
	index: 0
	input: "China-ShanDong"
	length: 3

加个名称构成 具名组匹配(名称尽量使用英文,这里仅便于观察):

let rep= /(?<国家>\w{5})-(?<城市>\w{8})/;
console.log(rep.exec("China-ShanDong"))

输出:

	0: "China-ShanDong"
	1: "China"
	2: "ShanDong"
	groups:{
		国家: "China"
		城市: "ShanDong"
	}
	index: 0
	input: "China-ShanDong"
	length: 3
23.2:引入

可以使用 \k<组名>$ 的写法引用某个 具名组匹配

let rep= /(?<名字>\w{4})-\k<名字>$/;
console.log(rep.test("anny-anny")) // true
console.log(rep.test("anny-anny1")) // false

24:JSON.stringify 增强编码问题(转义字符串)

对于 无法编码 的字符串,返回 转义字符串

简单来说就是遇到无法编码的字符串时,直接返回你传入的原始字符串(之前是报错)。

25:flat

按照指定的深度递归数组,将所有元素和遍历到的子数组数据合并为一个新数组返回。

let arr = [1,2,3,[4,5,6]]
console.log(arr.flat(1)) 

输出:[1, 2, 3, 4, 5, 6]

let arr = [1,2,3,[[4,5,6]]]
console.log(arr.flat(1))

输出:[1, 2, 3, [4, 5, 6]]

25:flatMap

flatMap 使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 flat(1) 返回的值几乎相同。

let arr = [1,2,3,[4,5,6]]
console.log(arr.flatMap(e=>e))

输出:[1, 2, 3, 4, 5, 6]

26:trimStart/trimEnd 去除空格

顾名思义,一个是删除开始位置的空格,另一个是删除末尾位置的空格。

let str =`  123  `;
console.log(str.trimStart())
console.log(str.trimEnd())

27:Object.fromEntries()

Object.fromEntries() 作用是把键值对列表转换为一个对象。

如:

let arr = [
    ['name','anny'],
    ['age',20]
]
console.log(Object.fromEntries(arr));

输出:

{
	age: 20
	name: "anny"
}

28:Symbol.prototype.description

Symbol.prototype.description:返回 Symbol 对象的可选描述的字符串。

Symbol.prototype.toString() 的区别:

let a = Symbol('hello')
console.log(a.toString()) 
console.log(a.description);

a.toString() 输出:Symbol(hello)

a.description 输出:hello

你可能感兴趣的:(JavaScript,javascript,es6,前端)