ES6新手逆袭指南:7天写出清爽现代前端代码(附避坑秘籍)
- ES6新手逆袭指南:7天写出清爽现代前端代码(附避坑秘籍)
- 为啥还在用 var 写到秃头?
- ES6 到底香在哪——别被术语吓跑,其实就是帮你少敲键盘
- let 和 const:不是新瓶装旧酒,是彻底告别变量提升的噩梦
- 箭头函数真那么神?写回调再也不嵌套三层了
- 模板字符串:拼接字符串终于不用 + 号加到手抽筋
- 解构赋值:一行代码拿数据,老板看了直呼内行
- 默认参数 + 剩余参数:函数签名也能这么优雅?
- Promise 不是银弹,但比 callback 地狱强一百倍
- async/await 上手就停不下来,异步代码写得像同步一样爽
- 模块化开发:import/export 让你的代码不再一锅粥
- Class 只是语法糖?但团队协作时真的香
- Set 和 Map:别再用数组硬扛去重和键值对了
- 展开运算符 …:复制、合并、传参,一个点搞定
- 可选链和空值合并(虽然严格说不算 ES6 但你肯定用)
- 实际项目里怎么一步步把老代码迁移到 ES6
- 浏览器兼容性翻车现场:别光顾着写,先看看用户用啥手机
- Babel 配置踩过的坑:你以为转译完就万事大吉?
- 开发时的小技巧:比如用解构 + 默认值做配置项校验
- 遇到“xxx is not a function”别慌,90% 是 this 或作用域搞鬼
- console.log 调试太 low?试试用模板字符串 + 标签函数自定义日志
- 别卷了!ES6 不是炫技,是让代码更好读、更好改、更好睡
ES6新手逆袭指南:7天写出清爽现代前端代码(附避坑秘籍)
“哥,你还在用 var 写循环?头发还剩几根?”
这句话是我带新人时候的开场白,百试百灵。对方先是一愣,然后默默把帽子摘了——好家伙,地中海都出来了。别笑,我三年前也这德行。今天这篇,就当我在微信群里语音 60 秒一条给你连发 30 条,把 ES6 这壶酒从瓶盖到瓶底舔干净。能救一个是一个,毕竟植发挺贵的。
为啥还在用 var 写到秃头?
先讲个真事儿。
去年 11 月,老板甩给我一个 2014 年的祖传项目,让我“顺手加个深色模式”。我打开文件一看,好家伙,两千行var挤在一个立即执行函数里,变量名从a1排到z99,瞬间眼前一黑。
我改了一行,结果全局飘红——因为var会变量提升,同一个i在三层for循环里反复横跳,简直蹦迪。那一刻,我深刻体会到什么叫“写代码五分钟,调试两小时,掉两根头发算少的”。
所以,第一课:把var扔进历史的垃圾桶,让它跟 Flash 作伴去吧。
ES6 到底香在哪——别被术语吓跑,其实就是帮你少敲键盘
有人一听“ECMAScript 2015”就头大,以为要背八股文。其实一句话总结:ES6 就是前端界的“懒人神器”。
能写一行的绝不写五行,能声明一次的绝不声明第二次。
比如以前写个数组去重,你得:
// 祖传去重,看着都腰疼varunique=[];for(vari=0;i<arr.length;i++){if(unique.indexOf(arr[i])===-1){unique.push(arr[i]);}}ES6 之后:
constunique=[...newSet(arr)];// 完事儿,去撸串吧香不香?香就对了。下面咱逐个拆,包教包会,不会你把我微信拉黑。
let 和 const:不是新瓶装旧酒,是彻底告别变量提升的噩梦
先上代码,再上结论,别bb。
functiondemo(){console.log(a);// 报错:Cannot access 'a' before initializationleta=1;}demo();看到没?直接报错,而不是返回 undefined。这就是let的“暂时性死区”,翻译成人话:
“变量在我声明之前,谁也别想碰,碰就炸。”const同理,只是多了“绑定即锁死”的设定,但注意:锁的是绑定,不是值。
constobj={name:'kimi'};obj.name='moon';// ✅ 可以改内部obj={};// ❌ 直接报错,想都别想小技巧:默认全写const,实在要改再改成let,代码review 的时候一目了然——改动的都是重点,老板都夸你细。
箭头函数真那么神?写回调再也不嵌套三层了
先给你看看“回调地狱”长啥样:
getUserId(function(id){getUserInfo(id,function(info){getOrders(info.userId,function(orders){render(orders);// 三层缩进,像金字塔});});});换成箭头函数,先别管逻辑,颜值即正义:
getUserId(id=>getUserInfo(id,info=>getOrders(info.userId,render)));一行搞定,缩进直接腰斩。
更重要的是:箭头函数不绑定自己的 this,它会捕获外层 this,跟以前var self = this说拜拜。
functionTimer(){this.seconds=0;setInterval(()=>{this.seconds++;// 这里的 this 就是 Timer 实例console.log(this.seconds);},1000);}newTimer();写组件的时候,你就偷着乐吧。
模板字符串:拼接字符串终于不用 + 号加到手抽筋
过去写 DOM 拼接:
varhtml='<div class="item">'+'<h3>'+title+'</h3>'+'<p>'+desc+'</p>'+'</div>';手酸不酸?现在:
consthtml=`<div class="item"> <h3>${title}</h3> <p>${desc}</p> </div>`;支持换行、插变量、写表达式,甚至还能调用函数:
constupper=str=>str.toUpperCase();console.log(`hey,${upper('kimi')}!`);// hey, KIMI!标签模板进阶玩法,写日志神器后面讲,先别急。
解构赋值:一行代码拿数据,老板看了直呼内行
接口返了一坨 JSON,老代码这么拿:
vardata=res.data;varname=data.name;varage=data.age;varlist=data.list;ES6 之后:
const{name,age,list}=res.data;一行,收工。
嵌套也不怕:
const{user:{name,avatar},meta:{code}}=res.data;数组也能解构:
const[first,second]=[1,2];交换变量再也不用临时变量:
[a,b]=[b,a];// 优雅得像个芭蕾舞演员默认参数 + 剩余参数:函数签名也能这么优雅?
以前写函数,怕调用者不传值,你得在内部写一堆:
functionajax(url,type,data){type=type||'GET';data=data||{};}现在直接写在形参上:
functionajax(url,type='GET',data={}){// 清爽}剩余参数一抹多长的arguments终于可以退休了:
functionadd(...nums){returnnums.reduce((a,b)=>a+b,0);}console.log(add(1,2,3,4));// 10注意:剩余参数才是真数组,arguments是类数组,不好用mapfilter,谁用谁知道。
Promise 不是银弹,但比 callback 地狱强一百倍
把刚才金字塔回调用 Promise 改写:
getUserId().then(id=>getUserInfo(id)).then(info=>getOrders(info.userId)).then(render).catch(err=>console.error(err));链式调用,扁平化,还能统一错误处理。
自己封装一个 Promise 也不复杂:
functiondelay(ms){returnnewPromise(resolve=>setTimeout(resolve,ms));}delay(1000).then(()=>console.log('1s 后执行'));async/await 上手就停不下来,异步代码写得像同步一样爽
Promise 已经很好了,但一堆.then还是眼花。async/await让你回到最熟悉的写法:
asyncfunctionshowOrders(){try{constid=awaitgetUserId();constinfo=awaitgetUserInfo(id);constorders=awaitgetOrders(info.userId);render(orders);}catch(e){console.error(e);}}任何一个 await 报错,直接跳进 catch,逻辑清晰得像是同步代码。
注意:await后面如果不是 Promise,会自动包装成 Promise,但别作死写await 123,会被同事打。
模块化开发:import/export 让你的代码不再一锅粥
以前所有文件都挂在一个global上,命名冲突家常便饭。
现在:
// utils.jsexportfunctionformat(time){/* ... */}exportconstAPI='https://api.xxx.com';// main.jsimport{format,API}from'./utils.js';按需加载、树摇优化、依赖清晰,团队协作再也不怕“谁把谁覆盖了”。
动态 import 做代码分割:
btn.addEventListener('click',async()=>{const{initChart}=awaitimport('./chart.js');initChart();});打包工具直接帮你拆包,首页 JS 体积瞬间瘦身。
Class 只是语法糖?但团队协作时真的香
ES6 的 Class 骨子里还是原型链,但可读性蹭蹭上涨:
classAnimal{constructor(name){this.name=name;}speak(){console.log(`${this.name}makes a noise.`);}}classDogextendsAnimal{speak(){console.log(`${this.name}barks.`);}}extends+super,继承一步到位。
TypeScript 横行的今天,Class 写法更利于类型推导,后端小哥也能秒懂,减少沟通成本。
Set 和 Map:别再用数组硬扛去重和键值对了
数组去重老办法:
constunique=arr.filter((v,i,a)=>a.indexOf(v)===i);Set 一句话:
constunique=[...newSet(arr)];Map 更是对象无法比拟的:
- key 可以是任意类型;
- 有 size 属性;
- 插入顺序一致;
- 性能更好。
constm=newMap();m.set({a:1},'ok');console.log(m.get({a:1}));// ❌ 拿不到,因为是不同引用// 正确姿势constkey={a:1};m.set(key,'ok');console.log(m.get(key));// ✅ 'ok'展开运算符 …:复制、合并、传参,一个点搞定
复制数组:
constcopy=[...arr];合并对象:
constnewObj={...oldObj,age:18};函数多参:
constnums=[1,2,3];Math.max(...nums);// 3注意:展开运算符是浅拷贝,嵌套对象还是同引用,别踩坑。
可选链和空值合并(虽然严格说不算 ES6 但你肯定用)
老项目最怕:
conststreet=data&&data.user&&data.user.address&&data.user.address.street;可选链一行搞定:
conststreet=data?.user?.address?.street;空值合并??专治 0 和空字符串被冤枉:
constcount=input??10;// 仅当 input 为 null/undefined 才用 10实际项目里怎么一步步把老代码迁移到 ES6
- 先换语法糖不改逻辑:
var→let/const,函数 → 箭头函数,模板字符串替换拼接。 - 模块化拆分:按业务拆文件,先
export常用工具函数。 - 引入打包工具:webpack / vite + babel,配置
@babel/preset-env,根据浏览器列表自动转译。 - 异步改造:把回调 Promise 化,再逐步上
async/await。 - 加 ESLint 规则:
no-var一把梭,提交自动格式化,谁再写var直接 CI 报错。
踩坑提醒:别一口气全改,先挑一个模块试水,回滚不慌。
浏览器兼容性翻车现场:别光顾着写,先看看用户用啥手机
国内还有 3% 的微信内核停留在 Chrome 53,不支持 async/await。
所以打包一定要配core-js+regenerator-runtime:
// babel.config.jsmodule.exports={presets:[['@babel/preset-env',{useBuiltIns:'usage',corejs:3}]]}让 Babel 自动帮你垫片,别全局引入整个babel-polyfill,包体积爆炸。
Babel 配置踩过的坑:你以为转译完就万事大吉?
- 坑 1:忘了配
@babel/plugin-proposal-class-properties,打包后 Class 属性全飘红。 - 坑 2:用了
lodash全量引入,不会 tree-shaking,体积 200KB 起步。改成lodash-es+ 按需import。 - 坑 3:开发时把
babel-loader排除了node_modules,结果自己封装的 UI 包没被转译,线上老手机白屏。
记住:loader 的 exclude 别一刀切,用include精准指向源码目录。
开发时的小技巧:比如用解构 + 默认值做配置项校验
functioncreateChart({selector='#chart',width=800,height=400,data=[]}={}){if(!selector)thrownewError('selector 必填');// 直接拿参数用,爽}调用者不传也行,传了部分也行,函数内部永远有值,再也不用写||写到精神分裂。
遇到“xxx is not a function”别慌,90% 是 this 或作用域搞鬼
箭头函数没有自己的this,对象方法里别乱用:
constobj={count:0,start:()=>setInterval(function(){console.log(++this.count);// ❌ 这里的 this 是 window},1000)};obj.start();// 报错正确姿势:
start(){setInterval(()=>{console.log(++this.count);// ✅ 箭头函数捕获外层 this},1000);}console.log 调试太 low?试试用模板字符串 + 标签函数自定义日志
functionlog(strings,...values){constmsg=strings.reduce((prev,cur,i)=>prev+cur+(values[i]?`\x1b[36m${values[i]}\x1b[0m`:''),'');console.log(`[${newDate().toLocaleTimeString()}]${msg}`);}constuser='kimi',action='login';log`User${user}performed${action}`;// 彩色输出, timestamp 自动带群里甩日志截图,颜值 + 信息密度双高,测试小姐姐都夸你专业。
别卷了!ES6 不是炫技,是让代码更好读、更好改、更好睡
写完这篇文章,我回头瞅了眼自己 2015 年的代码,通篇var+ 回调 + 手动 for 循环,简直黑历史。
但别怕,谁不是从“能跑就行”过来的?
ES6 不是让你炫技,是让你10 点能关灯睡觉,头发留在脑门上,女朋友不嫌弃你油。
七天时间,每天啃一点,把var改掉,把箭头函数用上,把 Promise 学会,你就已经跑赢 80% 的同行。
剩下的 20%?他们在研究 ES2024 的异步原子模块,咱先养好头发,再谈进阶,不迟。
好了,语音到此结束,谁还有问题,群里 @ 我,发你红包版配置模板,回见。
欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
推荐:DTcode7的博客首页。
一个做过前端开发的产品经理,经历过睿智产品的折磨导致脱发之后,励志要翻身农奴把歌唱,一边打入敌人内部一边持续提升自己,为我们广大开发同胞谋福祉,坚决抵制睿智产品折磨我们码农兄弟!
| 专栏系列(点击解锁) | 学习路线(点击解锁) | 知识定位 |
|---|---|---|
| 《微信小程序相关博客》 | 持续更新中~ | 结合微信官方原生框架、uniapp等小程序框架,记录请求、封装、tabbar、UI组件的学习记录和使用技巧等 |
| 《AIGC相关博客》 | 持续更新中~ | AIGC、AI生产力工具的介绍,例如stable diffusion这种的AI绘画工具安装、使用、技巧等总结 |
| 《HTML网站开发相关》 | 《前端基础入门三大核心之html相关博客》 | 前端基础入门三大核心之html板块的内容,入坑前端或者辅助学习的必看知识 |
| 《前端基础入门三大核心之JS相关博客》 | 前端JS是JavaScript语言在网页开发中的应用,负责实现交互效果和动态内容。它与HTML和CSS并称前端三剑客,共同构建用户界面。 通过操作DOM元素、响应事件、发起网络请求等,JS使页面能够响应用户行为,实现数据动态展示和页面流畅跳转,是现代Web开发的核心 | |
| 《前端基础入门三大核心之CSS相关博客》 | 介绍前端开发中遇到的CSS疑问和各种奇妙的CSS语法,同时收集精美的CSS效果代码,用来丰富你的web网页 | |
| 《canvas绘图相关博客》 | Canvas是HTML5中用于绘制图形的元素,通过JavaScript及其提供的绘图API,开发者可以在网页上绘制出各种复杂的图形、动画和图像效果。Canvas提供了高度的灵活性和控制力,使得前端绘图技术更加丰富和多样化 | |
| 《Vue实战相关博客》 | 持续更新中~ | 详细总结了常用UI库elementUI的使用技巧以及Vue的学习之旅 |
| 《python相关博客》 | 持续更新中~ | Python,简洁易学的编程语言,强大到足以应对各种应用场景,是编程新手的理想选择,也是专业人士的得力工具 |
| 《sql数据库相关博客》 | 持续更新中~ | SQL数据库:高效管理数据的利器,学会SQL,轻松驾驭结构化数据,解锁数据分析与挖掘的无限可能 |
| 《算法系列相关博客》 | 持续更新中~ | 算法与数据结构学习总结,通过JS来编写处理复杂有趣的算法问题,提升你的技术思维 |
| 《IT信息技术相关博客》 | 持续更新中~ | 作为信息化人员所需要掌握的底层技术,涉及软件开发、网络建设、系统维护等领域的知识 |
| 《信息化人员基础技能知识相关博客》 | 无论你是开发、产品、实施、经理,只要是从事信息化相关行业的人员,都应该掌握这些信息化的基础知识,可以不精通但是一定要了解,避免日常工作中贻笑大方 | |
| 《信息化技能面试宝典相关博客》 | 涉及信息化相关工作基础知识和面试技巧,提升自我能力与面试通过率,扩展知识面 | |
| 《前端开发习惯与小技巧相关博客》 | 持续更新中~ | 罗列常用的开发工具使用技巧,如 Vscode快捷键操作、Git、CMD、游览器控制台等 |
| 《photoshop相关博客》 | 持续更新中~ | 基础的PS学习记录,含括PPI与DPI、物理像素dp、逻辑像素dip、矢量图和位图以及帧动画等的学习总结 |
| 日常开发&办公&生产【实用工具】分享相关博客》 | 持续更新中~ | 分享介绍各种开发中、工作中、个人生产以及学习上的工具,丰富阅历,给大家提供处理事情的更多角度,学习了解更多的便利工具,如Fiddler抓包、办公快捷键、虚拟机VMware等工具 |
吾辈才疏学浅,摹写之作,恐有瑕疵。望诸君海涵赐教。望轻喷,嘤嘤嘤
非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。愿斯文对汝有所裨益,纵其简陋未及渊博,亦足以略尽绵薄之力。倘若尚存阙漏,敬请不吝斧正,俾便精进!