news 2026/3/4 17:29:32

ES6与ESNext特性深度解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ES6与ESNext特性深度解析

前端 ES6 与 ESNext 特性全解析

ES6(ECMAScript 2015)作为JavaScript发展的重要转折点,带来了诸多革命性特性,显著提升了开发效率。此后,ES7、ES8等后续版本以及ESNext持续推动着JavaScript的演进。

ES6(ES2015)核心特性

1. 块级作用域:let 和 const

letconst解决了 ES5 中var的作用域问题。

let 关键字
// let 声明的变量具有块级作用域for(leti=0;i<3;i++){console.log(i);// 0, 1, 2}// console.log(i); // ReferenceError: i is not defined// 不会变量提升console.log(a);// ReferenceErrorleta=1;// 不允许重复声明letb=2;// let b = 3; // SyntaxError// 暂时性死区(Temporal Dead Zone){console.log(c);// ReferenceErrorletc=3;}
const 关键字
// const 声明常量,值不可修改(对于基本类型)constPI=3.14159;// PI = 3.14; // TypeError// 对于对象/数组,内容可以修改constobj={name:'JavaScript'};obj.name='ES6';// 允许// obj = {}; // TypeError// 同样具有块级作用域{constAPI_KEY='abc123';console.log(API_KEY);// abc123}// console.log(API_KEY); // ReferenceError

2. 解构赋值(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[p=1,q=2]=[5];console.log(p,q);// 5, 2// 交换变量letm=1,n=2;[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{score=0,grade='A'}={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){returna+b;}// 箭头函数constadd=(a,b)=>a+b;// 多个参数constmultiply=(x,y)=>x*y;// 单个参数(可省略括号)constsquare=x=>x*x;// 无参数constgetRandom=()=>Math.random();// 函数体多条语句constcalculate=(a,b)=>{constsum=a+b;constproduct=a*b;return{sum,product};};// 返回对象字面量constcreateUser=(name,age)=>({name,age});// 立即执行函数表达式(IIFE)(()=>console.log('IIFE'))();// 作为回调函数constnumbers=[1,2,3,4,5];constdoubled=numbers.map(n=>n*2);constevens=numbers.filter(n=>n%2===0);constsum=numbers.reduce((acc,n)=>acc+n,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.name=name;};// const p = new Person('John'); // TypeError// 4. 没有 prototype 属性constfn=()=>{};console.log(fn.prototype);// undefined

4. 模板字符串(Template Literals)

// 基本用法constname='World';constgreeting=`Hello,${name}!`;console.log(greeting);// Hello, World!// 表达式计算consta=5,b=10;console.log(`${a}+${b}=${a+b}`);// 5 + 10 = 15// 多行字符串constmultiline=`这是一个 多行字符串 不需要转义\n换行`;console.log(multiline);// 嵌套模板constvalue=20;constresult=`值是:${value>10?'大于10':'小于等于10'}`;// 标签模板(Tagged Templates)functiontag(strings,...values){console.log(strings);// ['前缀', ' 是 ', '']console.log(values);// [42]return'处理结果';}constresult=tag`前缀${42}`;// 原始字符串(保留转义字符)constraw=String.raw`第一行\n第二行`;console.log(raw);// 第一行\n第二行(而不是换行)

5. 类(Class)

基本类定义
// 类的定义classPerson{// 构造函数constructor(name,age){this.name=name;this.age=age;}// 实例方法greet(){return`Hello, I'm${this.name}`;}// 静态方法staticspecies(){return'Homo sapiens';}// gettergetinfo(){return`${this.name},${this.age}years old`;}// settersetinfo(data){const[name,age]=data.split(',');this.name=name;this.age=parseInt(age);}}constalice=newPerson('Alice',25);console.log(alice.greet());// Hello, I'm Aliceconsole.log(alice.info);// Alice, 25 years oldconsole.log(Person.species());// Homo sapiensalice.info='Bob, 30';console.log(alice.info);// Bob, 30 years old
继承
// 继承classStudentextendsPerson{constructor(name,age,major){super(name,age);// 调用父类构造函数this.major=major;}// 重写父类方法greet(){return`${super.greet()}and I study${this.major}`;}// 子类特有方法study(){return`${this.name}is studying${this.major}`;}}constbob=newStudent('Bob',20,'Computer Science');console.log(bob.greet());// Hello, I'm Bob and I study Computer Scienceconsole.log(bob.study());// Bob is studying Computer Science// instanceof 检查console.log(bobinstanceofStudent);// trueconsole.log(bobinstanceofPerson);// true
私有字段(ES2022)
classBankAccount{// 私有字段(ES2022)#balance=0;#accountNumber;constructor(accountNumber){this.#accountNumber=accountNumber;}deposit(amount){if(amount>0){this.#balance+=amount;returntrue;}returnfalse;}withdraw(amount){if(amount>0&&amount<=this.#balance){this.#balance-=amount;returntrue;}returnfalse;}getbalance(){returnthis.#balance;}getaccountNumber(){returnthis.#accountNumber;}}constaccount=newBankAccount('123456');account.deposit(1000);console.log(account.balance);// 1000// console.log(account.#balance); // SyntaxError: Private field

6. Promise

Promise 基本用法
// 创建 Promiseconstpromise=newPromise((resolve,reject)=>{// 异步操作setTimeout(()=>{constsuccess=true;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()constp1=Promise.resolve('成功');p1.then(v=>console.log(v));// 成功// Promise.reject()constp2=Promise.reject(newError('失败'));p2.catch(e=>console.log(e.message));// 失败// Promise.all() - 所有 Promise 都成功才成功constp3=Promise.resolve(1);constp4=Promise.resolve(2);constp5=Promise.resolve(3);Promise.all([p3,p4,p5]).then(values=>console.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(resolve=>setTimeout(()=>resolve(1),1000)),newPromise(resolve=>setTimeout(()=>resolve(2),500))]).then(value=>console.log(value));// 2// Promise.any() - 返回最先成功的 PromisePromise.any([Promise.reject(1),Promise.resolve(2),Promise.resolve(3)]).then(value=>console.log(value));// 2

7. 模块化(Module)

导出(Export)
// 命名导出// 方式1:声明时直接导出exportconstPI=3.14159;exportfunctionadd(a,b){returna+b;}exportclassCalculator{multiply(a,b){returna*b;}}// 方式2:统一导出constPI=3.14159;functionadd(a,b){returna+b;}export{PI,add};// 导出时重命名export{PIaspi,addassum};// 默认导出(每个模块只能有一个)exportdefaultfunctionsubtract(a,b){returna-b;}
导入(Import)
// 导入命名导出import{add,Calculator}from'./math.js';console.log(add(2,3));// 5constcalc=newCalculator();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
// 创建 MapconstuserMap=newMap();// 添加元素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 的键必须是对象,且不可枚举constweakMap=newWeakMap();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// 垃圾回收:如果没有其他引用,键值对会被自动清除obj1=null;// 垃圾回收器会清除 weakMap 中的对应项// 应用:缓存数据constcache=newWeakMap();functionexpensiveOperation(obj){if(cache.has(obj)){returncache.get(obj);}constresult=obj.id*100;cache.set(obj,result);returnresult;}
Set
// 创建 SetconstnumberSet=newSet([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 只能存储对象constweakSet=newWeakSet();constobj1={name:'Alice'};constobj2={name:'Bob'};constobj3={name:'Charlie'};weakSet.add(obj1);weakSet.add(obj2);weakSet.add(obj1);// 重复,不会添加console.log(weakSet.has(obj1));// true// 垃圾回收:没有其他引用时自动清除obj1=null;// 应用:追踪对象constvisited=newWeakSet();functionmarkVisited(obj){visited.add(obj);}functioncheckVisited(obj){returnvisited.has(obj);}

9. 迭代器与生成器

迭代器
// 创建可迭代对象constmyIterable={[Symbol.iterator](){letindex=0;return{next(){index++;if(index<=3){return{value:index,done:false};}return{value:undefined,done:true};}};}};for(constvalueofmyIterable){console.log(value);// 1, 2, 3}// 使用迭代器constiterator=myIterable[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;}constgen=numberGenerator();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(){leti=0;while(true){yieldi++;}}// 斐波那契数列function*fibonacci(){leta=0,b=1;while(true){yielda;[a,b]=[b,a+b];}}// 生成器作为可迭代对象function*range(start,end){for(leti=start;i<end;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;}constgen2=errorGenerator();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;}constgen3=returnGenerator();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

// 创建 Symbolconstsymbol1=Symbol();constsymbol2=Symbol('描述');constsymbol3=Symbol('描述');console.log(symbol2===symbol3);// false(每个 Symbol 都是唯一的)// Symbol.for() - 全局 Symbol 注册表constsymbol4=Symbol.for('global');constsymbol5=Symbol.for('global');console.log(symbol4===symbol5);// 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];constiterator=myArray[Symbol.iterator]();console.log(iterator.next());// { value: 1, done: false }// Symbol.toPrimitiveconstobj2={value:10,[Symbol.toPrimitive](hint){if(hint==='number'){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;}};constproxy=newProxy(target,handler);proxy.name='Alice';console.log(proxy.name);// Aliceconsole.log(proxy.age);// 获取属性: age; 默认值// 验证constvalidator={set(target,prop,value){if(prop==='age'){if(typeofvalue!=='number'||value<0||value>150){thrownewError('年龄必须是0-150之间的数字');}}target[prop]=value;returntrue;}};constperson=newProxy({},validator);person.age=25;// 正常// person.age = -5; // Error// 隐藏属性consthiddenProps=newWeakSet(['password','token']);constsecureObj=newProxy({},{get(target,prop){if(hiddenProps.has(prop)){thrownewError('禁止访问私有属性');}returntarget[prop];}});// 响应式系统(简化版)constreactive=(obj)=>{consthandlers=newMap();returnnewProxy(obj,{set(target,prop,value){target[prop]=value;constpropHandlers=handlers.get(prop);if(propHandlers){propHandlers.forEach(handler=>handler(value));}returntrue;},get(target,prop){if(typeoftarget[prop]==='object'&&target[prop]!==null){returnreactive(target[prop]);}returntarget[prop];}});};conststate=reactive({count:0});handlers.get('count')?.forEach(handler=>handler(1));state.count=1;

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{}constinstance=Reflect.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 配合使用constproxy=newProxy({},{get(target,prop,receiver){returnReflect.get(target,prop,receiver);},set(target,prop,value,receiver){returnReflect.set(target,prop,value,receiver);}});

ES7(ES2016)特性

1. Array.prototype.includes()

// 检查数组是否包含指定值constarray=[1,2,3,NaN];console.log(array.includes(2));// trueconsole.log(array.includes(4));// falseconsole.log(array.includes(NaN));// true(includes 可以检测 NaN)// 与 indexOf 对比console.log(array.indexOf(2)!==-1);// trueconsole.log(array.indexOf(NaN)!==-1);// false(indexOf 无法检测 NaN)

2. 幂运算符(**)

// 基本用法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// 赋值运算符letbase=2;base**=3;console.log(base);// 8

ES8(ES2017)特性

1. async/await

// 基本用法asyncfunctionfetchData(){try{constresponse=awaitfetch('https://api.example.com/data');constdata=awaitresponse.json();returndata;}catch(error){console.error('获取数据失败:',error);throwerror;}}// 箭头函数constfetchData=async()=>{constdata=awaitsomeAsyncOperation();returndata;};// 并行执行异步操作asyncfunctionfetchMultipleData(){const[data1,data2,data3]=awaitPromise.all([fetch('/api1'),fetch('/api2'),fetch('/api3')]);return[data1,data2,data3];}// 错误处理asyncfunctionsafeFetch(){try{constdata=awaitmightFail();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}`);}// 将对象转换为 Mapconstmap=newMap(Object.entries(obj));console.log(map.get('a'));// 1

3. Object.getOwnPropertyDescriptors()

constobj={name:'Alice',age:25,getinfo(){return`${this.name},${this.age}`;}};constdescriptors=Object.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 } } */// 浅拷贝constcopy=Object.create(Object.getPrototypeOf(obj),Object.getOwnPropertyDescriptors(obj));

4. String padding

// padStart()console.log('5'.padStart(3,'0'));// '005'console.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};// 获取所有属性的描述符constdescriptors=Object.getOwnPropertyDescriptors(obj);// 浅拷贝对象(包括 getter/setter)constcopy=Object.create(Object.getPrototypeOf(obj),descriptors);

ES9(ES2018)特性

1. 异步迭代

// 异步迭代器constasyncIterable={[Symbol.asyncIterator](){return{current:0,asyncnext(){awaitnewPromise(resolve=>setTimeout(resolve,100));if(this.current<3){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){returnx+y+rest.reduce((a,b)=>a+b,0);}console.log(sum(1,2,3,4,5));// 15

3. Promise.prototype.finally()

// 无论成功或失败都会执行fetch('/api/data').then(response=>response.json()).then(data=>console.log(data)).catch(error=>console.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})/;constmatch=dateRegex.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(不是100)console.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'));// true

ES10(ES2019)特性

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];constresult=numbers.flatMap(n=>[n,n*2]);console.log(result);// [1, 2, 2, 4, 3, 6]// 对比 mapconstmapResult=numbers.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']];constobj=Object.fromEntries(entries);console.log(obj);// { name: 'Alice', age: 25, city: 'Beijing' }// 应用:转换 Mapconstmap=newMap([['key1','value1'],['key2','value2']]);constfromMap=Object.fromEntries(map);console.log(fromMap);// { key1: 'value1', key2: 'value2' }// 应用:对象属性转换constobj={a:1,b:2,c:3};consttransformed=Object.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 world'(trimEnd 的别名)

4. Symbol.prototype.description

constsym=Symbol('描述');console.log(sym.description);// '描述'// 无描述的 Symbolconstsym2=Symbol();console.log(sym2.description);// undefined

5. 可选 catch 参数

// 以前必须声明参数try{// 可能失败的代码}catch(error){console.error(error);}// 现在可以省略参数try{// 可能失败的代码}catch{// 即使不使用 error 参数console.error('发生了错误');}

ES11(ES2020)特性

1. BigInt

// 创建 BigIntconstbigInt1=123456789012345678901234567890n;constbigInt2=BigInt('123456789012345678901234567890');// 基本运算console.log(bigInt1+bigInt2);console.log(bigInt1*2n);console.log(bigInt1/3n);// 不能与 Number 混合运算// console.log(bigInt1 + 1); // TypeError// 比较console.log(1n<2);// trueconsole.log(1n===1);// falseconsole.log(1n==1);// true// Number 与 BigInt 转换constnum=Number(bigInt1);constbig=BigInt(Number.MAX_SAFE_INTEGER);

2. 空值合并运算符(??)

// ?? 只有在值为 null 或 undefined 时才使用默认值consta=0;constb=null;constc=undefined;constd='default';console.log(a??d);// 0(0 不是 null 或 undefined)console.log(b??d);// 'default'console.log(c??d);// 'default'// 与 || 对比console.log(a||d);// 'default'(|| 将 0 视为 falsy)console.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);// 5

3. 可选链操作符(?.)

constuser={name:'Alice',address:{city:'Beijing'},getName(){returnthis.name;}};// 属性访问console.log(user.address?.city);// 'Beijing'console.log(user.profile?.age);// undefined// 方法调用console.log(user.getName?.());// 'Alice'console.log(user.getAge?.());// undefined// 动态属性constprop='address';console.log(user?.[prop]?.city);// 'Beijing'// 数组访问constarr=[1,2,3];console.log(arr?.[0]);// 1console.log(arr?.[10]);// undefined// 实际应用constresponse=awaitfetch('/api/user');constuserData=response?.data;constuserName=userData?.profile?.name;

4. dynamic-import

// 动态导入模块asyncfunctionloadFeature(){const{default:myModule,someFunction}=awaitimport('./module.js');constresult=someFunction();returnresult;}// 根据条件导入if(condition){const{utility}=awaitimport('./utility.js');utility();}// 导入模块路径constmodulePath='./utils.js';constutils=awaitimport(modulePath);// 导入缓存constmodule1=awaitimport('./module.js');constmodule2=awaitimport('./module.js');// 重新导入(可以缓存)console.log(module1===module2);// true

ES12(ES2021)特性

1. 数字分隔符(Numeric Separators)

// 改善大数字的可读性constbillion=1_000_000_000;constbytes=0xFF_FF_FF_FF;constbinary=0b1111_0000;constpi=3.14159_26535;console.log(billion);// 1000000000console.log(bytes);// 4294967295

2. String.prototype.replaceAll()

conststr='foo 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 bar'

3. Promise.any()

// Promise.any() 等待第一个成功的 Promiseconstp1=Promise.reject('错误1');constp2=Promise.resolve('成功2');constp3=Promise.resolve('成功3');Promise.any([p1,p2,p3]).then(value=>console.log(value))// '成功2'.catch(error=>{console.log(error.errors);// ['错误1', ...]});// 所有 Promise 都失败时抛出 AggregateErrorconstp4=Promise.reject('失败1');constp5=Promise.reject('失败2');Promise.any([p4,p5]).catch(error=>{console.log(errorinstanceofAggregateError);// trueconsole.log(error.errors);// ['失败1', '失败2']});

4. 逻辑赋值运算符

// ||= 逻辑或赋值leta=0;a||=10;console.log(a);// 10(0 是 falsy)letb=1;b||=10;console.log(b);// 1(1 是 truthy)// &&= 逻辑与赋值letc=1;c&&=10;console.log(c);// 10(1 是 truthy)letd=0;d&&=10;console.log(d);// 0(0 是 falsy)// ??= 逻辑空赋值lete=undefined;e??=10;console.log(e);// 10letf=0;f??=10;console.log(f);// 0(0 不是 null/undefined)// 实际应用config.timeout??=5000;config.retries&&=10;config.debug||=false;

ES13(ES2022)特性

1. 类静态初始化块

classMyClass{staticproperty1='值1';staticproperty2='值2';static{// 静态初始化块// 可以在此处执行复杂的静态属性初始化this.computed=this.property1+this.property2;console.log('静态初始化完成');}static{// 可以有多个静态块this.timestamp=Date.now();}}console.log(MyClass.computed);// '值1值2'console.log(MyClass.timestamp);// 当前时间戳

2. 私有字段检查

classBankAccount{#balance=0;deposit(amount){this.#balance+=amount;}checkBalance(){if(this.#balance<0){thrownewError('余额不能为负');}}// 检查私有字段是否存在hasBalance(){return#balanceinthis;}}constaccount=newBankAccount();console.log('#balance'inaccount);// 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// 字符串也支持conststr='hello';console.log(str.at(-1));// 'o'console.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.c=3;console.log(Object.hasOwn(obj,'a'));// trueconsole.log(Object.hasOwn(obj,'c'));// false(在原型上)console.log(Object.prototype.hasOwnProperty.call(obj,'c'));// false// 更简洁、更安全constobj2=Object.create(null);obj2.prop='exists';console.log(Object.hasOwn(obj2,'prop'));// true// console.log(obj2.hasOwnProperty('prop')); // TypeError(无 hasOwnProperty)

5. 错误原因(Error.cause)

try{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.cache=newMap();}asyncfetch(key,fetcher,ttl=60000){// 检查缓存if(this.cache.has(key)){const{data,timestamp}=this.cache.get(key);if(Date.now()-timestamp<ttl){returndata;}}// 获取新数据try{constdata=awaitfetcher();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();}}constdataCache=newDataCache();// 使用constuserData=awaitdataCache.fetch('user:123',()=>fetch('/api/user/123').then(r=>r.json()),300000// 5分钟缓存);

2. 响应式状态管理

functioncreateStore(initialState){letstate=initialState;constlisteners=newSet();conststore={getState(){returnstate;},setState(patcher){constnewState=patcher(state);if(newState!==state){state=newState;listeners.forEach(listener=>listener(state));}},subscribe(listener){listeners.add(listener);return()=>listeners.delete(listener);}};returnstore;}conststore=createStore({count:0});// 订阅状态变化constunsubscribe=store.subscribe(state=>{console.log('状态更新:',state);});// 更新状态store.setState(state=>({...state,count:state.count+1}));store.setState(state=>({...state,count:state.count*2}));// 取消订阅unsubscribe();

3. 异步并发控制

// 限制并发数量的异步函数asyncfunctionconcurrentMap(items,limit,mapper){constresults=[];constexecuting=newSet();for(constitemofitems){constpromise=mapper(item);results.push(promise);executing.add(promise);promise.then(()=>executing.delete(promise));if(executing.size>=limit){awaitPromise.race(executing);}}returnPromise.all(results);}// 使用示例consturls=['url1','url2','url3','url4','url5'];constfetchWithLimit=concurrentMap(urls,2,// 最多同时2个请求url=>fetch(url).then(r=>r.json()));

4. 错误边界处理

classErrorBoundary{constructor(fallback){this.fallback=fallback;this.errors=newWeakMap();}wrap(fn){returnasync(...args)=>{try{returnawaitfn(...args);}catch(error){consterrorId=Symbol('error');this.errors.set(errorId,error);returnthis.fallback(error,errorId);}};}getError(id){returnthis.errors.get(id);}}consterrorBoundary=newErrorBoundary((error,id)=>{console.error('捕获错误:',error.message);return{error:true,id};});constriskyOperation=errorBoundary.wrap(async()=>{thrownewError('可能失败的操作');});constresult=awaitriskyOperation();

5. 资源加载管理器

classResourceLoader{constructor(){this.cache=newMap();this.loading=newMap();}asyncload(key,fetcher){// 返回缓存if(this.cache.has(key)){returnthis.cache.get(key);}// 返回正在加载的 Promiseif(this.loading.has(key)){returnthis.loading.get(key);}// 开始加载constpromise=fetcher().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();}}// 使用constloader=newResourceLoader();constimage=awaitloader.load('hero-image',()=>fetch('/images/hero.jpg').then(r=>r.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 作为 polyfillimport'core-js/stable';// 或者按需引入import'core-js/features/promise';import'core-js/features/array/includes';import'core-js/features/object/entries';

浏览器支持检查

// 检查 ES6 支持if(typeofPromise==='undefined'){import('promise-polyfill').then(PromisePolyfill=>{window.Promise=PromisePolyfill;});}// 检查可选链if(!('optionalChaining'in({}))){// 使用 Babel 转译}

总结

ES6 带来的核心改进

  1. 语法现代化:let/const、箭头函数、类、解构赋值
  2. 模块化支持:原生 ES6 模块系统
  3. 异步编程:Promise、生成器
  4. 数据结构:Map/Set、Symbol、Proxy、Reflect
  5. 更好的开发体验:模板字符串、迭代器

ES7-ES12 的增强

  1. 更简洁的 API:includes、Object.entries、flat
  2. 更好的异步支持:async/await、Promise 新方法
  3. 可选链和空值合并:?. 和 ??
  4. 性能优化:BigInt、数字分隔符
  5. 开发者体验提升:String padding、Error.cause
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/3 16:23:00

7天掌握Arkime YARA:从零构建威胁检测防线

Arkime YARA规则是网络安全检测中的实用利器&#xff0c;通过简单的模式匹配就能识别网络流量中的可疑行为。对于刚开始接触网络安全的新手来说&#xff0c;掌握Arkime YARA规则可以让你在5分钟内快速部署基础检测能力&#xff0c;零基础也能轻松编写有效规则。 【免费下载链接…

作者头像 李华
网站建设 2026/3/4 21:48:28

MPV播放器播放进度自动保存:3分钟掌握断点续播全攻略

还在为每次观看视频都要重新寻找上次的播放位置而烦恼吗&#xff1f;MPV播放器作为一款强大的命令行视频播放器&#xff0c;其播放进度自动保存功能能够彻底解决这个痛点&#xff01;只需简单配置&#xff0c;就能实现智能断点续播&#xff0c;让你的观影体验更加流畅自然。 【…

作者头像 李华
网站建设 2026/3/3 16:28:35

6大技术突破:全面剖析MikroTik RouterOS 7.19.2 arm64版本性能升级

6大技术突破&#xff1a;全面剖析MikroTik RouterOS 7.19.2 arm64版本性能升级 【免费下载链接】MikroTikPatch 项目地址: https://gitcode.com/gh_mirrors/mikr/MikroTikPatch RouterOS补丁在arm64架构设备上的应用正迎来重要里程碑。MikroTik最新发布的7.19.2版本针对…

作者头像 李华
网站建设 2026/3/3 18:33:15

16、SAS数据处理:变量管理、条件赋值与数据读取

SAS数据处理:变量管理、条件赋值与数据读取 1. 变量排除:DROP和KEEP语句 在处理数据集时,有时需要排除某些变量。除了使用 DROP= 和 KEEP= 数据集选项外,还可以使用 DROP 和 KEEP 语句。不过,这两种语句与数据集选项存在一些区别: - 不能在SAS过程步骤中使用 …

作者头像 李华
网站建设 2026/3/3 18:33:13

GNOME Shell开发终极指南:从架构解析到深度定制

GNOME Shell开发终极指南&#xff1a;从架构解析到深度定制 【免费下载链接】gnome-shell Read-only mirror of https://gitlab.gnome.org/GNOME/gnome-shell 项目地址: https://gitcode.com/gh_mirrors/gn/gnome-shell GNOME Shell作为现代Linux桌面环境的核心组件&…

作者头像 李华
网站建设 2026/3/5 2:08:11

Linux应用打包分发终极指南:从入门到精通的最佳实践

Linux应用打包分发终极指南&#xff1a;从入门到精通的最佳实践 【免费下载链接】星火应用商店Spark-Store 星火应用商店是国内知名的linux应用分发平台&#xff0c;为中国linux桌面生态贡献力量 项目地址: https://gitcode.com/spark-store-project/spark-store 在Linu…

作者头像 李华