Object.defineProperty()

        该方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。应当直接在object构造器上调用此方法,而不是在任意一个object类型的实例上调用。

Object.defineProperty(obj, prop, descriptor)
参数:
obj:要定义属性的对象
prop:要定义或修改的属性名称或symbol
descriptor:要定义或修改的属性描述符

        对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。存取描述符是由getter函数和setter函数所描述的属性。一个描述符只能是这两者其中之一,不能同时是两者。

左对齐 右对齐 居中对齐
单元格 单元格 单元格
单元格 单元格 单元格
属性名 configurable enumerable value writable get Set
作用 是否可配置对象(删除属性) 是否可枚举 是否可以修改对象 获取obj.key 将修改的值重新赋值
默认值 false false(也就是object.defineproperty定义的属性默认是不能被遍历的) undefined false undefined undefined
数据描述符 可有 可有 可有 可有 不可有 不可有
存取描述符 可有 可有 不可有 不可有 可有 可有
Object.defineProperty(obj, key, {
  // 1.value
  enumerable: true,     // 4.可以枚举
  configurable: true,   // 2.可以配置对象,删除属性
  // writable: true     // 3.可以修改对象
  // get,set设置时不能设置writable和value,它们代替了 二者是互斥的   可以去看数据描述符和存取描述符
  // 5.获取obj.key的时候就会调用get方法
  get: function reactiveGetter () {
    const value = getter ? getter.call(obj) : val
    if (Dep.target) {
      dep.depend()
      if (childOb) {
        childOb.dep.depend()
        if (Array.isArray(value)) {
          dependArray(value)
        }
      }
    }
    return value
  },
  // 6.将修改的值重新赋值
  // 当我们更新data的时候,会触发set方法,执行dep.notify()方法
  set: function reactiveSetter (newVal) {
    const value = getter ? getter.call(obj) : val
    /* eslint-disable no-self-compare */
    if (newVal === value || (newVal !== newVal && value !== value)) {
      return
    }
    /* eslint-enable no-self-compare */
    if (process.env.NODE_ENV !== 'production' && customSetter) {
      customSetter()
    }
    // #7981: for accessor properties without setter
    if (getter && !setter) return
    if (setter) {
      setter.call(obj, newVal)
    } else {
      val = newVal
    }
    childOb = !shallow && observe(newVal)
    dep.notify()
  }
})

你可能感兴趣的:(Object.defineProperty())