资讯详情

资讯详情

JavaScript公开课笔记高效整理指南:从类型判断到运行时报错

简介《JS公开课资料及笔记》由邵山欢整理面向零基础初学者系统讲解从语法基础到ES6新特性的完整知识链涵盖变量与数据类型、运算符、DOM操作、BOM处理、事件监听、函数与闭包、异步编程、面向对象、Node.js基础及前端框架入门其中每个主题都配有简明示例适合想要快速上手Web前端开发的学习者。压缩包内共16个文件以12个HTML实战案例为主搭配1份PDF课堂笔记和3张辅助图片整体仅1.49MB便于直接查看和运行HTML示例包括点击盒子变蓝、仿网易选项卡、水平菜单、鼠标移入移出等交互场景笔记则对各章节要点做了梳理。目前已有529人学习下载。这套资料的价值在于用可运行的小案例串联知识点从第一个程序到综合实例循序渐进覆盖从入门到进阶的常见问题方便边看边练为后续深入学习Vue、React等框架打下扎实基础。1. 从一份JavaScript公开课笔记说起为什么我拿它当索引而不是从头读如果你手头有一份叫“[邵山欢]javascript公开课资料及笔记”的文档我的建议是先别从头读到尾。这份资料看起来是按公开课集数整理的讲义和代码但JavaScript知识点太散从第一集顺序往下看很容易出现“函数刚讲到一半被事件打断、事件还没吃透又开始讲框架”的混乱感。更好的用法是把它当成一本能按问题定位的索引想弄清“javascript判断数据类型”就翻类型章节想弄懂“javascript函数”为什么这么设计就翻函数章节遇到“javascript运行时报错”就去错误排查部分。这份资料适合谁新手需要一个能把语言基础、浏览器交互、常见库串起来的顺序熟手需要一个方便回查的笔记结构用来准备分享或做内部培训。我这次把整理思路和踩坑经验完整写出来你可以直接照着搭自己的学习环境。2. 先把学习路线理清楚公开课资料该按什么顺序吃透JavaScript2.1 拿到资料后先建一个“可检索的本地笔记仓库”公开课资料和笔记经常是几十个 Markdown 文件加一堆示例代码如果随手塞进“桌面/新建文件夹”后面想找一个概念只能凭记忆翻。我拿到手会先花十分钟建一个按主题分类的本地仓库把所有笔记都放进去并用命令行检索。mkdir -p js-notes/{01-type,02-function,03-event,04-error,05-browser,06-lib,07-tools} cd js-notes git init cat README.md EOF # JavaScript 公开课资料与笔记 按主题整理不按课时整理。每个主题一个目录。 EOF find . -name *.md -exec grep -n 闭包 {} 这段命令做的事情不复杂但很有用mkdir -p后面的花括号会展开成 7 个目录分别对应类型、函数、事件、错误、浏览器、框架和工具链git init是给自己的“后悔药”哪天删错笔记或改乱代码可以回到上一个提交最后一条find加grep在所有 Markdown 文件里搜“闭包”输出文件名和行号。我不用数据库也不用在线笔记就是本地纯文本加全文检索因为 JS 笔记要不停粘贴代码块纯文本格式最省心。为什么按主题而不是按课时公开课通常一集会同时讲函数、对象和事件如果按集数整理“this 指向”会散在十几集里到后面根本想不起来在哪见过。按主题整理一份资料就变成了一张地图一个主题一个目录目录里只放和该主题相关的讲义摘录、代码示例、踩坑记录。这样学习时不会迷路回查时也只要一个grep就能定位。2.2 学习路线排序类型、函数、事件、框架/库而不是跟着视频集数走把资料整理好之后下一个问题是按什么顺序学。我的排序是固定的先类型再函数再事件再错误排查然后才轮到浏览器 API 和框架/库。这个顺序和视频集数没关系而是按“依赖关系”排的后面的知识点几乎都依赖前面的基础。学习顺序主题为什么放在这里1javascript判断数据类型几乎所有代码都会用到类型判断而且这里最容易踩坑2javascript函数闭包、作用域、this 是语言特性核心不啃透后面寸步难行3javascript事件浏览器交互的入口事件委托和冒泡是高频面试点4javascript运行时报错学会读错误堆栈才能把前面学的东西用在真实项目里5Canvas、FullCalendar 等浏览器场景有语言基础后再学具体 API 才不会一头雾水6OC和JavaScript互相调用、Kettle等扩展工作里遇到了再补纯前端笔记不必全列我一般不会在刚开始就钻进框架或库。很多公开课会提前放一段 FullCalendar 或某个组件库的演示看起来效果很好看但如果没有函数和作用域的基础你连this指向都看不清。框架或库本质上就是一组能帮你生成跨浏览器兼容代码的工具和函数它们建立在原生语言之上所以把原生基础打牢再看框架就是看“它帮我做了什么”。扩展内容更不需要进主链路。就像“kettle中javascript代码”那是 ETL 工具里内嵌的 JavaScript 环境语法相近但运行环境和浏览器完全不同“OC和javascript互相调用”更是要原生环境配合。这些我都建议单独建目录什么时候工作需要什么时候再看绝不放进主学习路线里。3. 亲手记一遍JavaScript四块硬骨头类型判断、函数、事件、运行时报错3.1 数据类型判断typeof 会骗你笔记里要写“边界”数据类型判断是资料里第一个值得认真记的章节。最朴素的反应是直接用typeof但typeof有很多反直觉的地方比如typeof null返回的是object数组返回的也是objecttypeof NaN返回的又是number。如果笔记里只写一句“typeof 能判断类型”那这段笔记基本是废纸。真正稳妥的通用方法是借助Object.prototype.toString它会返回每个内置类型的标准标记。function typeName(value) { return Object.prototype.toString.call(value).slice(8, -1); } console.log(typeName(null)); // Null console.log(typeName([])); // Array console.log(typeName(new Date())); // Date console.log(typeName(() {})); // Function这段代码的逻辑是Object.prototype.toString调用后会返回[object Null]、[object Array]这样的字符串。slice(8, -1)就是从第 8 个字符开始取去掉开头的[object 再去掉末尾的]最后只剩下类型名。参数 8 是因为[object 恰好 8 个字符-1表示截到倒数第一个字符之前。笔记里我会专门留一个边界区把容易判断错的例子写清楚typeof null object而不是nulltypeof [] object判断数组要用Array.isArraytypeof function(){} function这是函数和对象的明显区别instanceof适合判断对象是否属于某个构造函数的实例但跨iframe场景会失效因为不同全局环境里的构造函数不是同一个。这段话的意思是typeof只适合快速判断原始类型遇到null、数组、日期和自定义对象要继续用Object.prototype.toString或instanceof。公开课资料里通常只讲一个笼统的“判断类型方法”我会在笔记旁边补上这些边界因为面试和项目里考的就是边界。3.2 函数笔记作用域、闭包、this 指向要分开记函数是 JavaScript 里信息密度最大的一块也是最容易“听得懂、写不对”的地方。我的笔记会把它拆成作用域、闭包和this三部分每一部分都配一个能独立运行的例子。闭包最经典的开场是计数器function createCounter() { let count 0; return function () { count 1; return count; }; } const counter createCounter(); counter(); // 返回 1 counter(); // 返回 2这里的逻辑是createCounter执行时创建了一个局部变量count然后返回一个匿名函数。这个匿名函数本身没有count但它定义在createCounter内部所以它会把外层作用域里的count留在自己的作用域链上。即使createCounter已经执行完count也不会被回收这就是闭包。笔记要写一句最关键的话闭包让函数记住了定义时所在作用域而不是调用时所在作用域。this就正好相反普通函数的this由调用方式决定而不是定义位置决定。const obj { name: public-course, getName: function () { return this.name; } }; console.log(obj.getName()); // public-course const getter obj.getName; console.log(getter()); // 这里 this 不是 objgetName作为obj.getName()调用时this指向obj一旦把它赋值给getter再单独调用this就变成undefined或全局对象取决于运行环境。箭头函数则相反它不绑定自己的this会按定义位置向外层找。所以处理回调时我常用箭头函数来“锁死”外层thisclass Button { constructor() { this.count 0; this.click this.click.bind(this); } click() { this.count 1; } }bind会返回一个永久改变this的新函数这在事件回调里特别有用。笔记里要写清楚的选型规则是普通函数适合做方法因为它能拿到调用者箭头函数适合做回调因为它不需要自己的this当两者都不方便时用bind显式绑定。函数这块没有捷径只能在笔记里反复记“调用方式决定 this”这一句话并配合实验。3.3 事件笔记监听、冒泡、委托用例子代替概念事件是浏览器开发的骨架。公开课资料里经常会讲冒泡和捕获但只讲概念的话新手还是不知道为什么页面上明明监听了父容器结果绑定在子元素上的处理器没生效。我会把事件笔记的重点放在“事件委托”上因为这是一个能直接减少代码量的实用技巧。const list document.querySelector(#list); list.addEventListener(click, (e) { const li e.target.closest(li); if (li) { console.log(点击了, li.textContent); } });这段代码的逻辑是只在#list上绑定一次click监听事件发生时通过e.target拿到真正被点击的元素再用closest(li)向上找最近的li。这样以后往列表里新增li不需要再给每个新元素单独绑定监听因为事件会冒泡到list由挂在上面的处理器统一处理。参数这块要注意三点e.target是实际触发事件的元素不是绑定监听的元素closest会从当前元素一路向上找匹配的祖先找不到就返回null如果直接写e.target.matches(li)心里要清楚它只检查“当前元素”本身一旦点到li里的span就会漏掉。用closest更稳。事件流顺序也写进笔记捕获阶段从根节点往下到目标目标阶段触发目标上的监听冒泡阶段从目标往上回到根节点。日常开发里 90% 的监听都在冒泡阶段处理。e.stopPropagation()能阻止事件继续向上传播e.preventDefault()阻止默认行为比如阻止表单提交或链接跳转。这两个方法经常被一起混用笔记里必须分开记一个管传播路径一个管默认行为。3.4 运行时报错把错误当线索不要当黑匣子学习 JavaScript 到一定程度代码一定会跑不出预期结果。公开课资料如果不能教会你读错误那后面的 Canvas、FullCalendar 都学不踏实。我的错误笔记会用一个标准模板记录每次遇到报错都尽量按模板走。try { const data JSON.parse({name: js-course}); processData(data); } catch (err) { console.error(错误名, err.name); console.error(错误信息, err.message); console.error(错误堆栈, err.stack); }这里try模拟一个可能出错的区域catch里的err是错误对象。err.name告诉我们错误类型err.message是给人读的说明err.stack是调用堆栈。排查时我只看两个东西错误名是TypeError、ReferenceError还是SyntaxError以及堆栈里第一次出现自己项目文件的行号。常见的对应关系是读取undefined的属性会抛TypeError使用没有声明的变量会抛ReferenceError数组下标越界或递归太深会抛RangeErrorJSON.parse遇到不合法字符串会抛SyntaxError。笔记里要加一个“运行时报错自查清单”先看错误名再看 message最后顺着 stack 找自己的代码。最怕的就是只截图 error.message 然后到处问因为 message 常常只能说明是哪类错误不能说明是哪一行。这段笔记的价值在于它把“运行时报错”从不可控的黑匣子变成了可检索的线索。后面只要再遇到相似报错我会立刻查自己的错误笔记而不是重新搜索一遍全部资料。4. 把公开课里的代码变成自己的笔记Canvas、小数保留、FullCalendar 这些经典场景4.1 保留两位小数浮点数精度问题不是玄学是二进制浮点在很多格式化场景里都要求保留两位小数最常见的就是价格和百分比。公开课里通常简单一句toFixed(2)带过但真要拿它去处理1.005时结果可能会让你意外二进制浮点数在十进制小数的转换上天然有误差直接乘 100 再四舍五入未必能得到你想要的“四舍五入”。我的笔记里会放一个带方案的例子function round2(value) { return Math.round((value Number.EPSILON) * 100) / 100; } console.log(round2(2.675)); // 常见做法加一个最小单位再乘 100这里的Number.EPSILON是浮点数能识别的最小差值加上它能修正一部分“刚好差一点点”的情况* 100是为了把两位小数变成整数再取整/ 100再还原。但我会在注释旁边写清楚这不算银弹不同数值组合下仍然可能出现边界误差。公开课资料教到这里其实是合格的但真实项目里我更保守。要展示时用toFixed要计算时先把金额转成“分”这样的整数再运算const yuan 1.005; const cents Math.round(yuan * 100); // 先转成整数分 console.log(cents); // 可能得到 100而不是 101这个现象会让你觉得“JavaScript 在针对我”其实是十进制小数在二进制里很多都不能精确表示。笔记里必须记录一条结论不要拿浮点数直接做金额计算保留两位小数之前先确认自己是“只用来显示”还是“还要继续算”。显示用toFixed计算用整数分这样才能避免后面返工。4.2 Canvas 与素材公开课里那朵云彩自己画一遍Canvas 是公开课里视觉效果最明显的一章但也是最容易“照着画一遍就以为会了”的章节。资料里经常给一张图可能是云彩素材、粒子动画或者折线图。我记 Canvas 笔记时会专门拆解一次绘图命令而不是整段复制。const canvas document.querySelector(#sky); const ctx canvas.getContext(2d); canvas.width 640; canvas.height 400; ctx.fillStyle #87CEEB; ctx.fillRect(0, 0, canvas.width, canvas.height); function drawCloud(x, y, scale) { ctx.fillStyle #fff; ctx.beginPath(); ctx.arc(x, y, 30 * scale, 0, Math.PI * 2); ctx.arc(x 35 * scale, y - 15 * scale, 40 * scale, 0, Math.PI * 2); ctx.arc(x 70 * scale, y, 30 * scale, 0, Math.PI * 2); ctx.fill(); } drawCloud(120, 100, 1);getContext(2d)是拿到 2D 绘图上下文后续所有绘图命令都作用在这个上下文上fillRect(x, y, width, height)从左上角开始填充矩形ctx.arc(x, y, r, startAngle, endAngle)的五个参数分别是圆心横坐标、圆心纵坐标、半径、起始角和结束角Math.PI * 2代表整个圆。beginPath()很重要它告诉 canvas“下面要画一个新的图形”不然多个云朵会粘连在一起。我把这个云彩函数当成“素材生成器”以后想在页面上加点氛围感不需要去网上找图片直接用函数画就可以。真正做动画时再配合requestAnimationFrame每帧先clearRect清空画布再按新坐标重新画一次。这份笔记写清楚后Canvas 就从“看一遍视频”变成“自己手里的一套小工具”。4.3 FullCalendar 这类框架/库先跑官方示例再记 APIFullCalendar 是公开课资料里很常见的一个日历框架。框架或库本质上是一组能帮你生成跨浏览器兼容代码的工具和函数它把很多重复的月份计算、星期排列、事件渲染工作封装好。但框架也有一个麻烦版本更新快API 经常变公开课里抄下来的老代码换到新版可能直接报错。我记 FullCalendar 笔记时会先写一个“最小可跑示例”再往上加自己的需求const calendarEl document.getElementById(calendar); const calendar new FullCalendar.Calendar(calendarEl, { initialView: dayGridMonth, locale: zh-cn, headerToolbar: { left: prev,next today, center: title, right: dayGridMonth,timeGridWeek,timeGridDay }, events: [] }); calendar.render();这里关键是搞清楚四个配置initialView是首次渲染的视图locale控制中文文案headerToolbar左边是上一页/下一页按钮和今天按钮中间是大标题右边是月/周/日视图切换events用来传事件数据。要记清楚的是这段代码只描述“结构”不能保证不同版本都跑通所以笔记顶部要写“记录当时所用的版本号”遇到报错先问自己“是不是版本不匹配”。我的习惯是先把官方示例原样跑通再改成自己的数据。不要一上来就把几十个配置项全复制到项目里那样出错时根本分不清是数据问题、配置问题还是版本问题。这个笔记习惯对所有 JavaScript 框架/库都适用先最小化复现再逐项加参数记笔记时只记“为什么配这个参数”不记“配了以后看起来怎么样”。5. 避坑公开课笔记最常见的 5 个翻车现场5.1 现象只抄代码不抄边界类型判断写到一半就翻车只看公开课里的typeof示例就会把数组、null和对象全判断成object。原因不是代码写错而是笔记只记了“能用的场景”没记“不能用的边界”。解决方法是每段笔记后面加一个“边界提醒”把null、数组、instanceof跨环境问题都写上去。我后来回查笔记都会先看边界区域因为那里才是真正区分懂不懂的地方。5.2 现象函数笔记里闭包会写但用事件回调时 this 又丢了闭包只是函数的一半另一半是this。现象是对象方法被当作事件回调时方法里的this拿不到对象属性。原因很简单普通函数的this由调用方式决定回调时调用者变成了事件系统this自然就变了。解决方法是直接记住需要对象的方法时用bind固定this或者用箭头函数引用外层this。笔记里每个函数示例后我都会补一行“这里的 this 是什么”这一行已经帮我避免好几次线上事故。5.3 现象事件委托点不到具体的 li事件委托代码看起来没问题但点击列表里的文字时e.target指向的是span不是li于是条件判断失败。原因是我只用了e.target.matches(li)没有考虑事件目标可能是更深层的子元素。解决方法是改用e.target.closest(li)让匹配逻辑向上找最近的li。这个坑是公开课里讲得最少、实际项目里出现最多的必须单独记。5.4 现象看到运行时报错就慌只会截图 error.message不会看堆栈报错信息一长串经常淹没在第三方库的调用栈里。原因是没有建立“错误对象三要素”的意识其实err.name是类型、err.message是描述、err.stack是定位线索。解决方法是把console.error(err.name, err.message, err.stack)这个组合写进笔记遇到报错先看stack里第一行是自己的文件那个文件行号就是出问题的地方。这个习惯能省掉大半调试时间。5.5 现象把 OC 和 JavaScript 互相调用的代码直接搬进 Web 项目公开课有一段“OC和javascript互相调用”的演示表面看是 JavaScript 代码实际依赖 iOS WebView 注入的桥对象。纯 Web 项目里根本没有这个对象一调用就报not a function。原因是没有区分运行环境。解决方法是把这类代码放到“原生桥接”单独目录笔记头标注“需要原生环境”同时提醒自己“kettle中javascript代码”也是一样Kettle 环境有自己的 API不能拿浏览器那套直接套。环境区分永远是 JavaScript 笔记的第一原则。6. 用“回写”验证笔记把公开课资料变成自己的速查手册我整理这套资料的过程中走过一段弯路笔记越抄越多但过两周再看只记得“我没有记熟”。后来改成一个笨办法叫“回写”——先拼记忆再开卷对照。做法很简单。拿到一份公开课笔记先只看章节标题把代码块遮住凭记忆写一遍核心示例。写完之后再打开资料逐行对比把对不上的地方用另一种颜色标记到笔记最前面。这些“对不上的地方”不是抄错了而是我真实的理解缺口比资料里所有知识点都更值得反复看。下面的自测代码就是我平时用来检查基础笔记的工具function typeName(value) { return Object.prototype.toString.call(value).slice(8, -1); } console.assert(typeName([]) Array, 数组类型判断失败); console.assert(typeName(null) Null, null 类型判断失败); console.assert(typeName(new Date()) Date, Date 类型判断失败);这段代码没有依赖任何框架直接在浏览器控制台或 Node 里都能跑。console.assert的第一个参数是断言条件第二个参数是失败时打印的信息。我习惯把当天刚学的函数也放进这种自测函数里比如事件委托的closest写法、闭包的计数器每个主题至少补一条断言。回写最大的好处是它逼我放弃“看过就会”的错觉。以前我会觉得公开课老师讲得我都懂一旦让我合上资料写才意识到漏掉了多少个参数。现在我的每份 JavaScript 笔记末尾都留着一个“回写自查区”只列标题和自测用例不看答案地过一遍过不了就回到对应章节补锅。这个习惯是我自己踩了半年坑才捡回来的现在每次学新库、新框架都会先造一份类似的速查脚本而不是直接开项目。希望帮到你也希望你的资料笔记能真的变成知识而不是一堆躺在硬盘里的 Markdown 文件。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →