【JS】JavaScript编程语言-(Object)对象属性标志与对象属性描述符(2024-06-05)

我们知道,对象可以存储属性。

到目前为止,属性对我们来说只是一个简单的“键值”对。但对象属性实际上是更灵活且更强大的东西:其他配置选项。


1、属性标志

对象属性(properties),除 value 外,还有三个特殊的特性(attributes),也就是所谓的“标志”:

writable — 如果为 true,则值可以被修改,否则它是只可读的。
enumerable — 如果为 true,则会被在循环中列出,否则不会被列出。
configurable — 如果为 true,则此属性可以被删除,这些特性也可以被修改,否则不可以。


我们到现在还没看到它们,是因为它们通常不会出现。当我们用“常用的方式”创建一个属性时,它们都为 true。但我们也可以随时更改它们。

首先,让我们来看看如何获得这些标志。

Object.getOwnPropertyDescriptor 方法允许查询有关属性的 完整 信息。

语法是:

let descriptor = Object.getOwnPropertyDescriptor(obj, propertyName);

obj

需要从中获取信息的对象。

propertyName

属性的名称。

返回值是一个所谓的“属性描述符”对象:它包含值和所有的标志。

例如:

let user = {name: "John"
};let descriptor = Object.getOwnPropertyDescriptor(user, 'name');alert( JSON.stringify(descriptor, null, 2 ) );
/* 属性描述符:
{"value": "John","writable": true,"enumerable": true,"configurable": true
}
*/

为了修改标志,我们可以使用 Object.defineProperty。

语法是:

Object.defineProperty(obj, propertyName, descriptor)

objpropertyName

要应用描述符的对象及其属性。

descriptor

要应用的属性描述符对象。

如果该属性存在,defineProperty 会更新其标志。否则,它会使用给定的值和标志创建属性;在这种情况下,如果没有提供标志,则会假定它是 false

例如,这里创建了一个属性 name,该属性的所有标志都为 false

let user = {};Object.defineProperty(user, "name", {value: "John"
});let descriptor = Object.getOwnPropertyDescriptor(user, 'name');alert( JSON.stringify(descriptor, null, 2 ) );
/*
{"value": "John","writable": false,"enumerable": false,"configurable": false
}*/

将它与上面的“以常用方式创建的” user.name 进行比较:现在所有标志都为 false。如果这不是我们想要的,那么我们最好在 descriptor 中将它们设置为 true

现在让我们通过示例来看看标志的影响。


2、只读

让我们通过更改 writable 标志来把 user.name 设置为只读(user.name 不能被重新赋值):

let user = {name: "John"
};Object.defineProperty(user, "name", {writable: false
});user.name = "Pete"; // Error: Cannot assign to read only property 'name'

现在没有人可以改变我们 user 的 name,除非它们应用自己的 defineProperty 来覆盖我们的 user 的 name

只在严格模式下会出现 Errors

在非严格模式下,在对不可写的属性等进行写入操作时,不会出现错误。但是操作仍然不会成功。在非严格模式下,违反标志的行为(flag-violating action)只会被默默地忽略掉。

这是相同的示例,但针对的是属性不存在的情况:

let user = { };Object.defineProperty(user, "name", {value: "John",// 对于新属性,我们需要明确地列出哪些是 trueenumerable: true,configurable: true
});alert(user.name); // John
user.name = "Pete"; // Error

3、不可枚举

现在让我们向 user 添加一个自定义的 toString

通常,对象中内建的 toString 是不可枚举的,它不会显示在 for..in 中。但是如果我们添加我们自己的 toString,那么默认情况下它将显示在 for..in 中,如下所示:

let user = {name: "John",toString() {return this.name;}
};// 默认情况下,我们的两个属性都会被列出:
for (let key in user) alert(key); // name, toString

如果我们不喜欢它,那么我们可以设置 enumerable:false。之后它就不会出现在 for..in 循环中了,就像内建的 toString 一样:

let user = {name: "John",toString() {return this.name;}
};Object.defineProperty(user, "toString", {enumerable: false
});// 现在我们的 toString 消失了:
for (let key in user) alert(key); // name

不可枚举的属性也会被 Object.keys 排除:

alert(Object.keys(user)); // name

4、不可配置

不可配置标志(configurable:false)有时会预设在内建对象和属性中。

不可配置的属性不能被删除,它的特性(attribute)不能被修改。

例如,Math.PI 是只读的、不可枚举和不可配置的:

let descriptor = Object.getOwnPropertyDescriptor(Math, 'PI');alert( JSON.stringify(descriptor, null, 2 ) );
/*
{"value": 3.141592653589793,"writable": false,"enumerable": false,"configurable": false
}
*/

因此,开发人员无法修改 Math.PI 的值或覆盖它。

Math.PI = 3; // Error,因为其 writable: false// 删除 Math.PI 也不会起作用

我们也无法将 Math.PI 改为 writable

// Error,因为 configurable: false
Object.defineProperty(Math, "PI", { writable: true });

我们对 Math.PI 什么也做不了。

使属性变成不可配置是一条单行道。我们无法通过 defineProperty 再把它改回来。

请注意:configurable: false 防止更改和删除属性标志,但是允许更改对象的值。

这里的 user.name 是不可配置的,但是我们仍然可以更改它,因为它是可写的:

let user = {name: "John"
};Object.defineProperty(user, "name", {configurable: false
});user.name = "Pete"; // 正常工作
delete user.name; // Error

现在,我们将 user.name 设置为一个“永不可改”的常量,就像内建的 Math.PI

let user = {name: "John"
};Object.defineProperty(user, "name", {writable: false,configurable: false
});// 不能修改 user.name 或它的标志
// 下面的所有操作都不起作用:
user.name = "Pete";
delete user.name;
Object.defineProperty(user, "name", { value: "Pete" });

唯一可行的特性更改:writable true → false

对于更改标志,有一个小例外。

对于不可配置的属性,我们可以将 writable: true 更改为 false,从而防止其值被修改(以添加另一层保护)。但无法反向行之。


5、Object.defineProperties

有一个方法Object.defineProperties(obj,descriptors),允许一次定义多个属性。

语法是:

Object.defineProperties(obj, {prop1: descriptor1,prop2: descriptor2// ...
});

例如:

Object.defineProperties(user, {name: { value: "John", writable: false },surname: { value: "Smith", writable: false },// ...
});

所以,我们可以一次性设置多个属性。


6、Object.getOwnPropertyDescriptors

要一次获取所有属性描述符,我们可以使用 Object.getOwnPropertyDescriptors(obj) 方法。

它与 Object.defineProperties 一起可以用作克隆对象的“标志感知”方式:

let clone = Object.defineProperties({}, Object.getOwnPropertyDescriptors(obj));

通常,当我们克隆一个对象时,我们使用赋值的方式来复制属性,像这样:

for (let key in user) {clone[key] = user[key]
}

但是,这并不能复制标志。所以如果我们想要一个“更好”的克隆,那么 Object.defineProperties 是首选。

另一个区别是 for..in 会忽略 symbol 类型的和不可枚举的属性,但是 Object.getOwnPropertyDescriptors 返回包含 symbol 类型的和不可枚举的属性在内的 所有 属性描述符。


7、设定一个全局的密封对象

属性描述符在单个属性的级别上工作。 还有一些限制访问 整个 对象的方法:

Object.preventExtensions(obj)禁止向对象添加新属性。

Object.seal(obj)禁止添加/删除属性。为所有现有的属性设置 configurable: false。

Object.freeze(obj)禁止添加/删除/更改属性。为所有现有的属性设置 configurable: false, writable: false。

还有针对它们的测试:

Object.isExtensible(obj)如果添加属性被禁止,则返回 false,否则返回 true。

Object.isSealed(obj)如果添加/删除属性被禁止,并且所有现有的属性都具有 configurable: false则返回 true。

Object.isFrozen(obj)如果添加/删除/更改属性被禁止,并且所有当前属性都是 configurable: false, writable: false,则返回 true。

这些方法在实际中很少使用。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/23271.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nvidia Jetson/Orin +FPGA+AI大算力边缘计算盒子:无人机自主飞行软件平台

案例简介 北京泛化智能科技有限公司(gi)所主导开发的 Generalized Autonomy Aviation System (GAAS) 是为无人机以及城市空中交通 (UAM, Urban Air Mobility) 所设计的开源无人机自主飞行框架。通过 SLAM、路径规划和 Global Optimization Graph 等功能…

【Linux】(三)—— 文件管理和软件安装

文件管理 Linux的文件管理是系统管理中的核心部分,它涉及到如何组织、访问、修改和保护文件及目录结构。 目录 文件管理基本概念常用命令查看和切换目录创建文件和目录删除文件和目录文件拷贝移动和重命名文件文件查看cat文件查看more查找文件查找文本 数据流和管道…

redsystems教程的基本使用之重置密码(忘记密码解决方法)

前言: 相信很多人都有疑惑,要是我不记得密码怎么办?如果你登录了,点击更改密码后,还是要你填写登录密码才能修改。为了解决这问题,博主通过了钻研成功搞出来了!!!&#…

DS:数与二叉树的相关概念

欢迎来到Harper.Lee的学习世界!博主主页传送门:Harper.Lee的博客主页想要一起进步的uu可以来后台找我哦! 一、树的概念及其结构 1.1 树的概念亲缘关系 树是一种非线性的数据结构,它是由n(n>0)个有限节点…

Marvelous Designer中一些棉质布料预设

Marvelous Designer中一些棉质布料预设的解释: Cotton_14_Wale_Corduroy:14条细鲸鱼纹的灯芯绒,适合制作温暖且有质感的服装。Cotton_40s_Chambray:40支精梳针织的府绸布,通常用于制作休闲衬衫。Cotton_40s_Poplin&am…

Nginx目录文件

Nginx目录文件 在 Nginx 的安装目录下,你可能会看到许多文件夹和文件。以下是对各个文件夹和文件的简要解释: conf.d: 这个文件夹通常用于存放额外的配置文件。Nginx 在启动时,会读取该文件夹下的所有配置文件,并将其内容合并到…

Face Forgery Detection by 3D Decomposition

文章目录 Face Forgery Detection by 3D Decomposition研究背景研究目标创新点方法提出问题研究过程技术贡献实验结果未来工作Face Forgery Detection by 3D Decomposition 会议:CVPR2021 作者: 研究背景 面部伪造引发关注传统面部伪造检测主要关注原始RGB图像

邮箱地址验证软件

邮箱地址验证软件是一种用于检测邮箱地址是否真实存在、有效和可送达的工具。这些软件通常服务于邮件营销、客户数据清洗或研究领域,以帮助用户提高邮件发送的成功率并减少 bounce rate(退回率)。易邮地址验证软件就是这么一款软件。 易邮件…

学Python,看一篇就够

学Python,看一篇就够 python基础注释变量标识符命名规则使用变量认识bugDebug工具打断点 数据类型输出转义字符输入输入语法输入的特点 转换数据类型pycharm交互运算符的分类赋值运算符复合赋值运算符比较运算符逻辑运算符拓展 条件语句单分支语法多分支语法拓展 if…

XFF注入【墨者靶场】

目录 XFF介绍 靶场练习 最近在复习XFF注入,这里使用墨者靶场来简单的练习一下该漏洞的利用方法 XFF介绍 X-Forwarded-For:简称XFF头,代表了HTTP的请求端真实的IP。 它被认为是客户端通过HTTP代理或者负载均衡器连接到web服务端获取源ip地…

植物大战僵尸杂交版2.0.88最新版安装包

游戏简介 游戏中独特的杂交植物更是为游戏增添了不少亮点。这些杂交植物不仅外观独特,而且拥有更强大的能力,能够帮助玩家更好地应对游戏中的挑战。玩家可以通过一定的条件和方式,解锁并培养这些杂交植物,从而不断提升自己的战斗…

http和websocket区别

HTTP和WebSocket在多个方面存在显著的区别: 1. 通信方式:HTTP协议是一种基于请求-响应模式的通信方式,客户端发送请求,服务器响应请求。这种通信方式相对简单直观,但它是单向的,即每次通信都是由客户端发起…

市政环境卫生乙级资质申请:费用详解与预算

市政环境卫生乙级资质申请的费用详解与预算如下: 一、基本成本 注册资本:根据规定,申请市政环境卫生乙级资质的企业需具备独立法人资格,且注册资本不少于100万元人民币。 二、行政与申报费用 行政性收费:向住房和城…

打开C# 大门:Hallo, World!

C# 介绍 C#(C Sharp)是一种面向对象的编程语言,由微软公司开发。它是 .NET Framework 的一部分,用于构建 Windows 应用程序、Web 应用程序、移动应用程序等。C# 语言的设计目标是简单、现代化、易于学习和使用。在本文中&#xf…

量化交易:Miniqmt获取可转债数据和交易python代码

哈喽,大家好,我是木头左! 低风险资产除了国债外,还有可转债,兼容有高收益的股性和低风险的债性,号称“下有保底,上不封顶”。 🔍 可转债:金融市场的双面娇娃 可转债&am…

使用C++版本的opencv dnn 部署onnx模型

使用OpenCV的DNN模块在C中部署ONNX模型涉及几个步骤&#xff0c;包括加载模型、预处理输入数据、进行推理以及处理输出。 构建了yolo类&#xff0c;方便调用 yolo.h 文件 #ifndef YOLO_H #define YOLO_H #include <fstream> #include <sstream> #include <io…

python篮球队员招募 2024年3月青少年编程电子学会python编程等级考试二级真题解析

目录 python篮球队员招募 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序代码 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python篮球队员招募 2024年3月 python编程等级考试级编程题 一、题目…

apsw,一个超强的 Python 库!

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个超强的 Python 库 - apsw。 Github地址&#xff1a;https://github.com/rogerbinns/apsw 在现代应用开发中&#xff0c;数据库是一个非常重要的组成部分。SQLite 是一个轻量级的嵌入式关系数据…

斯坦福AI团队抄袭事件,清华回应:也算国际认可

近日&#xff0c;斯坦福大学人工智能&#xff08;AI&#xff09;团队的一项备受瞩目的研究——Llama3-V大模型&#xff0c;陷入了抄袭风波。该团队原本以其创新的模型和低廉的训练成本为亮点&#xff0c;声称能够在低成本下训练出性能卓越的SOTA多模态大模型。然而&#xff0c;…

Redis实战篇——搭建主从复制

Redis实战篇——搭建主从复制 1.Redis主从1.1.主从集群结构1.2.搭建主从集群1.2.1.启动多个Redis实例1.2.2.建立集群1.2.3.测试 1.Redis主从 单节点Redis的并发能力是有上限的&#xff0c;要进一步提高Redis的并发能力&#xff0c;就需要搭建主从集群&#xff0c;实现读写分离…