属性描述符是对JavaScript属性的描述,包括:value、writable、enumerable、configurable,除value其他默认为true。


本文包括:

  • 取得属性描述符、 Object.getOwnPropertyDescriptor( obj, "property-name" );
  • 属性描述符详解、

    1. writable[对象是否可以再赋值], enumerable[对象是否可以迭代], configurable[是否可以通过Object.defineProperty对对象再次配置]

  • 属性描述符应用、 writable: false  &&  configurable: false 产生对象常量
  • 其他相关:
  1. 禁止扩展:Object.preventExtensions(obj),阻止对象再添加属性,对象不可以扩展。
  2. 封装: Object.seal(obj),封装一个对象,对象上不能再添加新的属性、不能重新定义属性描述符、不能删除某个属性,

      等价于 Object.preventExtensions(obj),并设置现有的所有属性为 configurable:false。

  3.冻结:Object.freeze(obj),对象不能再做任何修改或者删除属性的操作,

    效果相当于调用了 Object.seal(obj) 并设置所有属性为 writable: false


1.取得属性描述符

var myObject = {
a: 2
}; Object.getOwnPropertyDescriptor( myObject, "a" );
// { value: 2, writable: true, enumerable: true, configurable: true }

可以看到,对象myObject的属性a,除了拥有value描述符,还拥有writable、enumerable、configurable三个用于描述属性描述符。

var myObject = {};

Object.defineProperty( myObject, "a", {
value: 2,
writable: true,
configurable: true,
enumerable: true
} );
// 上面的定义等同于 myObject.a = 2; 
// 所以如果不需要修改这三个特性,我们不会用 `Object.defineProperty` myObject.a; //

通过Object.defineProperty(obj,"propertyname",{})可以为对象添加属性,并且通过属性描述符为属性添加一些特性。


2.属性描述符详解

 

2.1 writable[对象是否可以再赋值]

// "use strict";
var myObject = {}; Object.defineProperty( myObject, "a", {
value: 2,
writable: false, // 不可写!
configurable: true,
enumerable: true
} ); myObject.a = 3; // 写入的值将会被忽略 myObject.a; // /*
如果应用了 strict mode 的话,那么 myObject.a 将会抛出 TypeError,而不是仅仅忽略写入的值。
ES5 还引入了对象属性的 Getter 和 Setter,这里的 writable: false可以认为是和没有定义或者定义了没有任何操作的 setters 的情况大致等同。
当然了,如果是 strict mode 下,需要在 setters 里面抛出 TypeError 来完全模拟 writable: false 的情形。
*/

2.2 enumerable[对象是否可以迭代]

var myObject = {
a: 2
}; myObject.a = 3;
myObject.a; // Object.defineProperty( myObject, "a", {
value: 4,
writable: true,
configurable: false, // 不可配置!
enumerable: true
} ); myObject.a; //
myObject.a = 5;
myObject.a; // Object.defineProperty( myObject, "a", {
value: 6,
writable: true,
configurable: true, //同样的,也不能用delete删除对象这个属性了
enumerable: true
} ); // TypeError /*
注意,一旦某个属性被指定为 configurable: false,
那么就不能从新指定为configurable: true 了,这个操作是单向,不可逆的。
*/

2.3 configurable[是否可以通过Object.defineProperty对对象再次配置]

var myObject = { };

Object.defineProperty(
myObject,
"a",
// make `a` enumerable, as normal
{ enumerable: true, value: 2 }
); Object.defineProperty(
myObject,
"b",
// make `b` NON-enumerable
{ enumerable: false, value: 3 }
); myObject.b; //
("b" in myObject); // true
myObject.hasOwnProperty( "b" ); // true // ....... for (var k in myObject) {
console.log( k, myObject[k] );
}
// "a" 2 myObject.propertyIsEnumerable( "a" ); // true
myObject.propertyIsEnumerable( "b" ); // false Object.keys( myObject ); // ["a"]
Object.getOwnPropertyNames( myObject ); // ["a", "b"] /*
这里可以看到,enumerable: false 使得该属性从对象属性枚举操作中被隐藏,
但Object.hasOwnProperty(...) 仍然可以检测到属性的存在。
另外,Object.propertyIsEnumerable(..) 可以用来检测某个属性是否可枚举,
Object.keys(...) 仅仅返回可枚举的属性,
而Object.getOwnPropertyNames(...) 则返回该对象上的所有属性,
包括不可枚举的。
*/

3.属性描述符应用

var myObject = {};

Object.defineProperty( myObject, "FAVORITE_NUMBER", {
value: 42,
writable: false,
configurable: false
} ); /*
通过组合 writable: false 和 configurable: false,可以创建一个不能修改、重新定义或删除其属性的对象常量
这里对该对象属性的删除,修改操作会被忽略,不能再用Object.defineProperty(...) 来重新配置该属性的特性
*/

4.其他相关

4.1禁止扩展

/*
如果希望阻止新的属性被加入到对象,可以通过调用
Object.preventExtensions(...) 来做到这一点:
*/ var myObject = {
a: 2
}; Object.preventExtensions( myObject ); myObject.b = 3;
myObject.b; // undefined //在 strict mode 下,行为稍有不同,对属性的赋值会抛出 TypeError, 而不是仅仅忽略赋值操作

4.2封装

/*
可以通过 Object.seal(...) 来封装一个对象。在调用这个操作之后,
对象上不能再添加新的属性,也不能重新定义属性描述符或者删除某个属性:
*/
var myObject = {
a: 2
};
Object.seal(myObject);
myObject.b = 'b';
console.log(myObject); // {a: 2} myObject.a = 6;
console.log(myObject); // {a: 6} /*
Object.seal(...)
相当于调用了 Object.preventExtensions(..),并设置现有的所有属性为 configurable:false。
*/

4.3冻结

/*
调用 Object.freeze(...) 可以创建一个被冻结的对象,这个对象拥有不能再被做任何修改或者删除属性的操作
*/ var myObject = {
a: 2
};
Object.seal(myObject);
myObject.b = 'b';
console.log(myObject); // {a: 2} myObject.a = 6;
console.log(myObject); // {a: 2} //相当于调用了 Object.seal(...) 并设置所有属性为 writable: false

原文

JavaScript.descriptor(属性描述符)的更多相关文章

  1. 深入理解javascript对象系列第三篇——神秘的属性描述符

    × 目录 [1]类型 [2]方法 [3]详述[4]状态 前面的话 对于操作系统中的文件,我们可以驾轻就熟将其设置为只读.隐藏.系统文件或普通文件.于对象来说,属性描述符提供类似的功能,用来描述对象的值 ...

  2. JavaScript 属性描述符

    属性描述符(Property Descriptor)是 ES5 之后出现的概念,顾名思义,它用于描述属性应该是什么样,例如是否只读,能否枚举,能否可配置等.所有对象属性均可使用属性描述符来定义. 属性 ...

  3. 理解JavaScript中的属性描述符

    我们把描述JavaScript中定义内部特性的属性叫做属性描述符 分为两大类:数据描述符和存取描述符 数据描述符是一个拥有可写或不可写的属性(Writable); 存取描述符不包含数据值,是一组拥有g ...

  4. Object.defineProperty 与 属性描述符

    为JavaScript对象新增或者修改属性,有两种不同方式:直接使用=赋值或者使用Object.defineProperty 定义,使用后者的话还可以设置属性的描述符. Object.definePr ...

  5. Python:高级主题之(属性取值和赋值过程、属性描述符、装饰器)

    Python:高级主题之(属性取值和赋值过程.属性描述符.装饰器) 背景 学习了Javascript才知道原来属性的取值和赋值操作访问的“位置”可能不同.还有词法作用域这个东西,这也是我学习任何一门语 ...

  6. JS属性描述符之Object.defineProperty()定义对象属性特性

    一.Object.defineProperty的作用 用来给对象新增属性,和修改对象中的属性. 二.JS对象中的描述符 js对象中两种属性描述符:数据描述符和存取描述符(访问描述符). 注意事项: 1 ...

  7. python 属性描述符

    import numbers class IntField: # 一个类只要实现了这个魔法函数,那么它就是属性描述符 #数据描述符 def __get__(self, instance, owner) ...

  8. 元类编程--__get__ __set__属性描述符

    from datetime import date, datetime import numbers class IntField: #数据描述符,实现以下任意一个,都会变为属性描述符 def __g ...

  9. js 面向对象之属性描述符

    上回介绍了面向对象之构造器属性.这次介绍下属性描述符 遍历对象属性 let person = {name: "lisi"} for (key in person) { consol ...

随机推荐

  1. 用Navicat连接阿里云ECS服务器上的MySQL数据库,连接不上,并且报10060错误

    设置远程访问(使用root密码): grant all privileges on . to 'root' @'%' identified by '123456'; flush privileges; ...

  2. [转]简单总结一下解决 添加 inline-block 后多出来的空隙

    添加 inline-block 后: 查询.借鉴的原网址:http://www.zhangxinxu.com/wordpress/?p=2357 html 结构: <ul class=" ...

  3. C/C++网络编程1——linux下实现

    网络编程就是编写程序使两台联网的计算机相互交换数据. 例子:服务器端开启一个socket,监听9999端口.客户端向服务器端发起请求,服务器端收到请求以后,给客户端发送一句:"hello w ...

  4. Node.js npm基础安装配置&创建第一个VUE项目

    使用之前,我们先来明白这几个东西是用来干什么的. node.js: 一种javascript的运行环境,能够使得javascript脱离浏览器运行.Node.js的出现,使得前后端使用同一种语言,统一 ...

  5. window查看连接过的无线密码

    for /f "skip=9 tokens=1,2 delims=:" %i in ('netsh wlan show profiles') do  @echo %j | find ...

  6. python对文件中光标的操作迭代器

    seek()    默认从文件开头开始.seek(10) seek(10,1)   需要以b的模式读取文件,从相对位置进行移动光标 seek(-3,2)  倒着移动光标的模式 例如: f= open( ...

  7. 第1节 kafka消息队列:1、kafka基本介绍以及与传统消息队列的对比

    1. Kafka介绍 l  Apache Kafka是一个开源消息系统,由Scala写成.是由Apache软件基金会开发的一个开源消息系统项目. l  Kafka最初是由LinkedIn开发,并于20 ...

  8. canvas的其他应用

    画布的基础知识 专门研究画布的大佬 手动实现echar的大佬 echar官方 画布之水印 ctx.font = "bold 20px Arial"; ctx.lineWidth = ...

  9. vue小程序ref和v-for结合使用得到ref数组的一些问题

    项目中需要对每一个民宿里的每一个房间都需要popup弹出层来介绍每一个房间,房间数据都在一个接口(此民宿)上. 主要代码如下: HTML: <view v-for='(item,index) i ...

  10. Windows安装OpenSSH服务

    一.背景 在做国盛通项目的时候,有两套并行测试环境,因为基本架构采用的是供应商提供的程序,需要将两套banner图做同步,因为图片数量多,进GitLab版本控制进行分支策略管理,进而同步两套环境,意义 ...