JavaScript.descriptor(属性描述符)
属性描述符是对JavaScript属性的描述,包括:value、writable、enumerable、configurable,除value其他默认为true。
本文包括:
- 取得属性描述符、 Object.getOwnPropertyDescriptor( obj, "property-name" );
- 属性描述符详解、
1. writable[对象是否可以再赋值], enumerable[对象是否可以迭代], configurable[是否可以通过Object.defineProperty对对象再次配置]
- 属性描述符应用、 writable: false && configurable: false 产生对象常量
- 其他相关:
- 禁止扩展:Object.preventExtensions(obj),阻止对象再添加属性,对象不可以扩展。
- 封装: 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(属性描述符)的更多相关文章
- 深入理解javascript对象系列第三篇——神秘的属性描述符
× 目录 [1]类型 [2]方法 [3]详述[4]状态 前面的话 对于操作系统中的文件,我们可以驾轻就熟将其设置为只读.隐藏.系统文件或普通文件.于对象来说,属性描述符提供类似的功能,用来描述对象的值 ...
- JavaScript 属性描述符
属性描述符(Property Descriptor)是 ES5 之后出现的概念,顾名思义,它用于描述属性应该是什么样,例如是否只读,能否枚举,能否可配置等.所有对象属性均可使用属性描述符来定义. 属性 ...
- 理解JavaScript中的属性描述符
我们把描述JavaScript中定义内部特性的属性叫做属性描述符 分为两大类:数据描述符和存取描述符 数据描述符是一个拥有可写或不可写的属性(Writable); 存取描述符不包含数据值,是一组拥有g ...
- Object.defineProperty 与 属性描述符
为JavaScript对象新增或者修改属性,有两种不同方式:直接使用=赋值或者使用Object.defineProperty 定义,使用后者的话还可以设置属性的描述符. Object.definePr ...
- Python:高级主题之(属性取值和赋值过程、属性描述符、装饰器)
Python:高级主题之(属性取值和赋值过程.属性描述符.装饰器) 背景 学习了Javascript才知道原来属性的取值和赋值操作访问的“位置”可能不同.还有词法作用域这个东西,这也是我学习任何一门语 ...
- JS属性描述符之Object.defineProperty()定义对象属性特性
一.Object.defineProperty的作用 用来给对象新增属性,和修改对象中的属性. 二.JS对象中的描述符 js对象中两种属性描述符:数据描述符和存取描述符(访问描述符). 注意事项: 1 ...
- python 属性描述符
import numbers class IntField: # 一个类只要实现了这个魔法函数,那么它就是属性描述符 #数据描述符 def __get__(self, instance, owner) ...
- 元类编程--__get__ __set__属性描述符
from datetime import date, datetime import numbers class IntField: #数据描述符,实现以下任意一个,都会变为属性描述符 def __g ...
- js 面向对象之属性描述符
上回介绍了面向对象之构造器属性.这次介绍下属性描述符 遍历对象属性 let person = {name: "lisi"} for (key in person) { consol ...
随机推荐
- ffmpeg使用C语言sdk实现抽取视频中的视频数据
主要使用函数 特征码:Start code 解码的一些视频参数,分辨率和帧率:SPS/PPS ffmpeg获取SPS/PPS:codec->extradata 实例 #include <s ...
- Input输入框日期控件
案例 https://pan.baidu.com/s/1i6BNLcT 密码:p77m
- android studio升级之后项目报错Could not find com.android.tools.build:aapt2:3.2.1-4818971
导致问题的原因为源代码根目录下的build.gradle中缺少对于google源服务器的配置(话说,貌似以前版本的都在jcenter中可以找到,最新版本的,好像没有上传到jcenter服务器了,估计是 ...
- c++类的创建与使用
c++类的创建与使用 前言: 之前一直对c++的类的创建与使用不太熟悉,有些概念还是有点模糊,借着这次休息的机会整理一下对应是知识点.如有不正确的地方还希望各位读者批评指正. 一.C++中public ...
- mybatis查询时间段
参考:https://bbs.csdn.net/topics/391838987 <!-- 查询条件:创建开始时间 --> <if test="createdBeginti ...
- nginx 安装部署前篇
官网:https://nginx.org/ 特性:既可以作为HTTP服务器,也可以作为反向代理服务器或者邮件服务器或者邮件服务器:能够快递响应静态页面的请求:支持 Fast CGI.SSL.Virtu ...
- Duilib自定义控件
新版博客已经搭建好了,有问题请访问 htt://www.crazydebug.com 在公司二期项目中为了将谷歌内核嵌入到duilib中,采用了自定义duilib控件的方法,由于也是第一次用duili ...
- Kubernetes 二进制部署(一)单节点部署(Master 与 Node 同一机器)
0. 前言 最近受“新冠肺炎”疫情影响,在家等着,入职暂时延后,在家里办公和学习 尝试通过源码编译二进制的方式在单一节点(Master 与 Node 部署在同一个机器上)上部署一个 k8s 环境,整理 ...
- 嵊州普及Day6T1
题意:有一个矩形,由正负整数构成.一个位子的魅力值为相邻的格子,若与邻格同号则减去绝对值,若异号则加上绝对值. 思路:一个格子一个格子计算即可,没什么好说的. 见代码: #include<ios ...
- 几道经典的SQL笔试题目
几道经典的SQL笔试题目(有答案) (1)表名:购物信息 购物人 商品名称 数量 A 甲 2 B 乙 ...