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

【JS】Object.defineProperty与Proxy

一、Object.defineProperty

这里只是简单描述,具体请看另一篇文章:Object.defineProperty。

Object.defineProperty 是 JavaScript 中用于定义或修改对象属性的功能强大的方法。它可以精确地控制属性的行为,如是否可枚举、可配置、可写等。

基本用法

Object.defineProperty(obj, prop, descriptor)

Object.defineProperty 方法接受三个参数:

  1. 『目标对象』:要在其上定义属性的对象。
  2. 『属性名称』:要定义或修改的属性名称。
  3. 『描述符对象』:属性描述符对象,用于描述该属性的行为。
    属性描述符对象可以包含以下键:
    value:属性的值。默认为 undefined。
    writable:属性是否可写。默认为 false。
    configurable:属性是否可配置。默认为 false。
    enumerable:属性是否可枚举。默认为 false。
    get:属性的 getter 函数。如果没有 getter,值为 undefined。
    set:属性的 setter 函数。如果没有 setter,值为 undefined。

用例

1. 定义一个只读属性

let obj = {};Object.defineProperty(obj, 'message', {value: 'Hello, world!',writable: false
});console.log(obj.message); // 输出 "Hello, world!"
obj.message = 'Hi!'; // 无效,因为属性是只读的
console.log(obj.message); // 仍然输出 "Hello, world!"

2. 定义一个不可枚举属性

let obj = {};Object.defineProperty(obj, 'message', {value: 'Hello, world!',enumerable: false
});console.log(obj.message); // 输出 "Hello, world!"
console.log(Object.keys(obj)); // 输出 [], 因为属性不可枚举

3. getter与setter

let obj = {};
let value = 'Hello, world!';Object.defineProperty(obj, 'message', {get() {return value;},set(newValue) {value = newValue;},enumerable: true,configurable: true
});console.log(obj.message); // 输出 "Hello, world!"
obj.message = 'Hi!';
console.log(obj.message); // 输出 "Hi!"

4. 定义不可配置属性

let obj = {};Object.defineProperty(obj, 'message', {value: 'Hello, world!',configurable: false
});console.log(obj.message); // 输出 "Hello, world!"Object.defineProperty(obj, 'message', {value: 'Hi!'
}); // 抛出错误,因为属性不可配置

二、Proxy

Proxy 是 ES6 引入的一项功能,用于定义自定义行为来拦截并改变对某个对象的基本操作(例如属性读取、赋值、枚举、函数调用等)。

基本语法

let proxy = new Proxy(target, handler);

Proxy 构造函数接受两个参数:

  1. target:要包装的目标对象(可以是任何类型的对象,包括数组、函数等)。
  2. handler:一个对象,其中包含一组捕捉器(traps)。这些捕捉器定义了在执行各种操作时,代理对象如何处理这些操作。
    捕捉器(Traps)包含:
    get(target, prop, receiver):拦截对象属性的读取。
    set(target, prop, value, receiver):拦截对象属性的设置。
    has(target, prop):拦截 in 操作符。
    deleteProperty(target, prop):拦截 delete 操作符。
    ownKeys(target):拦截 Object.getOwnPropertyNames 和 Object.getOwnPropertySymbols 方法。
    apply(target, thisArg, argumentsList):拦截函数调用。
    construct(target, args):拦截 new 操作符。

用例

1. 基本使用

let target = {message: "Hello, world!"
};let handler = {get(target, prop) {return prop in target ? target[prop] : `Property ${prop} does not exist.`;},set(target, prop, value) {console.log(`Setting ${prop} to ${value}`);target[prop] = value;return true;}
};let proxy = new Proxy(target, handler);console.log(proxy.message); // 输出 "Hello, world!"
console.log(proxy.nonExistent); // 输出 "Property nonExistent does not exist."
proxy.message = "Hi!"; // 输出 "Setting message to Hi!"

2. 拦截函数调用

let target = function() {return "I am the target";
};let handler = {apply(target, thisArg, argumentsList) {return "I am the proxy";}
};let proxy = new Proxy(target, handler);console.log(proxy()); // 输出 "I am the proxy"

3. 拦截属性删除

let target = {message: "Hello, world!"
};let handler = {deleteProperty(target, prop) {if (prop in target) {delete target[prop];console.log(`Property ${prop} deleted`);return true;} else {console.log(`Property ${prop} does not exist`);return false;}}
};let proxy = new Proxy(target, handler);delete proxy.message; // 输出 "Property message deleted"
delete proxy.nonExistent; // 输出 "Property nonExistent does not exist"

三、二者对比

代理的粒度不同

defineProperty 只能代理属性,Proxy 代理的是对象。
defineProperty 如果想代理对象的所有属性,需要遍历并为每个属性添加 setter 和 getter。
Proxy 只需要配置一个可以获取属性名参数的函数即可。

是否破坏原对象

defineProperty 的代理行为会破坏原对象,它会将原本的 value 变成了 setter 和 getter。
Proxy 则不会破坏原对象,只是在原对象上覆盖了一层。当新增属性时,希望属性被代理,defineProperty 需要显式调用该 API,而 Proxy 则可以直接用 obj.key = val的形式

Object.definePropertyProxy
拦截范围只能拦截对象的单个属性操作,即只能定义特定属性的getter和setter可以拦截对对象的所有操作,包括属性访问、赋值、删除、函数调用等,可以使用get、set、deleteProperty等捕捉器来拦截这些操作
动态属性不可以处理动态属性可以处理对象的动态添加和删除属性
是否破坏原对象
性能性能逊于Proxy对于处理嵌套对象和大量属性的情况,性能好
兼容性兼容性更好由于ES6中才引入Proxy,所以兼容性略差

四、与Vue2、Vue3的关系

vue2响应式数据原理是Object.defineProperty。

Vue3响应式数据原理是Proxy。

相关文章:

【JS】Object.defineProperty与Proxy

一、Object.defineProperty 这里只是简单描述,具体请看另一篇文章:Object.defineProperty。 Object.defineProperty 是 JavaScript 中用于定义或修改对象属性的功能强大的方法。它可以精确地控制属性的行为,如是否可枚举、可配置、可写等。…...

《计算机网络》(第8版)第8章 互联网上的音频/视频服务 复习笔记

第 8 章 互联网上的音频/视频服务 一、概述 1 多媒体信息的特点 多媒体信息(包括声音和图像信息)最主要的两个特点如下: (1)多媒体信息的信息量往往很大; (2)在传输多媒体数据时&a…...

linux进程控制——进程替换——exec函数接口

前言: 本节内容进入linux进程控制板块的最后一个知识点——进程替换。 通过本板块的学习, 我们了解了进程的基本控制方法——进程创建, 进程退出, 进程终止, 进程替换。 进程控制章节和上一节进程概念板块都是在谈进程…...

Apache解析漏洞~CVE-2017-15715漏洞分析

Apache解析漏洞 漏洞原理 # Apache HTTPD 支持一个文件拥有多个后缀,并为不同后缀执行不同的指令。比如如下配置文件: AddType text/html .html AddLanguage zh-CN .cn# 其给 .html 后缀增加了 media-type ,值为 text/html ;给 …...

Xilinx管脚验证流程及常见问题

1 流程 1.1 新建I/O Planning Project I/O Planning Project中可以不需要RTL的top层.v代码,仅图形化界面即可配置管脚约束XDC文件的生成: Create I/O Ports: 导出XDC文件和自动生成的top_interface.v文件: 1.2 新建test Project …...

格雷厄姆的《聪明的投资者》被誉为“投资圣经”

本杰明格雷厄姆的《聪明的投资者》(The Intelligent Investor: A Book of Practical Counsel)是投资领域的一部经典之作,被誉为“投资圣经”。以下是对该书的详细解析: 一、书籍基本信息 书名:《聪明的投资者》&…...

TypeScript声明文件

TypeScript声明文件 在JavaScript的生态系统中,随着项目的复杂度和规模不断增加,开发者对于类型安全和代码质量的追求也日益增长。TypeScript,作为JavaScript的一个超集,通过添加静态类型检查和ES6等新特性支持,极大地…...

.NET_WPF_使用Livecharts数据绑定图表

相关概念 LiveCharts 是一个开源的图表库,适用于多种 .NET 平台,包括 WPF、UWP、WinForms 等。LiveCharts 通过数据绑定与 MVVM 模式兼容,使得视图模型可以直接控制图表的显示,无需直接操作 UI 元素。这使得代码更加模块化&#x…...

一句JS代码,实现随机颜色的生成

今天我们只用 一句JS代码,实现随机颜色的生成,首先看一下效果: 每次刷新浏览器背景颜色都不一样 实现此效果的JS函数 : let randomColor () > ...: 定义一个箭头函数randomColor,用于生成一个随机颜色。 Math.ra…...

校园抢课助手【7】-抢课接口限流

在上一节中,该接口已经接受过风控的处理,过滤掉了机器人脚本请求,剩下都是人为的下单请求。为了防止用户短时间内高频率点击抢课链接,海量请求造成服务器过载,这里使用接口限流算法。 先介绍下几种常用的接口限流策略…...

char类型和int类型

一、char类型 在Java中,char(字符)类型用于表示单个字符,它是基本数据类型之一。以下是关于Java中char类型的一些重要信息: 表示方式: char类型用于存储Unicode字符,占用16位(即2个字…...

C++参悟:stl中的比较最大最小操作

stl中的比较最大最小操作 一、概述二、最小值1. min2. min_element 三、最大值1. max2. max_element 四、混合1. minmax2. minmax_element 一、概述 记录这里C11中常用的最小值和最大值的比较函数,最好的参考资料其实就是 https://zh.cppreference.com 最重要的查…...

JAVA读取netCdf文件并绘制热力图

读取netCdf的依赖 <dependency><groupId>ucar</groupId><artifactId>netcdfAll</artifactId><version>5.5.3</version><scope>system</scope><exclusions><exclusion><groupId>org.slf4j</groupId…...

数据结构——八大排序

一.排序的概念和其应用 1.1排序的概念 排序&#xff1a;排列或排序是将一组数据按照一定的规则或顺序重新组织的过程&#xff0c;数据既可以被组织成递增顺序&#xff08;升序&#xff09;&#xff0c;或者递减顺序&#xff08;降序&#xff09;。稳定性&#xff1a;假定在待…...

【Unity】RPG2D龙城纷争(十九)流程与UI界面(终章)

更新日期:2024年8月1日。 项目源码:第五章发布(正式开始游戏逻辑的章节) 索引 简介一、游戏流程1.初始化流程2.开始流程3.关卡流程4.关卡结束流程5.启用所有流程二、UI界面逻辑1.开始界面2.存档界面3.关卡界面DataRegion 数据显示逻辑区域RoundRegion 回合逻辑区域RoleMenu…...

C#类和结构体的区别

1、类class是引用类型&#xff0c;多个引用类型变量的值会互相影响。存储在堆&#xff08;heap&#xff09;上 2、结构体struct是值类型&#xff0c;多个值类型变量的值不会互相影响。存储在栈&#xff08;stack&#xff09;上 类结构关键字classstruct类型引用类型值类型存储…...

【RabbitMQ】RabbitMQ持久化

一、简介 RabbitMQ的持久化机制是一种确保数据在RabbitMQ服务重启或异常情况下不会丢失的重要特性。RabbitMQ的持久化主要包括三个方面的内容&#xff1a;交换器的持久化、队列的持久化、消息的持久化。 二、交换器的持久化 1、实现方式 在RabbitMQ中&#xff0c;实现交换器…...

算法刷题笔记 Kruskal算法求最小生成树(详细算法介绍,详细注释C++代码实现)

文章目录 题目描述基本思路实现代码 题目描述 给定一个n个点m条边的无向图&#xff0c;图中可能存在重边和自环&#xff0c;边权可能为负数。求最小生成树的树边权重之和&#xff0c;如果最小生成树不存在则输出impossible。 最小生成树的概念&#xff1a;给定一张边带权的无向…...

5年经验的软件测试人员,碰到这样的面试题居然会心虚......

我们这边最近的面试机会比较多&#xff0c;但是根据他们的反馈&#xff0c;结束后大部分都没音信了&#xff0c;因为现在企业面试问的非常多&#xff0c;范围非常广&#xff0c;而且开放性的问题很多&#xff0c;很多人即便面试前刷了成百上千道面试题&#xff0c;也很难碰到一…...

C#进阶-轻量级ORM框架Dapper的使用教程与原理详解

本文详细介绍了Dapper在C#中的使用方法&#xff0c;包括Dapper的基本概念、与其他持久层框架的比较、基本语法和高级语法的使用&#xff0c;并通过实例讲解了如何在项目中集成和使用Dapper。Dapper以其高效的性能和简洁的API受到开发者的青睐&#xff0c;适用于各种数据库操作需…...

NaViL-9B多模态能力详解:从API调用到温度参数优化的完整指南

NaViL-9B多模态能力详解&#xff1a;从API调用到温度参数优化的完整指南 1. 平台概述与核心能力 NaViL-9B是一款原生多模态大语言模型&#xff0c;由专业研究机构开发。它同时具备文本理解和图像分析能力&#xff0c;能够处理纯文本问答和图片内容理解任务。这种双模态能力使…...

MCP Server避坑指南:用Java写一个能连数据库、读文件的AI工具集

MCP Server避坑指南&#xff1a;用Java构建企业级AI工具链 在数字化转型浪潮中&#xff0c;企业积累的海量数据正成为AI应用的"金矿"。但如何让大语言模型安全访问这些分布在数据库、文件系统的"数据孤岛"&#xff1f;MCP协议为这个问题提供了优雅的解决方…...

戴森球计划FactoryBluePrints蓝图库:从新手到专家的终极工厂建设指南

戴森球计划FactoryBluePrints蓝图库&#xff1a;从新手到专家的终极工厂建设指南 【免费下载链接】FactoryBluePrints 游戏戴森球计划的**工厂**蓝图仓库 项目地址: https://gitcode.com/GitHub_Trending/fa/FactoryBluePrints FactoryBluePrints蓝图库是戴森球计划游戏…...

Goofys安全最佳实践:保护你的S3文件系统访问的终极指南

Goofys安全最佳实践&#xff1a;保护你的S3文件系统访问的终极指南 【免费下载链接】goofys a high-performance, POSIX-ish Amazon S3 file system written in Go 项目地址: https://gitcode.com/gh_mirrors/go/goofys 在当今云原生时代&#xff0c;安全访问云存储变得…...

智慧小区网络设计避坑指南:华为设备选型、无线覆盖与安全策略实战解析

智慧小区网络设计实战&#xff1a;华为设备选型与无线覆盖避坑指南 当接到智慧小区网络建设项目时&#xff0c;很多工程师会陷入理论完美主义陷阱——画出漂亮的拓扑图&#xff0c;却在实际部署中遭遇信号死角、设备过载、策略冲突等现实问题。本文将从三个真实项目复盘出发&am…...

数据库优化:高效查询GUID的技巧

在日常的数据库操作中,如何高效地查询数据是一个永恒的话题。特别是当我们处理大型数据集和需要在文本字段中查找特定模式(如GUID)时,查询效率显得尤为关键。今天,我将分享一种优化查询GUID的方法,帮助你从长达数小时的查询时间中解脱出来。 背景 假设我们有一个数据库…...

React Native Chart Kit 性能优化技巧:大数据量下的流畅图表渲染

React Native Chart Kit 性能优化技巧&#xff1a;大数据量下的流畅图表渲染 【免费下载链接】react-native-chart-kit &#x1f4ca;React Native Chart Kit: Line Chart, Bezier Line Chart, Progress Ring, Bar chart, Pie chart, Contribution graph (heatmap) 项目地址:…...

图解Linux内核DRM框架:从用户态ioctl到plane更新的完整数据流(以4.14版本为例)

图解Linux内核DRM框架&#xff1a;从用户态ioctl到plane更新的完整数据流&#xff08;以4.14版本为例&#xff09; 在图形显示技术领域&#xff0c;Linux内核的DRM&#xff08;Direct Rendering Manager&#xff09;框架扮演着核心角色。本文将聚焦于DRM_IOCTL_MODE_SETPLANE这…...

【大英赛】2009-2026年大英赛ABCD类历年真题、样卷、听力音频及答案PDF电子版

2026年大英赛将于4月12日9:00—11:00举行&#xff0c;开始倒计时啦&#xff01;小编整理了最新的2009-2026年大学生英语竞赛&#xff08;大英赛NECCS&#xff09;ABCD类历年真题、样卷、听力音频及答案解析&#xff0c;PDF电子版&#xff0c;可下载打印&#xff01; 资料下载&a…...

如何用Obsidian Image Converter实现图像高效管理?超实用技巧分享

如何用Obsidian Image Converter实现图像高效管理&#xff1f;超实用技巧分享 【免费下载链接】obsidian-image-converter ⚡️ Convert, compress, resize, annotate, markup, draw, crop, rotate, flip, align images directly in Obsidian. Drag-resize, rename with variab…...