Object.defineProperty() 方法的使用.

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

语法:  Object.defineProperty(obj, prop, descriptor)

  参数:   参数1:  要定义属性的对象

             参数2:  要定义或修改的属性的名称或Symbol

             参数3:  要定义或修改的属性描述符

  返回值:   返回传递给函数的对象.sdf

配置项:

      const object1 = {
        name: 999
      };

      Object.defineProperty(object1, 'property1', {
        configurable: true, //该属性的描述符是否能够改变,默认为false
        value: 42,          //属性名称的值.默认undefined
        writable: true,     //可读,可写,为true时,value的值才能被改变,默认false
        enumerable: true,   //是否可枚举,默认为false
        // get  属性的getter函数,没有则为undefined,访问该属性时,会调用此函数.
        get() { return xxx }
        // set  属性的setter函数,没有则为undefined,当属性值被修改时,调用此函数,
                该方法接受一个参数(也就是被赋予的新值)
        set(newValue) { xxx = newValue }
      });




       var obj = {};
      //方法1:
      // var descriptor = Object.create(null); // 没有继承的属性
      // // 默认没有 enumerable,没有 configurable,没有 writable
      // descriptor.value = 'static';
      // Object.defineProperty(obj, 'key', descriptor);
      //方法2:
      // 显式
      // Object.defineProperty(obj, "key", {
      //   enumerable: false,
      //   configurable: false,
      //   writable: false,
      //   value: "static"
      // });
      // console.log(obj)
        
      //方法3:
      // 循环使用同一对象
        function withValue(value) {
          return {
              enumerable: false,
              writable: false,
              configurable: false,
              value
        };
    }
    // ... 并且 ...
    Object.defineProperty(obj, "key", withValue("static"));

Writable属性:

当 writable 属性设置为 false 时,该属性被称为“不可写的”。它不能被重新赋值。

var o = {}; // 创建一个新对象

Object.defineProperty(o, 'a', {
  value: 37,
  writable: false
});

console.log(o.a); // 37
o.a = 25;         // "TypeError: Cannot assign to read only property 'a' of object                     
                     '#<Object>'"

Enumerable属性:

enumerable定义了对象的属性是否可以在for...in和Object.keys()中被枚举.

var o = {};
Object.defineProperty(o, "a", { value : 1, enumerable: true });
Object.defineProperty(o, "b", { value : 2, enumerable: false });
Object.defineProperty(o, "c", { value : 3 }); // enumerable 默认为 false
o.d = 4; // 如果使用直接赋值的方式创建对象的属性,则 enumerable 为 true
for (var i in o) { console.log(i) } //返回a,d

Configurable属性:

configurable 特性表示对象的属性是否可以被删除,以及除 value 和 writable 特性外的其他特性是否可以被修改。

      var o = {};
      Object.defineProperty(o, 'a', {
        get() { return '999' },
        // value: '88',      //报错
        // enumerable: true, //报错
        configurable: false

      })

      console.log(o.a)
      delete o.a  //报错:"TypeError: Cannot delete property 'a' of #<Object>"
      console.log(o.a)

添加多个属性和默认值:

var o = {};

o.a = 1;
// 等同于:
Object.defineProperty(o, "a", {
  value: 1,
  writable: true,
  configurable: true,
  enumerable: true
});


// 另一方面,
Object.defineProperty(o, "a", { value : 1 });
// 等同于:
Object.defineProperty(o, "a", {
  value: 1,
  writable: false,
  configurable: false,
  enumerable: false
});

自定义Setters和Getters

      function Archiver() {
        var temperature = null;
        var archive = [];
        Object.defineProperty(this, 'temperature', {
          get: function() {
            return temperature;
          },
          set: function(value) {
            temperature = value;
            archive.push({ val: temperature });
          }
        });

        this.getArchive = function() { return archive; };
      }

      var arc = new Archiver();
      arc.temperature = 11;
      console.log(arc.temperature) // 'get!'  11
      arc.temperature = 13;
      console.log(arc.temperature) // 'get!'  13
      console.log(arc.getArchive()); // [{ val: 11 }, { val: 13 }]

继承属性:

如果访问者的属性是继承的,它的get和set方法会在子对象的属性被访问或修改时被调用.

如果这些方法用一个变量存值,该值会被所有对象共享.

function myClass() {
}

var value;
Object.defineProperty(myClass.prototype, "x", {
  get() {
    return value;
  },
  set(x) {
    value = x;
  }
});

var a = new myClass();
var b = new myClass();
a.x = 1;
console.log(b.x); // 1

这可以通过将值存储在另一个属性中解决.

在get个set方法中,this指向某个被访问和修改属性的对象.

function myClass() {
}

Object.defineProperty(myClass.prototype, "x", {
  // 这里this指向myClass
  get() {
    return this.stored_x;
  },
  set(x) {
    this.stored_x = x;
  }
});

var a = new myClass();
var b = new myClass();
a.x = 1;
console.log(b.x); // undefined

不想访问者属性,值属性始终在对象自身上设置,而不是一个原型.

然而,如果一份不可写的属性被继承,它仍可以防止修改对象的属性.

function myClass() {
}

myClass.prototype.x = 1;
Object.defineProperty(myClass.prototype, "y", {
  writable: false,
  value: 1
});

var a = new myClass();
a.x = 2;
console.log(a.x); // 2
console.log(myClass.prototype.x); // 1
a.y = 2; // 报错: 不能为对象的只读属性赋值
console.log(a.y); // 1
console.log(myClass.prototype.y); // 1

总结于MDN,链接

Object.defineProperty() - JavaScript | MDN

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值