资讯专栏INFORMATION COLUMN

属性描述符

stackfing / 3039人阅读

摘要:决定该属性是否可重新设置描述符。此时,属性的描述符被称为访问描述符。屏蔽属性当你给一个对象赋值一个新的属性时,如果该对象的原型链上已存在属性,并且被标记为只读时,严格模式下会抛出异常,非严格模式下,这条赋值语句会被忽略。

属性描述符
在ES5开始,所有属性都具备了属性描述符。

我们可以通过Object.getOwnPropertyDescriptor来观察到属性的描述符,它是长这样子的。

Object.getOwnPropertyDescriptor({a: 1}, "a");

// {
//   value: 1,
//   writable: true,
//   enumerable: true,
//   configurable: true
// }

writable决定该属性是否只读。
enumerable决定该属性是否可枚举。
configurable决定该属性是否可重新设置描述符。

属性描述符的设置

当属性的configurable为true时,我们可以通过Object.defineProperty来修改属性描述符。

"use strict";

var foo = {a: 1};

for(var i in foo) {console.log(i)};
// "a"

Object.defineProperty(foo, "a", {
  writable: false,
  enumerable: false,
  configurable: false
});

foo.a = 2;// Uncaught TypeError: Cannot assign to read only property "a" of object "#"

for(var i in foo) {console.log(i)};
// "nothing happend"

Object.defineProperty(foo, "a", { // Uncaught TypeError: Cannot redefine property: a
  configurable: true
});

访问描述符(getter和setter)

getter和setter有两种方式定义

字面量定义

var foo = {
  get a(){
    return this._a;
  },
  set a(value){
    this._a = value;
  }
};

使用Object.defineProperty定义

var foo = {a: 1};

Object.defineProperty(
  foo,
  "a",
  {
    get(){
      return this._a;
    },
    set(value){
      this._a = value;
    }
  }
);

这个时候再看看属性a的描述符。

Object.getOwnPropertyDescriptor(foo, "a")

// {
//   get: ƒ a(),
//   set: ƒ a(value),
//   enumerable: true,
//   configurable: true
// }

当出现gettersetter时,valuewritable就会失效。
此时,属性a的描述符被称为访问描述符
访问描述符属性描述符互斥,如果此时再重新设置value或者writable描述符,settergetter也会被丢弃。

屏蔽属性
当你给一个对象赋值一个新的属性foo时,如果该对象的原型链上已存在属性foo,并且foo被标记为只读(writable: false)时,严格模式下会抛出异常,非严格模式下,这条赋值语句会被忽略。这种属性称为屏蔽属性

举个例子

"use strict";

var anotherObject = {};

Object.defineProperty(anotherObject, "foo", {// 将anotherObject的foo属性设为只读
  value: 1,
  writable: false
});

var myObject = Object.create(anotherObject);// 将myObject的原型设置为anotherObject

console.log(myObject);// {}
console.log(myObject.foo);// 1

myObject.foo = 2;// Uncaught TypeError: Cannot assign to read only property "a" of object "#"

还有一种情况

当你给一个对象赋值一个新的属性foo时,如果该对象的原型链上已存在属性foo,并且foo被设置了setter时,将会调用这个setter,并且该赋值语句将会被忽略,此时也会发生属性屏蔽。
var anotherObject = {};

Object.defineProperty(anotherObject, "foo", {// 给anotherObject的foo属性设置setter
  set(value) {
    console.log(value);
    this._foo = value;
  },
  get() {
    return this._foo;
  }
});

var myObject = Object.create(anotherObject);// 将myObject的原型设置为anotherObject

myObject.foo = 2;// 此时会触发anotherObject.foo的setter,控制台输出2

console.log(Object.hasOwnProperty(myObject, "foo"));// false
解决方案

使用Object.defineProperty来添加属性。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100257.html

相关文章

  • [译] 属性访问、特性和描述 2

    摘要:不像其他属性,描述符在类级别上创建。当所有者类被定义时,每个描述符对象都是被绑定到一个不同的类级别属性的描述符类实例。这必须返回描述符的值。此外,描述符对有一个方便的响应和请求格式。 注:原书作者 Steven F. Lott,原书名为 Mastering Object-oriented Python __getattribute__()方法 __getattribute__()方法是...

    CloudwiseAPM 评论0 收藏0
  • Python中的属性描述

    摘要:下面我们用描述符来实现中的动态属性和特性中提及的订单结算代码第四版使用描述符实现订单结算功能描述符基于协议实现,无需创建子类。特性是覆盖型描述符。非覆盖型描述符没有实现方法的描述符属于非覆盖型描述符。类中定义的方法是非覆盖型描述符。 导语:本文章记录了本人在学习Python基础之元编程篇的重点知识及个人心得,打算入门Python的朋友们可以来一起学习并交流。 本文重点: 1、了解描述符...

    geekzhou 评论0 收藏0
  • 讲清楚之 javascript 对象属性描述

    摘要:所以搞清楚是理解对象属性描述符的唯一途径。是一个对象,对象里的属性描述符有两种类型数据描述符和存取描述符。描述符必须是这两种形式之一不能同时是两者。描述符中未显示设置的特性使用其默认值。创建一个新属性默认描述符的键值都是或者。 对象属性描述符 当别人对你提及对象属性描述符,可能会蒙逼。而如果提及对象属性的 get/set 方法就秒懂了,标准描述和习惯表述在这里有些差别,但是指向的是同一...

    zhjx922 评论0 收藏0
  • python 描述解析

    摘要:之所以是这样是因为当访问一个实例描述符对象时,会将转换为。而类的字典中则有描述符对象。这主要就是因为描述符优先。此外,非数据描述符的优先级低于实例属性。参考以上就是本人对描述符的一些理解,有什么不正确的地方还请不吝指出,谢谢 什么是描述符 python描述符是一个绑定行为的对象属性,在描述符协议中,它可以通过方法重写属性的访问。这些方法有 __get__(), __set__(), 和...

    rozbo 评论0 收藏0
  • javaScript中的Object类型

    摘要:默认为当该属性的为时,才能被赋值运算符改变。可以是任何有效的值数值,对象,函数等。而这些篡改可能会影响对象的内置属性或方法,从而导致对象的正常功能可能无法使用。 属性描述符 JavaScript提供了一个内部数据结构,用于描述对象的值,控制其行为,例如该属性是否可写、是否可配置、是否可修改以及是否可枚举等。这个内部数据结构被称为‘属性描述符’。每个属性都有自己对应的属性描述符,保存该属...

    hyuan 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<