目录
- 一、ES6介绍
- 1.1 Let变量定义
- 1.2 箭头函数
- 1.2.1 基本语法
- 1.2.2 this 绑定(重要区别!)
- 1.3 模板字符串
- 1.4 解构赋值
- 1.4.1 数组解构
- 1.4.2 对象解构
- 1.5 扩展运算符
- 1.5.1 数组扩展
- 1.5.2 对象扩展
- 1.6 默认参数
- 1.7 剩余参数
- 1.8 Symbol 类型
- 1.10 Set 和 Map
- 1.10.1 Set
- 1.10.2 Map
- 1.11 Promise 和异步
- 1.12 async/await
- 1.13 模块化
- 1.13.1 导出
- 1.13.2 导入
一、ES6介绍
ECMAScript 6(简称ES6)是于2015年6月正式发布的JavaScript语言的标准,正式名为ECMAScript 2015(ES2015)。它的目标是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言 。
另外,一些情况下ES6也泛指ES2015及之后的新增特性,虽然之后的版本应当称为ES7、ES8等。
1.1 Let变量定义
functiontest1(){// var 声明的变量往往会越域// let 声明的变量有严格局部作用域{vara=1;letb=2;}console.log(a);// 1//console.log(b); // ReferenceError: b is not defined}functiontest1(){// var 可以声明多次// let 只能声明一次varm=1varm=2letn=3//let n = 4console.log(m)// 2console.log(n)// Identifier 'n' has already been declared}functiontest2(){// var 会变量提升// let 不存在变量提升console.log(x);// undefinedvarx=10;console.log(y);//ReferenceError: y is not definedlety=20;1.2 箭头函数
1.2.1 基本语法
// 传统函数functionsum1(a,b){returna+b;}// 箭头函数constsum2=(a,b)=>a+b;// 不同写法constsquare=n=>n*n;// 单参数constsayHello=()=>'Hello';// 无参数constlog=msg=>console.log(msg);// 单语句// 多语句需要大括号constcalculate=(a,b)=>{constsum=a+b;constproduct=a*b;return{sum,product};};// 返回对象需要用括号包裹constcreateUser=(name,age)=>({name,age});1.2.2 this 绑定(重要区别!)
// 传统函数的 this 问题constobj1={name:'张三',sayName:function(){setTimeout(function(){console.log(this.name);// undefined(this指向window)},100);}};// 箭头函数解决 this 问题constobj2={name:'李四',sayName:function(){setTimeout(()=>{console.log(this.name);// '李四'(this继承自外层)},100);}};// 类方法中不要用箭头函数classPerson{constructor(name){this.name=name;}// ❌ 错误:箭头函数在原型上,this不对sayName=()=>{console.log(this.name);}// ✅ 正确sayName2(){console.log(this.name);}}1.3 模板字符串
constname='张三';constage=25;// ES5console.log('姓名:'+name+',年龄:'+age);// ES6console.log(`姓名:${name},年龄:${age}`);// 多行字符串consthtml=`<div class="user-card"> <h2>${name}</h2> <p>年龄:${age}</p> <p>状态:${age>=18?'成年人':'未成年人'}</p> </div>`;// 标签模板(高级用法)functionhighlight(strings,...values){returnstrings.reduce((result,str,i)=>{constvalue=values[i]?`<span class="highlight">${values[i]}</span>`:'';returnresult+str+value;},'');}constresult=highlight`用户${name}今年${age}岁`;// 输出:用户 <span class="highlight">张三</span> 今年 <span class="highlight">25</span> 岁1.4 解构赋值
1.4.1 数组解构
// 基本解构const[a,b]=[1,2];// a=1, b=2const[x,,z]=[1,2,3];// x=1, z=3(跳过第二个)// 默认值const[n1=10,n2=20]=[1];// n1=1, n2=20// 剩余元素const[first,...rest]=[1,2,3,4];// first=1, rest=[2,3,4]// 交换变量letm=1,n=2;[m,n]=[n,m];// m=2, n=1// 函数返回多个值functiongetUser(){return['张三',25,'北京'];}const[userName,userAge,city]=getUser();1.4.2 对象解构
constuser={name:'张三',age:25,address:{city:'北京',street:'朝阳路'}};// 基本解构const{name,age}=user;// name='张三', age=25// 重命名const{name:userName,age:userAge}=user;// 默认值const{name,gender='男'}=user;// gender='男'// 嵌套解构const{address:{city}}=user;// city='北京'// 函数参数解构functionprintUser({name,age=18}){console.log(`${name}-${age}岁`);}printUser({name:'李四'});// 李四 - 18岁// 多次解构functiongetData(){return{data:{users:[{id:1,name:'张三'}],total:100},code:200};}const{data:{users,total}}=getData();1.5 扩展运算符
1.5.1 数组扩展
// 复制数组constarr1=[1,2,3];constarr2=[...arr1];// 深拷贝一层arr2[0]=100;// arr1不受影响// 合并数组constarr3=[1,2];constarr4=[3,4];constmerged=[...arr3,...arr4];// [1,2,3,4]// 函数参数functionsum(a,b,c){returna+b+c;}constnumbers=[1,2,3];sum(...numbers);// 6// 替代 applyMath.max(...[1,2,3]);// 相当于 Math.max(1, 2, 3)// 创建新数组constnewArr=[0,...arr1,4,5];// [0,1,2,3,4,5]// 字符串转数组constchars=[...'hello'];// ['h','e','l','l','o']1.5.2 对象扩展
constobj1={a:1,b:2};constobj2={c:3,d:4};// 合并对象(浅拷贝)constmerged={...obj1,...obj2};// {a:1,b:2,c:3,d:4}// 后面的覆盖前面的constobj3={a:1,b:2};constobj4={b:3,c:4};constresult={...obj3,...obj4};// {a:1,b:3,c:4}// 添加新属性constuser={name:'张三',age:25};constuserWithId={id:1,...user};// {id:1,name:'张三',age:25}// 默认值constdefaults={theme:'dark',fontSize:14};constsettings={fontSize:16,...defaults};// {theme:'dark',fontSize:14}1.6 默认参数
// ES5 方式functiongreet(name){name=name||'游客';return'你好,'+name;}// ES6 方式functiongreet(name='游客'){return`你好,${name}`;}// 表达式作为默认值functioncreateUser(name,role='user',createTime=newDate()){return{name,role,createTime};}// 默认参数可以是函数调用functiongetDefaultAge(){return18;}functioncreatePerson(name,age=getDefaultAge()){return{name,age};}// 结合解构functiondrawChart({size='big',coords={x:0,y:0},radius=25}={}){console.log(size,coords,radius);}drawChart();// big {x:0,y:0} 25// 注意事项:默认参数在函数参数列表中形成独立作用域letx=1;functionfoo(x,y=()=>{x=2;}){varx=3;// 这里不会影响参数xy();console.log(x);// 3}foo();// 输出 31.7 剩余参数
// 收集剩余参数functionsum(...numbers){returnnumbers.reduce((total,num)=>total+num,0);}sum(1,2,3,4);// 10// 与普通参数结合functionmultiply(multiplier,...numbers){returnnumbers.map(n=>n*multiplier);}multiply(2,1,2,3);// [2,4,6]// 替代 argumentsfunctionmax(...args){returnMath.max(...args);}// 在箭头函数中(箭头函数没有arguments)constmax=(...args)=>Math.max(...args);// 解构中的剩余参数const[first,second,...others]=[1,2,3,4,5];// first=1, second=2, others=[3,4,5]const{a,b,...rest}={a:1,b:2,c:3,d:4};// a=1, b=2, rest={c:3,d:4}1.8 Symbol 类型
// 创建 Symbolconstsym1=Symbol();constsym2=Symbol('description');// 可选的描述constsym3=Symbol('description');sym2===sym3;// false,每个 Symbol 都是唯一的// 作为对象属性constuser={name:'张三',[Symbol('id')]:123,// 不可枚举[Symbol.for('email')]:'zhangsan@example.com'// 全局 Symbol};// 获取 Symbol 属性constsymbols=Object.getOwnPropertySymbols(user);console.log(symbols);// [Symbol(id), Symbol(email)]// 常用内置 SymbolclassMyArray{constructor(...args){this.data=args;}// 自定义迭代行为[Symbol.iterator](){letindex=0;constdata=this.data;return{next(){return{value:data[index++],done:index>data.length};}};}// 转为原始值[Symbol.toPrimitive](hint){if(hint==='number'){returnthis.data.reduce((a,b)=>a+b,0);}if(hint==='string'){returnthis.data.join(',');}returnthis.data.length;}}constarr=newMyArray(1,2,3);[...arr];// [1,2,3]Number(arr);// 6String(arr);// "1,2,3"1.10 Set 和 Map
1.10.1 Set
// 创建 Setconstset=newSet([1,2,3,3,4]);// [1,2,3,4]// 基本操作set.add(5);// 添加元素set.has(3);// trueset.delete(2);// 删除元素set.size;// 4set.clear();// 清空// 去重数组constarr=[1,2,2,3,4,4,5];constunique=[...newSet(arr)];// [1,2,3,4,5]// 集合操作constset1=newSet([1,2,3]);constset2=newSet([3,4,5]);// 并集constunion=newSet([...set1,...set2]);// [1,2,3,4,5]// 交集constintersection=newSet([...set1].filter(x=>set2.has(x)));// [3]// 差集constdifference=newSet([...set1].filter(x=>!set2.has(x)));// [1,2]// WeakSet(弱引用)constweakSet=newWeakSet();constobj={};weakSet.add(obj);console.log(weakSet.has(obj));// true1.10.2 Map
// 创建 Mapconstmap=newMap();map.set('name','张三');map.set('age',25);// 可迭代对象初始化constmap2=newMap([['name','李四'],['age',30]]);// 基本操作map.get('name');// '张三'map.has('age');// truemap.delete('age');// 删除map.size;// 1map.clear();// 清空// 遍历for(let[key,value]ofmap){console.log(key,value);}// 与 Object 对比constobjKey={};map.set(objKey,'value');// ✅ Map允许对象作为键constobj={[objKey]:'value'};// ❌ Object会把对象转为字符串"[object Object]"// WeakMap(弱引用)constweakMap=newWeakMap();constelement=document.getElementById('app');weakMap.set(element,{clickCount:0});1.11 Promise 和异步
// 创建 Promiseconstpromise=newPromise((resolve,reject)=>{setTimeout(()=>{constsuccess=Math.random()>0.5;if(success){resolve('操作成功');}else{reject(newError('操作失败'));}},1000);});// 使用 Promisepromise.then(result=>{console.log('成功:',result);returnresult.toUpperCase();}).then(upperResult=>{console.log('处理后的结果:',upperResult);}).catch(error=>{console.error('失败:',error.message);}).finally(()=>{console.log('无论成功失败都会执行');});// Promise 静态方法Promise.all([fetch('/api/user'),fetch('/api/posts'),fetch('/api/comments')]).then(([user,posts,comments])=>{// 所有请求都成功}).catch(error=>{// 任意一个失败});Promise.race([fetch('/api/data'),newPromise((_,reject)=>setTimeout(()=>reject(newError('超时')),5000))]);Promise.allSettled([Promise.resolve('成功'),Promise.reject('失败')]).then(results=>{console.log(results);// [// { status: "fulfilled", value: "成功" },// { status: "rejected", reason: "失败" }// ]});1.12 async/await
// 基本用法asyncfunctionfetchData(){try{constresponse=awaitfetch('/api/data');if(!response.ok){thrownewError('网络请求失败');}constdata=awaitresponse.json();returndata;}catch(error){console.error('错误:',error);throwerror;// 重新抛出错误}}// 并行执行asyncfunctionfetchAllData(){// 并行执行const[user,posts]=awaitPromise.all([fetch('/api/user'),fetch('/api/posts')]);// 顺序执行constuserData=awaituser.json();constpostsData=awaitposts.json();return{user:userData,posts:postsData};}// 在箭头函数中使用constfetchUser=async(userId)=>{constresponse=awaitfetch(`/api/users/${userId}`);returnresponse.json();};// 在类方法中使用classUserService{asyncgetUser(id){constresponse=awaitfetch(`/api/users/${id}`);returnresponse.json();}// 注意:async 方法返回的是 PromiseasyncupdateUser(id,data){constresponse=awaitfetch(`/api/users/${id}`,{method:'PUT',body:JSON.stringify(data)});returnresponse.json();}}// 立即执行 async 函数(async()=>{constdata=awaitfetchData();console.log(data);})();// 错误处理最佳实践asyncfunctionprocess(){constresult=awaitfetchData().catch(error=>{console.error('处理错误:',error);returnnull;// 返回默认值});if(result){// 处理成功结果}}1.13 模块化
1.13.1 导出
// math.js// 命名导出exportconstPI=3.14159;exportfunctionadd(a,b){returna+b;}exportclassCalculator{multiply(a,b){returna*b;}}// 默认导出(一个文件只能有一个)exportdefaultfunction(){console.log('默认导出');}// 聚合导出export{add,PI}from'./math.js';1.13.2 导入
// 导入命名导出import{PI,add}from'./math.js';// 导入默认导出importmyFunctionfrom'./math.js';// 重命名import{addasaddNumbers}from'./math.js';// 导入所有import*asmathfrom'./math.js';math.PI;// 3.14159// 动态导入constmodule=awaitimport('./math.js');module.add(1,2);// 浏览器原生支持<script type="module"src="app.js"></script>