目录
1. ES6 新特征 (2015)
1.1 module
1.1.1 export
1.1.2 import
1.2 Arrow function (箭头函数)
1.2.1 箭头函数结构
1.3 默认参数
1.4 模板字符串
1.5. 解构赋值
1.5.1数组的结构赋值
1.5.2 对象解构赋值
1.6 扩展运算符
1.7Promise(异步)
2 ES7新特征 (2016)
2.1 includes()
2.2 index operator** (指数运算符 **)
3 es8 新特征(2017)
3.1 async/await
3.2 Object.keys()
3.3 Object.values()
3.4 Object.entries()
3.5 字符串填充
3.6 Object.getOwnPropertyDescriptors()
3.8 原子对象
4 ES9新特征 (2018)
4.1 asynchronous iterator (异步迭代器)
4.2 非转义序列的模板字符串
4.3 正则表达式反向断言
4.4 正则表达式Unicode转义
4.5 正则表达式s/dotAll模式
4.6 正则表达式命名捕获组
4.7 object expansion operator
4.8 Promise.finally()
5 ES10 新特征 (2019)
5.1 添加Array的flat()方法和flatMap()方法
5.1.1 flat()
5.1.2 flatMap()
5.2 增加了String的trimStart()方法和trimEnd()方法
5.3 Object.fromEntries()
5.4 Symbol.prototype.description
5.5 String.protype.matchAll()
5.6 Function.prototype.toString()现在返回精确的字符,包括空格和注释
5.7 JSON⊂ECMAScript
5.8 简化try {} catch{}并修改catch绑定
5.9 新的基本数据类型BigInt
1. ES6 新特征 (2015)
- class (类)
- Modularization (模块化)
- Arrow function (箭头函数)
- Function parameter defaults (函数参数的默认值)
- Template string (模板字符串)
- Destructuring assignment (结构赋值)
- Extension operator (扩展运算符)
- Object attribute shorthand (对象属性简写)
- Promise
- Let and Const
1.1 module
ES5不支持本机模块化,添加模块是ES6的重要组成部分。模块的功能主要由导出和导入两部分组成。每个模块都有自己的作用域。模块之间的相互调用关系是通过导出指定模块暴露的接口,通过导入引用其他模块提供的接口。同时,它还为模块创建命名空间,以防止函数命名冲突。
1.1.1 export
//导出变量 export var name = 'Rainbow'var name = 'Rainbow'; var age = '24'; export {name, age};//导出常数 export const sqrt = Math.sqrt;//导出函数 export function myModule(someArg) {return someArg;
1.1.2 import
import {myModule} from 'myModule';//使用解构赋值 import {name,age} from 'test';//import语句可以同时导入默认函数和其他变量。 import defaultMethod, { otherMethod } from 'xxx.js';
1.2 Arrow function (箭头函数)
这是ES6最令人兴奋的特性之一。它不仅仅是关键字function的缩写,它还带来了其他好处。箭头函数与周围的代码共享相同的this,可以帮助您解决这个指向的问题。有经验的JavaScript开发人员熟悉var self = this;或者var that = this指向周边this。但是如果使用= >,则不需要这种模式。
1.2.1 箭头函数结构
箭头函数的箭头= >前面是一个空括号,一个参数名,或括号内括的多个参数名,箭头后面可以是一个表达式(作为函数的返回值),或花括号内括的函数体(需要自己返回值,否则为undefined)。
// 箭头函数例子 ()=>1 v=>v+1 (a,b)=>a+b ()=>{alert("foo"); } e=>{if (e == 0){return 0;}return 1000/e;
无论它是一个箭头函数还是一个绑定函数,它都会在每次执行时返回一个新的函数引用,所以如果你需要一个函数引用来做其他事情(比如卸载监听器),你必须自己保存这个引用
//错误例子 class PauseMenu extends React.Component{componentWillMount(){AppStateIOS.addEventListener('change', this.onAppPaused.bind(this));}componentWillUnmount(){AppStateIOS.removeEventListener('change', this.onAppPaused.bind(this));}onAppPaused(event){} }//正确例子 class PauseMenu extends React.Component{constructor(props){super(props);this._onAppPaused = this.onAppPaused.bind(this);}componentWillMount(){AppStateIOS.addEventListener('change', this._onAppPaused);}componentWillUnmount(){AppStateIOS.removeEventListener('change', this._onAppPaused);}onAppPaused(event){} }//简化的正确方法 class PauseMenu extends React.Component{componentWillMount(){AppStateIOS.addEventListener('change', this.onAppPaused);}componentWillUnmount(){AppStateIOS.removeEventListener('change', this.onAppPaused);}onAppPaused = (event) => {//Define the function directly as an arrow function attribute, and bind this pointer when initializing} }//需要注意的是,无论bind函数还是arrow函数,每次都会返回一个新的函数引用, //因此,如果你需要一个函数引用来做其他事情(比如卸载监听器),你必须自己保存这个引用。
1.3 默认参数
const test = (a='a',b='b',c='c')=>{return a+b+c }console.log(test('A','B','C')) //ABC console.log(test('A','B')) //ABc console.log(test('A')) //Abc
1.4 模板字符串
//Use template string:var name = `Your name is ${first} ${last}.`
1.5. 解构赋值
1.5.1数组的结构赋值
var foo = ["one", "two", "three", "four"];var [one, two, three] = foo; console.log(one); // "one" console.log(two); // "two" console.log(three); // "three"//如果你想忽略一些值,你可以得到你想要的值如下所示 var [first, , , last] = foo; console.log(first); // "one" console.log(last); // "four"//你可以这样写 var a, b; //首先声明一个变量[a, b] = [1, 2]; console.log(a); // 1 console.log(b); // 2
使用结构赋值来交换两个变量的值
var a = 1; var b = 3;[a, b] = [b, a]; console.log(a); // 3 console.log(b); // 1
1.5.2 对象解构赋值
const student = {name:'Ming',age:'18',city:'Shanghai' };const {name,age,city} = student; console.log(name); // "Ming" console.log(age); // "18" console.log(city); // "Shanghai"
1.6 扩展运算符
var arr1 = [0, 1, 2]; var arr2 = [3, 4, 5]; var arr3 = [...arr1, ...arr2];// 将arr2中的所有元素追加到arr1之后并返回 //等同于 var arr4 = arr1.concat(arr2);var obj1 = { foo: 'bar', x: 42 }; var obj2 = { foo: 'baz', y: 13 };var clonedObj = { ...obj1 }; // 克隆对象: {foo: 'bar', X: 42}var mergedObj = { ...obj1, ...obj2 }; //合并对象: {foo: 'Baz', X: 42, Y: 13}
在react中的应用
const params = {name: 'Jine',age: 21 } <CustomComponent {...params} />var params = {name: '123',title: '456',type: 'aaa' }var { type, ...other } = params;<CustomComponent type='normal' number={2} {...other} /> //等同于 <CustomComponent type='normal' number={2} name='123' title='456' />
1.7Promise(异步)
var test = (a,b)=>{return new Promise((reslove,reject)=>{//Asynchronous operation//...reslove(resoult)//Return correct results//...reject(err) //Results on error}) }//Usetest(a,b).then(res=>{//... promise reslove() 返回正确的结果并在这里执行 }).catch(err=>{//在前面的拒绝(错误)之后,代码将执行成 })//perhapstry{var resoult = await test(a,b)//... }catch(er){//... }
2 ES7新特征 (2016)
- array includes()方法用于确定数组是否包含指定的值。如果是,则返回true,否则返回false
-
a ** b 指数运算符 等同于 Math.pow(a, b).
2.1 includes()
includes()函数用于确定数组是否包含指定的值。如果是,则返回true。否则,它返回false
let arr = ['react', 'angular', 'vue'];if (arr.includes('react')) {console.log('react existence'); }
2.2 index operator** (指数运算符 **)
在ES7中,引入了指数算符,其结果等价于Math.pow(..)
console.log(2**10);// Output 1024 console.log(Math.pow(2, 10)) // Output 1024
3 es8 新特征(2017)
- async/await
- Object.values()
- Object.entries()
- 字符串填充: padStart() and padEnd(), 填充字符串达到当前长度
- 允许在函数参数列表的末尾使用逗号
- Object.getOwnPropertyDescriptors()
-
ShareArrayBuffer和Atomics对象,用于从共享内存位置进行读写s
3.1 async/await
async function init() {console.log('start')await this.testSync()console.log('End')}this.init()async function testSync() {const response = await new Promise(resolve => {setTimeout(() => {resolve("async await test...");}, 1000);});console.log(response);}
3.2 Object.keys()
var obj = { foo: "bar", baz: 42 }; Object.keys(obj) // ["foo", "baz"]
3.3 Object.values()
var obj = { foo: "bar", baz: 42 }; Object.values(obj) // ["bar", 42]
3.4 Object.entries()
Object.entries 方法返回参数对象本身的所有可枚举属性(不包括继承)的键值对数组。
var obj = { foo: 'bar', baz: 42 }; Object.entries(obj) // [ ["foo", "bar"], ["baz", 42] ]const obj1 = {a: 1, b: 2, c: 3} for(let [key,value] of Object.entries(obj1)){console.log(`key: ${key} value:${value}`) } //key:a value:1 //key:b value:2 //key:c value:3
Object.entries 方法把一个对象变成一个真正的Map结构。
var obj = { foo: 'bar', baz: 42 }; var map = new Map(Object.entries(obj)); map // Map { foo: "bar", baz: 42 }
Object object keys(), values() entries()
3.5 字符串填充
String.padStart(targetLength,[padString])
String.padEnd(targetLength,padString])
- targetLength:当前字符串需要填充到的目标长度。如果该值小于当前字符串的长度,则返回当前字符串本身。
- padString:(可选)填充字符串。如果字符串太长,以致填充字符串的长度超过目标长度,则只保留最左边的部分,其余部分将被截断。该参数的默认值是' '。
console.log('0.0'.padStart(4,'*')) console.log('0.0'.padStart(20)) console.log('0.0'.padEnd(4,'*')) console.log('0.0'.padEnd(10,'*'))/* *0.00.0 0.0* 0.0******* */
3.6 Object.getOwnPropertyDescriptors()
Object.getOwnPropertyDescriptor 方法返回一个对象(描述符)。ES6引入了Object。方法,该方法返回指定对象的所有自身属性(非继承属性)的描述对象。
const obj = {foo: 123,get bar() { return 'abc' } };Object.getOwnPropertyDescriptors(obj) // { foo: // { value: 123, // writable: true, // enumerable: true, // configurable: true }, // bar: // { get: [Function: bar], // set: undefined, // enumerable: true, // configurable: true } }
在上面的代码中,对象。方法返回一个对象。所有原始对象的属性名称就是对象的属性名称,对应的属性值就是属性描述对象。
该方法的主要目的是解决Object.assign()不能正确复制获取和设置属性的问题。
const source = {set foo(value) {console.log(value);} };const target1 = {}; Object.assign(target1, source);Object.getOwnPropertyDescriptor(target1, 'foo') // { value: undefined, // writable: true, // enumerable: true, // configurable: true }
在上面的代码中,源对象的foo属性值是一个赋值函数。对象。Assign方法将此属性复制到target1对象。因此,该属性的值没有定义。这是因为对象。赋值方法总是复制属性的值,而不是属性后面的赋值方法或值方法。
ES6 object extension - Object.getOwnPropertyDescriptors()
3.7 SharedArrayBuffer对象
使用SharedArrayBuffer,多个web工作者可以同时读写同一块内存。您不再需要延迟的postMessage通信。多个web工作者在访问数据时没有延迟
SharedArrayBuffer对象用于表示一个通用的、固定长度的原始二进制数据缓冲区,类似于ArrayBuffer对象,它可以用于在共享内存上创建视图。与ArrayBuffer不同,SharedArrayBuffer不能被分离。
/*** * @param {*} length创建的数组缓冲区的大小,以字节为单位。 * @returns {SharedArrayBuffer} 指定大小的新SharedArrayBuffer对象。它的内容被初始化为0*/ new SharedArrayBuffer(length)
Illustration of ArrayBuffers and shared ArrayBuffers
3.8 原子对象
Atomics对象提供了一组静态方法,用于对SharedArrayBuffer对象进行原子操作。
这些原子操作属于Atomics模块。与一般全局对象不同,Atomics不是构造函数,因此不能用new操作符调用它,也不能直接作为函数调用它。Atomics的所有属性和方法都是静态的(像Math对象一样)。
共享内存的多个线程可以同时在同一位置读和写数据。原子操作确保正在读或写的数据的值满足预期,即下一个原子操作直到前一个原子操作结束才开始,其操作过程不会中断。
Atomics.add() //将指定位置的数组元素添加到给定值,并返回添加该元素之前的值。Atomics.and() //将指定位置的数组元素与给定值进行比较,并返回操作前元素的值。Atomics.compareExchange() //如果数组中指定的元素等于给定值,则更新为新值并返回元素的原始值。Atomics.exchange() //将数组中指定的元素更新为给定值,并在更新元素之前返回该值。Atomics.load() //返回数组中指定元素的值Atomics.or() //将指定位置的数组元素与给定值进行比较,并返回or操作之前元素的值。Atomics.store() //将数组中指定的元素设置为给定值并返回该值。Atomics.sub() //从给定值中减去指定位置上的数组元素,并返回减法前的元素值。Atomics.xor() //指定位置的数组元素与给定值或不同,并且返回排他或操作之前的元素的值。// wait()和wake()方法使用Linux上的futexes模型(快速用户空间互斥锁, //快速用户空间互斥锁),它允许进程等待,直到特定的条件为真,主要用于实现阻塞。Atomics.wait() //检查数组中指定位置的值是否仍然为给定值,如果是,则保持直到唤醒或超时。 //返回值为"ok", "not equal"或"time out"调用时,如果当前线程不允许阻塞,则抛出异常 //大多数浏览器不允许在主线程中调用wait()。Atomics.wake() //唤醒等待队列中等待数组中指定位置的元素的线程。返回值是成功唤醒的线程数Atomics.isLockFree(size) //它可用于检测当前系统是否支持硬件级原子操作。对于指定大小的数组,如果当前系统支持硬件级原子操作, //返回true;否则,这意味着对于数组,Atomics对象中的每个原子操作只能通过一个锁实现。这个功能是为技术专家准备的。
4 ES9新特征 (2018)
- Asynchronous iterator ( 异步迭代器)
- 非转义序列的模板字符串
- 反向正则表达式
- 正则表达式Unicode转义
- 正则表达式s/dotAll模式
- 正则表达式命名捕获组
- 对象扩展运算符
- Promise.prototype.finally
4.1 asynchronous iterator (异步迭代器)
ES2018引入了异步迭代器,就像常规迭代器一样,只是next()方法返回一个Promise。因此,await可以与for…连用。的循环以串行方式运行异步操作。例如:
async function process(array) {for await (let i of array) {doSomething(i);} }
4.2 非转义序列的模板字符串
标签允许你用函数解析模板字符串。tag函数的第一个参数包含一个字符串值数组。其余的参数依赖于表达式。最后,函数可以返回处理过的字符串(也可以返回完全不同的内容)。
function foo(str) {return str[0].toUpperCase(); }foo`justjavac`; // Output JUSTJAVAC foo`Xyz`; // Output XYZ
New features of ES2018: template string of non escape sequence
4.3 正则表达式反向断言
断言是对当前匹配位置之前或之后的字符进行测试。它实际上并不消耗任何字符,因此断言也被称为“非消耗匹配”或“非获取匹配”。
正则表达式断言有四种形式:
- (? = pattern) 零宽度正向前视断言
- (?! pattern) 零宽负向先行断言
- (? < pattern) 零宽度正面看背后断言
- (? <! Pattern) 零宽度负向后看断言
这里的模式是一个正则表达式。
Look behind assertion
4.4 正则表达式Unicode转义
一般来说,数字字符解释[0-9],单词字符是[0-9a-zA-Z],空白字符包括空格、回车和其他字符,但这是在ASCII编码中,而不是在Unicode编码中。
. Therefore, if 在Python 2中指定正则表达式使用Unicode模式(最简单的解释方法是指定模式修饰符(?u)在正则表达式的开头),\ d \ w \ s可以匹配所有的角号、汉字和所有的角空格。在本例中,本书将其称为Unicode匹配规则;相应的,前面ASCII编码中的匹配称为ASCII匹配规则。
Regular expression -- Unicode matching rule
4.5 正则表达式s/dotAll模式
Regular expression s/dotAll mode
4.6 正则表达式命名捕获组
constreDate = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/,match = reDate.exec('2018-04-30'),year = match.groups.year, // 2018month = match.groups.month, // 04day = match.groups.day; // 30constreDate = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/,d = '2018-04-30',usDate = d.replace(reDate, '$<month>-$<day>-$<year>');
4.7 object expansion operator
let a = [1,2,3]; let b = [0, ...a, 4]; // [0,1,2,3,4]let obj = { a: 1, b: 2 }; let obj2 = { ...obj, c: 3 }; // { a:1, b:2, c:3 } let obj3 = { ...obj, a: 3 }; // { a:3, b:2 }
let object = {a: '01', b: '02' };let newObject = {c: '03',...object };console.log(newObject); //{c: "03", a: "01", b: "02"}
4.8 Promise.finally()
Promise调用链要么成功到达最后一个。则(),或无法触发。赶上()。在某些情况下,无论Promise运行成功还是失败,您都希望运行相同的代码,例如清除、删除对话、关闭数据库连接等。
function doSomething() {doSomething1().then(doSomething2).then(doSomething3).catch(err => {console.log(err);}).finally(() => {// finish here!}); }
5 ES10 新特征 (2019)
- 增加Array的flat()方法和flatMap()方法
- 增加了String的trimStart()方法和trimEnd()方法
- Object.fromEntries()
- Symbol.prototype.description
- String.prototype.matchAll
- Function.prototype.toString()现在返回精确的字符,包括空格和注释
- JSON⊂ECMAScript
- 简化try {} catch{}并修改catch绑定
- 新的基本数据类型BigInt
- globalThis
- import()
- 遗留的正则表达式
- 私有实例方法和访问器
5.1 添加Array的flat()方法和flatMap()方法
lat()和flatMap()本质上是reduce和concat的操作。
flat()方法递归地遍历指定深度的数组,并将遍历子数组中的所有元素和元素合并到要返回的新数组中。
- flat()方法的基本功能是降低数组的维数
- 其次,我们可以使用flat()方法的特性来删除数组中的空项
5.1.1 flat()
var arr1 = [1, 2, [3, 4]]; arr1.flat(); // [1, 2, 3, 4]var arr2 = [1, 2, [3, 4, [5, 6]]]; arr2.flat(); // [1, 2, 3, 4, [5, 6]]var arr3 = [1, 2, [3, 4, [5, 6]]]; arr3.flat(2); // [1, 2, 3, 4, 5, 6]//使用Infinity作为深度,展开任意深度的嵌套数组 arr3.flat(Infinity); // [1, 2, 3, 4, 5, 6]//删除空项 var arr4 = [1, 2, , 4, 5]; arr4.flat(); // [1, 2, 4, 5]
5.1.2 flatMap()
var arr1 = [1, 2, 3, 4];arr1.map(x => [x * 2]); // [[2], [4], [6], [8]]arr1.flatMap(x => [x * 2]); // [2, 4, 6, 8]// 只将flatMap中函数返回的数组“flatten” arr1.flatMap(x => [[x * 2]]); // [[2], [4], [6], [8]]
5.2 增加了String的trimStart()方法和trimEnd()方法
string. trimstart()可用于删除字符串开头的空格。
string. trimend()可用于删除字符串末尾的空格。
let greeting = " Hello World"; console.log(greeting.trimStart());// "Hello World"let greeting = "Hello World "; console.log(greeting.trimEnd());// "Hello World"
5.3 Object.fromEntries()
object .entries()方法的功能是返回给定对象的可枚举属性的键值对数组,其排列顺序与for…In循环用于遍历对象(不同之处在于for In循环还枚举原型链中的属性)。
Object.fromEntries() 与Object.entries()相反.
object . fromentries()函数传入键值对列表,并返回一个包含这些键值对的新对象。迭代形参应该是一个可以实现@ iterator方法并返回迭代器对象的对象。它生成一个类似数组的对象,其中包含两个元素,第一个是用作属性键的值,第二个是与属性键相关联的值。
-
通过Object. fromentries, Map可以转换为Object:
const map = new Map([ ['foo', 'bar'], ['baz', 42] ]); const obj = Object.fromEntries(map); console.log(obj); // { foo: "bar", baz: 42 }
- 通过Object. fromentries,你可以将Array转换为Object
const arr = [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]; const obj = Object.fromEntries(arr); console.log(obj); // { 0: "a", 1: "b", 2: "c" }
5.4 Symbol.prototype.description
只读描述属性,它是返回Symbol对象的可选描述的字符串。
let mySymbol = `My Symbol`;let symObj = Symbol(mySymbol);console.log(symObj) // Symbol(mySymbol);console.log(String(symObj) === `Symbol(${mySymbol})`); // trueconsole.log(symObj.description); // "My Symbol"
5.5 String.protype.matchAll()
matchAll()方法返回一个迭代器,其中包含匹配字符串与正则表达式的所有结果,包括捕获组。
const string = 'Hexadecimal number:DEADBEEF CAFE' const regex = '\b\p{ASCII_Hex_digit}+\b/gu'for(const match of string.match(regex)) {console.log(Math) } /*outputDEADBEEFCAFE */ // 2.字符串。matchAll给出关于每个匹配项的更详细信息 const string = 'Hexadecimal number:DEADBEEF CAFE' const regex = '\b\p{ASCII_Hex_digit}+\b/gu'for(const match of string.matchAll(regex)) {console.log(Math) } /*output["DEADBEEF", index: 8, input: "Hexadecimal number: DEADBEEF CAFE", groups: undefind]["CAFE", index: 17, input: "Hexadecimal number: DEADBEEF CAFE", groups: undefind] */
5.6 Function.prototype.toString()现在返回精确的字符,包括空格和注释
toString()方法返回一个表示函数源代码的字符串。在ES6中,当在函数上调用toString时,它根据ECMAScript引擎返回函数的字符串表示形式。如果可能,它将返回源代码,否则返回一个标准化的占位符。
this.fruits = [] function buyFruits(fruit) {this.fruits = [...this.fruits, fruit] } console.log(buyFruits.toString())/* function buyFruits(fruit) {this.fruits = [...this.fruits, fruit] } */
5.7 JSON⊂ECMAScript
在ES10之前的版本中,不接受非转义行分隔符U+2028和段落分隔符U+2029。
U+2028是段落分隔符。
U+2029为行分隔符。
let LS = "" const PS = eval("'\u2029'")
5.8 简化try {} catch{}并修改catch绑定
可选的catch绑定允许开发人员在catch块中使用try/catch,而不使用error参数。
// Use before ES2019 try {// some code }catch (err) {// 错误代码处理 }// 现在像ES2019一样使用try / catch: try {// some code }catch {// error handling code }
5.9 新的基本数据类型BigInt
BigInt是第七个原语类型,它是一个精度任意的整数。而不仅仅是900719925474092的最大值。