Object.defineProperty()

Object.defineProperty() 方法会直接在对象上定义一个新属性,或者修改一个现有属性,并返回该对象。

应当直接在Object 构造器对象上调用此方法,而不是在任意一个Object实例上调用

var obj1 = {}
Object.defineProperty(obj1,'prop1',{
    value:10,
    writable:false
})
console.log(obj1.prop1) //10
obj1.prop1 = 20
console.log(obj1.prop1) //10
  • 语法

    Object.defineProperty(obj,prop,descriptor)

    • obj

      要定义的属性的对象

    • prop

      要定义或修改的属性的名称或 Symbol

    • descriptor

      属性描述符,是一个对象

      • 键值

        描述 默认值
        configurable 属性描述符能否被改变,属性能否从对象上删除 false
        enumerabel 属性是否出现在对象的枚举属性中,for...in.. false
        value 属性的值 undefined
        writable 属性的值能否被赋值运算符=改变,即可写与否 false
        get 访问该属性时会调用此函数 undefined
        set 属性值被修改是会调用此函数 undefined
      • 描述符可以拥有的键值

        configurable enumerable value writable get set
        数据描述符 可以 可以 可以 可以 不可以 不可以
        存取描述符 可以 可以 不可以 不可以 可以 可以
  • 创建属性

    var o = {}
    //在对象中添加一个属性和数据描述符
    Object.defineProperty(o,"a",{
        value:37,
        writable:true,
        enumerable:true,
        configurable:true
    })
    console.log(o.a)    //37
    
    //在对象中添加一个属性和存取描述符
    var bValue = 38
    Object.defineProperty(o,"b",{
        get(){ return bValue},
        set(newValue){bValue = newValue},
        enumerable:true,
        configurable:true,
    })
    console.log(o.b)    //从此 属性 b的值就和 变量 bValue绑定了(Vue的双向绑定就是通过此实现的)
    
    • 如果直接通过赋值的方式创建对象的属性obj.a = 1,则

      writable:true,
      enumerable:true,
      configurable:true`
      
    • 如果通过Object.defineProperty() 设置属性则去没有设置属性描述符,则取默认值

  • 修改属性

    如果旧描述符 configurablefalse ,则该属性被认为是“不可配置的”,并且没有属性可以被改变(除了 value 和 单向改变 writablefalse

    var obj = {}
    Object.defineProperty(obj,'a',{
        value: 1,
        writable: false
        //configurable 和 enumerabel 默认为 false
    })
    
    Object.defineProperty(obj,'a',{
        value:2,
        enumerable:true     //Uncaught TypeError: Cannot redefine property: a
    })
    
原文地址:https://www.cnblogs.com/angle-yan/p/13345699.html