本文集中整理 JavaScript 中容易混淆的三组基础知识:数据类型、for...infor...of,以及 spliceslicetoSpliced。读完后可以根据遍历目标和是否修改原数组选择合适的写法。

1. JavaScript 数据类型

JavaScript 的值可以分为原始值(primitive)对象(object)

1.1 七种原始类型

  • undefined
  • null
  • boolean
  • number
  • bigint
  • string
  • symbol
原始值不可变。所谓不可变,是指不能直接改变这个值本身;变量仍然可以重新赋值。

1.2 对象类型

除原始值外,其余值都属于对象,包括:
  • 普通对象 Object
  • 数组 Array
  • 函数 Function
  • 日期 Date
  • 正则表达式 RegExp
  • MapSet
  • Promise
数组和函数在类型体系上也是对象,但函数还具有可调用能力。

1.3 typeof 常见结果

判断数组应使用:
判断 null 应直接比较:

1.4 number 的注意事项

JavaScript 的普通数字采用 IEEE 754 双精度浮点格式,因此:
需要精确处理货币时,常见做法是使用整数最小单位,例如把 10.25 元保存为 1025 分;超出安全整数范围时可考虑 bigint
numberbigint 不能直接混合运算:

2. for...infor...of

本章比较对象键遍历、可迭代值遍历和数组遍历三类场景。

2.1 for...in

for...in 遍历对象的可枚举字符串属性键,也可能包含原型链上的属性。
现代代码优先使用 Object.hasOwn(obj, key),而不是直接调用 obj.hasOwnProperty(key),因为对象可能没有继承该方法,或存在同名属性。
适合场景:
  • 枚举普通对象的键;
  • 需要处理属性名;
  • 明确理解原型链和可枚举性。

2.2 for...of

for...of 遍历可迭代对象产生的值
常见可迭代对象:
  • Array
  • String
  • Map
  • Set
  • TypedArray
  • NodeList
  • 自定义实现 [Symbol.iterator] 的对象

2.3 为什么不推荐用 for...in 遍历数组

可能输出:
而且数组索引以字符串键出现,遍历顺序和数组值语义也不是 for...in 的设计重点。
需要数组值:
需要索引和值:
需要支持 breakcontinueawait 时,for...of 通常比 .forEach() 更合适。

3. spliceslicetoSpliced

本章从「splice:修改原数组」「slice:提取浅拷贝,不修改原数组」和「toSpliced:不修改原数组的增删改」等方面说明 splice、slice 与 toSpliced。

3.1 splice:修改原数组

签名:
返回被删除元素组成的新数组。

3.2 slice:提取浅拷贝,不修改原数组

签名:
区间为左闭右开 [start, end)
“浅拷贝”意味着嵌套对象仍然共享引用:

3.3 toSpliced:不修改原数组的增删改

现代 JavaScript 提供 toSpliced
在 React 等强调不可变更新的场景中,toSpliced 或展开运算符通常比直接 splice 更安全。

4. 快速选择

  • 遍历对象键:Object.keys()Object.entries() 或谨慎使用 for...in
  • 遍历数组和集合值:for...of
  • 需要索引:普通 forentries().forEach()
  • 修改原数组并插入、删除、替换:splice
  • 截取子数组且不改原数组:slice
  • 想使用 splice 的语义但保持不可变:toSpliced

5. 常见易错点

  • typeof null 返回 "object",不能用它判断 null
  • 数组也是对象,判断数组使用 Array.isArray
  • for...in 得到键,for...of 得到迭代值。
  • for...in 可能遍历到继承的可枚举属性。
  • splice 会修改原数组,slice 不会。
  • slice 是浅拷贝,不会递归复制嵌套对象。

6. 总结

JavaScript 中应先区分值的类型,再根据目标选择遍历和数组操作:对象键适合 Object.keys()Object.entries() 或谨慎使用 for...in,可迭代值适合 for...of;需要原地修改数组时使用 splice,需要新数组时使用 slicetoSpliced

7. 官方参考