JavaScript 核心概念地图:作用域、原型、this、闭包与 DOM
本文目录
旧笔记常把“预解析、栈堆、原型三角、DOM 增删改查”压成口诀。口诀可提醒关键词,却不能解释模块、严格模式、浏览器宿主 API 和异步生命周期。本文从可观察的语言行为建立一张实用地图。
类型、真值与值语义
假值包括 false、0、-0、0n、空字符串、null、undefined 和 NaN;对象(包括空数组、空对象)是真值。默认值若只针对 nullish 值,使用 ??,不要把有效的 0 或空字符串误覆盖。
原始值按值传递;对象变量保存对象引用,赋值或浅拷贝会复制引用,不会自动复制整棵对象图。JavaScript 规范不要求引擎必须以某种具体栈/堆布局实现这些语义,因此把“基本类型一定在栈、对象一定在堆”当作可依赖规则并不准确。克隆和嵌套变更见对象实战指南。
词法作用域、闭包与 this
词法作用域由代码结构决定;var 按函数作用域,let / const 按块作用域,并受 TDZ 约束。声明的处理不是把代码文本真的搬到文件顶部。闭包是函数连同它可访问的词法环境;它可维护私有状态,也会继续持有引用。组件卸载、路由切换或任务结束时,应清除不再需要的计时器、监听器和订阅。
普通函数的 this 取决于调用方式:obj.method() 中接收者为 obj;分离调用时接收者会改变;严格模式下普通裸调用为 undefined。call/apply/bind 可显式设置 this;箭头函数则沿用定义位置的 this,适合回调,不适合作为需要动态接收者的对象方法。
立即调用函数表达式(IIFE)可建立局部作用域,是经典 script 的常见模式。ES modules 自带模块作用域;新代码通常用模块和显式导出,不必再用 IIFE 包住每个文件。闭包能让值继续存活,但不能据此断言变量何时被垃圾回收。
原型链与面向对象
对象读取属性时先查自身,再沿内部原型链继续查找,直至 null。class 是建立原型关系的语法形式,不改变“实例方法可共享在原型上”的基本理解。检查自有属性用 Object.hasOwn;不要把非标准旧式 __proto__ 属性当成一般业务 API,也尽量不在运行时频繁更换对象原型。
当多个对象共享行为时,可以用 class/原型;若关系只是组合多个能力,组合对象或函数通常更容易测试。密码、权限等敏感数据不能依靠“私有命名习惯”保护;前端隐藏属性不是服务端授权。
DOM 与事件边界
DOM 元素可用 querySelector 查找、createElement 创建、append 插入、remove 移除。childNodes 含文本和注释节点,children 只列元素子节点;Attribute 节点不等于现代代码中常见的 child node。集合是否实时取决于 API,不能把所有 DOM 集合概括成同一种类数组。
事件流程包括捕获、目标和冒泡阶段。stopPropagation 阻止后续传播,preventDefault 阻止浏览器默认行为,两者不是一回事。委托监听时优先检查 currentTarget 与 target.closest() 的边界,并在页面销毁时移除监听器。
textContent 读写纯文本,innerHTML 解析 HTML,innerText 会受样式和布局影响。不可信内容默认写入 textContent;需要富文本时先用经过审查的 sanitizer。Math.random 适合一般随机展示,不适合令牌、验证码或密钥,安全随机值要用 Web Crypto。
参考:MDN JavaScript Guide、MDN Closures、MDN this、MDN Inheritance and the prototype chain、MDN Event phases、MDN textContent、MDN Web Crypto。
Live Notes
留言提交后会先进入审核,审核通过后对其他读者公开。