作者:晓问(小问) 淘系前端团队
转发链接:/d/file/gt/2023-09/xz0g02o0lpo 开发又迎来了一个新的 10 年,而在如今这个百花齐放的时代, 我们应该如何学习前端开发呢?
NO.1 0x00 先说结论我们可以把学习路线比作游戏中的段位上分,在不同的分段都有自己的定位和要锻炼的事情:
青铜 - 从零开始小学生:怀着满腔的热血,看到了这一个行业的希望和未来,准备开始学习 Web 开发知识。先通过 w3cschool 等免费学习资源把 HTML、CSS 和 JavaScript 的基本操作学会了写一个简单的表白页面送给你的女/男朋友,展示一下自己努力的成果,如果没有就当我没说白银 - 懵懵懂懂初学者:懂得如何使用 HTML、CSS 和 JavaScript 三大件来实现基本页面开发功能选择一个可以覆盖多种场景、可以随自己意愿调整难度的项目尝试实现,如博客系统、记账本、Markdown 编辑器等从 React 和 Vue 这两个框架中选择一个进行学习黄金 - 轻车熟路新玩家:懂得使用框架来实现上面所举例项目学习 Redux、Vuex 或者 MobX 等状态管理工具,并将它们使用到前面的项目中思考状态管理工具为你的项目带来了什么好处铂金 V - 初出茅庐新司机: 懂得如何使用脚手架创建项目,并且能将代码结构根据模块化的思想进行安排学习 TypeScript,对前面的项目进行重写,注重对数据结构和类型的控制学习 Node.js,试着配合数据库实现一个比博客系统更为复杂的 CMS(内容管理系统),如 图书馆管理系统、仓库管理系统铂金 I - 基本上手好司机:如果是懂得如何利用 Node.js 或 TypeScript 编写业务代码的思考在前面使用框架开发的项目中,有哪些代码是重复冗余的,有哪些逻辑是可以在多个组件之间共用的学习利用 ES2015 或更新的 JavaScript 标准,逐步替换使用框架所编写的代码钻石 V - 淡定自然老司机:如果是对逻辑抽象、模块封装有了一定的理解和经验的思考如何使用纯 JavaScript 对业务组件中的非渲染、非 DOM 相关代码进行抽象引入单元测试工具,对纯逻辑代码进行测试,争取覆盖率达到 80% 以上钻石 I - 赛道新手初学者:如果上面的条件你都已经满足了思考不同的代码哲学(OO、FP 等)、不同的代码结构(MVC、MVVM 等)的区别思考不同的框架之间设计的初衷,思考不同的编程语言中对同一类问题不同解法的区别到这里我画了一条从 0 到高级前端工程师级别的纯技术路线。相信有不少有经验的同学会发现中间我省略了不少内容,但也不难发现路线中从前半段的“学习”逐步变成后半段的“思考”。优秀的工程师除了需要有在纯技术领域的沉淀以外,还需要更多对技术、团队、ROI(投资回报率)的思考,当然这依然不足以支撑我们平稳地渡过“程序员 35 岁危机”,前面的路还有很长,钻石往上还有王者呢,谁说程序员就是青春饭碗的?
回想起很多年前我也跟你一样是一个完全的新手,从 0 开始慢慢自学摸索 Web 开发,甚至后来我也没有进入科班学习计算机,那么来听听我作为一个“前人”是如何完全靠自学至今的故事吧。
NO.2 0x01 我的从 0 开始我是一个完全从自学开始的前端工程师,想起来第一次接触前端就是初中那会特别流行合租 VPS 然后注册一个 .tk 的免费域名。而作为一个刚入门 Web 开发不久的小屁孩来说,用这种方式一探“大人的世界”属实让人兴奋。而当时最流行的博客管理软件就是用 PHP 写的 WordPress,作为一个十分成熟的 CMS 软件来说 WordPress 当时就有了非常丰富的社区资源,比如主题、模板、插件等等。而作为一个十分注重个性化的小屁孩来说,当然是要自己做一个主题的啊!于是我就从此踏上了 Web 开发的不归路,在此之前我所接触的都是 Visual Basic 这样的 Native 的语言。
以 WordPress 主题作为切入点,我开始学习 PHP 用于调用 WordPress 的 API 并输出内容、学习 HTML 用于写主题的模板、学习 CSS 用于“装潢”我的博客、学习 jQuery 用于实现页面动态效果。是的,那个时候基本上大部分人接触的是 jQuery 而不是 JavaScript,一个$ 函数就可以完成非常多的效果这让我第一次感受到了“框架”所带来的价值。于是便一步一步地发生了以下事情(不一定完全对,毕竟时间过太久了):
我发现页面上的一些样式效果无法在 IE 浏览器上正常显示,于是我就开始到网上学习 CSS 在 IE 的各种特殊处理,包括 reset.css、normalize.css 等工具的使用;每次点击链接都要刷新页面,在那个网速不怎么好的年代体验非常糟糕,于是乎就开始研究怎么用 jQuery/JavaScript 实现不需要刷新页面的情况下切换页面的内容;通过查看文档发现浏览器支持一种叫做 XMLHTTPRequest 的技术,可以让我们不需要通过跳转的方式从服务器获取到信息,从这里开始了解到 HTML、XML 和 JSON 三种不同格式的区别;第一次知道了可以通过服务器传递 JSON 格式的纯数据,然后前端通过 JavaScript 对数据进行解析,并且结合前端的模板引擎渲染成完整的 HTML;从这里又可以学习到如何通过 URL 中的 path、query、hash 以及 POST 和 PUT 请求正文等信息向服务器传递信息,服务器通过这些信息动态地对各种数据进行处理并返回结果;SPA(Single Page Application)开发习惯初见雏形;这样我就来到了“白银”阶段了。
NO.3 0x02 接触 Node.js当我正在愉快地设计着 WordPress 的自定义主题时,偶然间我在某前端网站上了解到了一个新的技术 —— Node.js。与它的相遇改变了我以后的学习路径,影响至今。2009 年 Ryan Dahl 发布了一个基于 Chrome JavaScript V8 引擎开发的程序运行环境 Node.js,它允许开发者在除了浏览器以外的地方运行 JavaScript 语言,并且提供一些标准库允许 JavaScript 脚本启动进行启动一个 HTTP 服务端应用这种以前在浏览器无法完成的事情。
var http = require('http');http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n');}).listen(8124, "127.0.0.1");console.log('Server running at http://127.0.0.1:8124/');
这一份代码是 2010 年写在 Node.js 官网的一段实例代码,机缘巧合之下我被这么一段简单的代码深深地吸引住了,虽然当时安装它仍需要从 GitHub 上克隆整个项目代码到本地并依次运行以下指令:
$ ./configure$ make$ make install
这一次编译就得花上至少十分钟,但完成安装后运行上面的一段代码,并在浏览器中打开http://127.0.0.1:8124/,然后在浏览器上看到Hello World 字样时仿佛新世界的门打开了。因为当时我所接触过的服务端程序只有 PHP,而 PHP 本质上就是一个模板引擎,它并不能很直观地处理请求本身而是借助 CGI 进行响应。能做更多的事情,这件事情对刚学习编程不久的新手来说是具有很大诱惑力的。
从这里开始,Node.js 配合 npm 便开始了长达 10 年的快速发展。从纯服务端应用开发,到开发工具、工程工具,再到如今的 FaaS(Function as a Service,Serverless)开发方式。Node.js 已经成为 Web 工程师不可或缺的一项技能,不管是用来开发服务端应用还是开发工具类应用,甚至是使用 Electron 开发桌面端应用还是配合 React Native 开发移动端 App,Node.js 能让前端工程师了解更多系统级别的概念,如网络、I/O、内存、文件系统等等,这些很多都是原本在浏览器端上看不到的。而学习这些知识对你理解前端开发背后的一些原理有非常好的价值,就跟学习算法一样。
结论:请学习 Node.js 和其中涉及到的一些基本计算机原理。
NO.4 0x03 框架时代当我在做 WordPress 主题的时候,绝大部分的主题开发者都会在前端做一些简单的效果,甚至有甚者会通过 JavaScript 实现一些原本只能通过后端来完成的事情,比如文章列表、文章内容的加载和渲染。而当年这些主题开发者基本上都会使用 jQuery 来进行这些 JavaScript 的操作,因为纯手写 JavaScript 在当时来说非常的繁琐(ES4时代,很多现在被广泛使用的原生 API 都仍未具备)所以当时 jQuery 就是大家的首选方案。
从非常早的 PrototypeJS、后来的 jQuery、进入 MVC 时代的 Backbone,AngularJS 开启 MVVM 模式,React 引入 FP 的概念,Vue 成功开启了渐进式开发体验的道路。一路下来一地的鸡毛,被各路人马诟病前端领域一个月开发一个新框架,“学不动了”。然而作为一个也写过框架、写过工具类库的开发者,我很喜欢用一个经常用于泛科技领域的例子来类比前端领域:
科技的终极目标,就是让人民感觉不到科技。
jQuery 时代,前端开发者使用 JavaScript 的模式是从页面中获取 DOM 元素,添加事件,然后通过class 和style 对页面进行动态的变更,以完成对用户行为的响应;
Backbone 时代,原本用在桌面端软件开发中的 MVC 模式被引入到了前端开发中,前端开发者们发现 Web 开发的复杂度已经需要用这些更成熟的开发模式进行管理了;
AngularJS 时代,从这里开始 Google 把数据双向绑定模式带到前端开发中,将原本需要通过 JavaScript 控制 DOM 元素这一繁琐的操作变成了只需要关心 Model 层需要改动什么内容即可。而 Vue 则将这种模式的开发成本降低到了一种相当可观的程度,让很多新手开发者也能很简单地入手这种便捷的开发模式。React 时代,Facebook 的科学家们把函数式编程的思想引入到前端开发中,注重的是数据链路的可跟踪、可回溯、可管理,让整个数据链路是尽可能以单链路流转。
虽然前端领域常被说“一个月一个新框架”,但实际上每一个框架在迭代的过程中都是解决了它们所在业务场景的实际需求的,并不是“拍脑袋”地想要把每一个技术细节做出一个 break change。
而目前我目前推荐的学习的框架是 React 和 Vue:
同样都是目前最流行的框架之一,而且可以预见未来 3~5 年内都是能满足找工作的需求的;React:引入函数式编程(Functional Programming)的概念,使得写代码的思路更加严谨,更具有可维护性和逻辑可导性;Vue:将 MVVM 模式变得非常简单易于入手,把 Progressive JavaScript Framework 的定位实践得非常到位。且如今 Vue 3.0 的 Composition API 更是在某种程度上将 Hooks 的玩法实现得比 React Hooks 更优;结论:请不要害怕学习!不要惧怕新技术!
NO.5 0x04 工程之路虽然我在接触了框架和 Node.js 之后,发现 JavaScript 除了能实现一半只用于展示内容和呈现简单交互以外还能做更多的事情。但本质上还是围绕着多个页面进行页面上 DOM 元素的控制,而直到我打开了 Google 的一些网站时,我才发现原来网站除了能叫页面以外,还能称之为“应用”。自从 Google 上线了一个完全不需要刷新页面就能完成所有事情而且体验很不错的 GMail 之后,我们发现网页原来也是可以承载那么复杂的逻辑和应用场景的。大家的热情异常地高涨,想着能不能让自己所负责的项目也有这么厉害高级的样子。但随着项目不断地复杂,代码规模也变得非常难以管理,而这个时候就需要工程化的引入。工程化协作
对于企业来说除了研发效率要足够高以外,研发链路的安全、合规也是同样重要的。什么叫安全合规?可管理的代码版本、可控制的发布流程、可管控的灰度机制,都是大厂用于保证项目流程稳定进行的必要工具。有很多初学者或者还没有大公司经验的同学在写项目时都是单打独斗的,但更多的一线项目都需要至少 2~3 个甚至更多的人员一同参与开发的。而这种时候,因为每个人的水平和开发习惯都是不一致的,而这些不一致就直接导致整体研发效率和项目进度受到极大的影响。所以就需要一种能够让大家在一个水平线上进行开发的模式,工程化需求便应运而
版本控制Git:GitHub、GitLab、Coding……SVN:BitBucket、Google Code……代码样式检查工具 JavaScript/TypeScript:ESLint测试工具单元测试:Karma、Jest、Mocha……持续集成:CI……工程化开发工具
从直接将 JavaScript 代码用<script> 标签,到需要将 jQuery 文件和主要程序文件分别引入,再到 Node.js 出现后使用 npm 进行依赖库管理并使用 webpack 进行打包和压缩。工程类工具的发展见证着前端工程近十年的发展历史,对目前我们所常用的工程工具有更好的了解和实践,绝对是通往优秀路上不可或缺的一步。
依赖包管理工具:npm、yarn打包工具:webpack、rollup脚手架工具:create-react-app……工程化开发语言
相信很多同学都听说过 JavaScript 诞生之初的一些轶事,比如根本没有特别多的严谨思考,或者在非常多的场景中十分地晦涩,比如隐性转换等。有人认为 JavaScript 能发展到如今的地位跟它的这种“灵活度”或者“松散度”有关联,虽然在某种程度上确实因为这种特性造成的 JavaScript 学习门槛比较低而间接导致。但就如我上面所说,当项目规模和人员规模不断发展乃至膨胀过后,这些特性会逐渐表现出来非常糟糕的体验:
团队之间因为没有良好的技术文档沉淀,信息不对等的情况直接导致代码在没有良好的单元测试时出现逻辑冲突;第三方依赖库的 API 在设计上大量使用了 JavaScript 松散的特性,导致使用方在引用时频繁出现“迷惑”的状态;当需要使用 JavaScript 与其他语言(特别是强类型语言)进行交互时,JS 过于松散的习惯会让对接方感到非常迷惑,对于双方的实际接入成本会比前期预估的大得多;为了解决这种情况,来自不同编程领域的大牛们都纷纷开始想办法,于是乎便诞生了非常多的“轮子”:
Java 系:Scala.js(https://wwwala-js/)、ClojureScript(https://www.google/search?sxsrf=ALeKk00XEy9SiEysGUdwzUi_oTVZDGGH9w:1590113700966&q=ClojureScript&spell=1&sa=X&ved=2ahUKEwiop7GSs8bpAhXGEqYKHZivCvYQBSgAegQIEBAr)Go 系:GopherJS(https://github/gopherjs/gopherjs)Microsoft:TypeScript(https://typescriptlang/)Facebook:Flow(https://flow/)、Reason(https://reasonml.github.io/)目前 TypeScript 已经影响了前端乃至整个 Web 领域的开发生态,TypeScript 之父 Anders Hejlsberg 创造过 Turbo Pascal、Delphi、C# 等在整个计算机科学领域都举足轻重的语言,而 TypeScript 又再次创造出翻天覆地的变化:
强类型的引入能让我们在写代码的时候从值优先的思维转变成类型优先;强类型的引入能帮助开发工具(IDE 等)更好地为开发者提供便利性能力,如智能补全、类型检测、编译式检查等等;TypeScript 可以让 JavaScript 更好地与其他语言进行交互,甚至转换为其他语言;工程化通用组件
当需求不断变多后,“爱偷懒”的工程师们就会把经常用到的内容进行抽象,比如从很早以前就有的 ExtJS、Twitter 工程师发布的 Bootstrap 再到今天的 Ant Design、Element UI 等,都帮助我们更快更好更稳定地完成一些通用页面能力的开发。
React:Ant Design(https://ant/index-cn)、Fusion Design(/d/file/gt/2023-09/2dkznoplyhl UI(https://element.eleme.io/)、iView(https://www.iviewui/)、Ant Design of Vue(/d/file/gt/2023-09/yn5pnaj4ssx.6 0x05 逻辑抽象能力随着我对 JavaScript 应用的编写经验不断增加,我所尝试的技术和场景也在不断地变得更加复杂。而当逻辑代码变得越来越复杂时我也渐渐发现一个新的问题,很多时候我所编写的逻辑代码是相似的,但相似之余其中的一些细节不尽相同,而这些代码往往是后期维护成本最高的。这就让我感到十分困惑,如何让我的代码写起来没有那么繁琐的同时,又不丢失原本代码的应有逻辑呢?这就让我想起了之前学习的框架,它们的实现原理不就是把原本我们写得非常繁琐的逻辑代码进行压缩,让我们写起来更加简洁直观吗?
这是我曾经面试过的一位校招候选人写的代码,其背景是用于快速判断自走棋类游戏中不同的增益能力(Buff)的成立状态。但显然这样的代码在实际开发中是绝对不允许存在的:
代码逻辑过于冗余;一旦通用判断逻辑出现变动,需要每一个都进行手动维护;没有良好的可维护性;所以我便提出如何让这些代码写得更加“优雅”和利于维护。
export default { beastBuff: (state) => { let arr = []; if (state.raceCount[0]['beast'] == 2 || state.raceCount[0]['beast'] == 3) { console.log(`you got 2 beast`) arr.push(state.racebuffdata[8]) } else if (state.raceCount[0]['beast'] == 4 || state.raceCount[0]['beast'] == 5) { console.log(`you got 4 beast`) arr.pop() arr.push(state.racebuffdata[9]) } else if (state.raceCount[0]['beast'] == 6) { console.log(`you got 6 beast`) arr.pop() arr.push(state.racebuffdata[10]) } else if (state.raceCount[0]['beast'] < 2 && arr.length == 1) { arr.pop() } return arr; }, caveclanBuff: (state) => { let arr = []; if (state.raceCount[1]['caveclan'] == 2 || state.raceCount[1]['caveclan'] == 3) { console.log(`you got 2 caveclan`) arr.push(state.racebuffdata[11]) } else if (state.raceCount[1]['caveclan'] == 4) { console.log(`you got 4 caveclan`) arr.pop() arr.push(state.racebuffdata[12]) } else if (state.raceCount[1]['caveclan'] < 2 && arr.length == 1) { arr.pop() } return arr; }, demonBuff: (state) => { let arr = []; if (state.raceCount[2]['demon'] == 1) { console.log(`you got 1 demon`) arr.push(state.racebuffdata[5]) } else if (state.raceCount[2]['demon'] < 1 && arr.length == 1) { arr.pop() } return arr; } // ...}
我们不难发现这几个xxxBuff 函数中的逻辑都非常接近,但也各有不同。那么如何能将这段代码进行优化和抽象呢?我当时给 TA 提出了一份示例代码:
const beastConfig = [ [2, [2, 3], 8], [4, [4, 5], 9], [6, [6], 10], [2]]
这份代码中的每一个数字在上面的beastBuff 函数中都可以一一找到,那么要怎么将它们复用到逻辑代码中,实现与原本的代码一样的功能呢?
我同样给他写了一份参考答案:
const generateBuff = (race, configArr) => { return state => { const arr = [] for (const [ output, conditions, index ] of configArr) { if (conditions && index) { // Buff calculatingconst isHit = conditionsme(condition => state.raceCount[0][race] == condition) if (isHit) { console.log(`you got ${output} ${race}`) arr.pop() arr.push(state.racebuffdata[index]) break } } else if (state.raceCount[0][race] < output && arr.length === 1) { // Last condition arr.pop() } } return arr }}export default { beastBuff: generateBuff('beast', [ [2, [2, 3], 8], [4, [4, 5], 9], [6, [6], 10], [2] ]), caveclanBuff: generateBuff('caveclan', [ [2, [2, 3], 11], [4, [4], 12], [2] ]), // ...}
原本代码里面通过 hard code 实现的判断逻辑,通过观察其中的共同点,并思考能否通转换为可抽象部分,这同样也是一名优秀的工程师所必须具备的能力。Be D.R.Y.! (Don't repeat yourself)
NO.7 0x06 更高层次的思考能力随着我对不同业务、不同场景和不同代码难度的不断探索和研究,我发现在前端领域乃至整个编程领域里,不同的框架和架构层出不穷的发展,其实在根本上就是各种实际业务场景在寻找更合适的 Better Practice(更好实践)。就如前面的所说的那样,不同的框架作者在开发的时候会采取不同的代码结构甚至代码哲学,这些不同的思维角度可能在框架的源码中并不会直接表现出来。但我不会说研读源码完全没有用!因为研读源码最起码可以学习其中的一些 trick 或者代码习惯。
但更重要的是理解从 API、系统架构上进行思考,因为只有多思考了,你才能逐渐变得比其他人更加对不同的技术游刃有余。
NO.8 EOF这一个流程并不是严谨的学习路线,更多的是我个人的一些经验总结。当然除了我所提到的学习知识点以外,还有很多不同的分支对应着不同的实际业务和场景,比如配合 Electron 开发桌面端应用、配合 React Native/Flutter 开发移动端应用、配合 Node.js/QuickJS/FibJS 开发嵌入式应用、配合 TensorFlow.js 开发适用于前端甚至适用于边缘计算的机器学习应用、配合 WebAssembly 将 Web 应用的使用体验提升到接近原生应用的境界……
关于 JavaScript 有一个很有名的预言:
凡是能用 JavaScript 重写的,终将会使用 JavaScript 重写
无论这句话会不会最终完全实现,但目前我们已经能看到很多应用逐渐通过 Web 应用的形式云端化,比如 Photoshop、音视频编辑软件、代码编辑器甚至是大型游戏等等原本我们完全没想到可以运行在浏览器中。前端开发困难吗?不困难、门槛相对比较低。简单吗?不简单,通过相信看到这里的你也已经有所体会了。当然实际要如何选择路线和方向,还是你自己所遇到的经历和机遇来决定的。
推荐JavaScript经典实例学习资料文章《一文带你彻底解决背景跟随弹窗滚动问题「干货」》
《推荐常用的5款代码比较工具「值得收藏」》
《Node.js实现将文字与图片合成技巧》
《爱奇艺云剪辑Web端的技术实现》
《我再也不敢说我会写前端 Button组件「实践」》
《NodeX Component - 滴滴集团 Node.js 生态组件体系「实践」》
《Node Buffers 完整指南》
《推荐18个webpack精美插件「干货」》
《前端开发需要了解常用7种JavaScript设计模式》
《浅谈浏览器架构、单线程js、事件循环、消息队列、宏任务和微任务》
《了不起的 Webpack HMR 学习指南(上)「含源码讲解」》
《了不起的 Webpack HMR 学习指南(下)「含源码讲解」》
《10个打开了我新世界大门的 WebAPI(上)「实践」》
《10个打开了我新世界大门的 WebAPI(中)「实践」》
《10个打开了我新世界大门的 WebAPI(下)「实践」》
《「图文」ESLint 在中大型团队的应用实践》
《Deno是代码的浏览器,你认同吗?》
《前端存储除了 localStorage 还有啥?》
《Javascript 多线程编程的前世今生》
《微前端方案 qiankun(实践及总结)》
《「图文」V8 垃圾回收原来这么简单?》
《Webpack 5模块联邦引发微前端的革命?》
《基于 Web 端的人脸识别身份验证「实践」》
《「前端进阶」高性能渲染十万条数据(时间分片)》
《「前端进阶」高性能渲染十万条数据(虚拟列表)》
《图解 Promise 实现原理(一):基础实现》
《图解 Promise 实现原理(二):Promise 链式调用》
《图解 Promise 实现原理(三):Promise 原型方法实现》
《图解 Promise 实现原理(四):Promise 静态方法实现》
《实践教你从零构建前端 Lint 工作流「干货」》
《高性能多级多选级联组件开发「JS篇」》
《深入浅出讲解Node.js CLI 工具最佳实战》
《延迟加载图像以提高Web网站性能的五种方法「实践」》
《比较 JavaScript 对象的四种方式「实践」》
《使用Service Worker让你的 Web 应用如虎添翼(上)「干货」》
《使用Service Worker让你的 Web 应用如虎添翼(中)「干货」》
《使用Service Worker让你的 Web 应用如虎添翼(下)「干货」》
《前端如何一次性处理10万条数据「进阶篇」》
《推荐三款正则可视化工具「JS篇」》
《如何让用户选择是否离开当前页面?「JS篇」》
《JavaScript开发人员更喜欢Deno的五大原因》
《仅用18行JavaScript实现一个倒数计时器》
《图文细说JavaScript 的运行机制》
《一个轻量级 JavaScript 全文搜索库,轻松实现站内离线搜索》
《推荐Web程序员常用的15个源代码编辑器》
《10个实用的JS技巧「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(一)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(二)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(三)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(四)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(五)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(六)「值得收藏」》
《深入JavaScript教你内存泄漏如何防范》
《手把手教你7个有趣的JavaScript 项目-上「附源码」》
《手把手教你7个有趣的JavaScript 项目-下「附源码」》
《JavaScript 使用 mediaDevices API 访问摄像头自拍》
《手把手教你前端代码如何做错误上报「JS篇」》
《一文让你彻底搞懂移动前端和Web 前端区别在哪里》
《63个JavaScript 正则大礼包「值得收藏」》
《提高你的 JavaScript 技能10 个问答题》
《JavaScript图表库的5个首选》
《一文彻底搞懂JavaScript 中Object.freeze与Object.seal的用法》
《可视化的 JS:动态图演示 - 事件循环 Event Loop的过程》
《教你如何用动态规划和贪心算法实现前端瀑布流布局「实践」》
《可视化的 js:动态图演示 Promises & Async/Await 的过程》
《原生JS封装拖动验证滑块你会吗?「实践」》
《如何实现高性能的在线 PDF 预览》
《细说使用字体库加密数据-仿58同城》
《Node.js要完了吗?》
《Pug 3.0.0正式发布,不再支持 Node.js 6/8》
《纯JS手写轮播图(代码逻辑清晰,通俗易懂)》
《JavaScript 20 年 中文版之创立标准》
《值得收藏的前端常用60余种工具方法「JS篇」》
《箭头函数和常规函数之间的 5 个区别》
《通过发布/订阅的设计模式搞懂 Node.js 核心模块 Events》
《「前端篇」不再为正则烦恼》
《「速围」Node.js V14.3.0 发布支持顶级 Await 和 REPL 增强功能》
《深入细品浏览器原理「流程图」》
《JavaScript 已进入第三个时代,未来将何去何从?》
《前端上传前预览文件 image、text、json、video、audio「实践」》
《深入细品 EventLoop 和浏览器渲染、帧动画、空闲回调的关系》
《推荐13个有用的JavaScript数组技巧「值得收藏」》
《前端必备基础知识:window.location 详解》
《不要再依赖CommonJS了》
《犀牛书作者:最该忘记的JavaScript特性》
《36个工作中常用的JavaScript函数片段「值得收藏」》
《Node + H5 实现大文件分片上传、断点续传》
《一文了解文件上传全过程(1.8w字深度解析)「前端进阶必备」》
《【实践总结】关于小程序挣脱枷锁实现批量上传》
《手把手教你前端的各种文件上传攻略和大文件断点续传》
《字节跳动面试官:请你实现一个大文件上传和断点续传》
《谈谈前端关于文件上传下载那些事【实践】》
《手把手教你如何编写一个前端图片压缩、方向纠正、预览、上传插件》
《最全的 JavaScript 模块化方案和工具》
《「前端进阶」JS中的内存管理》
《JavaScript正则深入以及10个非常有意思的正则实战》
《前端面试者经常忽视的一道JavaScript 面试题》
《一行JS代码实现一个简单的模板字符串替换「实践」》
《JS代码是如何被压缩的「前端高级进阶」》
《前端开发规范:命名规范、html规范、css规范、js规范》
《【规范篇】前端团队代码规范最佳实践》
《100个原生JavaScript代码片段知识点详细汇总【实践】》
《关于前端174道 JavaScript知识点汇总(一)》
《关于前端174道 JavaScript知识点汇总(二)》
《关于前端174道 JavaScript知识点汇总(三)》
《几个非常有意思的javascript知识点总结【实践】》
《都2020年了,你还不会JavaScript 装饰器?》
《JavaScript实现图片合成下载》
《70个JavaScript知识点详细总结(上)【实践】》
《70个JavaScript知识点详细总结(下)【实践】》
《开源了一个 JavaScript 版敏感词过滤库》
《送你 43 道 JavaScript 面试题》
《3个很棒的小众JavaScript库,你值得拥有》
《手把手教你深入巩固JavaScript知识体系【思维导图】》
《推荐7个很棒的JavaScript产品步骤引导库》
《Echa哥教你彻底弄懂 JavaScript 执行机制》
《一个合格的中级前端工程师需要掌握的 28 个 JavaScript 技巧》
《深入解析高频项目中运用到的知识点汇总【JS篇】》
《JavaScript 工具函数大全【新】》
《从JavaScript中看设计模式(总结)》
《身份证号码的正则表达式及验证详解(JavaScript,Regex)》
《浏览器中实现JavaScript计时器的4种创新方式》
《Three.js 动效方案》
《手把手教你常用的59个JS类方法》
《127个常用的JS代码片段,每段代码花30秒就能看懂-【上】》
《深入浅出讲解 js 深拷贝 vs 浅拷贝》
《手把手教你JS开发H5游戏【消灭星星】》
《深入浅出讲解JS中this/apply/call/bind巧妙用法【实践】》
《手把手教你全方位解读JS中this真正含义【实践】》
《书到用时方恨少,一大波JS开发工具函数来了》
《干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)》
《手把手教你JS 异步编程六种方案【实践】》
《让你减少加班的15条高效JS技巧知识点汇总【实践】》
《手把手教你JS开发H5游戏【黄金矿工】》
《手把手教你JS实现监控浏览器上下左右滚动》
《JS 经典实例知识点整理汇总【实践】》
《2.6万字JS干货分享,带你领略前端魅力【基础篇】》
《2.6万字JS干货分享,带你领略前端魅力【实践篇】》
《简单几步让你的 JS 写得更漂亮》
《恭喜你获得治疗JS this的详细药方》
《谈谈前端关于文件上传下载那些事【实践】》
《面试中教你绕过关于 JavaScript 作用域的 5 个坑》
《Jquery插件(常用的插件库)》
《【JS】如何防止重复发送ajax请求》
《JavaScript+Canvas实现自定义画板》
《Continuation 在 JS 中的应用「前端篇」》
作者:晓问(小问) 淘系前端团队
转发链接:/d/file/gt/2023-09/04jijbqccqi