冻结window下的变量

背景:有时候我们会把很多重要的数据(如用户信息,权限相关信息)直接挂载在window下的,之前就碰到过因为将全局变量赋值给别的变量,导致该全局变量在代码中被多次覆写,同时在页面中也出现了一些不可预知的错误。因为这种错误有时候很难被发现,而且挂载在window在的变量会暴露在浏览器的控制台中,可能会给项目埋下一些安全隐患。因此就有了下面这篇文章。

目的:让某些全局变量完全只读而不可以被覆写。

1.TypeScript readonly

TypeScript 类型系统允许你在一个接口里使用 readonly 来标记属性。顾名思义,在 TypeScript 中它可以把一个属性变成只读的。

但是readonly 只能确保在直接赋值时不能修改属性,但是当你把这个属性交给其他并没有这种保证的使用者(允许出于类型兼容性的原因),他们能改变它。
冻结window下的变量

同时在浏览器的控制台中也能够对readonly属性进行操作。综上所述,该方案不可行。

2.Object.freeze()

我们看看MDN上该方法的定义:

Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象。

看上去该方法能够满足我们的需求,而且为了使整个对象不可变,MDN上还提供了递归冻结每个类型为对象的属性的方法(深冻结)。

冻结window下的变量

只要将各个全局进行深冻结,问题似乎就能够被解决。但上面所做的只能避免全局变量内的属性不被更改,但无法避免全局变量被完全重写。因此,我们还需要通过通过 Object.defineProperty 来设置全部变量的 configurable 和 writable 为 false。最终可得到让全局变量完全只读,不可以被修改的方法:
冻结window下的变量
冻结window下的变量