- Published on
【译】JavaScript中Object.freeze()和const的区别
- Authors

- Name
- 薯仔
- @Henry_Yangs
ES6的发布带来了很多新的特性和方法。这些特性帮助JavaScript的开发者们显著地提高了他们的开发流程和生产力。Object.freeze()方法和const体现得最明显。
在一部分开发者之中,尤其是新手,他们会争论说这两个特性没有区别,但其实不是这样的。Object.freeze()和const其实很有区别。让我们一起来看看吧。
概览
const和Object.freeze()是完全不同的。
const的行为和let类似。它们俩唯一的区别是,前者定义了一个不能重新赋值的变量。使用const定义的变量是有块级作用域的并且不像var定义的变量那样有函数级作用域。
Object.freeze()接受一个对象作为参数,同时返回一个不能被修改的和参数一样的对象。这也就是说,不能对对象的属性做添加、删除、修改的操作。
可变对象的属性是可以被修改的。不可变对象在被创建之后,所有属性都不能被修改。
例子
Const
const user = 'Henry'
user = 'YANG'
这会抛出一个Uncaught TypeError,因为我们尝试修改一个用const定义的变量重新赋值。这是不合法的。而类似的操作应该是用var或者let定义变量,而不是用const。
Const的问题
当使用const声明对象时,这只能保障这个变量不被重新赋值,而不能保证它是不可变的。
考虑以下代码。我们用const声明了一个变量叫做user并且给它赋值了一个对象。
const user = {
first_name: 'Henry',
last_name: 'YANG',
email: 'sephenry@gmail.com',
age: 18,
}
user.last_name = 'WANG'
// 这是正常的,因为user仍是一个可变的变量
user.age = 30
// 这也是正常的,而且,user长大了。。。
虽然我们不能给这个变量重新赋值,但是我们可以修改这个对象的内容。
const user = {
user_name: 'Emma Waston',
}
// 这样就会报错了
我们肯定是希望这个对象的属性是不能被修改或删除的。const是做不到的,而Object.freeze()是可以的。
看看Object.freeze()
它可以拒绝我们对对象做的任何操作:
const user = {
first_name: 'Henry',
last_name: 'YANG',
email: 'sephenry@gmail.com`,
age: 18
}
Object.freeze(user)
user.last_name = 'WANG'
// 这样是不行的,user现在是不可变的了
嵌套的对象的属性并不能被冻结
好吧,Object.freeze()也有它自己的不足,如果有嵌套的对象,你需要自己对嵌套的内容再应用Object.freeze()。
const user = {
first_name: 'Henry',
last_name: 'YANG',
contact: {
email: 'sephenry@gmail.com',
telephone: 008688888888,
},
}
Object.freeze(user)
user.last_name = 'WANG'
// 这个操作是不被允许的
user.contact.teleplhone = 114
// 这个操作是生效的,因为嵌套的对象不会被冻结
所以,Object.freeze()并不会完全冻结一个对象中的嵌套对象。
如果想对嵌套的对象也冻结,我们可以写适合自己的库函数或者使用一些成熟的库,例如:Deepfreeze或者immutable-js
小结一下
const和Object.freeze()是不同的,const防止变量被重新定义和赋值,而Object.freeze()使对象不可变。