关于 Object.defineProperty()

122 阅读2分钟

Object.defineProperty

  1. 接收3个参数,第一个参数是需要操作的对象,第二个参数是需要操作的对象属性名,第三个参数是一个配置对象,

  2. 这个配置对象里面有4个选项,如下

         1.configurable:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性,默认值为false2.enumerable:表示能否通过for in循环访问属性,默认值为false
    
         3.writable:表示能否修改属性的值。默认值为false4.value:包含这个属性的数据值。默认值为undefined

在调用Object.defineProperty()方法创建一个新属性时,如不指定前三个属性字段,默认值都为false, 如果是修改已定义的属性时,则没有此限制

// 表示在obj这个对象里新增一个d属性,属性值为10,可写,可更改,可迭代
Object.defineProperty(obj,"d",{
    value:10,
    writable:true,
    configurable:true,
    enumerable:true
})

3.第三个参数配置里面还有2个可选键值get和set,这两个是函数,value和get当中只能有一个,set和writable当中只能有一个

//如果想通过Object.defineProperty里的get和set函数修改对象里原有的数据,需要使用一个第三方变量来进行转换
let temp=0
Object.defineProperty(obj,"c",{
  // value:6,
  // writable:false,
  get(){
    console.log('正在获取属性',this);
    return temp  //get的返回值会作为c属性的属性值
  },
  set(val){
    console.log('正在设置属性',val);
   // temp=val  将新值赋值给中间转换的值
  }
})

当获取obj.c属性的时候,get可以捕获到,这时,执行get函数里面的逻辑代码,如果修改obj.c属性的值,set可以捕获到,这个时候执行set里面的逻辑代码,set接收一个参数,这个参数就是修改后的新值

Object.defineProperty()监听对象设置还可以通过闭包进行实现,通过闭包,就不用再额外设置一个中间变量

function defineReactive(target,key,val){ 
  Object.defineProperty(target,key,{
  // value:6,
  // writable:false,
  get(){
    console.log(`正在获取${key}的属性`);
    return val
  },
  set(newval){
    console.log(`正在设置${key}的属性`,newval);
      val=newval
  }
})
}
defineReactive(obj,"a")
obj.a=6
console.log(obj);