Artikel ini akan mengatur dan berkongsi ciri ECMAScript dengan anda. Anda akan mengambil masa sejam untuk memahami semua ciri ES6~ES12 dengan cepat. Ia mempunyai nilai rujukan tertentu Rakan-rakan yang memerlukan boleh merujuk kepadanya.
Sebagai newbie yang suka menaip kod, saya rasa kod tersebut perlu ditaip sendiri supaya lebih menghafalnya dengan hati, jadi hari ini saya akan memperkenalkan tentang ES6~ Ciri ES12. Jika anda mempunyai bintik buta dalam penggunaan ES, atau tidak tahu banyak tentang ciri baharuSaya percaya artikel ini sepatutnya dapat membantu anda dengan baik~
Untuk memahami dengan lebih baik , kami menggunakan mod Kes untuk pemahaman yang lebih baik Pada masa yang sama, kes ini juga menyokong penyahpepijatan dalam mod pembangun. Saya harap anda boleh menyokongnya~
ECMAScript ialah bahasa pengaturcaraan skrip yang diseragamkan oleh Ecma International (dahulunya Persatuan Pengilang Komputer Eropah) melalui ECMA-262. Ia juga boleh dikatakan bahawa ia adalah standard JavaScript
Dalam dunia pengaturcara, hanya terdapat dua versi: dan ES5
ES6, tetapi ia sebenarnya dikeluarkan pada 2015. Ia juga merupakan masa apabila era front-end besar secara rasmi bermula, iaitu, mengambil 2015 sebagai had, sebelum 2015 ia dipanggil ES6
, dan selepas 2016 ia adalah secara kolektif dipanggil ES5
ES6
, sila lihat Ruan Teacher Yifeng ES6
"Pengenalan kepada Standard ES6"
mengisytiharkan objek, sifat objek boleh ditukar, kerana: const
obj yang diisytiharkan oleh const hanya menyimpan alamat rujukan objeknya selagi alamat tidak berubah, akan ada tiada ralat
...
undefined
let [a, b, c] = [1, 2, 3] console.log(a, b, c) // 1 2 3 let [a, , c] = [1, 2, 3] console.log(a, , c) // 1 3 let [a, b, ...c] = [1, 2, 3, 4, 5] console.log(a, b, c) // 1 2 [3, 4, 5] let [a, b, ...c] = [1] console.log(a, b, c) // 1 undefined [] let [a = 1, b = a] = [] const.log(a, b) // 1 1 let [a = 1, b = a] = [2] const.log(a, b) // 2 2
undefined
:
let { a, b } = { a: 1, b: 2 }; console.log(a, b); // 1 2 let { a } = { b: 2 }; console.log(a); // undefined let { a, b = 2 } = { a: 1 }; console.log(a, b); // 1 2 let { a: b = 2 } = { a: 1 }; console.log(a); // 不存在 a 这个变量 console.log(b); // 1
length
let [a, b, c, d, e] = "hello" console.log(a, b, c, d, e) // h e l l o let { length } = "hello" console.log(length) // 5
let { toString: s } = 123; console.log(s === Number.prototype.toString) // true let { toString: s } = true; console.log(s === Boolean.prototype.toString) // true
let arr = [[1,2], [3, 4]] let res = arr.map([a, b] => a + b) console.log(res) // [3, 7] let arr = [1, undefined, 2] let res = arr.map((a = 'test') => a); console.log(res) // [1, 'test', 2] let func = ({x, y} = {x: 0, y: 0}) => { return [x, y] } console.log(func(1, 2)) // [undefined, undefined] console.log(func()) // [0, 0] console.log(func({})) // [undefined, undefined] console.log(func({x: 1})) // [1, undefined] let func = ({x=0, y=0}) => { return [x, y] } console.log(func({x:1,y:2})) // [1, 2] console.log(func()) // error console.log(func({})) // [0, 0] console.log(func({x: 1})) // [1, 0]
dan JS分格
perl 分格
let re = new RegExp('a'); //查找一个字符串内是否有a let re = new RegExp('a', 'i'); //第一个是查找的对象,第二个是选项
let re = /a/; //查找一个字符串内是否有a let re = /a/i;//第一个是查找的对象,第二个是选项
大括号包含
表示Unicode字符//Unicode console.log("a", "\u0061"); // a a console.log("d", "\u{4E25}"); // d 严 let str = 'Domesy' //codePointAt() console.log(str.codePointAt(0)) // 68 //String.fromCharCode() console.log(String.fromCharCode(68)) // D //String.raw() console.log(String.raw`Hi\n${1 + 2}`); // Hi\n3 console.log(`Hi\n${1 + 2}`); // Hi 3 let str = 'Domesy' //startsWith() console.log(str.startsWith("D")) // true console.log(str.startsWith("s")) // false //endsWith() console.log(str.endsWith("y")) // true console.log(str.endsWith("s")) // false //repeat(): 所传的参数会自动向上取整,如果是字符串会转化为数字 console.log(str.repeat(2)) // DomesyDomesy console.log(str.repeat(2.9)) // DomesyDomesy // 遍历:for-of for(let code of str){ console.log(code) // 一次返回 D o m e s y } //includes() console.log(str.includes("s")) // true console.log(str.includes("a")) // false // trimStart() const string = " Hello world! "; console.log(string.trimStart()); // "Hello world! " console.log(string.trimLeft()); // "Hello world! " // trimEnd() const string = " Hello world! "; console.log(string.trimEnd()); // " Hello world!" console.log(string.trimRight()); // " Hello world!"
let str = `Dome sy` console.log(str) //会自动换行 // Dome // sy
const str = { name: '小杜杜', info: '大家好‘ } console.log(`${str.info}, 我是`${str.name}`) // 大家好,我是小杜杜
let arr = [1, 2, 3, 4, 5] //Array.of() let arr1 = Array.of(1, 2, 3); console.log(arr1) // [1, 2, 3] //copyWithin(): 三个参数 (target, start = 0, end = this.length) // target: 目标的位置 // start: 开始位置,可以省略,可以是负数。 // end: 结束位置,可以省略,可以是负数,实际位置是end-1。 console.log(arr.copyWithin(0, 3, 5)) // [4, 5, 3, 4, 5] //find() console.log(arr.find((item) => item > 3 )) // 4 //findIndex() console.log(arr.findIndex((item) => item > 3 )) // 3 // keys() for (let index of arr.keys()) { console.log(index); // 一次返回 0 1 2 3 4 } // values() for (let index of arr.values()) { console.log(index); // 一次返回 1 2 3 4 5 } // entries() for (let index of arr.entries()) { console.log(index); // 一次返回 [0, 1] [1, 2] [2, 3] [3, 4] [4, 5] } let arr = [1, 2, 3, 4, 5] // Array.from(): 遍历的可以是伪数组,如 String、Set结构,Node节点 let arr1 = Array.from([1, 3, 5], (item) => { return item * 2; }) console.log(arr1) // [2, 6, 10] // fill(): 三个参数 (target, start = 0, end = this.length) // target: 目标的位置 // start: 开始位置,可以省略,可以是负数。 // end: 结束位置,可以省略,可以是负数,实际位置是end-1。 console.log(arr.fill(7)) // [7, 7, 7, 7, 7] console.log(arr.fill(7, 1, 3)) // [1, 7, 7, 4, 5] let arr = [1, 2, 3, 4] //includes() console.log(arr.includes(3)) // true console.log([1, 2, NaN].includes(NaN)); // true
// 其作用为展开数组 let arr = [3, 4, 5] console.log(...arr) // 3 4 5 let arr1 = [1, 2, ...arr] console.log(...arr1) // 1 2 3 4 5
for-in
//Object.is() console.log(Object.is('abc', 'abc')) // true console.log(Object.is([], [])) // false //遍历:for-in let obj = { name: 'Domesy', value: 'React' } for(let key in obj){ console.log(key); // 依次返回属性值 name value console.log(obj[key]); // 依次返回属性值 Domesy React } //Object.keys() console.log(Object.keys(obj)) // ['name', 'value'] //Object.assign() const target = { a: 1, b: 2 }; const source = { b: 4, c: 5 }; const result = Object.assign(target, source) console.log(result) // {a: 1, b: 4, c: 5} console.log(target) // {a: 1, b: 4, c: 5}
let a = 1; let b = 2; let obj = { a, b } console.log(obj) // { a: 1, b: 2 } let method = { hello() { console.log('hello') } } console.log(method.hello())// hello
let a = "b" let obj = { [a]: "c" } console.log(obj) // {b : "c"}
// 其作用为展开数组 let { a, b, ...c } = { a: 1, b: 2, c: 3, d: 4}; console.log(c) // {c: 3, d: 4} let obj1 = { c: 3 } let obj = { a: 1, b: 2, ...obj1} console.log(obj) // { a: 1, b: 2, c: 3}
0b
或 0B
开头,表示二进制00
或 0O
开头,表示二进制正数为1
、负数为-1
、正零 0
、负零 -0
、NaN
parseInt
parseFloat
//二进制 console.log(0b101) // 5 console.log(0o151) //105 //Number.isFinite() console.log(Number.isFinite(7)); // true console.log(Number.isFinite(true)); // false //Number.isNaN() console.log(Number.isNaN(NaN)); // true console.log(Number.isNaN("true" / 0)); // true console.log(Number.isNaN(true)); // false //Number.isInteger() console.log(Number.isInteger(17)); // true console.log(Number.isInteger(17.58)); // false //Number.isSafeInteger() console.log(Number.isSafeInteger(3)); // true console.log(Number.isSafeInteger(3.0)); // true console.log(Number.isSafeInteger("3")); // false console.log(Number.isSafeInteger(3.1)); // false //Math.trunc() console.log(Math.trunc(13.71)); // 13 console.log(Math.trunc(0)); // 0 console.log(Math.trunc(true)); // 1 console.log(Math.trunc(false)); // 0 //Math.sign() console.log(Math.sign(3)); // 1 console.log(Math.sign(-3)); // -1 console.log(Math.sign(0)); // 0 console.log(Math.sign(-0)); // -0 console.log(Math.sign(NaN)); // NaN console.log(Math.sign(true)); // 1 console.log(Math.sign(false)); // 0 //Math.abrt() console.log(Math.cbrt(8)); // 2 //Number.parseInt() console.log(Number.parseInt("6.71")); // 6 console.log(parseInt("6.71")); // 6 //Number.parseFloat() console.log(Number.parseFloat("6.71@")); // 6.71 console.log(parseFloat("6.71@")); // 6.71
//参数默认赋值具体的数值 let x = 1 function fun(x, y = x){ console.log(x, y) } function fun1(c, y = x){ console.log(c, x, y) } fun(2); //2 2 fun1(1); //1 1 1
function fun(...arg){ console.log(arg) // [1, 2, 3, 4] } fun(1, 2, 3, 4)
let arrow = (v) => v + 2 console.log(arrow(1)) // 3
箭头函数与普通函数的区别
Set 是ES6中新的数据结构,是类似数组,但成员的值是唯一的,没有重复的值
声明:const set = new Set()
属性:
方法:
特别注意:
iterator
对象,按插入顺序,为 [Key, Value] 形式let list = new Set() //add() list.add("1") list.add(1) console(list) // Set(2) {1, "1"} //size console(list.size) // 2 //delete() list.delete("1") console(list) // Set(1) {1} //has() list.has(1) // true list.has(3) // false //clear() list.clear() console(list) // Set(0) {} let arr = [{id: 1}, {id: 2}, {id: 3}] let list = new Set(arr) // keys() for (let key of list.keys()) { console.log(key); // 以此打印:{id: 1} {id: 2} {id: 3} } //values() for (let key of list.values()) { console.log(key); // 以此打印:{id: 1} {id: 2} {id: 3} } //entries() for (let data of list.entries()) { console.log(data); // 以此打印:[{id: 1},{id: 1}] [{id: 2},{id: 2}] [{id: 3},{id: 3}] } //forEach list.forEach((item) => { console.log(item)// 以此打印:{id: 1} {id: 2} {id: 3} });
应用:
new Set
无法去除对象let arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a']; console.log([...new Set(arr)]) //或 console.log(Array.from(new Set(arr))) // [1, 'true', true, 15, false, undefined, null, NaN, 'NaN', 0, 'a']
let a = new Set([1, 2, 3]) let b = new Set([2, 3, 4]) //并集 console.log(new Set([...a, ...b])) // Set(4) {1, 2, 3, 4} //交集 console.log(new Set([...a].filter(v => b.has(v)))) // Set(2) {2, 3} //差集 new Set([...a].filter(v => !b.has(v))) // Set(1) {1}
let set = new Set([1,2,3]) console.log(new Set([...set].map(v => v * 2))) // Set(3) {2, 4, 6}
定义: 和Set的结构,但成员值只能为对象
声明: const set = new WeakSet()
方法:
注意:
推荐指数: ⭐️⭐️
Map 是ES6中新的数据结构,是类似对象,成员键是任何类型的值
声明:const map = new Map()
属性:
方法:
特别注意:
let map = new Map() //set() map.set('a', 1) map.set('b', 2) console.log(map) // Map(2) {'a' => 1, 'b' => 2} //get map.get("a") // 1 //size console.log(map.size) // 2 //delete() map.delete("a") // true console.log(map) // Map(1) {'b' => 2} //has() map.has('b') // true map.has(1) // false //clear() map.clear() console.log(map) // Map(0) {} let arr = [["a", 1], ["b", 2], ["c", 3]] let map = new Map(arr) // keys() for (let key of map.keys()) { console.log(key); // 以此打印:a b c } //values() for (let value of map.values()) { console.log(value); // 以此打印:1 2 3 } //entries() for (let data of map.entries()) { console.log(data); // 以此打印:["a", 1] ["b", 2] ["c", 3] } //forEach map.forEach((item) => { console.log(item)// 以此打印:1 2 3 });
定义: 和Map的结构,但成员值只能为对象
声明: const set = new WeakMap()
方法:
Symbol 是ES6中引入的原始数据类型,代表着独一无二
的
声明:const sy = Stmbol()
参数: string(可选)
方法:
Symbol值
,如存在此参数则返回原有的Symbol值
(先搜索后创建,登记在全局环境)Symbol值
的描述(只能返回Symbol.for()
的key
)Symbol值
的数组// 声明 let a = Symbol(); let b = Symbol(); console.log(a === b); // false //Symbol.for() let c = Symbol.for("domesy"); let d = Symbol.for("domesy"); console.log(c === d); // true //Symbol.keyFor() const e = Symbol.for("1"); console.log(Symbol.keyFor(e)); // 1 //Symbol.description let symbol = Symbol("es"); console.log(symbol.description); // es console.log(Symbol("es") === Symbol("es")); // false console.log(symbol === symbol); // true console.log(symbol.description === "es"); // true
Proxy用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程
可以这样理解,Proxy就是在目标对象之前设置的一层拦截
,外界想要访问都要经过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
Proxy 在这里可以理解为代理器
声明: const proxy = new Proxy(target, handler)
方法:
let obj = { name: 'domesy', time: '2022-01-27', value: 1 } let data = new Proxy(obj, { //get() get(target, key){ return target[key].replace("2022", '2015') }, //set() set(target, key, value) { if (key === "name") { return (target[key] = value); } else { return target[key]; } }, // has() has(target, key) { if (key === "name") { return target[key]; } else { return false; } }, // deleteProperty() deleteProperty(target, key) { if (key.indexOf("_") > -1) { delete target[key]; return true; } else { return target[key]; } }, // ownKeys() ownKeys(target) { return Object.keys(target).filter((item) => item != "time"); }, }) console.log(data.time) // 2015-01-27 data.time = '2020' data.name = 'React' console.log(data) //Proxy {name: 'React', time: '2022-01-27', value: 1} // 拦截has() console.log("name" in data) // true console.log("time" in data) // false // 删除deleteProperty() delete data.time; // true // 遍历 ownKeys() console.log(Object.keys(data)); //['name', 'value'] //apply() let sum = (...args) => { let num = 0; args.forEach((item) => { num += item; }); return num; }; sum = new Proxy(sum, { apply(target, ctx, args) { return target(...args) * 2; }, }); console.log(sum(1, 2)); // 6 console.log(sum.call(null, 1, 2, 3)); // 12 console.log(sum.apply(null, [1, 2, 3])); // 12 //constructor() let User = class { constructor(name) { this.name = name; } } User = new Proxy(User, { construct(target, args, newTarget) { return new target(...args); }, }); console.log(new User("domesy")); // User {name: 'domesy'}
Reflect 与 Proxy 类似,只是保持Object
的默认行为
Reflect 的方法与 Proxy 的方法一一对应,这里就不进行介绍了
Class: 对一类具有共同特征的事物的抽象(构造函数语法糖)
class Parent { constructor(name = 'es6'){ this.name = name } } let data = new Parent('domesy') console.log(data) // Parent { name: 'domesy'}
class Parent { constructor(name = 'es6'){ this.name = name } } // 普通继承 class Child extends Parent {} console.log(new Child()) // Child { name: 'es6'} // 传递参数 class Child extends Parent { constructor(name = "child") { super(name); this.type = "child"; } } console.log(new Child('domesy')) // Child { name: 'domesy', type: 'child'}
class Parent { constructor(name = 'es6'){ this.name = name } // getter get getName() { return 'sy' + this.name } // setter set setName(value){ this.name = value } } let data = new Parent() console.log(data.getName) // syes6 data.setName = 'domesy' console.log(data.getName) // domesy
class Parent { static getName = (name) => { return `你好!${name}` } } console.log(Parent.getName('domesy')) // 你好!domesy
class Parent {} Parent.type = "test"; console.log(Parent.type); //test
Promise
就是为了解决“回调地狱”问题的,它可以将异步操作的处理变得很优雅。
Promise
可以支持多个并发的请求,获取并发请求中的数据这个 Promise
可以解决异步的问题,本身不能说 Promise
是异步的
定义: 包含异步操作结果的对象
状态:
注意:
//普通定义 let ajax = (callback) => { console.log('≈') setTimeout(() => { callback && callback.call(); }, 1000) } ajax(() => { console.log('timeout') }) // 先会打出 开始执行,1s 后打出 timeout //Promise let ajax = () => { console.log("开始执行"); return new Promise((resolve, reject) => { setTimeout(() => { resolve(); }, 1000); }); }; ajax().then(() => { console.log("timeout"); }); // 先会打出 开始执行,1s 后打出 timeout // then() let ajax = () => { console.log("开始执行"); return new Promise((resolve, reject) => { setTimeout(() => { resolve(); }, 1000); }); }; ajax() .then(() => { return new Promise((resolve, reject) => { setTimeout(() => { resolve(); }, 2000); }); }) .then(() => { console.log("timeout") }) // 先会打出 开始执行,3s(1+2) 后打出 timeout // catch() let ajax = (num) => { console.log("开始执行"); return new Promise((resolve, reject) => { if (num > 5) { resolve(); } else { throw new Error("出错了"); } }); }; ajax(6) .then(function () { console.log("timeout"); // 先会打出 开始执行,1s 后打出 timeout }) .catch(function (err) { console.log("catch", err); }); ajax(3) .then(function () { console.log("timeout"); }) .catch(function (err) { console.log("catch"); // 先会打出 开始执行,1s 后打出 catch });
//所有图片加载完成后添加到页面 const loadImg = (src) => { return new Promise(resolve, reject) => { let img = document.createElement("img"); img.src = src; img.onload = function () { resolve(img); }; img.onerror = function (err) { reject(err); }; }); } const showImgs = (imgs) => { imgs.forEach((img) => { document.body.appendChild(img); }) } Promise.all([ loadImg("https://ss0.baidu.com/7Po3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/71cf3bc79f3df8dcc6551159cd11728b46102889.jpg"), loadImg("https://ss0.baidu.com/7Po3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/71cf3bc79f3df8dcc6551159cd11728b46102889.jpg"), loadImg("https://ss0.baidu.com/7Po3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/71cf3bc79f3df8dcc6551159cd11728b46102889.jpg"), ]).then(showImgs);
//有一个执行完就回加载到页面 const loadImg = (src) => { return new Promise(resolve, reject) => { let img = document.createElement("img"); img.src = src; img.onload = function () { resolve(img); }; img.onerror = function (err) { reject(err); }; }); } const showImgs = (imgs) => { let p = document.createElement("p"); p.appendChild(img); document.body.appendChild(p); } Promise.race([ loadImg("https://ss0.baidu.com/7Po3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/71cf3bc79f3df8dcc6551159cd11728b46102889.jpg"), loadImg("https://ss0.baidu.com/7Po3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/71cf3bc79f3df8dcc6551159cd11728b46102889.jpg"), loadImg("https://ss0.baidu.com/7Po3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/71cf3bc79f3df8dcc6551159cd11728b46102889.jpg"), ]).then(showImgs);
Generator: 是可以用来控制迭代器的函数,也是封装多个内部状态的异步编程解决方案,也叫生成器函数
参数说明
value
和 done
value
代表值, done
返回布尔(如果为false,代表后续还有,为true则已完成)恢复
程序执行let data = function* (){ yield "a"; yield "b"; return "c" } let generator = data(); console.log(generator.next()) //{value: 'a', done: false} console.log(generator.next()) //{value: 'b', done: false} console.log(generator.next()) //{value: 'c', done: true} console.log(generator.next()) //{value: undefined, done: true}
Iterator是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。
Iterator的作用:
注意:
数组
、某些类似数组的对象
、Set
和Map结构
。// 基本使用 let arr = ["hello", "world"]; let map = arr[Symbol.iterator](); console.log(map.next()); // {value: 'hello', done: false} console.log(map.next()); // {value: 'world', done: false} console.log(map.next()); // {value: undefined, done: true} // for of 循环 let arr = ["hello", "world"]; for (let value of arr) { console.log(value); // hello world } // 对象处理 let obj = { start: [1, 5, 2], end: [7, 9, 6], [Symbol.iterator](){ let index = 0; let arr = this.start.concat(this.end) return { next(){ if(index < arr.length){ return { value: arr[index++], done: false } }else{ return { value: arr[index++], done: true } } } } } } for (let key of obj) { console.log(key); // 1 5 2 7 9 6 }
@
符号,用来扩展,修改类的行为core-decorators
const name = (target) => { target.name = "domesy" } @name class Test{} console.log(Test.name) //domesy
在早期,使用立即执行函数实现模块化是常见的手段,通过函数作用域解决了命名冲突、污染全局作用域的问题
使用模块化的好处:
方案:
export default Index
export { name as newName }
import Index from './Index'
import * as Index from './Index'
import { name, value, id } from './Index'
import { name as newName } from './Index'
import './Index'
import Index, { name, value, id } from './Index'
export命令
和import命令
结合在一起写成一行,变量实质没有被导入当前模块,相当于对外转发接口,导致当前模块无法直接使用其导入变量,适用于 全部子模块导出
let arr = [1, 2, 3, 4] //includes() ES6 console.log(arr.includes(3)) // true console.log([1, 2, NaN].includes(NaN)); // true // includes() ES7 console.log(arr.includes(1, 0)) // true console.log(arr.includes(1, 1)) // false
**
代表 Math.pow()
// 幂运算符 ES7 console.log(Math.pow(2, 3)) // 8 console.log(2 ** 8) // 256
let str = 'Domesy' //padStart(): 会以空格的形式补位吗,这里用0代替,第二个参数会定义一个模板形式,会以模板进行替换 console.log("1".padStart(2, "0")); // 01 console.log("8-27".padStart(10, "YYYY-0M-0D")); // YYYY-08-27 // padEnd():与padStart()用法相同 console.log("1".padEnd(2, "0")); // 10
let obj = { name: 'Domesy', value: 'React' } //Object.values() console.log(Object.values(obj)) // ['React', 'React'] //Object.entries() console.log(Object.entries(obj)) // [['name', 'value'], ['React', 'React']]
作用: 将异步函数改为同步函数,(Generator的语法糖)
const func = async () => { let promise = new Promise((resolve, reject) => { setTimeout(() => { resolve("执行"); }, 1000); }); console.log(await promise); console.log(await 0); console.log(await Promise.resolve(1)); console.log(2); return Promise.resolve(3); } func().then(val => { console.log(val); // 依次执行: 执行 0 1 2 3 });
特别注意:
Promise
对象,因此可以使用 then
forEach()
执行 async/await
会失效,可以使用 for-of
和 Promise.all()
代替reject
对象,需要使用 try catch
来捕捉这里分为两种情况: 是否为 promise 对象
如果不是promise , await会阻塞后面的代码,先执行async外面的同步代码,同步代码执行完,再回到async内部,把这个非promise的东西,作为 await表达式的结果。
如果它等到的是一个 promise 对象,await 也会暂停async后面的代码,先执行async外面的同步代码,等着 Promise 对象 fulfilled,然后把 resolve 的参数作为 await 表达式的运算结果。
优点:
缺点:
undefined
,并且从raw
上可获取原字符串。// 放松字符串的限制 const test = (value) => { console.log(value) } test `domesy` // ['domesy', raw: ["domesy"]]
Promise.finally()
let func = time => { return new Promise((res, rej) => { setTimeout(() => { if(time < 500){ res(time) }else{ rej(time) } }, time) }) } func(300) .then((val) => console.log('res', val)) .catch((erro) => console.log('rej', erro)) .finally(() => console.log('完成')) // 执行结果: res 300 完成 func(700) .then((val) => console.log('res', val)) .catch((erro) => console.log('rej', erro)) .finally(() => console.log('完成')) // 执行结果: rej 700 完成
for-await-of: 异步迭代器,循环等待每个Promise对象
变为resolved状态
才进入下一步
let getTime = (seconds) => { return new Promise(res => { setTimeout(() => { res(seconds) }, seconds) }) } async function test(){ let arr = [getTime(2000),getTime(500),getTime(1000)] for await (let x of arr){ console.log(x); } } test() //以此执行 2000 500 1000
//JSON.stringify() 升级 console.log(JSON.stringify("\uD83D\uDE0E")); console.log(JSON.stringify("\u{D800}")); // \ud800
Infinity
自动解到最底层))let arr = [1, 2, 3, 4] // flatMap() console.log(arr.map((x) => [x * 2])); // [ [ 2 ], [ 4 ], [ 6 ], [ 8 ] ] console.log(arr.flatMap((x) => [x * 2])); // [ 2, 4, 6, 8 ] console.log(arr.flatMap((x) => [[x * 2]])); // [ [ 2 ], [ 4 ], [ 6 ], [ 8 ] ] const arr1 = [0, 1, 2, [3, 4]]; const arr2 = [0, 1, 2, [[[3, 4]]]]; console.log(arr1.flat()); // [ 0, 1, 2, 3, 4 ] console.log(arr2.flat(2)); // [ 0, 1, 2, [ 3, 4 ] ] console.log(arr2.flat(Infinity)); // [ 0, 1, 2, 3, 4 ]
Object.entries()
的逆操作let map = new Map([ ["a", 1], ["b", 2], ]); let obj = Object.fromEntries(map); console.log(obj); // {a: 1, b: 2}
// 注意数组的形式 let arr = [ ["a", 1], ["b", 2], ] let obj = Object.fromEntries(arr); console.log(obj); // {a: 1, b: 2}
let obj = { a: 1, b: 2, c: 3 } let res = Object.fromEntries( Object.entries(obj).filter(([key, val]) => value !== 3) ) console.log(res) //{a: 1, b: 2}
//toString() function test () { consople.log('domesy') } console.log(test.toString()); // function test () { // consople.log('domesy') // }
在 ES10 中,try catch 可忽略 catch的参数
let func = (name) => { try { return JSON.parse(name) } catch { return false } } console.log(func(1)) // 1 console.log(func({a: '1'})) // false
特别注意:
// Number console.log(2 ** 53) // 9007199254740992 console.log(Number.MAX_SAFE_INTEGER) // 9007199254740991 //BigInt const bigInt = 9007199254740993n console.log(bigInt) // 9007199254740993n console.log(typeof bigInt) // bigint console.log(1n == 1) // true console.log(1n === 1) // false const bigIntNum = BigInt(9007199254740993n) console.log(bigIntNum) // 9007199254740993n
在ES6中一共有7种,分别是:srting
、number
、boolean
、object
、null
、undefined
、symbol
其中 object
包含: Array
、Function
、Date
、RegExp
而在ES11后新增一中,为 8中 分别是:srting
、number
、boolean
、object
、null
、undefined
、symbol
、BigInt
Promise.allSettled():
Promise.all()
Promise.allSettled([ Promise.reject({ code: 500, msg: "服务异常", }), Promise.resolve({ code: 200, data: ["1", "2", "3"], }), Promise.resolve({ code: 200, data: ["4", "5", "6"], }), ]).then((res) =>{ console.log(res) // [{ reason: {code: 500, msg: '服务异常'}, status: "rejected" }, // { reason: {code: 200, data: ["1", "2", "3"]}, status: "rejected" }, // { reason: {code: 200, data: ["4", "5", "6"]}, status: "rejected" }] const data = res.filter((item) => item.status === "fulfilled"); console.log(data); // [{ reason: {code: 200, data: ["1", "2", "3"]}, status: "rejected" }, // { reason: {code: 200, data: ["4", "5", "6"]}, status: "rejected" }] })
require
的区别是:require()
是同步加载,import()
是异步加载// then() let modulePage = "index.js"; import(modulePage).then((module) => { module.init(); }); // 结合 async await (async () => { const modulePage = 'index.js' const module = await import(modulePage); console.log(module) })
// 浏览器环境 console.log(globalThis) // window // node console.log(globalThis) // global
const user = { name: 'domesy' } //ES11之前 let a = user && user.name //现在 let b = user?.name
"" || "default value"; // default value "" ?? "default value"; // "" const b = 0; const a = b || 5; console.log(a); // 5 const b = null // undefined const a = b ?? 123; console.log(a); // 123
replaceAll()
let str = "Hi!,这是ES6~ES12的新特性,目前为ES12" console.log(str.replace("ES", "SY")); // Hi!,这是SY6~ES12的新特性,目前为ES12 console.log(str.replace(/ES/g, "Sy")); // Hi!,这是Sy6~Sy12的新特性,目前为Sy12 console.log(str.replaceAll("ES", "Sy")); // Hi!,这是Sy6~Sy12的新特性,目前为Sy12 console.log(str.replaceAll(/ES/g, "Sy")); // Hi!,这是Sy6~Sy12的新特性,目前为Sy12
Promise.any()
Promise.any([ Promise.reject("Third"), Promise.resolve("Second"), Promise.resolve("First"), ]) .then((res) => console.log(res)) // Second .catch((err) => console.error(err)); Promise.any([ Promise.reject("Error 1"), Promise.reject("Error 2"), Promise.reject("Error 3"), ]) .then((res) => console.log(res)) .catch((err) => console.error(err)); // AggregateError: All promises were rejected Promise.any([ Promise.resolve("Third"), Promise.resolve("Second"), Promise.resolve("First"), ]) .then((res) => console.log(res)) // Third .catch((err) => console.error(err));
let weakref = new WeakRef({name: 'domesy', year: 24}) weakref.deref() // {name: 'domesy', year: 24} weakref.deref().year // 24
let num1 = 5; let num2 = 10; num1 &&= num2; console.log(num1); // 10 // 等价于 num1 && (num1 = num2); if (num1) { num1 = num2; }
let num1; let num2 = 10; num1 ||= num2; console.log(num1); // 10 // 等价于 num1 || (num1 = num2); if (!num1) { num1 = num2; }
let num1; let num2 = 10; let num3 = null; // undefined num1 ??= num2; console.log(num1); // 10 num1 = false; num1 ??= num2; console.log(num1); // false num3 ??= 123; console.log(num3); // 123 // 等价于 // num1 ?? (num1 = num2);
let num1 = 100000; let num2 = 100_000; console.log(num1); // 100000 console.log(num2); // 100000 const num3 = 10.12_34_56 console.log(num3); // 10.123456
【相关推荐:javascript视频教程、web前端】
Atas ialah kandungan terperinci Penjelasan pantas dan terperinci tentang semua ciri ES6~ES12 dalam satu artikel!. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!