ES2015到ES2017(即ES6开始)新特性总结

    科技2025-04-05  13

    ES2015 俗称ES6 新特性

    官网链接: https://www.ecma-international.org/ecma-262/6.0/

    新特性主要目的:

    解决原有语法上的一些问题或者不足 let、const对原有语法增强 结构、展开、模板字符串等全新的对象、方法、功能 Promise、Proxy、Reflect等全新的数据类型、数据结构 set 、Map等

    常见新特性:

    作用域 全局作用域(旧版本) 函数作用域(旧版本) 块级作用域

    声明变量 var (旧版本) 可实现变量声明的提升,JS只有函数作用域和全局作用域,在声明变量之前调用,返回undefined,用法上不够严谨 let let声明的成员,删除变量声明的提升功能,只能在其块级作用域中被访问到

    const const声明的成员是只读的,只能修改const声明变量的内容,不能改变变量内存地址。 全局 const声明的变量不会挂载到windows上。因为没有块级作用域环境。

    const arr = [1,2,3] arr.push(4) // [1,2,3,4] arr = [1,2] // 报错 剩余参数( … 的 rest 作用) function (param1,param2,...params) { ​ statements }

    数组解构( … 的 解构 作用)

    […arr]

    ​ …必须在最后一个元素前使用(越界会被解构成undefind)

    ​ [name=‘xiaoming’,age] = arr 解构可赋值默认值

    模板字符串 字符串换行直接换行实现 插值表达式

    `${js语句 1+2 或 变量 name} 这一句是换行后的内容。`

    可以添加标签tag(实际是个函数)

    includes()、startWith()、endsWith() 字符串扩展方法

    参数默认值()

    在需要默认值的形参后加默认值

    function (name = xiaoming) {}

    参数扩展,数组扩展

    参数扩展 function (…args) {}

    数组扩展 const arr = [‘foo’, ‘bar’, ‘baz’]

    console.log.apply(console, arr) =>旧

    console.log(…arr) =>新

    箭头函数

    fira Code 编程连体字体

    不会改变this指向。没有自己的this,arguments,super或new.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。

    不会绑定普通函数的arguments对象

    普通函数中,this始终会指向调用者对象

    可简化返回值的表达方式

    对象字面量

    value为值:当属性名和属性值名称相同时,可省略value

    value为普通函数():可省略:与 function关键字

    可以使用表达式或函数返回值作为属性名

    const obj = { ​ name,method () {return "hello world"},[1+1] : "this is JS" }

    对象扩展

    相同属性覆盖,不同属性扩展

    Object.assign

    const source1 = { a: 123, b: 123 } const source2 = { a: 123, b: 123 } const target = { b: 456, c: 456 } const newTarget = Object.assign(target, source1, source2) console.log(newTarget === target) // {a:123, c: 456, b: 123} // true // 应用🌰: function (obj) { // 复制,标识默认值 const newObj = Object.assign({},obj) newObj.name = obj.name || "defaultValue" }

    Object.is

    比较的三种形式:

    方式特点==比较前会进行类型转换(0==faluse 成立)===推荐常用:严格模式(0=faluse 不成立,+0=-0 不成立,NaN === NaN 不成立)Object.is()+0===-0 成立,NaN === NaN 成立

    Object.defineProperty 的加强版—> Proxy

    为对象设置访问代理器,监听对象的读写等

    二者比较:

    类型功能具体表现Proxy监听范围1. 可监视到属性的读写、调用,删除等操作2. 可监听和重写数组方法(set 监听数组的写入 ,获取 下标 值)Object.defineProperty监听范围只能监听属性的读写Proxy监听形式必须特定写法才能监听特定属性Object.defineProperty监听形式Proxy是以非侵入方式监听,不必指定属性名Object.defineProperty(person,"name",{ set() {} get() {} })

    Reflect

    静态方法,不能实例化,有13个成员方法(14个废弃掉一个),是Proxy处理对象的默认实现,提供了一套统一操作对象的API

    const person = { name: "xiaoming", sex: "man", age: 18 } const personProxy = new Proxy(person, { get(target, property) { // 监听的对象target,对象的属性property return Reflect.get(target,property) }, set(target, property, value) { // 监听的对象target,对象的属性property,属性的值value }, deleteProperty (target, property) { delete target[property] } }) delete personProxy.age Reflect.has(person, 'name') Reflect.deleteProperty(person, 'age') Reflect.ownKeys(person)

    Promise

    用于解决异步编程的新增解决方案

    class 类,继承

    class Person { contructor (name) { this.name = name } // 静态方法 static create (name) { return new Person(name) } // 实例方法 say () { } } class Student extends Person { contructor (name) { super(name) } say(){ super.say() } } const p1 = new Person('xiaoming') const p1 = Person.create('xiaoming') const s = new Person('xiaohong')

    set

    常用作数组去重

    常见方法:clear()、add(value)

    map

    与对象的本质都是键值对集合。但是 对象的key必须为字符串或者Symbol,map的key可以使用任意数据类型

    // Obj const obj = { name: "xiaoming" } Object.keys(obj) // ['name'] // Map const map = new Map() const name = {leader: 'xiaoming',member: 'xiaohong'} map.set(name,'xiaomingTeam') map.get(name) map.forEach(value,key) => { console.log(value,key) } // 'xiaomingTeam' {leader: 'xiaoming',member: 'xiaohong'}

    Symbol

    用于表示对象的一个独一无二的属性名(例如避免对象属性扩展时覆盖)

    const name = Symbol() const person = { [name]: 'xiaoming', say(){ console.log(`hello ${this[name]}`) } }

    获取Symbol:

    Object.getOwnPropertySymbols(obj) 只能获取到Symbol属性名。

    以下操作无法获取到Symbol:

    for inObject.keys(obj)JSON.stringify(obj)

    只能获取到字符串属性名。

    // .for 接收字符串。不是字符串也会转换成字符串 const s1 = Symbol.for('haha') const s2 = Symbol.for('haha') console.log(s1 === s2) // true Symbol.for('true') === Symbol.for(true) // true // 标识tag const obj = { [Symbol.toString]: 'NewObj' } console.log(obj.toString()) // [object NewObj]

    for of 循环

    用于遍历数组、伪数组、set、map

    获取到的是数组中每一个元素(map获取到的是[key, value]数组),可以使用break终止循环,而forEach是不能break终止遍历的。

    arr.some()

    arr.every()

    也是可以通过返回true或者false终止遍历的

    ES2015提供了Iterable接口,能够使用for of遍历的数据结构。

    数组、Map、set都实现了Iterable接口,挂载了iterator方法。iterator.next()可按顺序返回数据结构中的每一个元素,并通过done是否为true来标记循环的结束。

    如何使对象 实现for of?

    // 实现可迭代接口irerable const obj = { let index = 0 const originArr = ['hello', 'world','!'] [Symbol,iterator]: function() { // 实现iterator return { next: function() { // 实现 iterationresult const result = { value: originArr[index], done: index++ >= self.originArr.length } return result } } } }

    迭代器模式:实现统一迭代接口,不用关心数据内部数据结构

    Generator

    减少异步回调嵌套,提供更好的异步编程解决方案

    // 实现了迭代接口协议 function * func() { return 100 } const result = func() console.log(result) // Object [Generator] {} console.log(result.next()) // {value: 100, done: true} // yield 惰性执行迭代 function * func2() { console.log("111") yield 100 console.log("222") yield 200 console.log("333") yield 300 } const generator = func2() console.log(generator.next()) // 111 // {value: 100, done: false} console.log(generator.next()) // 111 // {value: 100, done: false} // 222 // {value: 200, done: false} console.log(generator.next()) // 111 // {value: 100, done: false} // 222 // {value: 200, done: false} // 333 // {value: 300, done: false} function * createIdMaker () { let id = 1 while (true) { yield id ++ } } const idMaker = createIdMaker().next().value // 实现可迭代接口irerable const obj = { let index = 0 const originArr1 = ['hello', 'world','!'] const originArr2 = ['a','b','c'] [Symbol,iterator]: function * () { const all = [...originArr1, ...originArr2] // 实现iterator next: function * () { // 实现 iterationresult for (const item of all) { yield item } } } } for (const item of obj) { console.log(item) }

    ES Modules 模块化

    ES2016(ECMAScript第七个版本)

    数组的includes()

    返回bool值,表达是否存在,也可检测NaN(indexof不能判断NaN(NaN是一个值))

    指数运算符

    2 ** 10 // 1024

    ES2017 (ECMAScript第八个版本)

    Object.values

    所有值组成的数组

    Object.entries

    数组形式返回键值对 [‘key’, ‘value’]

    Object.getOwnPropertyDescriptors

    获取对象的属性完整信息

    const p1 = { firstName : 'ming', lastName : 'xiao' get fullName () { return this.firstName + ' ' + this.lastName } } const descriptors = Object.getOwnPropertyDescriptors(p1) const p2 = Object.defineProperties({},descriptors) p2.firstName = 'hong' console.log(p2.fullName) // hong xiao

    string.prototype.padStart / String.prototype.padEnd

    字符串添加方法

    在函数参数中添加尾逗号

    const arr = [100, 200, 300,]

    async 函数

    配合await,可以彻底解决异步回调嵌套问题,本质上是Promise语法糖

    Processed: 0.009, SQL: 8