ES7-ES11新特性汇总
前言
ES全称ECMAScript,ECMAScript 和 JavaScript 的关系是,前者是后者的规范,后者是前者的一种实现,从15年es6发版后,到目前的es11,es的新特性被广泛使用,成为项目开发必不可少的工具,这段时间又系统的学习了这部分的相关知识,对其归纳总结,作为这段时间学习成果的检验。
ES7-ES11新特性汇总
ES7新特性归纳
Array.prototype.includes()
我们如何判断一个数组是否包含一个元素?
熟悉es5的小伙伴会首先想到indexOf(),这个方法会返回当前数组元素的下标:
const arr = ["es6", "es7", "es8", "es9", "es10", "es11"] console.log(arr.indexOf("es6")) // 0 console.log(arr.indexOf("es12")) // -1
亦或者:
const item = arr.find((item) => {return item === "es6" }) console.log(item) // "es6"
那么这两种方式有什么弊端呢,我们往下看:
const arr = ["es6", "es7", "es8", "es9", "es10", "es11", NaN] console.log(arr.indexOf(NaN)) // -1const item = arr.find((item) => {return item === NaN }) console.log(item) // undefined
由此可以看出,es5的传统方法不满足我们的需求,无法判断数组中是否含有NaN,由此,es7提供给数组一个新的API,就是我们所说的Array.prototype.includes。
基本用法
const arr = ["es6", "es7", "es8", "es9", "es10", "es11",NaN] console.log(arr.includes("es6")) // true console.log(arr.includes(NaN)) // true console.log(arr.includes("es12")) // false
- Array.prototype.includes():可以接收两个参数,要搜索的值和搜索的开始索引。第二个参数可选,若为负数表示从末尾开始计数下标。
- 只能判断简单类型的数据,对于复杂类型的数据,比如对象类型的数组,二维数组,这些是无法判断的。
includes的用法和indexOf用法相似,都可以用来判断数组中是否包含一个元素,唯一的区别在于includes可以识别NaN。
幂运算符
我们如何求一个数的幂运算呢?
在es5中我们可以通过以下两种方式来实现:
// 通过Math.pow() console.log(Math.pow(2,53))// 自定义pow函数 function pow(base, exponent) {let sum = 1;for (let i = 0; i <exponent; i += 1) {sum *= base}return sum } console.log(pow(2, 53));
es7提供了一种 ** 运算符,可以更简单实现
console.log(2**53)
- 幂运算符的两个*号之间不能出现空格,前后有无空格都可以。
- 注意最大安全数:Number.MAX_SAFE_INTEGER = (2**53)-1
ES8新特性
async/await
- async/await是继es6中promise、generator后又一种更加优雅的异步编程的解决方案
- async函数是generator函数的语法糖
基本用法
// 不使用async/await function getPromise() {return new Promise((resolve, reject) => {setTimeout(() => {console.log(1);resolve(2);}, 1000);}); }function foo() {const res = getPromise();console.log(res);console.log(3); }foo(); // Promise {<pending>} // 3 // 1// 使用async/await async function foo() {const res = await getPromise();console.log(res);console.log(3); }foo();// 1 // 2 // 3
由上面两个例子的对比就能发现,async/await可以使异步任务处理起来像是同步任务,这是因为await关键字在执行的时候会停下来,等待异步任务执行完毕(await后面一般跟的是异步任务,否则没有意义)在继续执行同步任务。
更优雅的异步编程的解决方案
在es6之前我们对于这个过程应该不陌生
ajax('xxx/a', res => {console.log(res)ajax('xxx/b', res => {console.log(res)ajax('xxx/c', res => {console.log(res)})}) })
这种回调之后再回调的调用方式我们称之为“回调地狱”,这种回调方式在日常开发和项目维护当中很让人头疼。我们对比下es6中Promise的处理和es8中的async/await的处理方式就知道了为什么我们称async/await为更优雅的异步编程的解决方案。
// 以下都是模拟接口请求的代码 // Promise function getPromise(url) {return new Promise((resolve, reject) => {ajax(url, res => {resolve(res)}, err => {reject(err)})}) }getPromise('xxx/a').then(res => {console.log(res)return getPromise('xxx/b')}).then(res => {console.log(res)return getPromise('xxx/c')}).then(res => {console.log(res)}).catch(err => {console.log(err)})// async/awaitfunction request(url) {return new Promise(resolve => {ajax(url, res => {resolve(res)})}) } async function getData() {let res1 = await request('xxx/a')console.log(res1)let res2 = await request('xxx/b')console.log(res2)let res3 = await request('xxx/c')console.log(res3) } getData()
从两者的对比可以看出,Promise虽然将回调嵌套回调的方式改成平级调用,但是这种调用方式相比于async/await还是显得繁琐,而且async/await不存在回调。
Object.values()/Object.entries()
我们如何获取一个对象的每一个属性值?
在es5中我们常用Object,keys()及for in来直接获取
// Object,keys() const obj = {name: "张三",age: 18,sex: "male", }const values = Object.keys(obj).map(item => {return obj[item] }) console.log(values) // ["张三", 18, "male"]// for in for (let key in obj) {console.log(obj[key]) } // "张三", 18, "male"
es8为我们扩展了两个新的静态方法
Object.values()
Object.values() 返回一个数组,其元素是在对象上找到的可枚举属性值。
const obj = {name: "张三",age: 18,sex: "male", } console.log(Object.values(obj)) // ["张三", 18, "male"]
Object.entries
Object.entries()方法返回一个给定对象自身可枚举属性的键值对数组。
const obj = {name: "张三",age: 18,sex: "male", } console.log(Object.entries(obj)) // [["name", "张三"],["age", "18"], ["sex", "male"]]
for in 与Object.keys()/Object.values()/Object.entries()区别
从前面的例子可以看出for in与Object.keys()/Object.values()/Object.entries()均可以遍历对象的可枚举属性,那他们直接有什么区别呢
const obj = {name: "张三",age: 18,sex: "male", } Object.prototype.test = "test"for (let key in obj) {console.log(obj[key]) } // "张三", 18, "male","test" console.log(Object.keys(obj).map(key => obj[key])) // ["张三", 18, "male"] console.log(Object.values(obj)) // ["张三", 18, "male"] console.log(Object.entries(obj).map(([key, value]) => value)) // ["张三", 18, "male"]
for in可以遍历出原型链上的可枚举属性,而Object.keys()/Object.values()/Object.entries()只能遍历自身的可枚举属性
如何实现一个Object.values()/Object.entries()
const obj = {name: "张三",age: 18,sex: "male", } // Object.values function values(obj) {return Object.keys(obj).map(key => obj[key]) }// Object.entries function entries(obj) {return Object.keys(obj).map(key => [key, obj[key]]) }console.log(values(obj)) console.log(entries(obj))
Object.getOwnPropertyDescriptors()
前面提到可枚举属性,我们怎么设置属性的值可枚举呢?
Object.defineProperty()可以通过对描述符的设置进行更精准的控制对象属性,所谓描述符:
- value [属性的值]
- writable [属性的值是否可被改变]
- enumerable [属性的值是否可被枚举]
- configurable [描述符本身是否可被修改,属性是否可被删除]
var test = {name: '测试',value: 5 } Object.defineProperty(test, "name", {enumerable: false })for (let key in test) {console.log(key) } // value
Object.getOwnPropertyDescriptors ()
Object.getOwnPropertyDescriptors ()可以返回对象属性的描述符
let test = {name: '测试',value: 5 } console.log(Object.getOwnPropertyDescriptors(test)) // { // name: {value: "测试", writable: true, enumerable: true, configurable: true} // value: {value: 5, writable: true, enumerable: true, configurable: true} // }
Object.getOwnPropertyDescriptors(target,param)接收两个参数,返回某一个参数的描述符,通过这个方法可以实现一个Object.getOwnPropertyDescriptors ()
Object.getOwnPropertyDescriptors()实现
let test = {name: '测试',value: 5 }function getOwnPropertyDescriptors(obj) {const result = {};for (let key of Reflect.ownKeys(obj)) {result[key] = Object.getOwnPropertyDescriptor(obj, key);}return result; } getOwnPropertyDescriptors(test)
String.prototype.padStart()/String.prototype.padEnd()
padStart()
先看一个例子,希望把当前日期格式化:yyyy-mm-dd的格式:
// 返回一个yyyy-mm-dd格式的日期 function getTime() {const date = new Date();const year = date.getFullYear()const month = date.getMonth() + 1const day = date.getDate()return `${year}-${month}-${day}` } console.log(getTime()) // 2020-7-9
es8 中 String 新增了两个实例函数 String.prototype.padStart() 和 String.prototype.padEnd(),允许将空字符串或其他字符串添加到原始字符串的开头或结尾。
function getTime() {const date = new Date();const year = date.getFullYear()const month = (date.getMonth() + 1).toString().padStart(2, "0")const day = (date.getDate()).toString().padStart(2, "0")return `${year}-${month}-${day}` }console.log(getTime()) // 2020-07-09
padEnd()
在正式项目中后台返回的数据中时间一般会转为时间戳格式,处理时间戳的时候单位都是ms毫秒(13位),但有时候有可能是s秒做单位(10位),这个时候我们需要做一个13位的补全,保证单位是毫秒。
time = String(time).padEnd(13, '0')
尾逗号
此前,函数定义和调用时,都不允许最后一个参数后面出现逗号,es8 允许函数的最后一个参数有尾逗号
// es8以前 function foo(a, b, c, d) {console.log(a, b, c, d) }// es8 function foo(a, b, c, d,) {console.log(a, b, c, d) }
ES9新特性
for await of/Symbol.asyncIterator
es6中有一个新特性Iteartor,只要元素符合两个协议:
- 可迭代协议:对象包含Symbol.iterator属性;
- 迭代器协议:Symbol.iterator属性必须返回一个对象,这个对象包含一个next方法,且next方法也返回一个对象,此对象包含value,done两个属性
我们就可以使用for…of去遍历这个元素。
我们知道 for…of 可以遍历同步运行的任务,那如果是异步任务呢,如下:
function getPromise(time) {return new Promise((resolve, reject) => {setTimeout(() => {resolve(time)}, time)}) }const asyncArr = [getPromise(1000), getPromise(200), getPromise(3000)]for (let item of asyncArr) {console.log(item, item.then(res => {console.log(res)})) } // Promise {<pending>} // Promise {<pending>} // Promise {<pending>} // 200 // 1000 // 3000
在上述遍历的过程中可以看到三个任务是同步启动的,我们期望的是一个异步任务执行完,在执行下一个异步任务,然而从输出可以看出不是按任务的执行顺序输出的,这显然不太符合我们的要求,在 es9 中也可以用 for…await…of 来操作:
function getPromise(time) {return new Promise((resolve, reject) => {setTimeout(() => {resolve({value: time,done: false,});}, time);}); }const asyncArr = [getPromise(1000), getPromise(200), getPromise(3000)]; asyncArr[Symbol.asyncIterator] = function () {let nextIndex = 0;return {next() {return nextIndex < asyncArr.length? asyncArr[nextIndex++]: Promise.resolve({value: undefined,done: true,});},}; };async function test() {for await (let item of asyncArr) {console.log(Date.now(), item);} }test();// 1594374685156 1000 // 1594374685157 200 // 1594374687157 3000
await需要在async 函数或者 async 生成器里面使用
同步迭代器/异步迭代器
类别 同步迭代器 异步迭代器 迭代器协议 Symbol.iterator Symbol.asyncIteartor 遍历 for…of for…await…of
正则的扩展
dotAll/s
一句话总结dotAll模式就是:在正则中使用(.)字符时使用s修饰符可以解决(.)字符不能匹配行终止符的例外
console.log(/./.test(1)); console.log(/./.test("1")); console.log(/./.test("\n")); console.log(/./.test("\r")); console.log(/./.test("\u{2028}")); // true // true // false // false // false// 使用s修饰符 console.log(/./s.test(1)); console.log(/./s.test("1")); console.log(/./s.test("\n")); console.log(/./s.test("\r")); console.log(/./s.test("\u{2028}")); // true // true // true // true // true
- (.)是一个特殊字符,代表任意的单个字符,但是有两个例外。一个是四个字节的 UTF-16 字符,这个可以用u修饰符解决;另一个是行终止符
- 正则中可以使用的修饰符有i,g,m,y,u,s
具名组匹配
我们先看一个例子
console.log("2020-07-10".match(/(\d{4})-(\d{2})-(\d{2})/)); // ["2020-07-10", "2020", "07", "10", index: 0, input: "2020-07-10", groups: undefined]
按照 match 的语法,没有使用 g 修饰符,所以返回值第一个数值是正则表达式的完整匹配,接下来的第二个值到第四个值是分组匹配(2020, 07, 10),我们想要获取年月日的时候不得不通过数组的下标去获取,这样显得不灵活。仔细观察 match 返回值还有几个属性,分别是 index、input、groups。
- index [匹配的结果的开始位置]
- input [匹配的字符串]
- groups [捕获组 ]
所谓的具名组匹配就是命名捕获分组:
console.log("2020-07-10".match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/));// groups的值 groups: {year: "2020", month: "07", day: "10"}
这样我们就可以通过groups及命名分组获取对应的年月日的值了。
后行断言
let test = 'world hello' console.log(test.match(/(?<=world\s)hello/))
(?<)是后行断言的符号配合= 、!等使用。
对象的Rest和Spread语法
一个例子对比理解对象的Rest和Spread语法
const arr1 = [1, 2, 3]; const arr2 = [4, 5, 6];// 数组合并 const arr = [...arr1, ...arr2]; console.log(arr);const obj1 = { a: 1 }; const obj2 = { b: 2 };// 对象合并 const obj = { ...obj1, ...obj2 }; console.log(obj);// [1, 2, 3, 4, 5, 6] // {a: 1, b: 2}
一句话总结就是(…)运算符在数组中可以怎样使用,在对象就可以怎样使用。
Promise.prototype.finally()
不管promise状态如何都会执行的回调函数
new Promise((resolve, reject) => {resolve(1); }).then((res) => {console.log(res);}).catch((err) => {console.log(err);}).finally(() => {console.log("finally");}); // 1 // promise
带标签的模板字符串扩展
es9 新特性中移除了对 ECMAScript带标签的模板字符串中转义序列的语法限制。 遇到不合法的字符串转义返回undefined,并且从raw上可获取原字符串
function foo(str) {console.log(str); }foo`\undfdfdf`; // es9以前报错 // es9:[undefined, raw:["\undfdfdf"]]
ES10新特性
Object.fromEntries()
es8中对象添加了一个entries()静态方法,这个方法返回一个给定对象自身可枚举属性的键值对数组 ,Object.fromEntries()方法与 Object.entries() 正好相对,可以将键值对列表转换为一个对象 。
const obj = {x: 1,y: 2, };const entries = Object.entries(obj);console.log(entries); console.log(Object.fromEntries(entries));// [["x",1],["y":2]] // {x:1,y:2}
只要符合entries结构的都可以使用Object.fromEntries(entries)将键值对列表转换为一个对象,比如Map
String.prototype.trimStart()/String.prototype.trimEnd()
trimStart() /trimLeft()
trimLeft是trimStart的别名,作用是去掉字符串左边的空格
trimEnd() / trimRight()
trimEnd是trimRight的别名,作用是去掉字符串右边的空格
const str = " hello world "; console.log(str.trimStart()); console.log(str.trimEnd()); console.log(str.trim());// "hello world " // " hello world" // "hello world"
Array.prototype.flat()/Array.prototype.flatMap()
Array.prototype.flat()
flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回 。
const arr = [1, [2, [3, [4, [5, [6, 7], 8], 9]]]]; console.log(arr.flat(1)); console.log(arr.flat(5)); console.log(arr.flat(Infinity));// [1,2,[3, [4, [5, [6, 7], 8], 9]]] // [1,2,3,4,5,6,7,8,9] // [1,2,3,4,5,6,7,8,9]
自定义实现flat
function flat(arr, deep = 1) {const newArray = [];let deepNum = 0;const flatMap = (arr) => {arr.map((item, index, array) => {if (Array.isArray(item)) {if (deepNum < deep) {deepNum++;flatMap(item);} else {newArray.push(item);}} else {newArray.push(item);if (index === array.length - 1) deepNum = 0;}});};flatMap(arr);return newArray; }const arr = [1, [2, [3, [4, [5, 6], 7], 8]]]; console.log(flat(arr, 4));
Array.prototype.flatMap()
flatMap实质上包含两部分功能,一是map,二是flat
const numbers = [1, 2, 3];console.log(numbers.map((x) => [x ** 2]).flat()); console.log(numbers.flatMap((x) => [x ** 2]));// [1,4,9] // [1,4,9]
Symbol.description
可以通过 description 获取 Symbol 的描述
const symbol = Symbol("symbol"); console.log(symbol.description); // symbol console.log(symbol.description === "symbol"); // true
在es10以前,我们只能通过调用 Symbol 的 toString() 时才可以读取这个属性
console.log(symbol.toString() === "Symbol(symbol)");
Function.prototype.toString()
Function.prototype.toString() 方法返回一个表示当前函数源代码的字符串
function test(a) {// es10以前不返回注释部分console.log(a); } console.log(test.toString());// function test(a) { // // es10以前不返回注释部分 // console.log(a); // }
catch Building
es10允许我们在捕获异常时省略catch的参数
// es10以前 try {throw new Error(); } catch (error) {console.log("fail"); }// es10 try {throw new Error(); } catch {console.log("fail"); }
JSON扩展
JSON 内容可以支持包含 U+2028行分隔符 与 U+2029段分隔符
在 ES10 JSON.stringify 会用转义字符的方式来处理 超出范围的 Unicode 展示错误的问题 而非编码的方式
console.log(JSON.stringify('\uD83D\uDE0E')) // 笑脸// 单独的\uD83D其实是个无效的字符串 // 之前的版本 ,这些字符将替换为特殊字符,而现在将未配对的代理代码点表示为JSON转义序列 console.log(JSON.stringify('\uD83D')) // "\ud83d"
ES11新特性
BigInt
es11为我们提供了第七种新的原始数据类型,对于js来说,他的最大取值范围是2的53次方
console.log(2 ** 53); console.log(2 ** 53 + 1); console.log(Number.MAX_SAFE_INTEGER); // 9007199254740992 // 9007199254740992 // 9007199254740991
BigInt,表示一个任意精度的整数,可以表示超长数据,可以超出2的53次方 。
使用方式
// 方式一console.log(9007199254740993);console.log(9007199254740993n);// 9007199254740992// 9007199254740993n// 方式二console.log(9007199254740993);console.log(BigInt(9007199254740993n));// 9007199254740992// 9007199254740993n
- 1==1n // true
- 1 === 1n // false
- typeof 1n // bigint
- BigInt(9007199254740993n).toString() // 9007199254740993
可选链
可选链可以使我们在查询具有多层级的对象时,不再需要进行冗余的各种前置校验。
const a = {b: {c: {d: {e: "111",},},}, };// es11前 const value = a && a.b && a.b.c && a.b.c.d && a.b.c.d.e; console.log(value);// es11:可选链 const value2 = a?.b?.c?.d?.e; console.log(value2);
可选链中的 ? 表示如果问号左边表达式有值, 就会继续查询问号后面的字段 , 可以大量简化类似繁琐的前置校验操作 。
空值合并运算符
当我们查询某个属性时,经常会遇到,如果没有该属性就会设置一个默认的值。
const a = 0; const b = a || 1; console.log(b);// 1
我们在使用||运算符时, 变量值为 0 就是 false ,所以我们会看到上述结果会输出1,但是很多时候我们希望b的输出结果就是a的值0,es11提出了空值合并运算符(??),当左侧操作数为 null 或 undefined 时,其返回右侧的操作数。否则返回左侧的操作数。
const a = 0; const b = a ?? 1; console.log(b);// 0
Promise.allSettled()
es6中 Promise.all方法接受一个数组元素都是由 Promise.resolve 包装的数组, 生成并返回一个新的 Promise 对象, 如果参数中的任何一个promise为reject的话,则整个Promise.all调用会立即终止,并返回一个reject的新的 Promise 对象。
// 全部返回resolve function getPromise(time) {return new Promise((resolve, reject) => {setTimeout(() => {resolve(time);}, time);}); }Promise.all([getPromise(1000), getPromise(2000), getPromise(3000)]).then((res) => {console.log(res);} );// [1000,2000,3000]// 返回reject function getPromise(time) {return new Promise((resolve, reject) => {setTimeout(() => {resolve(time);}, time);}); }function getReject(time) {return new Promise((resolve, reject) => {setTimeout(() => {reject(time);}, time);}); }Promise.all([getPromise(1000), getReject(2000), getPromise(3000)]).then((res) => {console.log(res);}).catch((err) => {console.log(err);});// 2000
从上面可以看出Promise.all只要有一个任务返回reject,整个任务都会失败, 我们需要一种机制,如果并发任务中,无论一个任务正常或者异常,都会返回对应的的状态 ,这就是Promise.allSettled()的作用。
function getPromise(time) {return new Promise((resolve, reject) => {setTimeout(() => {resolve(time);}, time);}); }function getReject(time) {return new Promise((resolve, reject) => {setTimeout(() => {reject(time);}, time);}); }Promise.allSettled([getPromise(1000), getReject(2000), getPromise(3000)]).then((res) => {console.log(res);}).catch((err) => {console.log(err);});// [{status: "fulfilled", value: 1000}, // {status: "rejected", reason: 2000}, // {status: // "fulfilled", value: 3000}]
import
按需加载
现代前端打包资源越来越大,打包成几M的JS资源已成常态,而往往前端应用初始化时根本不需要全量加载逻辑资源,为了首屏渲染速度更快,很多时候都是按需加载,比如懒加载图片等。
(async () => {if (somethingIsTrue) {// import module for side effectsawait import('xxx/xxx.js');} })();
String.prototype.matchAll()
- matchAll() 方法返回一个包含所有匹配正则表达式及分组捕获结果的迭代器 ;
- 使用: str.matchAll(regexp) ;
字符串处理的一个常见场景是想要匹配出字符串中的所有目标子串,例如:
match()
const str ="es2015/es6 es2016/es7 es2017/es8 es2018/es9 es2019/es10 es2020/es10"; console.log(str.match(/(es\d+)\/es(\d+)/g)); // ["es2015/es6", "es2016/es7", "es2017/es8", "es2018/es9", "es2019/es10", //"es2020/es10"]
match()方法中,正则表达式所匹配到的多个结果会被打包成数组返回,但无法得知每个匹配除结果之外的相关信息,比如捕获到的子串,匹配到的
index
位置等 。exec ()
const str ="es2015/es6 es2016/es7 es2017/es8 es2018/es9 es2019/es10 es2020/es10"; const reg = /(es\d+)\/es(\d+)/g; let matched; let formatted = []; while ((matched = reg.exec(str))) {formatted.push(`${matched[1]}-es${matched[2]}`); } console.log(formatted);//["es2015-es6","es2016-es7","es2017-es8","es2018-es9","es2019-es10", //"es2020-es10"]
matchAll()
const str ="es2015/es6 es2016/es7 es2017/es8 es2018/es9 es2019/es10 es2020/es10"; const reg = /(es\d+)\/es(\d+)/g;const matchs = []; for (let match of str.matchAll(reg)) {matchs.push(`${match[1]}-es${match[2]}`); } console.log(matchs); // ["es2015-es6", "es2016-es7", "es2017-es8", "es2018-es9", "es2019-es10", "es2020-es10"]
matchAll() 是返回一个迭代器,对大数据量的场景更友好 。
globalThis
Javascript 在不同的环境获取全局对象有不通的方式:
- node 中通过 global,
- web 中通过 window, self 。
es11提出的globalThis一句话总结就是: 无论是在node环境还是web中,全局作用域中的 this 可以通过globalThis访问, 不必担心它的运行环境 。
for…in遍历机制
JavaScript 中通过for-in遍历对象时 key 的顺序是不确定的,因为规范没有明确定义,并且能够遍历原型属性让for-in的实现机制变得相当复杂,不同 JavaScript 引擎有各自根深蒂固的不同实现,很难统一
- 所以 es11不要求统一属性遍历顺序,而是对遍历过程中的一些特殊 Case 明确定义了一些规则:
- 遍历不到 Symbol 类型的属性
- 遍历过程中,目标对象的属性能被删除,忽略掉尚未遍历到却已经被删掉的属性
- 遍历过程中,如果有新增属性,不保证新的属性能被当次遍历处理到
- 属性名不会重复出现(一个属性名最多出现一次)
- 目标对象整条原型链上的属性都能遍历到
相关文档:
- 新特性概览
ES7-ES11新特性汇总相关推荐
- ES6/ES7/ES8新特性汇总
ES6起各个版本的新特性汇总 ES全称ECMAScript,ECMAScript是ECMA制定的标准化脚本语言.目前JavaScript使用的ECMAScript版本为ECMA-417.关于ECMA的 ...
- ES7、ES8、ES9、ES10、ES11 新特性 总结
目录 ES7新特性 一.Array.prototype.includes 二.指数操作符 ES8新特性 一.async 和 await 1.async 函数 2.await 表达式 async和awa ...
- 七月学习之E6、ES7、ES8、ES9、ES10、ES11新特性
目录 ES6新特性(2015) 1. let 和 const 命令 2. 解构赋值 3. 扩展运算符(spread) 4. 箭头函数 5. 函数参数默认值 6. 模板字符串 7. 对象属性和方法的简写 ...
- ES7、ES8、ES9、ES10、ES11新特性
一.ES7新特性 1. Array.prototype.includes includes 方法用来检测数组中是否包含某个元素,返回布尔值 2. 指数操作符 指数运算符 ** ,用来实现幂运算,功能与 ...
- oracle12c 新特性,12c Oracle数据库新特性汇总
12c Oracle数据库新特性汇总 中文社区 (MOSC) 数据库 (MOSC) 8 Replies Last updated on February 15, 2017 12c Oracle数据库有 ...
- Oracle 21C 新特性:数据泵相关新特性汇总
墨墨导读:本文来自墨天轮用户"JiekeXu"投稿,墨天轮主页:https://www.modb.pro/u/434,本文分享Oracle 21c 新特性:数据泵相关新特性汇总. ...
- coreldraw x7 分布_CorelDRAW X7新特性汇总
这篇教程是向大家介绍CorelDRAW X7新特性汇总,教程很不错,推荐过来,喜欢的朋友一起来学习吧 CorelDRAW X7新特性 一. 轻松启动和运行 CorelDRAW Graphics Sui ...
- android l 新功能,Android L怎么样 安卓L新特性汇总
在刚刚结束的2014谷歌IO大会上,谷歌共发布了8款新品,其中Android L成为发布会的一大看点.此次谷歌并没有将新安卓系统命名为Android 5.0,而是命名为Android L.仅从命名来看 ...
- jdk8 新特性汇总
jdk8 新特性汇总 1.掌握Lambda表达式的基本用法以及省略模式 2.掌握接口中新增的静态方法跟默认方法的使用 3.掌握函数接口的用法 4.掌握方法引用的使用 5.掌握Stream流在集合中的使 ...
最新文章
- MySQL 备份和恢复策略
- CentOS LVM
- [深入理解Android卷一全文-第九章]深入理解Vold和Rild
- 为何gpio_to_irq不能静态使用?【转】
- 奇妙的安全旅行之MD算法
- mysql抖动可能的原因_MySQL应对网络抖动问题
- jni c 回调 java,JNI - 如何从C ++或C回调到Java?
- android在github上调用aar文件
- PHP连数据库生成数据字典
- FPGA:生成占空比可调的PWM波
- 智能工厂具体的名词解释
- java --help_java help
- 【數論】【搜索】【SCOI2009】遊戲
- Python练习:四叶玫瑰数求解
- 【菜菜子力扣刷题】1.两数之和
- TP50 TP90 TP95 TP99 TP999 TP9999
- C Primer Plus中文 第6版勘误表
- SwiftUI iOS 精品完成项目之宠物展示与领养App MVVM(教程含源码)
- [offer收割]编程联系赛2-A 买零食
- 新中新DKQ-A16D身份证读卡器C#对接程序出坑记