为什么有对象属性符

当我们想对一些对象内的属性进行设置的时候,比如这个属性是否可以通过delete删除,是否可以遍历出来,想要对一个属性进行精准的操作控制的时候,这个时候我们就可以使用我的对象属性符。

如何来表示对象属性符

我们可以通过Object.defineProperty()
该方法是可以直接在一个对象上进行一个新的属性定义,并且返回此对象
比如:
image.png
该方法可以接受3个参数,
obj表示要定义属性的对象,
“xxx”表示要修改的属性的名称
{}要定义的属性修饰符

属性描述符分类

数据属性(Data Properties)描述符

该属性一共4个特征:

  1. [[Configurable]]:表示属性是否可以通过delete删除属性,是否可以修改它的特性,或者是否可以将它修改为存取属性
  2. [[Enumerable]]:表示属性是否可以通过for-in或者Object.keys()返回该属性
  3. [[Writable]]:表示是否可以修改属性的值
  4. [[value]]:属性的value值,读取属性时会返回该值,修改属性时,会对其进行修改
    实例:
var obj = {};
Object.defineProperty(obj, 'x', {
    value : 1,  //设置属性默认值为1
    writable : false  //禁止修改属性值
});
obj.x = 2;  //修改属性x的值
console.log(obj.x);  //1,说明修改失败

存取属性(Accessor访问器 Properties)描述符

也有4个特征

  1. [[Configurable]]:表示属性是否可以通过delete删除属性,是否可以修改它的特性,或者是否可以将它修改为存取属性
  2. [[Enumerable]]:表示属性是否可以通过for-in或者Object.keys()返回该属性
  3. [[get]]:获取属性时会执行的函数。
  4. [[set]]:设置属性时会执行的函数。
var obj = {
  name: "why",
  age: 18,
  _address: "北京市"
}

// 存取属性描述符
// 1.隐藏某一个私有属性被希望直接被外界使用和赋值
// 2.如果我们希望截获某一个属性它访问和设置值的过程时, 也会使用存储属性描述符
Object.defineProperty(obj, "address", {
  enumerable: true,
  configurable: true,
  get: function() {
    foo()
    return this._address
  },
  set: function(value) {
    bar()
    this._address = value
  }
})

console.log(obj.address)

obj.address = "上海市"
console.log(obj.address)

function foo() {
  console.log("获取了一次address的值")
}

function bar() {
  console.log("设置了addres的值")
}



定义多个属性描述符

Object.defineProperties(obj,{"xxx:xxx","xxx:xxx"})

var obj = {
  age: 18,
  name: "张三"
}
Object.defineProperties(obj, {
  gender: {
    enumerable: true,
    configurable: true,
    writable: true,
    value: "男"
  },
  fun: {
    enumerable: true,
    configurable: true,
    get: function (value) {
      console.log("get", value);
      return value
    },
    set: function (value) {
      console.log("set", value);
      this.name = "李五"
    }
  }
})

obj.fun = "aa"
console.log(obj);

获取属性描述符

console.log(Object.getOwnPropertyDescriptor(obj, "属性名"))

Object方法对属性进行限制

Object.seal(obj) //禁止对象配置/删除里面的属性
Object.preventExtensions(obj)// 禁止对象继续添加新的属性
Object.freeze(obj)//让属性不可以修改(writable: false)

Q.E.D.