对象的每个属性,额外有几个选项:

 value:默认值

 writable:是否可写

  configurable:是否可以重新配置

enumerable:是否可遍历

 get:getter,读取属性时触发, 对象.属性名      作用:计算属性

set:setter,为属性赋值时触发, 对象.属性名=值    作用:赋值检查

        直接声明的属性:{属性名:值},其配置项默认都是true

        用Object.defineProperty(…),新增属性所有配置默认都是false

        get,set 属性与write  enumerable:互斥,不能同时存在

Object.defineProperty(obj, "id", {
      writable: false, //是否可写 
      configurable: false, //是否可重新配置   
      enumerable:false,  //是否可遍历 
    })

1、精确添加对象属性

 Object.defineProperty(参数1,参数2,参数3):

          参数1:要修改的对象

          参数2:要修改的属性名,必须是字符串格式

          参数3:要修改的具体配置

        例如新增一个id属性,默认值001:

Object.defineProperty(obj, "id", {value: 001,writable: false … })

        新增属性,所有配置默认都是假

2、精确配置多个对象属性

        Object.defineProperties(要修改的对象, {属性1:{writable:false… },属性2:{ }…. }}

var obj = {
      id: 100,
    }
    //id不可修改,配置不可改
    //新增name属性,默认值“刚刚”,不可修改,配置不可改
    //新增salary,默认值9999,不可改,不可配置,不可遍历
    Object.defineProperties(obj, {
      //此方式添加的属性,所有的默认值都是true
      id: {
        writable: false,
        configurable: false
      },
      //用此方式添加的新属性,所有的默认值都是false
      name: {
        value: "刚刚",
        enumerable: true //要主动声明,才能遍历
      },
      salary: {
        value: 9999,
      }
    });
    console.log(obj);
    for (var name in obj) {
      console.log(name); //salary不可遍历,不可见
    }

3、计算属性 getter

        计算属性get 与value/writable配置项是互斥的

        get 获取,当读取一个属性时,会自动触发get属性的函数,把此函数的返回值 作为属性的值

        调用时:对象.方法,不需要写()

写法1:

写法2(语法糖写法):

Object.defineProperty(r1, "area", {
      get: function ( ) {
        return this.width * this.height;
      }
var  r1 = {
      width: 100,  height: 30,
      get area( ) {
        return this.width * this.height;
      },
var r1 = {
      width: 100,
      height: 50,
      //面积:特点:值是计算出来的
    }
    //声明计算属性:getter
    Object.defineProperty(r1, "area", {
      //计算属性get 与value/writable配置项是互斥的
      //get 获取,当读取一个属性时,会自动触发get属性的函数,
      //把此函数的返回值 作为属性的值
      get: function () {
        console.log("有人要读取面积!!");
        return this.width * this.height;
      }
    })
    console.log(r1.area);

    //得到周长
    Object.defineProperty(r1,"perimeter",{
      get:function(){
        console.log("周长");
        return (this.width+this.height)*2;
      }
    })
    console.log(r1.perimeter);

4、赋值监听 setter

        赋值监听:防止一些明显错误的值的添加

        做法:修改属性的set,在此方法中接收赋值,然后对值进行检查,如果正确才赋值,此处不能给当前属性赋值,会触发当前属性的set方法,导致无限循环,所以必须额外声明一个变量来存储值,读取时,再通过get方法,来返回存储的变量(额外声明的变量一般用前缀__)

写法1:

写法2(语法糖写法):

var __age;    
Object.defineProperty(yanan, "age", {
 set: function (value)
        if (value >= 1 && value <= 100) {
          // this.age=value;    无限循环
  __age = value;
        } else {
          throw Error("年龄范围错误" + value);
        }
      },
 get: function ()
 return __age;
      }
})
var yanan = {
      name: "芳芳",
 set age(value)
        if (value >= 1 && value <= 100) {
          this.__age = value; //自动创建
        } else {
          throw Error("年龄范围错误");
        }
      },
 get age( )
        return this.__age;
      },

};