TypeScript const断言的JavaScript等效实现,如何避免数组突变?
TypeScript const断言在JavaScript中的等效实现
TypeScript里的const arr = [1,2,3,4] as const主要做两件事:类型层面将数组转为只读元组,同时在编译时限制对数组的修改操作。但编译后的JavaScript仍是普通可修改数组。如果要在JavaScript中实现运行时不可修改的等效效果,或者模拟类型层面的只读提示,有以下几种方案:
1. 运行时强制不可变:Object.freeze()
这是最常用的方式,直接冻结数组,阻止任何修改、添加、删除操作:
const arr = Object.freeze([1, 2, 3, 4]); // 尝试修改会静默失败(非严格模式),严格模式下抛出TypeError arr[0] = 5; // 无效 arr.push(5); // 报错(严格模式)
注意:Object.freeze()是浅冻结,如果数组包含引用类型元素(比如对象),元素内部仍可修改,需要递归冻结才能实现深层不可变。
2. 主动拦截修改操作:Proxy
如果需要更严格的拦截(比如修改时主动抛出错误),可以使用Proxy包装数组:
function createImmutableArray(arr) { return new Proxy(arr, { // 拦截赋值操作 set(target, prop) { throw new Error("无法修改不可变数组"); }, // 拦截删除操作 deleteProperty(target, prop) { throw new Error("无法从不可变数组中删除元素"); }, // 拦截可能修改数组的方法(如push、pop) get(target, prop) { if (typeof target[prop] === 'function') { throw new Error(`不可调用数组方法 ${prop} 修改数组`); } return Reflect.get(target, prop); } }); } const arr = createImmutableArray([1, 2, 3, 4]); arr[0] = 5; // 抛出错误 arr.push(5); // 抛出错误
这种方式能更直观地阻止所有修改行为,适合需要强约束的场景。
3. 仅类型层面提示只读(无运行时约束)
如果只是想在编辑器中获得类似TS的只读提示(不强制运行时不可变),可以用JSDoc标注:
/** @type {readonly number[]} */ const arr = [1, 2, 3, 4];
此时编辑器会提示你不能修改数组,但运行时仍可以正常修改,适合只需要代码提示的场景。
内容的提问来源于stack exchange,提问作者Kaneki21
相关产品推荐
相关产品推荐

