当前位置: 首页 > news >正文

深入理解 JavaScript 对象、属性、解构和增强语法

ECMA-262将对象定义为一组属性的无序集合

1 内部属性描述

1.1 数据属性

  • [[Configurable]]:可配置性,直接定义在对象的属性该特性默认为true,表示可以对属性进行删除、修改等操作。
  • [[Enumerable]]:可枚举性,直接定义在对象的属性该特性默认为true,它决定了我们是否可以通过for-in循环遍历对象的属性。
  • [[Writable]]:可写性,直接定义在对象的属性该特性默认为true,表示属性的值是否可以被修改。
  • [[Value]]:属性的实际数据值,默认为undefined。

我们可以使用Object.defineProperty来定义数据属性。

let student1 = { name: "student1" };
Object.defineProperty(student1, "sex", {configurable: false,enumerable: false,writable: false,value: "male",
});
//测试可配置性
delete student1.sex;
console.log(student1.sex);
console.log();
//测试可枚举性
for (const key in student1) {console.log(key + " ");
}
console.log();
//测试可写性
student1.sex = "female";
console.log(student1.sex);

输出:

malenamemale

除了属性configurable属性为false的情况,我们可以多次调用defineProperty

如果调用了defineProperty但不指定configurable、enumerable、writable的值,则它们默认被设为false

1.2 访问器属性

  • [[Configurable]]:表示属性是否可修改。直接定义在对象的属性该特性默认为true。
  • [[Enumberable]]:表示属性是否可枚举。直接定义在对象的属性该特性默认为true。
  • [[Get]]:获取属性时调用的函数。默认为undefined。
  • [[Set]]:设置属性时调用的函数。默认为undefined。

同样我们使用Object.defineProperty来定义访问器属性。

let person = {firstName: "John",lastName: "Doe",
};
Object.defineProperty(person, 'fullName', {get() {return this.firstName + " " + this.lastName;},set(value) {const parts = value.split(" ");this.firstName = parts[0];this.lastName = parts[1];}
});
console.log(person.fullName);
person.fullName = "Jane Smith";
console.log(person.firstName);
console.log(person.lastName);

输出:

John Doe
Jane
Smith

访问器属性和数据属性的不同之处在于:

数据属性关注于数据的值与可写性,访问器属性关注获取和设置数据时进行的操作

2 定义多个属性

可以使用Object.defineProperties一次性定义多个属性。

let person={};
Object.defineProperties(person,{name:{value: 'Jane'},age:{get(){return this.age;},set(value){this.age=value;}}
});

3 读取属性特性

使用Object.getOwnPropertyDescriptor读取属性的属性描述符。

使用上面一节中定义好的person对象。

let descriptor1=Object.getOwnPropertyDescriptor(person,'name');
console.log('descriptor1.configurable:'+descriptor1.configurable);
console.log('descriptor1.enumerable:'+descriptor1.enumerable);
console.log('descriptor1.writable:'+descriptor1.writable);
console.log('descriptor1.value:'+descriptor1.value);
let descriptor2=Object.getOwnPropertyDescriptor(person,'age');
console.log('descriptor2.configurable:'+descriptor2.configurable);
console.log('descriptor2.enumerable:'+descriptor2.enumerable);
console.log('descriptor2.get:'+descriptor2.get);
console.log('descriptor2.set:'+descriptor2.set);

运行结果:

descriptor1.configurable:false
descriptor1.enumerable:false
descriptor1.writable:false
descriptor1.value:Jane
descriptor2.configurable:false
descriptor2.enumerable:false
descriptor2.get:get() {return this.age;}
descriptor2.set:set(value) {this.age = value;}

注意到没有设置的configurable、enumerable、writable都被设置为false。

4 合并对象

合并对象即将一个对象的属性复制到目标对象上,这也被称为混入(mixin)。学过Vue的知道,Vue里面也有个混入的概念,Vue2 混入。

ES6提供Object.assign()方法来合并对象。

该方法将一个或多个源对象的可枚举和自有属性复制到目标对象上。

  • 可枚举判断:Object.propertyIsEnumerable()
  • 自有属性判断:Object.hasOwnProperty()

复制的具体操作是调用源对象的get获取属性,再调用目标对象的set属性

const target = {_a:'',// set a(val) {//     console.log("调用target属性a的set");//     this._a = val;// }
};
Object.defineProperty(target, 'a', {set(val) {console.log('调用target属性a的set');this._a = val;},
});
const source1 = {// get a() {//     console.log("调用source1属性a的get");//     return "a";// }
};
Object.defineProperty(source1, "a", {get() {console.log("调用source1属性a的get");return "a";},enumerable: true
});
const source2 = { b: 'b' };
Object.assign(target, source1, source2);
console.log(target);

在字面中定义的属性的未设置的数据属性和访问器属性都为默认值,而在Object.defineProperty中定义的属性的未设置的特性要么为false,要么为undefined。

上面我们给source1的访问器属性a设置enumerable: true就是这个原因,不然无法复制a属性。

运行结果:

调用source1属性a的get
调用target属性a的set
{ _a: 'a', b: 'b' }

Object.assign还有以下注意的地方:

  1. 同名的属性,后面的会覆盖前面的

  2. Object.assign是浅复制,即只复制对象内部元素的引用

    const originalObject={a:1}
    const anotherShallowCopy = Object.assign({}, originalObject);
    console.log(anotherShallowCopy === originalObject);//false
    console.log(anotherShallowCopy.a === originalObject.a);//true
    
  3. 在复制过程出现错误,Object.assign不会回滚到初始状态

5 严格相等判断

大多数情况我们可以使用===来判断严格相等,但以下的特殊边界情况却不尽人意:

console.log(+0 === -0); //true
console.log(+0 === 0); //true
console.log(-0 === 0); //true
console.log(NaN === NaN); //false

其中NaN表示Not a Number,可以使用全局函数isNaN检查。

ES6提供了Object.is来应对上述所有情况。

Object.is(v1,v2);

使用递归+Object.is+剩余参数比较多个值的相等性:

function areValuesEqual(a,...values){return Object.is(a,values[0])&&(values.length<2||areValuesEqual(...values));
}

或者使用every:

function areValuesEqual(a, ...values) {return values.every(value => Object.is(a, value));
}

6 增强的对象语法

6.1 属性值的简写

const name = "John";
const age = 30;// 使用属性值简写创建对象
const person = {name,age,sayHello() {console.log(`Hello, my name is ${this.name}.`);}
};console.log(person); // 输出 { name: 'John', age: 30 }
person.sayHello(); // 输出 "Hello, my name is John."

6.2 可计算属性

可计算属性允许你在定义对象时在方括号内使用表达式来定义对象名。

const methodSuffix = "Hello";const dynamicObject = {["say" + methodSuffix]() {console.log("Hello, World!");}
};dynamicObject.sayHello(); // 输出 "Hello, World!"

6.3 简写属性名

let key='Age';
let person={_name: 'Jane',_age: '18',get name(){return this._name;},set name(val){this._name=val;},sayHello() {console.log(`Hello, my name is ${this._name}.`);},['say'+key](){console.log(`Hello, my age is ${this._age}.`);}
};

7 对象解构

对象解构指可以使用与对象匹配的结构来实现对象属性赋值。

let person={name: 'Jane',age: 18
};
//别名
let {name:personName,age:personAge}=person;
//属性简写
let {name,age}=person;
//没有匹配的属性被赋值为undefined
let {name,age,height}=person;
//解构时赋值
let {name,age,height=180}=person;

解构的本质是使用ToObject函数将元数据转为对象。

因此,null和undefined不能被解构。

如果给事先声明好的变量赋值,则解构表达式整个需要包裹在一对括号里

1)嵌套解构

let {outer:{inter}}=obj;

2)部分解构

解构像我们的对象合并一样,是尽力而为的行为,一旦解构过程发生错误,过程终止且无法回滚,也就是只解构了部分。

3)对象解构为函数参数

function sum([a, b]) {return a + b;
}const numbers = [3, 5];console.log(sum(numbers)); // 输出 8

相关文章:

深入理解 JavaScript 对象、属性、解构和增强语法

ECMA-262将对象定义为一组属性的无序集合。 1 内部属性描述 1.1 数据属性 [[Configurable]]&#xff1a;可配置性&#xff0c;直接定义在对象的属性该特性默认为true&#xff0c;表示可以对属性进行删除、修改等操作。[[Enumerable]]&#xff1a;可枚举性&#xff0c;直接定…...

2023年IT服务行业研究报告

第一章 行业概况 1.1 定义 IT服务行业是一个广泛的术语&#xff0c;涵盖了所有提供技术支持和服务的公司。这些服务包括系统集成&#xff0c;云计算服务&#xff0c;软件和硬件支持&#xff0c;网络服务&#xff0c;咨询服务&#xff0c;以及一系列其他类型的技术服务。此外&…...

腾讯云服务器镜像TencentOS Server有用过的吗?

腾讯云服务器镜像TencentOS Server操作系统有用过的吗&#xff1f;踩过坑吗&#xff1f;TencentOS性能和稳定性如何&#xff1f;TencentOS Server与CentOS保持兼容&#xff0c;在稳定性、性能、容器基础设施等核心能力方面做了全面的增强和优化&#xff0c;能为企业提供稳定高可…...

小区村庄集中生活废水处理设备厂家直销价格

小区村庄集中生活废水处理设备厂家直销价格 设备的构造 1、填料 该填料选用特制塑料和树脂组成&#xff0c;结构科学、新颖、填料比表面积达1000m2/m3&#xff0c;比重轻0.97g/cm3&#xff0c;不堵塞、易挂膜。 该填料是由纤细球体&#xff0c;网络外壳和通心多孔柱体组成的球形…...

Redisson实现分布式锁案例

Redisson实现分布式锁案例 引入依赖 <dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.23.2</version> </dependency>创建Redisson配置类 Configuration pub…...

Generated Knowledge Prompting for Commonsense Reasoning

本文是知识图谱系列相关的文章&#xff0c;针对《Generated Knowledge Prompting for Commonsense Reasoning》的翻译。 常识推理的生成知识提示 摘要1 引言2 生成知识提示3 实验设置4 实验结果5 相关工作6 结论 摘要 结合外部知识是否有利于常识推理&#xff0c;同时保持预训…...

mybatisPlus多数据源方案

背景 在微服务李娜一般一个服务只有一个数据源&#xff0c;但是在有的老项目或者一些特定场景需要多数据源链接不同的数据库&#xff0c;本文以mybatisPlus为基础给出解决方案 多数据源场景分类 情形一&#xff1a;项目启动就确定了情形一&#xff1a;一些sass系统里面动态确…...

MonoDETR: Depth-guided Transformer for Monocular 3D Object Detection 论文解读

MonoDETR论文解读 abstract 单目目标检测在自动驾驶领域&#xff0c;一直是一个具有挑战的任务。现在大部分的方式都是沿用基于卷积的2D 检测器&#xff0c;首先检测物体中心&#xff0c;后通过中心附近的特征去预测3D属性。 但是仅仅通过局部的特征去预测3D特征是不高效的&…...

Vulnhub内网渗透DC-7靶场通关

个人博客: xzajyjs.cn DC系列共9个靶场&#xff0c;本次来试玩一下一个 DC-7&#xff0c;下载地址。 下载下来后是 .ova 格式&#xff0c;建议使用vitualbox进行搭建&#xff0c;vmware可能存在兼容性问题。靶场推荐使用NAT(共享)模式&#xff0c;桥接模式可能会造成目标过多不…...

acunetix2023安装教程

1、解压之后一键安装exe文件 2、将解压出来的Awv2023.6[Windows]文件夹下的wvsc.exe文件放置于AWVS安装目录&#xff0c;与原文件进行替换&#xff0c;如图所示。&#xff08;注&#xff1a;如果是默认安装&#xff0c;则文件位置位于C:\Program Files (x86)\Acunetix\14.2.210…...

pytest pytest.ini 配置日志输出至文件

创建pytest.ini 文件 [pytest] log_file pytest_log.txt log_file_level INFO log_file_date_format %Y-%m-%d %H:%M:%S log_file_format %(asctime)s | %(filename)s | %(funcName)s | line:%(lineno)d | %(levelname)s | %(message)s import pytest import loggingdef …...

Linux脚本-将当前文件夹下所有包含main函数的.c文件提取出来

实现一个Linux脚本&#xff0c;该脚本使用 for 循环遍历当前目录下的所有 .c 文件。 对于每个 .c 文件&#xff0c;使用 grep 命令来查找是否包含字符串 “main”。 如果该 .c 文件包含 “main”&#xff0c;则输出到/home/majn/llvm_project/extract_main目录下。 #!/bin/bas…...

Spring依赖注入(DI)

目录 构造器注入 set注入 拓展注入 bean的作用域 Singleton Prototype Dependency Injection 依赖 : 指Bean对象的创建依赖于容器 . Bean对象的依赖资源 . 注入 : 指Bean对象所依赖的资源 , 由容器来设置和装配 . 构造器注入 具体实现&#xff1a;SpringIOC创建对象的…...

论文笔记: 深度学习速度模型构建的层次迁移学习方法 (未完)

摘要: 分享对论文的理解, 原文见 Jrome Simon, Gabriel Fabien-Ouellet, Erwan Gloaguen, and Ishan Khurjekar, Hierarchical transfer learning for deep learning velocity model building, Geophysics, 2003, R79–R93. 这次的层次迁移应该指从 1D 到 2D 再到 3D. 摘要 深…...

苹果为 Vision Pro 头显申请游戏手柄专利

苹果Vision Pro 推出后&#xff0c;美国专利局公布了两项苹果公司申请的游戏手柄专利&#xff0c;其中一项的专利图如下图所示。据 PatentlyApple 报道&#xff0c;虽然申请专利并不能保证苹果公司会推出游戏手柄&#xff0c;但是苹果公司同时也为游戏手柄申请了商标&#xff0…...

【数据结构】多叉树转换为二叉树-c++代码实现-POJ 3437 Tree Grafting

文章目录 写这个题目的原因寻找提交网址题目解决思路AC代码成功AC 写这个题目的原因 1、今天在看王道考研数据结构的课&#xff08;虽然我要保研&#xff0c;但是因为这些看保研面试的时候会问&#xff0c;所以看一下嘞orz&#xff09;&#xff0c;看到了这个多叉树转换为二叉…...

ASP.NET Core 中基于 Controller 的 Web API

基于 Controller 的 Web API ASP.NET Wep API 的请求架构 客户端发送Http请求&#xff0c;Contoller响应请求&#xff0c;并从数据库读取数据&#xff0c;序列化数据&#xff0c;然后通过 Http Response返回序列化的数据。 ControllerBase 类 Web API 的所有controllers 一般…...

iOS系统修复软件 Fix My iPhone for Mac

Fix My iPhone for Mac是一款iOS系统恢复工具。修复您的iPhone卡在Apple徽标&#xff0c;黑屏&#xff0c;冻结屏幕&#xff0c;iTunes更新/还原错误和超过20个iOS 12升级失败。这个macOS桌面应用程序提供快速&#xff0c;即时的解决方案来修复您的iOS系统问题&#xff0c;而不…...

Git企业开发控制理论和实操-从入门到深入(七)|企业级开发模型

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量博客汇总 然后就是博主最近最花时间的一个专栏…...

15. 卡牌游戏

目录 题目 思路 C整体代码&#xff08;含详细注释&#xff09; 题目 Description 小张在玩一种卡牌游戏&#xff0c;牌组由张牌组成&#xff0c;其中张上写有数字各一张&#xff0c;其余张上全部是数字。 现在牌组经过随机打乱后&#xff0c;小张拿走其中张牌作为手牌&#…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官

。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量&#xff1a;setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !

我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...

Linux部署私有文件管理系统MinIO

最近需要用到一个文件管理服务&#xff0c;但是又不想花钱&#xff0c;所以就想着自己搭建一个&#xff0c;刚好我们用的一个开源框架已经集成了MinIO&#xff0c;所以就选了这个 我这边对文件服务性能要求不是太高&#xff0c;单机版就可以 安装非常简单&#xff0c;几个命令就…...