外观
JavaScript 数据类型与拷贝
- 状态:未准备
- 适用方向:前端 / Go 全栈
- 最近复习:待填写
- 下次复习:待安排
一句话回答
JavaScript 有七种原始类型和对象类型;对象赋值共享对象引用,浅拷贝只复制一层,深拷贝要明确支持哪些类型,状态更新通常采用按修改路径复制。
原理解释
类型判断
原始类型为 undefined、null、boolean、number、bigint、string、symbol。typeof null 是历史遗留的 "object";数组使用 Array.isArray,函数的 typeof 为 "function"。instanceof 检查原型链,跨 realm 时不适合可靠判断数组。
相等判断
=== 不做宽松相等转换,但 NaN !== NaN,+0 === -0。Object.is 认为 NaN 与自身相同,并区分正负零。对象即使内容相同,只要引用不同就不严格相等。避免用 == 推理复杂混合类型比较。
浅拷贝与深拷贝
js
const a = { user: { name: 'A' }, count: 1 }
const b = { ...a }
b.user.name = 'B'
console.log(a.user.name) // B,嵌套对象仍共享
const c = { ...a, user: { ...a.user, name: 'C' } }
console.log(a.user.name, c.user.name) // B C展开语法和 Object.assign 是常用浅拷贝,不保留原对象的完整原型和属性描述符。JSON 往返不是通用深拷贝:会丢失部分值,日期变字符串,循环引用和 BigInt 等会失败。
场景与边界
structuredClone 支持循环引用及多种内建数据类型,但不能复制函数、DOM 节点,也不保证保留自定义类原型。它支持 transfer 可转移资源,转移后原资源可能不可再使用。更新 React 状态通常只复制受影响路径,不必每次深拷贝整棵树。
项目中的应用
结合 SimulSpeak 字幕状态合并,检查字幕更新如何生成新状态,并解释哪些旧引用可以复用。不能把“复制了对象”直接等同于完成性能优化。
常见追问
- const 对象能改吗? const 限制绑定重新赋值,不禁止修改对象属性。
- 传参是引用传递吗? JavaScript 按值传参;对象参数传入的是引用值,改属性会影响同一对象,重绑形参不会重绑实参变量。
- 如何支持循环引用拷贝? 用 WeakMap 记录源对象到副本的映射,并先登记再递归;还需明确 Map、Set、日期、原型等支持范围。