当前位置: 首页 > 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;适用于各种数据库操作需…...

Windows图形界面(GUI)-MFC-C/C++ - 编辑框(Edit Control) - CEdit

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 编辑框(Edit Control) - CEdit 基本概念 成员函数 示例代码 编辑框(Edit Control) - CEdit 基本概念 编辑框&#xff08;Edit Control&#xff09;是一个允许用户输入和编辑文本的窗…...

网络安全防御【IPsec VPN搭建】

目录 一、实验拓扑图 二、实验要求 三、实验思路 四、实验步骤&#xff1a; 修改双机热备的为主备模式&#xff1a; 2、配置交换机LSW6新增的配置&#xff1a; 3、防火墙&#xff08;FW4&#xff09;做相关的基础配置&#xff1a; 4、搭建IPsec VPN通道 &#xff08;1…...

java环境配置与tomcat的配置

1、java环境配置 一、JDK下载 访问Oracle官网&#xff1a; 前往Oracle官网&#xff08;Oracle | Cloud Applications and Cloud Platform&#xff09;&#xff0c;在首页的顶部菜单中选择“Resources” > “Downloads” > “Java” > “JDK”。注意&#xff1a;Orac…...

OD C卷 - 来自异国的客人/幸运数字

来自异国的客人/幸运数字&#xff08;100&#xff09; 输入描述&#xff1a; 输入k,n,m k表示物品价值&#xff08;十进制&#xff09; k>0 n表示幸运数字, n > 0 m表示异国采用的进制&#xff1b;m > 1 n < m 输出描述&#xff1a; 输出幸运数字的个数&#xff0…...

C++ | 动态内存管理 new、delete (用法、底层)详解

目录 简单回顾C语言动态内存管理 new、delete的用法 内置类型 new delete 自定义类型 new、delete底层讲解&#xff08;重要&#xff09; operator new 与 operator delete 定位 new 结语 简单回顾C语言动态内存管理 在C语言的学习阶段 我们接触到了三个能在堆上开辟…...

【C语言】结构体内存布局解析——字节对齐

&#x1f984;个人主页:小米里的大麦-CSDN博客 &#x1f38f;所属专栏:https://blog.csdn.net/huangcancan666/category_12718530.html &#x1f381;代码托管:黄灿灿 (huang-cancan-xbc) - Gitee.com ⚙️操作环境:Visual Studio 2022 目录 一、引言 二、什么是字节对齐&…...

模型表达方式

目录 一、模型表达概述 二、模型精确表达 2.1 几何表示 (Geometrical Representation) 三、模型非精确表达 3.1 网格表示 (Mesh Representation) 3.2 体素表示 (Voxel Representation) 一、模型表达概述 模型的表达方式多种多样,选择适合的表达方式取决于具体应用场景和…...

校园课程助手【4】-使用Elasticsearch实现课程检索

本节将介绍本项目的查询模块&#xff0c;使用Elasticsearch又不是查询接口&#xff0c;具体流程如图所示&#xff08;如果不了解Elasticsearch可以使用sql语句进行查询&#xff09;&#xff1a; 这里是两种方法的异同点&#xff1a; Mysql&#xff1a;擅长事务类型操作&#…...

经典运维面试题

1、Linux常见的日志文件都有哪些&#xff0c;各自的用途&#xff1f;日志轮询配置文件在哪里&#xff1f;欢迎界面配置文件在哪里&#xff1f; /var/log/messages #内核及公共消息日志/var/log/cron #计划任务日志/var/log/dmesg #系统引导日志/var/log/malilog #邮件系…...

别再盲目推广了!Xinstall助你开启App线下推广新篇章

在这个数字化飞速发展的时代&#xff0c;App已经成为我们生活中不可或缺的一部分。然而&#xff0c;App市场的竞争也日益激烈&#xff0c;如何让你的App在众多竞争者中脱颖而出&#xff0c;成为每个推广者必须面对的问题。今天&#xff0c;就让我们一起探讨一下App线下推广的痛…...

网站管理后台地址怎么查询/网站建设步骤

一、众所周知的与不为所知的 我们平时涉及点击交互事件的时候&#xff0c;都是使用的a元素或者button元素&#xff0c;原因是可以相应键盘focus效果以及回车触发点击事件&#xff0c;这是众所周知的。 但是&#xff0c;可能存在一些特殊情况&#xff0c;我们需要使用默认没有键…...

.net做网站用mvc/网络营销的内涵

函数应用和映射 numpy 的通用函数&#xff08;逐元素数组方法&#xff09;对pandas 同样有效。通用函数 脑补链接 frame pd.DataFrame(np.random.randn(4,3),columnslist(bde),index[utah,ohio,texas,oregon]) frameb d e utah -0.794479 -0.739367 -0.965423 ohio -0.65755…...

衡水企业做网站推广/重庆森林影评

java实现 n人过桥问题##【问题描述】 n个人要晚上过桥&#xff0c;在任何时候最多两个人一组过桥&#xff0c;每组要有一只手电筒。在这n个人中只有一个手电筒能用&#xff0c;求这些人过桥所用的最短时间。##【输入】输入的第一行给出n,接下来的n行给出每个人的过桥时间例如&a…...

瓷砖网站建设/网络推广具体内容

matlab常用的几个适应度评价函数分析/niuyongjie/article/details/1619496?粒子群算法(6)-----几个适应度评价函数下面给出几个适应度评价函数&#xff0c;并给出图形表示????? 头几天机子种了病毒&#xff0c;重新安装了系统&#xff0c;不小心把程序全部格式化了&#…...

ppt模板做的好的网站有哪些/网络营销产品推广方案

一、通过api.ajax异步请求取个人服务器数据apiready function(){api.ajax({url: http://119.29.157.60/api/Shop/getAll, // 自己用PHP写的请求数据库的接口method: get,headers:{Content-Type: application/json;charsetutf-8}}, function(ret, err) {if (ret) {res $api.js…...

做视频网站需要流媒体吗/爱站网的关键词是怎么来的

多个文件压缩打包 tar -czvf my.tar file1 file2,... 多个目录同上 解包至当前目录&#xff1a;tar -xzvf my.tar...