严格模式不捕获数组赋值语法错误,但使隐式错误显式报错:禁止对只读/不可扩展数组赋值、禁止删除length属性、限制arguments误用,并暴露类数组与真数组差异。

严格模式本身不会直接捕获“数组赋值”这类操作的语法错误,但它能暴露因误用数组而引发的**隐式错误行为**——比如把对象属性当数组索引、给只读数组结构赋值、或在禁止扩展的对象上非法添加元素。关键在于:它让原本静默失败的操作变成明确报错,从而帮你快速定位逻辑漏洞。
禁止用字符串名索引数组(常见误用)
JavaScript 数组是对象,但设计上应使用数字索引。非严格模式下,以下写法不会报错,却产生意外结果:
var arr = [1, 2, 3]; arr["name"] = "test"; // 静默成功 → 实际给 arr 添加了一个普通对象属性 console.log(arr.length); // 仍是 3,"name" 不计入长度 console.log(arr.name); // "test"
这容易让人误以为 arr 是“带命名字段的数组”,实则是混淆了数组与对象。严格模式对此不干预(语法合法),但配合后续操作(如遍历)会暴露问题。真正被严格模式拦截的是更底层的非法赋值,比如对不可写属性赋值。
对只读/不可扩展数组结构赋值会立即报错
当你用 Object.defineProperty 或 Object.freeze 锁定数组或其原型时,严格模式会让非法修改立刻抛出 TypeError:
-
冻结数组后修改元素:
const a = Object.freeze([1, 2]); a[0] = 99;→ 严格模式下报TypeError: Cannot assign to read only property -
禁止扩展后添加新索引:
const b = Object.preventExtensions([]); b[100] = "x";→ 严格模式下同样报TypeError -
尝试删除数组 length 属性:
"use strict"; delete Array.prototype.length;→ 报TypeError(非严格模式仅返回false)
避免误将类数组对象当数组赋值
像 arguments、NodeList 这类类数组对象没有数组方法,也常被误赋值。严格模式虽不直接限制 arguments[0] = ...,但它禁用了 arguments.callee 和动态作用域,迫使你显式处理:
- 不能用
arguments[i] = x修改参数并期望影响实参(原始值类型本就不影响) - 更安全的做法是转为真数组:
const args = Array.from(arguments); args.push(...) - ES6+ 推荐用剩余参数替代:
function f(...args) { args[0] = "new"; }—— 此时args是真数组,赋值行为可预期
注意 delete 操作留下的“空槽位”陷阱
delete arr[1] 在严格模式下不报错(语法允许),但它会让数组出现 empty 槽位。这本身不是错误,但后续用 for...in 遍历时会跳过该位置,用 forEach 则完全忽略 —— 严格模式虽不阻止,却通过禁止 with 和限制 eval 减少了掩盖这类问题的执行路径,让你更早意识到数据结构异常。










