可结合属性描述符与代理 / 反射相关内容理解。
由于 ES5 环境没有 block 的概念,所以是无法百分百实现 const,只能是挂载到某个对象下,要么是全局的 window,要么就是自定义一个 object 来当容器
1var __const = function __const(data, value) {
2 window.data = value; // 把要定义的data挂载到window下,并赋值value
3 Object.defineProperty(window, data, {
4 // 利用Object.defineProperty的能力劫持当前对象,并修改其属性描述符
5 enumerable: false,
6 configurable: false,
7 get: function () {
8 return value;
9 },
10 set: function (data) {
11 if (data !== value) {
12 // 当要对当前属性进行赋值时,则抛出错误!
13 throw new TypeError("Assignment to constant variable.");
14 } else {
15 return value;
16 }
17 },
18 });
19};
20__const("a", 10);
21console.log(a);
22delete a;
23console.log(a);
24for (let item in window) {
25 // 因为const定义的属性在global下也是不存在的,所以用到了enumerable: false来模拟这一功能
26 if (item === "a") {
27 // 因为不可枚举,所以不执行
28 console.log(window[item]);
29 }
30}
31a = 20; // 报错