let 和 const

let和var和const

let

  • 不能重复声明

  • 不存在变量提升

  • 只在作用域内有效

常量

const Name = "kangkang"

NAME = "mary" // 报错

声明时必须被初始化(赋值),一经声明不可改变,常量为引用类型时,不能保证不可变

  1. 不存在提升
  2. 不能重复声明
  3. 只在当前作用域内有效

常量为对象时修改对象里的内容和修改常量的地址变量是不同的,常量对象被定义好意味着常量的地址不可再被改变,但是内容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

    当且仅当该属性的enumerabletrue时,该属性才能够出现在对象的枚举属性中。默认为 false

数据描述符同时具有以下可选键值

  • value

    该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined

  • writable

    当且仅当该属性的writabletrue时,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)

posted on 2019-06-18 22:52  2481  阅读(102)  评论(0编辑  收藏  举报

导航