let 和 const
let和var和const
let
- 
不能重复声明 
- 
不存在变量提升 
- 
只在作用域内有效 
常量
const Name = "kangkang"
NAME = "mary" // 报错
声明时必须被初始化(赋值),一经声明不可改变,常量为引用类型时,不能保证不可变
- 不存在提升
- 不能重复声明
- 只在当前作用域内有效
常量为对象时修改对象里的内容和修改常量的地址变量是不同的,常量对象被定义好意味着常量的地址不可再被改变,但是内容obj.name = 'kangkang'是可以改变的!!! (基本类型赋值是拷贝值,而引用类型是内存地址赋变量)
const obj = {
	name ="kangkang",
	age = 21
}
let obj2 = {}
let name ="Jack"
obj = obj2 // 报错
obj.name = name //修改成功 Jack
数组也是一样的
const Arr = []
Arr.push("2") 
console.log(Arr) // 2
如何避免常量被修改?
Object.freeze(obj);方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象。这个方法返回传递的对象,而不是创建一个被冻结的副本。
const Arr = []
Object.freeze(Arr)
Arr.push("2") //报错 
console.log(Arr) // []
ES6之前怎么声明常量?
Object.defineProperty(obj, prop, descriptor)
obj
要在其上定义属性的对象
prop
要定义或修改的属性的名称
descriptor
将被定义或修改的属性描述符
属性描述符
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。存取描述符是由getter-setter函数对描述的属性。描述符必须是这两种形式之一;不能同时是两者。
数据描述符和存取描述符均具有以下可选键值:
configurable当且仅当该属性的 configurable 为 true 时,该属性
描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。
enumerable当且仅当该属性的
enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为 false。数据描述符同时具有以下可选键值:
value该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
writable当且仅当该属性的
writable为true时,value才能被赋值运算符改变。默认为 false。存取描述符同时具有以下可选键值:
get一个给属性提供 getter 的方法,如果没有 getter 则为
undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。默认为 undefined。
set一个给属性提供 setter 的方法,如果没有 setter 则为
undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。默认为 undefined。
返回值
被传递给函数的对象
在ES6中,由于 Symbol类型的特殊性,用Symbol类型的值来做对象的key与常规的定义或修改不同,而
Object.defineProperty是定义key为Symbol的属性的方法之一。
objce.seal(obj)
方法封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要可写就可以改变。返回值是被封闭的对象。(和object.freeze(obj)区别是他可以对已存在的属性进行修改,阻止添加新属性)
        Object.defineProperty(Object,'freezeProfill',{
            value: function (obj) {
                for( let i in obj) {
                    if(obj.hasOwnProperty(i)) {
                        Object.defineProperty(obj,i,{
                            writable: false
                        })
                    }
                }
                Object.seal(obj)
            }
        })
        const profile = {
            name: "kangkang",
            age: 25
        }
        Object.freezeProfill(profile)
        
        // 实现未深层递归的Object.freeze()功能
递归版本
 Object.defineProperty(Object,"freezeProfill",{
        value: function(obj) {
            for(let  i in obj) {
                console.log(i)
                if(obj.hasOwnProperty(i)){
                    if(!(obj[i] instanceof Object)){
                        Object.defineProperty(obj,i, {writable : false})                       
                    } else {
                        Object.freezeProfill(obj[i])
                    }
                }
            }
            Object.seal(obj)
        }
    }) 
    
    const obj2 = {
        name: "kangkang",
        age: 32,
        profile: {
            adr: "laian"
        }
    }
    Object.freezeProfill(obj2)
 
                
            
         
 浙公网安备 33010602011771号
浙公网安备 33010602011771号