ES6 新增了letconst,它们声明的变量,都处于“块级作用域”。并且不存在“变量提升”,不允许重复声明。

同时,const声明的变量所指向的内存地址保存的数据不得改变:

  • 对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。
  • 对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),不能保证指向的数据结构不可变。

如果要保证指向的数据结构也不可变,需要自行封装:

/**
 * 冻结对象
 * @param {Object} obj
 * @return {Object}
 */
function constantize(obj) {
    if (Object.isFrozen(obj)) {
        return obj;
    }
    Reflect.ownKeys(obj).forEach(key => {
        // 如果属性是对象,递归冻结
        typeof obj[key] === "object" && (obj[key] = constantize(obj[key]));
    });
    return Object.freeze(obj);
}
/********测试代码 **********/
const obj = {
    a: 1,
    b: {
        c: 2,
        d: {
            a: 1
        }
    },
    d: [1, 2]
};
const fronzenObj = constantize(obj);
try {
    fronzenObj.d = [];
    fronzenObj.b.c = 3;
} catch (error) {
    console.log(error.message);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
来自: let 和 const 对比 | 心谭博客
作者:心谭
Star仓库:github