Object.defineProperty() 吴小明

定义:Object.defineProperty(object, propName, descriptor)为对象定义新的属性,或者对某个属性进行修改,并将这个对象返回出来

  object:对象  给谁加

  propName:属性名  要添加的属性的名字,是一个字符串

  descriptor:属性描述  要加的这个属性有什么特点

  属性描述对象的6个属性:

    value      属性的值

    writable     属性值是否可以重写,默认为false

    enumerable    属性值是否可枚举,默认为false

    configurable      属性值是否可删除/是否可以再次修改特性,默认为false

    set          目标属性设置值的方法

    get          目标属性获取值的方法

1、descriptor的第一个属性:value  要加的属性值是什么,默认值:undefined

      Object.defineProperty(user, 'name', {
        value: '小明'
      })
      Object.defineProperty(user, 'isShow', {
        value: true
      })
      Object.defineProperty(user, 'age', {
        value: 18
      })
      Object.defineProperty(user, 'sayHi', {
        value: function() {
          console.log('hi')
        }
      })
      Object.defineProperty(user, 'hobby', {
        value: { a: '篮球', b: '足球' }
      })
      console.log(user) // {name: '小明', isShow: true, age: 18, hobby: { a: '篮球', b: '足球' }, sayHi: ƒ}

2、descriptor的第二个属性:writable  属性是否可以被重新赋值,默认值:false

      const user = {}
      Object.defineProperty(user, 'name', {
        value: '小明'
      })
      user.name = '小小明' // 此时无法改变name的值
      console.log(user) // {name: '小明'}
      const user = {}
      Object.defineProperty(user, 'name', {
        value: '小明',
        writable: true // 默认值为false,当设置为true时可以重新赋值name
      })
      user.name = '小小明'
      console.log(user) // {name: '小小明'}

3、descriptor的第三个属性:enumerable  是否可以被枚举,默认值:false

      const user = {
        name: '小明',
        age: 18
      }
      Object.defineProperty(user, 'gender', {
        value: '男',
        enumerable: true
      })
      Object.defineProperty(user, 'score', {
        value: 100,
        enumerable: false // 此时该属性不可以被遍历
      })
      const keys = Object.keys(user)
      console.log(keys) // ['name', 'age', 'gender']

  要注意,不可枚举属性可以通过对象.获取,但是它是不可以被遍历的,并不是说不能通过对象去获取这个值了

      const user = {
        name: '小明',
        age: 18
      }
      Object.defineProperty(user, 'gender', {
        value: '男'
      })
      const keys = Object.keys(user)
      console.log(keys) // ['name', 'age']
      for (let item in user) {
        console.log(item) // name age
      }
      console.log(user) // {name: '小明', age: 18, gender: '男'}

4、descriptor的第四个属性:configurable  是否可以被删除,是否可以在第一次定义后再重新定义,默认值:false

      const user = {
        name: '小明',
        age: 18
      }
      Object.defineProperty(user, 'gender', {
        value: '男'
      })
      delete user.gender // 删除无效
      console.log(user) // {name: '小明', age: 18, gender: '男'}
      const user = {
        name: '小明',
        age: 18
      }
      Object.defineProperty(user, 'gender', {
        value: '男'
      })
      user.gender = '女' // 重新定义无效
      console.log(user) // {name: '小明', age: 18, gender: '男'}
      const user = {
        name: '小明',
        age: 18
      }
      Object.defineProperty(user, 'gender', {
        value: '男'
      })
      // 使用Object.defineProperty()重新定义gender会报错
      Object.defineProperty(user, 'gender', {
        value: '女'
      })
      console.log(user) // Uncaught TypeError: Cannot redefine property: gender

  

      const user = {
        name: '小明',
        age: 18
      }
      Object.defineProperty(user, 'gender', {
        value: '男',
        configurable: true
      })
      delete user.gender // 删除有效
      console.log(user) // {name: '小明', age: 18}
      const user = {
        name: '小明',
        age: 18
      }
      Object.defineProperty(user, 'gender', {
        value: '男',
        configurable: true
      })
      // 可以通过Object.defineProperty()重新定义gender
      Object.defineProperty(user, 'gender', {
        value: '女'
      })
      console.log(user) // {name: '小明', age: 18, gender: '女'}

  重新定义gender之后,configurable的值不设置为false即认为是继承了第一次设置的true,此时可以删除gender;一旦重新定义gender后设置了configurable为false,即不可以再进行设置,也不可以再删除

      const user = {
        name: '小明',
        age: 18
      }
      Object.defineProperty(user, 'gender', {
        value: '男',
        configurable: true
      })
      // 可以通过Object.defineProperty()重新定义gender
      Object.defineProperty(user, 'gender', {
        value: '女',
        // configurable: false // 写了这句则不可以删除,否则值默认为第一次定义时的true
      })
      delete user.gender // 若第二次定义gender时明确声明了configurable: false,此时不可以删除;若没有定义则认为继承了第一次定义时的true,此时可以删除
      console.log(user) // {name: '小明', age: 18}

5、descriptor的第五个属性:存取器(set、get)

      const user = {
        name: '小明'
      }
      let count = 12
      const obj = Object.defineProperty(user, 'age', {
        get: function() {
          return count
        },
        set: function(val) {
          count = val
        }
      })
      console.log(user.age) // 12
      user.age = 18
      console.log(user.age) // 18

  注意:

    ①set和get可以一起写,也可以写一个

    ②写了set或get后,不能设置value和writable属性了,否则会报错

原文地址:https://www.cnblogs.com/wuqilang/p/15569794.html