const 常量真的不可以被改变吗
const esObj = {
name: 'es6',
year: 2015
}
esObj.name = 'es2015'
console.log(esObj) // { name: 'es2015', year: 2015} name属性被改变
const arr = ['es6', 'es7', 'es8']
arr[0] = 'es2015'
console.log(arr) // ['es2015', 'es7', 'es8']
const 定义的常量
基本数据类型是存在栈内存,引用数据类型是存在堆内存中,在栈内存当中存储的是堆内存的内存地址,基本数据类型是不能被改变的,引用数据类型可以被改变,实际上const声明的常量并不是值不能被改变,是常量指向内存地址不能被改变。
引用数据类型,地址没有变,里面的内容改变了
当引用数据类型的内容不想被改变应该怎么办?
const esObj = {
name: 'es6',
year: 2015
}
Object.freeze(esObj ) // 该对象方法把对象冻结住
esObj.name = 'es2015'
console.log(esObj) // { name: 'es6', year: 2015}
// 没有被改变
const arr = ['es6', 'es7', 'es8']
Object.freeze(arr)
arr[0] = 'es2015'
console.log(arr) // ['es6', 'es7', 'es8']
const esObj = {
name: 'es6',
year: 2015,
extension: [ 'es7', 'es8']
}
// 在对象里面还有一个数组,数组也是一种引用类型
Object.freeze(esObj )
esObj.extension[0] = 'es2016'
console.log(esObj)
// esObj = { name: 'es6', year: 2015, extension: [ 'es2016', 'es8']}
// 被改变
// Object.freeze()只能浅层次的冻结,意思是只能冻结第一层
对深层次的对象是不能冻结的
那如何完全冻结呢?需要封装函数。递归的冻结属相的对象
封装函数,把当前对象里面的深层次属相的对象,每一层都冻结住
function myFreeze (obj) {
Object.freeze(obj)
Object.keys(obj).forEach(function(key) {
if (typeof obj[key] === 'object') {
myFreeze(obj[key])
}
})
}
调用:
const esObj = {
name: 'es6',
year: 2015,
extension: [ 'es7', 'es8']
}
myFreeze()
esObj.extension[0] = 'es2016'
console.log(esObj)
// esObj = { name: 'es6', year: 2015, extension: [ 'es7', 'es8']}
// 未被改变
在es6当中还有一个声明变量关键字let
什么时候用let,什么时候用const
默认的情况下,我们优先选择const, 只有当一些变量的对应的值需要被改变的时候,我们才去使用let,大多数情况是,变量的值在初始化之后不会被改变。