做海报哪个网站好,新网,女教师遭网课入侵视频,重庆涪陵网站设计公司推荐前端 ES6 与 ESNext 特性全解析
ES6#xff08;ECMAScript 2015#xff09;作为JavaScript发展的重要转折点#xff0c;带来了诸多革命性特性#xff0c;显著提升了开发效率。此后#xff0c;ES7、ES8等后续版本以及ESNext持续推动着JavaScript的演进。
ES6#xff08;…前端 ES6 与 ESNext 特性全解析ES6ECMAScript 2015作为JavaScript发展的重要转折点带来了诸多革命性特性显著提升了开发效率。此后ES7、ES8等后续版本以及ESNext持续推动着JavaScript的演进。ES6ES2015核心特性1. 块级作用域let 和 constlet和const解决了 ES5 中var的作用域问题。let 关键字// let 声明的变量具有块级作用域for(leti0;i3;i){console.log(i);// 0, 1, 2}// console.log(i); // ReferenceError: i is not defined// 不会变量提升console.log(a);// ReferenceErrorleta1;// 不允许重复声明letb2;// let b 3; // SyntaxError// 暂时性死区Temporal Dead Zone{console.log(c);// ReferenceErrorletc3;}const 关键字// const 声明常量值不可修改对于基本类型constPI3.14159;// PI 3.14; // TypeError// 对于对象/数组内容可以修改constobj{name:JavaScript};obj.nameES6;// 允许// obj {}; // TypeError// 同样具有块级作用域{constAPI_KEYabc123;console.log(API_KEY);// abc123}// console.log(API_KEY); // ReferenceError2. 解构赋值Destructuring数组解构// 基本数组解构const[a,b,c][1,2,3];console.log(a,b,c);// 1, 2, 3// 跳过元素const[x,,z][1,2,3];console.log(x,z);// 1, 3// 剩余操作符const[first,...rest][1,2,3,4];console.log(first,rest);// 1, [2, 3, 4]// 默认值const[p1,q2][5];console.log(p,q);// 5, 2// 交换变量letm1,n2;[m,n][n,m];console.log(m,n);// 2, 1对象解构// 基本对象解构const{name,age}{name:Alice,age:25};console.log(name,age);// Alice, 25// 变量重命名const{name:userName,age:userAge}{name:Bob,age:30};console.log(userName,userAge);// Bob, 30// 默认值const{score0,gradeA}{score:95};console.log(score,grade);// 95, A// 嵌套解构const{info:{city,country}}{info:{city:Beijing,country:China}};console.log(city,country);// Beijing, China// 剩余属性const{x,y,...coords}{x:1,y:2,z:3,w:4};console.log(x,y,coords);// 1, 2, { z: 3, w: 4 }3. 箭头函数Arrow Functions// 传统函数functionadd(a,b){returnab;}// 箭头函数constadd(a,b)ab;// 多个参数constmultiply(x,y)x*y;// 单个参数可省略括号constsquarexx*x;// 无参数constgetRandom()Math.random();// 函数体多条语句constcalculate(a,b){constsumab;constproducta*b;return{sum,product};};// 返回对象字面量constcreateUser(name,age)({name,age});// 立即执行函数表达式IIFE(()console.log(IIFE))();// 作为回调函数constnumbers[1,2,3,4,5];constdoublednumbers.map(nn*2);constevensnumbers.filter(nn%20);constsumnumbers.reduce((acc,n)accn,0);箭头函数的特性// 1. 没有自己的 this继承自外层作用域constobj{value:10,methods:function(){// this 指向 objsetTimeout((){console.log(this.value);// 10},100);}};// 2. 没有 arguments 对象functionouter(){constinner(){// arguments 来自外层函数console.log(arguments);// [1, 2, 3]};inner();}outer(1,2,3);// 3. 不能用作构造函数constPerson(name){this.namename;};// const p new Person(John); // TypeError// 4. 没有 prototype 属性constfn(){};console.log(fn.prototype);// undefined4. 模板字符串Template Literals// 基本用法constnameWorld;constgreetingHello,${name}!;console.log(greeting);// Hello, World!// 表达式计算consta5,b10;console.log(${a}${b}${ab});// 5 10 15// 多行字符串constmultiline这是一个 多行字符串 不需要转义\n换行;console.log(multiline);// 嵌套模板constvalue20;constresult值是:${value10?大于10:小于等于10};// 标签模板Tagged Templatesfunctiontag(strings,...values){console.log(strings);// [前缀, 是 , ]console.log(values);// [42]return处理结果;}constresulttag前缀${42};// 原始字符串保留转义字符constrawString.raw第一行\n第二行;console.log(raw);// 第一行\n第二行而不是换行5. 类Class基本类定义// 类的定义classPerson{// 构造函数constructor(name,age){this.namename;this.ageage;}// 实例方法greet(){returnHello, Im${this.name};}// 静态方法staticspecies(){returnHomo sapiens;}// gettergetinfo(){return${this.name},${this.age}years old;}// settersetinfo(data){const[name,age]data.split(,);this.namename;this.ageparseInt(age);}}constalicenewPerson(Alice,25);console.log(alice.greet());// Hello, Im Aliceconsole.log(alice.info);// Alice, 25 years oldconsole.log(Person.species());// Homo sapiensalice.infoBob, 30;console.log(alice.info);// Bob, 30 years old继承// 继承classStudentextendsPerson{constructor(name,age,major){super(name,age);// 调用父类构造函数this.majormajor;}// 重写父类方法greet(){return${super.greet()}and I study${this.major};}// 子类特有方法study(){return${this.name}is studying${this.major};}}constbobnewStudent(Bob,20,Computer Science);console.log(bob.greet());// Hello, Im Bob and I study Computer Scienceconsole.log(bob.study());// Bob is studying Computer Science// instanceof 检查console.log(bobinstanceofStudent);// trueconsole.log(bobinstanceofPerson);// true私有字段ES2022classBankAccount{// 私有字段ES2022#balance0;#accountNumber;constructor(accountNumber){this.#accountNumberaccountNumber;}deposit(amount){if(amount0){this.#balanceamount;returntrue;}returnfalse;}withdraw(amount){if(amount0amountthis.#balance){this.#balance-amount;returntrue;}returnfalse;}getbalance(){returnthis.#balance;}getaccountNumber(){returnthis.#accountNumber;}}constaccountnewBankAccount(123456);account.deposit(1000);console.log(account.balance);// 1000// console.log(account.#balance); // SyntaxError: Private field6. PromisePromise 基本用法// 创建 PromiseconstpromisenewPromise((resolve,reject){// 异步操作setTimeout((){constsuccesstrue;if(success){resolve(操作成功);}else{reject(newError(操作失败));}},1000);});// 使用 Promisepromise.then(result{console.log(result);// 操作成功}).catch(error{console.error(error.message);// 操作失败}).finally((){console.log(无论成功或失败都会执行);});Promise 静态方法// Promise.resolve()constp1Promise.resolve(成功);p1.then(vconsole.log(v));// 成功// Promise.reject()constp2Promise.reject(newError(失败));p2.catch(econsole.log(e.message));// 失败// Promise.all() - 所有 Promise 都成功才成功constp3Promise.resolve(1);constp4Promise.resolve(2);constp5Promise.resolve(3);Promise.all([p3,p4,p5]).then(valuesconsole.log(values));// [1, 2, 3]// Promise.allSettled() - 等待所有 Promise 完成Promise.allSettled([Promise.resolve(1),Promise.reject(2),Promise.resolve(3)]).then(results{console.log(results);// [// { status: fulfilled, value: 1 },// { status: rejected, reason: 2 },// { status: fulfilled, value: 3 }// ]});// Promise.race() - 返回最先完成的 PromisePromise.race([newPromise(resolvesetTimeout(()resolve(1),1000)),newPromise(resolvesetTimeout(()resolve(2),500))]).then(valueconsole.log(value));// 2// Promise.any() - 返回最先成功的 PromisePromise.any([Promise.reject(1),Promise.resolve(2),Promise.resolve(3)]).then(valueconsole.log(value));// 27. 模块化Module导出Export// 命名导出// 方式1声明时直接导出exportconstPI3.14159;exportfunctionadd(a,b){returnab;}exportclassCalculator{multiply(a,b){returna*b;}}// 方式2统一导出constPI3.14159;functionadd(a,b){returnab;}export{PI,add};// 导出时重命名export{PIaspi,addassum};// 默认导出每个模块只能有一个exportdefaultfunctionsubtract(a,b){returna-b;}导入Import// 导入命名导出import{add,Calculator}from./math.js;console.log(add(2,3));// 5constcalcnewCalculator();console.log(calc.multiply(4,5));// 20// 导入时重命名import{addassum}from./math.js;console.log(sum(2,3));// 5// 导入所有import*asmathfrom./math.js;console.log(math.add(2,3));// 5console.log(math.PI);// 3.14159// 导入默认导出importsubtractfrom./math.js;console.log(subtract(5,3));// 2// 混合导入importsubtract,{add,Calculator}from./math.js;// 动态导入asyncfunctionloadModule(){const{add}awaitimport(./math.js);console.log(add(2,3));}loadModule();8. 新的数据结构Map// 创建 MapconstuserMapnewMap();// 添加元素userMap.set(id001,{name:Alice,age:25});userMap.set(id002,{name:Bob,age:30});userMap.set(id003,{name:Charlie,age:35});// 获取元素console.log(userMap.get(id001));// { name: Alice, age: 25 }// 检查键是否存在console.log(userMap.has(id001));// true// 获取大小console.log(userMap.size);// 3// 删除元素userMap.delete(id003);// 遍历userMap.forEach((value,key){console.log(${key}:${value.name});});// 使用 for...offor(const[key,value]ofuserMap){console.log(${key}:${value.name});}// 获取所有键、值或键值对console.log([...userMap.keys()]);console.log([...userMap.values()]);console.log([...userMap.entries()]);WeakMap// WeakMap 的键必须是对象且不可枚举constweakMapnewWeakMap();constobj1{id:1};constobj2{id:2};weakMap.set(obj1,value1);weakMap.set(obj2,value2);console.log(weakMap.get(obj1));// value1console.log(weakMap.has(obj1));// true// 垃圾回收如果没有其他引用键值对会被自动清除obj1null;// 垃圾回收器会清除 weakMap 中的对应项// 应用缓存数据constcachenewWeakMap();functionexpensiveOperation(obj){if(cache.has(obj)){returncache.get(obj);}constresultobj.id*100;cache.set(obj,result);returnresult;}Set// 创建 SetconstnumberSetnewSet([1,2,3,3,4,5]);console.log(numberSet);// Set(5) { 1, 2, 3, 4, 5 }// 添加元素numberSet.add(6);numberSet.add(3);// 重复不会添加// 检查存在console.log(numberSet.has(3));// true// 删除元素numberSet.delete(6);// 大小console.log(numberSet.size);// 5// 遍历numberSet.forEach(value{console.log(value);});// 使用 for...offor(constvalueofnumberSet){console.log(value);}// 数组去重constuniqueNumbers[...newSet([1,2,2,3,3,4])];console.log(uniqueNumbers);// [1, 2, 3, 4]WeakSet// WeakSet 只能存储对象constweakSetnewWeakSet();constobj1{name:Alice};constobj2{name:Bob};constobj3{name:Charlie};weakSet.add(obj1);weakSet.add(obj2);weakSet.add(obj1);// 重复不会添加console.log(weakSet.has(obj1));// true// 垃圾回收没有其他引用时自动清除obj1null;// 应用追踪对象constvisitednewWeakSet();functionmarkVisited(obj){visited.add(obj);}functioncheckVisited(obj){returnvisited.has(obj);}9. 迭代器与生成器迭代器// 创建可迭代对象constmyIterable{[Symbol.iterator](){letindex0;return{next(){index;if(index3){return{value:index,done:false};}return{value:undefined,done:true};}};}};for(constvalueofmyIterable){console.log(value);// 1, 2, 3}// 使用迭代器constiteratormyIterable[Symbol.iterator]();console.log(iterator.next());// { value: 1, done: false }console.log(iterator.next());// { value: 2, done: false }console.log(iterator.next());// { value: 3, done: false }console.log(iterator.next());// { value: undefined, done: true }生成器函数// 生成器函数function*numberGenerator(){yield1;yield2;yield3;}constgennumberGenerator();console.log(gen.next());// { value: 1, done: false }console.log(gen.next());// { value: 2, done: false }console.log(gen.next());// { value: 3, done: false }console.log(gen.next());// { value: undefined, done: true }// 使用 for...of 遍历for(constnumofnumberGenerator()){console.log(num);// 1, 2, 3}// 无限序列function*infiniteSequence(){leti0;while(true){yieldi;}}// 斐波那契数列function*fibonacci(){leta0,b1;while(true){yielda;[a,b][b,ab];}}// 生成器作为可迭代对象function*range(start,end){for(letistart;iend;i){yieldi;}}for(constnumofrange(0,5)){console.log(num);// 0, 1, 2, 3, 4}生成器方法// throw 方法function*errorGenerator(){try{yield1;yield2;}catch(e){console.log(捕获错误:,e.message);}yield3;}constgen2errorGenerator();console.log(gen2.next());// { value: 1, done: false }console.log(gen2.throw(newError(测试错误)));// { value: 3, done: false }console.log(gen2.next());// { value: undefined, done: true }// return 方法function*returnGenerator(){yield1;yield2;yield3;}constgen3returnGenerator();console.log(gen3.next());// { value: 1, done: false }console.log(gen3.return(结束));// { value: 结束, done: true }console.log(gen3.next());// { value: undefined, done: true }10. Symbol// 创建 Symbolconstsymbol1Symbol();constsymbol2Symbol(描述);constsymbol3Symbol(描述);console.log(symbol2symbol3);// false每个 Symbol 都是唯一的// Symbol.for() - 全局 Symbol 注册表constsymbol4Symbol.for(global);constsymbol5Symbol.for(global);console.log(symbol4symbol5);// true// Symbol.keyFor() - 获取 Symbol 的键console.log(Symbol.keyFor(symbol4));// global// 作为对象属性名constobj{[Symbol(私有属性)]:值1,[Symbol(私有属性)]:值2,public:值3};console.log(Object.getOwnPropertySymbols(obj));// [Symbol(私有属性), Symbol(私有属性)]// 内置 SymbolconstmyArray[1,2,3];constiteratormyArray[Symbol.iterator]();console.log(iterator.next());// { value: 1, done: false }// Symbol.toPrimitiveconstobj2{value:10,[Symbol.toPrimitive](hint){if(hintnumber){returnthis.value;}returnString(this.value);}};console.log(obj2);// 10console.log(${obj2});// 10// Symbol.asyncIteratorconstasyncIterable{[Symbol.asyncIterator](){return{asyncnext(){return{value:异步值,done:false};}};}};11. Proxy// 创建 Proxyconsttarget{};consthandler{get(target,prop){console.log(获取属性:${prop});returnpropintarget?target[prop]:默认值;},set(target,prop,value){console.log(设置属性:${prop}${value});target[prop]value;returntrue;}};constproxynewProxy(target,handler);proxy.nameAlice;console.log(proxy.name);// Aliceconsole.log(proxy.age);// 获取属性: age; 默认值// 验证constvalidator{set(target,prop,value){if(propage){if(typeofvalue!number||value0||value150){thrownewError(年龄必须是0-150之间的数字);}}target[prop]value;returntrue;}};constpersonnewProxy({},validator);person.age25;// 正常// person.age -5; // Error// 隐藏属性consthiddenPropsnewWeakSet([password,token]);constsecureObjnewProxy({},{get(target,prop){if(hiddenProps.has(prop)){thrownewError(禁止访问私有属性);}returntarget[prop];}});// 响应式系统简化版constreactive(obj){consthandlersnewMap();returnnewProxy(obj,{set(target,prop,value){target[prop]value;constpropHandlershandlers.get(prop);if(propHandlers){propHandlers.forEach(handlerhandler(value));}returntrue;},get(target,prop){if(typeoftarget[prop]objecttarget[prop]!null){returnreactive(target[prop]);}returntarget[prop];}});};conststatereactive({count:0});handlers.get(count)?.forEach(handlerhandler(1));state.count1;12. Reflect// Reflect 是 ES6 引入的新对象提供了一系列静态方法// 1. 替代 Object 上的方法constobj{a:1,b:2};// Reflect.applyconsole.log(Reflect.apply(Math.max,null,[1,2,3]));// 3// Reflect.constructclassMyClass{}constinstanceReflect.construct(MyClass,[]);console.log(instanceinstanceofMyClass);// true// Reflect.definePropertyReflect.defineProperty(obj,c,{value:3});// Reflect.deletePropertyReflect.deleteProperty(obj,b);// Reflect.getconsole.log(Reflect.get(obj,a));// 1// Reflect.getOwnPropertyDescriptorconsole.log(Reflect.getOwnPropertyDescriptor(obj,a));// Reflect.getPrototypeOfconsole.log(Reflect.getPrototypeOf(obj));// Reflect.hasconsole.log(Reflect.has(obj,a));// true// Reflect.isExtensibleconsole.log(Reflect.isExtensible(obj));// Reflect.ownKeysconsole.log(Reflect.ownKeys(obj));// Reflect.preventExtensionsReflect.preventExtensions(obj);// Reflect.setReflect.set(obj,d,4);// Reflect.setPrototypeOfReflect.setPrototypeOf(obj,MyClass.prototype);// 2. 与 Proxy 配合使用constproxynewProxy({},{get(target,prop,receiver){returnReflect.get(target,prop,receiver);},set(target,prop,value,receiver){returnReflect.set(target,prop,value,receiver);}});ES7ES2016特性1. Array.prototype.includes()// 检查数组是否包含指定值constarray[1,2,3,NaN];console.log(array.includes(2));// trueconsole.log(array.includes(4));// falseconsole.log(array.includes(NaN));// trueincludes 可以检测 NaN// 与 indexOf 对比console.log(array.indexOf(2)!-1);// trueconsole.log(array.indexOf(NaN)!-1);// falseindexOf 无法检测 NaN2. 幂运算符**// 基本用法console.log(2**3);// 8console.log(10**2);// 100// 等同于 Math.powconsole.log(Math.pow(2,3));// 8// 右结合console.log(2**3**2);// 2 ** (3 ** 2) 2 ** 9 512// 赋值运算符letbase2;base**3;console.log(base);// 8ES8ES2017特性1. async/await// 基本用法asyncfunctionfetchData(){try{constresponseawaitfetch(https://api.example.com/data);constdataawaitresponse.json();returndata;}catch(error){console.error(获取数据失败:,error);throwerror;}}// 箭头函数constfetchDataasync(){constdataawaitsomeAsyncOperation();returndata;};// 并行执行异步操作asyncfunctionfetchMultipleData(){const[data1,data2,data3]awaitPromise.all([fetch(/api1),fetch(/api2),fetch(/api3)]);return[data1,data2,data3];}// 错误处理asyncfunctionsafeFetch(){try{constdataawaitmightFail();returndata;}catch(error){// 处理错误returndefaultValue;}}2. Object.entries() 和 Object.values()constobj{a:1,b:2,c:3};// Object.entries() - 返回键值对数组console.log(Object.entries(obj));// [[a, 1], [b, 2], [c, 3]]// Object.values() - 返回值数组console.log(Object.values(obj));// [1, 2, 3]// 遍历对象for(const[key,value]ofObject.entries(obj)){console.log(${key}:${value});}// 将对象转换为 MapconstmapnewMap(Object.entries(obj));console.log(map.get(a));// 13. Object.getOwnPropertyDescriptors()constobj{name:Alice,age:25,getinfo(){return${this.name},${this.age};}};constdescriptorsObject.getOwnPropertyDescriptors(obj);console.log(descriptors);/* { name: { value: Alice, writable: true, enumerable: true, configurable: true }, age: { value: 25, writable: true, enumerable: true, configurable: true }, info: { get: [Function: get info], set: undefined, enumerable: true, configurable: true } } */// 浅拷贝constcopyObject.create(Object.getPrototypeOf(obj),Object.getOwnPropertyDescriptors(obj));4. String padding// padStart()console.log(5.padStart(3,0));// 005console.log(abc.padStart(5));// abc// padEnd()console.log(abc.padEnd(5,*));// abc**console.log(abc.padEnd(8));// abc // 实际应用对齐输出constprices[{name:苹果,price:5.99},{name:香蕉,price:2.50},{name:榴莲,price:19.99}];prices.forEach(item{console.log(${item.name.padEnd(5)}- $${item.price.toFixed(2)});});/* 苹果 - $5.99 香蕉 - $2.50 榴莲 - $19.99 */5. Object.getOwnPropertyDescriptors()constobj{a:1,b:2};// 获取所有属性的描述符constdescriptorsObject.getOwnPropertyDescriptors(obj);// 浅拷贝对象包括 getter/setterconstcopyObject.create(Object.getPrototypeOf(obj),descriptors);ES9ES2018特性1. 异步迭代// 异步迭代器constasyncIterable{[Symbol.asyncIterator](){return{current:0,asyncnext(){awaitnewPromise(resolvesetTimeout(resolve,100));if(this.current3){return{value:this.current,done:false};}return{value:undefined,done:true};}};}};// 使用 for-await-ofasyncfunctioniterateAsync(){forawait(constvalueofasyncIterable){console.log(value);// 0, 1, 2}}iterateAsync();// 处理异步操作数组asyncfunctionprocessPromises(){constpromises[Promise.resolve(1),Promise.resolve(2),Promise.resolve(3)];forawait(constresultofpromises){console.log(result);// 1, 2, 3}}2. Rest/Spread 属性// Rest 参数用于解构const{x,y,...coords}{x:1,y:2,z:3,w:4};console.log(x,y,coords);// 1, 2, { z: 3, w: 4 }// Spread 语法用于对象constobj1{a:1,b:2};constobj2{c:3,d:4};constcombined{...obj1,...obj2};console.log(combined);// { a: 1, b: 2, c: 3, d: 4 }// 对象合并后面的属性会覆盖前面的constmerged{x:1,y:2,...{y:3,z:4}};console.log(merged);// { x: 1, y: 3, z: 4 }// 克隆对象constoriginal{a:1,b:2};constclone{...original};// 添加属性constuser{name:Alice};constuserWithAge{...user,age:25};// 函数参数functionsum(x,y,...rest){returnxyrest.reduce((a,b)ab,0);}console.log(sum(1,2,3,4,5));// 153. Promise.prototype.finally()// 无论成功或失败都会执行fetch(/api/data).then(responseresponse.json()).then(dataconsole.log(data)).catch(errorconsole.error(error)).finally((){console.log(请求完成);hideLoadingSpinner();});4. 正则表达式增强s 标志dotAll// . 不匹配换行符console.log(/^.{3}$/.test(abc));// trueconsole.log(/^.{3}$/.test(a\nc));// false// s 标志让 . 匹配换行符console.log(/^.{3}$/s.test(a\nc));// true命名捕获组// ES2018 引入constdateRegex/(?year\d{4})-(?month\d{2})-(?day\d{2})/;constmatchdateRegex.exec(2023-12-13);console.log(match.groups.year);// 2023console.log(match.groups.month);// 12console.log(match.groups.day);// 13先行断言和后行断言// 正向后行断言 (?...)constregex1/(?\$)\d/;console.log(regex1.exec($100)[0]);// 100console.log(regex1.exec(€100)[0]);// null// 负向后行断言 (?!...)constregex2/(?!\$)\d/;console.log(regex2.exec($100)[0]);// 0不是100console.log(regex2.exec(€100)[0]);// 100// 正向前瞻 (?...)constregex3/foo(?bar)/;console.log(regex3.test(foobar));// trueconsole.log(regex3.test(foobaz));// false// 负向前瞻 (?!...)constregex4/foo(?!bar)/;console.log(regex4.test(foobar));// falseconsole.log(regex4.test(foobaz));// trueES10ES2019特性1. Array.prototype.flat() 和 flatMap()// flat() - 多维数组扁平化constnestedArray[1,[2,3],[[4,5]]];console.log(nestedArray.flat());// [1, 2, 3, [4, 5]]console.log(nestedArray.flat(2));// [1, 2, 3, 4, 5]// flatMap() - 先 map 再 flatconstnumbers[1,2,3];constresultnumbers.flatMap(n[n,n*2]);console.log(result);// [1, 2, 2, 4, 3, 6]// 对比 mapconstmapResultnumbers.map(n[n,n*2]);console.log(mapResult);// [[1, 2], [2, 4], [3, 6]]// 实际应用移除空值constarrayWithHoles[1,,2,,3];console.log(arrayWithHoles.flat());// [1, 2, 3]2. Object.fromEntries()// 将键值对数组转换为对象constentries[[name,Alice],[age,25],[city,Beijing]];constobjObject.fromEntries(entries);console.log(obj);// { name: Alice, age: 25, city: Beijing }// 应用转换 MapconstmapnewMap([[key1,value1],[key2,value2]]);constfromMapObject.fromEntries(map);console.log(fromMap);// { key1: value1, key2: value2 }// 应用对象属性转换constobj{a:1,b:2,c:3};consttransformedObject.fromEntries(Object.entries(obj).map(([key,value])[key.toUpperCase(),value*2]));console.log(transformed);// { A: 2, B: 4, C: 6 }3. String.prototype.trimStart() 和 trimEnd()conststr hello world ;console.log(str.trimStart());// hello world console.log(str.trimEnd());// hello world// 别名console.log(str.trimLeft());// hello world trimStart 的别名console.log(str.trimRight());// hello worldtrimEnd 的别名4. Symbol.prototype.descriptionconstsymSymbol(描述);console.log(sym.description);// 描述// 无描述的 Symbolconstsym2Symbol();console.log(sym2.description);// undefined5. 可选 catch 参数// 以前必须声明参数try{// 可能失败的代码}catch(error){console.error(error);}// 现在可以省略参数try{// 可能失败的代码}catch{// 即使不使用 error 参数console.error(发生了错误);}ES11ES2020特性1. BigInt// 创建 BigIntconstbigInt1123456789012345678901234567890n;constbigInt2BigInt(123456789012345678901234567890);// 基本运算console.log(bigInt1bigInt2);console.log(bigInt1*2n);console.log(bigInt1/3n);// 不能与 Number 混合运算// console.log(bigInt1 1); // TypeError// 比较console.log(1n2);// trueconsole.log(1n1);// falseconsole.log(1n1);// true// Number 与 BigInt 转换constnumNumber(bigInt1);constbigBigInt(Number.MAX_SAFE_INTEGER);2. 空值合并运算符??// ?? 只有在值为 null 或 undefined 时才使用默认值consta0;constbnull;constcundefined;constddefault;console.log(a??d);// 00 不是 null 或 undefinedconsole.log(b??d);// defaultconsole.log(c??d);// default// 与 || 对比console.log(a||d);// default|| 将 0 视为 falsyconsole.log(a??d);// 0?? 只识别 null/undefined// 实际应用constconfig{timeout:0,retries:null};console.log(config.timeout??5000);// 0console.log(config.retries??3);// 3console.log(config.maxRetries??5);// 53. 可选链操作符?.constuser{name:Alice,address:{city:Beijing},getName(){returnthis.name;}};// 属性访问console.log(user.address?.city);// Beijingconsole.log(user.profile?.age);// undefined// 方法调用console.log(user.getName?.());// Aliceconsole.log(user.getAge?.());// undefined// 动态属性constpropaddress;console.log(user?.[prop]?.city);// Beijing// 数组访问constarr[1,2,3];console.log(arr?.[0]);// 1console.log(arr?.[10]);// undefined// 实际应用constresponseawaitfetch(/api/user);constuserDataresponse?.data;constuserNameuserData?.profile?.name;4. dynamic-import// 动态导入模块asyncfunctionloadFeature(){const{default:myModule,someFunction}awaitimport(./module.js);constresultsomeFunction();returnresult;}// 根据条件导入if(condition){const{utility}awaitimport(./utility.js);utility();}// 导入模块路径constmodulePath./utils.js;constutilsawaitimport(modulePath);// 导入缓存constmodule1awaitimport(./module.js);constmodule2awaitimport(./module.js);// 重新导入可以缓存console.log(module1module2);// trueES12ES2021特性1. 数字分隔符Numeric Separators// 改善大数字的可读性constbillion1_000_000_000;constbytes0xFF_FF_FF_FF;constbinary0b1111_0000;constpi3.14159_26535;console.log(billion);// 1000000000console.log(bytes);// 42949672952. String.prototype.replaceAll()conststrfoo bar foo baz foo;// 以前需要使用正则表达式console.log(str.replace(/foo/g,bar));// bar bar bar baz bar// 现在可以直接使用 replaceAllconsole.log(str.replaceAll(foo,bar));// bar bar bar baz bar3. Promise.any()// Promise.any() 等待第一个成功的 Promiseconstp1Promise.reject(错误1);constp2Promise.resolve(成功2);constp3Promise.resolve(成功3);Promise.any([p1,p2,p3]).then(valueconsole.log(value))// 成功2.catch(error{console.log(error.errors);// [错误1, ...]});// 所有 Promise 都失败时抛出 AggregateErrorconstp4Promise.reject(失败1);constp5Promise.reject(失败2);Promise.any([p4,p5]).catch(error{console.log(errorinstanceofAggregateError);// trueconsole.log(error.errors);// [失败1, 失败2]});4. 逻辑赋值运算符// || 逻辑或赋值leta0;a||10;console.log(a);// 100 是 falsyletb1;b||10;console.log(b);// 11 是 truthy// 逻辑与赋值letc1;c10;console.log(c);// 101 是 truthyletd0;d10;console.log(d);// 00 是 falsy// ?? 逻辑空赋值leteundefined;e??10;console.log(e);// 10letf0;f??10;console.log(f);// 00 不是 null/undefined// 实际应用config.timeout??5000;config.retries10;config.debug||false;ES13ES2022特性1. 类静态初始化块classMyClass{staticproperty1值1;staticproperty2值2;static{// 静态初始化块// 可以在此处执行复杂的静态属性初始化this.computedthis.property1this.property2;console.log(静态初始化完成);}static{// 可以有多个静态块this.timestampDate.now();}}console.log(MyClass.computed);// 值1值2console.log(MyClass.timestamp);// 当前时间戳2. 私有字段检查classBankAccount{#balance0;deposit(amount){this.#balanceamount;}checkBalance(){if(this.#balance0){thrownewError(余额不能为负);}}// 检查私有字段是否存在hasBalance(){return#balanceinthis;}}constaccountnewBankAccount();console.log(#balanceinaccount);// false私有字段不通过 in 检查console.log(account.hasBalance());// true使用 # 前缀语法检查3. at() 方法constarr[1,2,3,4,5];// 支持从末尾访问console.log(arr.at(-1));// 5console.log(arr.at(-2));// 4// 字符串也支持conststrhello;console.log(str.at(-1));// oconsole.log(str.at(-2));// l// 对比传统方法console.log(arr[arr.length-1]);// 5需要计算长度console.log(arr.at(-1));// 5更简洁4. Object.hasOwn()constobj{a:1,b:2};Object.prototype.c3;console.log(Object.hasOwn(obj,a));// trueconsole.log(Object.hasOwn(obj,c));// false在原型上console.log(Object.prototype.hasOwnProperty.call(obj,c));// false// 更简洁、更安全constobj2Object.create(null);obj2.propexists;console.log(Object.hasOwn(obj2,prop));// true// console.log(obj2.hasOwnProperty(prop)); // TypeError无 hasOwnProperty5. 错误原因Error.causetry{try{JSON.parse(invalid json);}catch(error){thrownewError(JSON 解析失败,{cause:error});}}catch(error){console.log(error.message);// JSON 解析失败console.log(error.cause);// SyntaxError: Unexpected token}实际开发应用案例1. 异步数据获取与缓存classDataCache{constructor(){this.cachenewMap();}asyncfetch(key,fetcher,ttl60000){// 检查缓存if(this.cache.has(key)){const{data,timestamp}this.cache.get(key);if(Date.now()-timestampttl){returndata;}}// 获取新数据try{constdataawaitfetcher();this.cache.set(key,{data,timestamp:Date.now()});returndata;}catch(error){// 如果有缓存数据返回过期数据作为降级if(this.cache.has(key)){console.warn(请求失败使用过期缓存);returnthis.cache.get(key).data;}throwerror;}}clear(key){this.cache.delete(key);}clearAll(){this.cache.clear();}}constdataCachenewDataCache();// 使用constuserDataawaitdataCache.fetch(user:123,()fetch(/api/user/123).then(rr.json()),300000// 5分钟缓存);2. 响应式状态管理functioncreateStore(initialState){letstateinitialState;constlistenersnewSet();conststore{getState(){returnstate;},setState(patcher){constnewStatepatcher(state);if(newState!state){statenewState;listeners.forEach(listenerlistener(state));}},subscribe(listener){listeners.add(listener);return()listeners.delete(listener);}};returnstore;}conststorecreateStore({count:0});// 订阅状态变化constunsubscribestore.subscribe(state{console.log(状态更新:,state);});// 更新状态store.setState(state({...state,count:state.count1}));store.setState(state({...state,count:state.count*2}));// 取消订阅unsubscribe();3. 异步并发控制// 限制并发数量的异步函数asyncfunctionconcurrentMap(items,limit,mapper){constresults[];constexecutingnewSet();for(constitemofitems){constpromisemapper(item);results.push(promise);executing.add(promise);promise.then(()executing.delete(promise));if(executing.sizelimit){awaitPromise.race(executing);}}returnPromise.all(results);}// 使用示例consturls[url1,url2,url3,url4,url5];constfetchWithLimitconcurrentMap(urls,2,// 最多同时2个请求urlfetch(url).then(rr.json()));4. 错误边界处理classErrorBoundary{constructor(fallback){this.fallbackfallback;this.errorsnewWeakMap();}wrap(fn){returnasync(...args){try{returnawaitfn(...args);}catch(error){consterrorIdSymbol(error);this.errors.set(errorId,error);returnthis.fallback(error,errorId);}};}getError(id){returnthis.errors.get(id);}}consterrorBoundarynewErrorBoundary((error,id){console.error(捕获错误:,error.message);return{error:true,id};});constriskyOperationerrorBoundary.wrap(async(){thrownewError(可能失败的操作);});constresultawaitriskyOperation();5. 资源加载管理器classResourceLoader{constructor(){this.cachenewMap();this.loadingnewMap();}asyncload(key,fetcher){// 返回缓存if(this.cache.has(key)){returnthis.cache.get(key);}// 返回正在加载的 Promiseif(this.loading.has(key)){returnthis.loading.get(key);}// 开始加载constpromisefetcher().then(data{this.cache.set(key,data);this.loading.delete(key);returndata;}).catch(error{this.loading.delete(key);throwerror;});this.loading.set(key,promise);returnpromise;}preload(key,fetcher){// 预加载但不等待this.load(key,fetcher);}unload(key){this.cache.delete(key);this.loading.delete(key);}clear(){this.cache.clear();this.loading.clear();}}// 使用constloadernewResourceLoader();constimageawaitloader.load(hero-image,()fetch(/images/hero.jpg).then(rr.blob()));兼容性说明Babel 转译// .babelrc 配置{presets:[[babel/preset-env,{targets:{browsers:[ 1%,last 2 versions]},useBuiltIns:usage,corejs:3}]],plugins:[[babel/plugin-proposal-decorators,{legacy:true}],babel/plugin-proposal-class-properties]}使用 Polyfill// 引入 core-js 作为 polyfillimportcore-js/stable;// 或者按需引入importcore-js/features/promise;importcore-js/features/array/includes;importcore-js/features/object/entries;浏览器支持检查// 检查 ES6 支持if(typeofPromiseundefined){import(promise-polyfill).then(PromisePolyfill{window.PromisePromisePolyfill;});}// 检查可选链if(!(optionalChainingin({}))){// 使用 Babel 转译}总结ES6 带来的核心改进语法现代化let/const、箭头函数、类、解构赋值模块化支持原生 ES6 模块系统异步编程Promise、生成器数据结构Map/Set、Symbol、Proxy、Reflect更好的开发体验模板字符串、迭代器ES7-ES12 的增强更简洁的 APIincludes、Object.entries、flat更好的异步支持async/await、Promise 新方法可选链和空值合并?. 和 ??性能优化BigInt、数字分隔符开发者体验提升String padding、Error.cause