html中给全局变量赋值后如何不让他改变

2次阅读

const声明的全局变量并非真正不可变,它仅防止变量重新赋值,不阻止对象属性修改;引用类型Object.freeze()浅冻结,深冻结需递归处理;挂载到window的变量须用object.defineproperty()锁定writable和configurable。

html中给全局变量赋值后如何不让他改变

JavaScript 中用 const 声明的全局变量真不会变吗?

不是。const 只保证绑定不被重新赋值,不保证值本身不可变。比如 const obj = {},后续写 obj.key = 1 完全合法,但 obj = {} 会报错。

  • 真正“不变”的是变量名和它指向的内存地址,不是对象内容
  • 原始类型(StringnumberBoolean)用 const 基本等效于“不可修改”
  • 引用类型(ObjectArrayfunction)必须额外冻结才安全

想让对象或数组全局变量彻底只读,得用 Object.freeze()

Object.freeze() 是唯一能阻止属性增删改的原生方法,但它只做浅冻结——只封顶层属性,不递归冻结嵌套对象。

  • 对全局对象直接调用:Object.freeze(myGlobalConfig)
  • 冻结后尝试 myGlobalConfig.x = 2严格模式下会静默失败(非严格模式也无效)
  • 如果 myGlobalConfig.nested 是个对象,myGlobalConfig.nested.prop = 1 仍能成功
  • 需要深冻结时,得自己递归调用 Object.freeze() 或用 structuredClone() + 冻结组合(注意兼容性)

浏览器环境里挂到 window 上的变量怎么防改?

手动挂到 window 的变量,默认是可配置、可写的,必须用 Object.defineProperty() 锁死。

  • 别写 window.API_BASE = 'https://api.example.com' —— 这种随时能被覆盖
  • 正确做法:
    Object.defineProperty(window, 'API_BASE', {   value: 'https://api.example.com',   writable: false,   configurable: false,   enumerable: true });
  • writable: false 阻止赋值;configurable: false 防止被 delete 或重新定义
  • 注意:IE9+ 支持,但某些老版本 safariconfigurable: falsebug

模块级全局变量(ESM)还有必要防改吗?

ES 模块顶层的 export const 在导入方是只读引用,但导出方内部仍可能改——除非你控制全部代码入口。

立即学习前端免费学习笔记(深入)”;

  • export const settings = { timeout: 5000 }; → 导入后 settings.timeout = 1000 有效(因为对象可变)
  • 如果模块内自己没改,且所有使用者都通过 import 使用,那实际风险较低
  • 真正要防的是第三方脚本或调试时在控制台直接操作,这时候还是得靠 Object.freeze()defineProperty
  • 构建工具(如 webpack)的 mode: 'production' 不会自动冻结变量,别依赖它

冻结和定义属性的行为在运行时生效,而且不可逆。一旦漏掉某一层嵌套,或者忘了锁 window 属性的 configurable,就等于留了后门。

text=ZqhQzanResources