ES6 Proxy 用法总结以及 Object.defineProperty用法区别
Proxy 是 ES6 引入的一种强大的拦截机制,用于定义对象的基本操作(如读取、赋值、删除等)的自定义行为。相较于 Object.defineProperty,Proxy 提供了更灵活、全面的拦截能力。
1. Proxy 语法
const proxy = new Proxy(target, handler);
target:被代理的对象handler:定义拦截行为的对象
2. Proxy 基本用法
(1) 拦截对象的属性访问
const person = {name: "Alice",age: 25,
};const proxyPerson = new Proxy(person, {get(target, prop) {console.log(`访问属性: ${prop}`);return prop in target ? target[prop] : "属性不存在";},
});console.log(proxyPerson.name); // 访问属性: name -> "Alice"
console.log(proxyPerson.gender); // 访问属性: gender -> "属性不存在"
(2) 拦截对象的属性修改
const proxyPerson = new Proxy(person, {set(target, prop, value) {if (prop === "age" && typeof value !== "number") {throw new Error("年龄必须是数字");}target[prop] = value;console.log(`设置 ${prop} 为 ${value}`);return true;},
});proxyPerson.age = 30; // 设置 age 为 30
proxyPerson.age = "abc"; // 抛出错误: 年龄必须是数字
(3) 拦截对象的属性删除
const proxyPerson = new Proxy(person, {deleteProperty(target, prop) {console.log(`删除属性: ${prop}`);return delete target[prop];},
});delete proxyPerson.age; // 删除属性: age
(4) 拦截 in 操作符 (has 方法)
const proxyPerson = new Proxy(person, {has(target, prop) {console.log(`检查属性是否存在: ${prop}`);return prop in target;},
});console.log("name" in proxyPerson); // 检查属性是否存在: name -> true
console.log("gender" in proxyPerson); // 检查属性是否存在: gender -> false
const range = { start: 10, end: 50 };const proxy = new Proxy(range, {has(target, prop) {return prop >= target.start && prop <= target.end;}
});console.log(15 in proxy); // true
console.log(60 in proxy); // false
(5) 拦截函数调用 (apply 方法)
const multiply = new Proxy((a, b) => a * b, {apply(target, thisArg, args) {console.log(`调用函数 multiply,参数: ${args}`);return target(...args);}
});console.log(multiply(3, 4)); // 调用函数 multiply,参数: 3,4 -> 12
(6) 拦截构造函数 (construct 方法)
const Person = new Proxy(class {constructor(name) {this.name = name;}
}, {construct(target, args) {console.log(`创建实例,参数: ${args}`);return new target(...args);}
});const user = new Person("Alice"); // 创建实例,参数: Alice
特点:
- 可以 监听整个对象,而不是单个属性。
- 能拦截 所有操作(如
get、set、has、deleteProperty、apply等)。 - 可以用于 动态代理,使得代码更具扩展性。
3. Proxy 实际使用场景
(1) 数据验证和格式化
const user = new Proxy({}, {set(target, prop, value) {if (prop === "age" && typeof value !== "number") {throw new Error("年龄必须是数字");}target[prop] = value;return true;}
});
(2) 实现私有属性和方法
const createUser = () => {const privateData = new WeakMap();return new Proxy({}, {get(target, prop) {if (prop.startsWith("_")) {throw new Error("无法访问私有属性");}return target[prop];}});
};
(3) 添加日志记录和调试功能
const logger = new Proxy({}, {get(target, prop) {console.log(`访问属性: ${prop}`);return target[prop];}
});
(4) 提供默认值和只读访问
const defaultSettings = new Proxy({}, {get(target, prop) {return prop in target ? target[prop] : "默认值";},set() {throw new Error("设置操作被禁止");}
});
(5) 实现惰性加载和缓存
const lazyObject = new Proxy({}, {get(target, prop) {if (!(prop in target)) {console.log(`初始化 ${prop}`);target[prop] = prop.toUpperCase();}return target[prop];}
});
(6) 解决 this 指向问题
const obj = {name: "Alice",greet() {return `Hello, ${this.name}`;}
};const proxyObj = new Proxy(obj, {get(target, prop, receiver) {return typeof target[prop] === "function" ? target[prop].bind(target) : target[prop];}
});const greet = proxyObj.greet;
console.log(greet()); // Hello, Alice
4.Object.defineProperty
Object.defineProperty() 允许直接在对象上定义新的属性,或者修改已有属性的特性(如可读写性、是否可枚举等)。
示例:
const person = {};Object.defineProperty(person, "name", {value: "Alice",writable: false, // 不能修改enumerable: true,configurable: false
});console.log(person.name); // Alice
person.name = "Bob"; // 失败,严格模式下会报错
console.log(person.name); // Alice
特点:
- 只能加工 单个属性,不能监听整个对象。
- 只能 定义静态的行为,不能动态处理对象属性的操作。
- 不能拦截 删除、新增属性 或 函数调用。
5. Proxy 与 Object.defineProperty 详细对比
| 特性 | Object.defineProperty | Proxy |
|---|---|---|
| 监听属性读取 | ❌ 不支持 | ✅ 支持 (get) |
| 监听属性赋值 | ✅ 支持 (set) | ✅ 支持 (set) |
| 监听属性删除 | ❌ 不支持 | ✅ 支持 (deleteProperty) |
| 监听属性存在性 | ❌ 不支持 | ✅ 支持 (has) (in 关键字) |
| 监听对象新增属性 | ❌ 不支持 | ✅ 支持 (set) |
| 监听函数调用 | ❌ 不支持 | ✅ 支持 (apply) |
| 监听构造函数 | ❌ 不支持 | ✅ 支持 (construct) |
| 监听整个对象 | ❌ 需要对每个属性定义 | ✅ 一次性监听整个对象 |
| 适用于数组或集合 | ❌ 不适合 | ✅ 适合 |
| 可扩展性 | ❌ 需手动定义 | ✅ 更强大,支持代理嵌套 |
相关文章:
ES6 Proxy 用法总结以及 Object.defineProperty用法区别
Proxy 是 ES6 引入的一种强大的拦截机制,用于定义对象的基本操作(如读取、赋值、删除等)的自定义行为。相较于 Object.defineProperty,Proxy 提供了更灵活、全面的拦截能力。 1. Proxy 语法 const proxy new Proxy(target, hand…...
数据结构——【二叉树模版】
#思路 1、二叉树不同于数的构建,在树节点类中,有数据,左子结点,右子节点三个属性,在树类的构造函数中,添加了变量maxNodes,用于后续列表索引的判断 2.GetTreeNode()函数是常用方法,…...
关闭浏览器安全dns解决访问速度慢的问题
谷歌浏览器加载速度突然变慢了?检查安全DNS功能(DoH)是否被默认开启。 谷歌浏览器在去年已经推出安全DNS功能(即DoH) , 启用此功能后可以通过加密的DNS增强网络连接安全性。例如查询请求被加密后网络运营商将无法嗅探用户访问的地址,因此对于增强用户的…...
【AIGC】语言模型的发展历程:从统计方法到大规模预训练模型的演化
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AIGC | ChatGPT 文章目录 💯前言💯语言模型的发展历程:从统计方法到大规模预训练模型的演化1 统计语言模型(Statistical Language Model, SLM):统…...
Spring Boot 中的事务管理:默认配置、失效场景及集中配置
Spring Boot 提供了强大的事务管理功能,基于 Spring 的 Transactional 注解。本文将详细介绍事务的默认配置、事务失效的常见场景、以及事务的几种集中配置方式,并给出相应的代码片段。 一、事务的默认配置 在 Spring Boot 中,默认情况下&am…...
DeepSeek 助力 Vue 开发:打造丝滑的进度条
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 Deep…...
deepseek的CoT优势、两阶段训练的有效性学习笔记
文章目录 1 DeepSeek的CoT思维链的优势1.2 open-r1的CoT训练数据1.3 ReAct任务与CoT任务适用场景 2 AI推理方向:deepseek与deepmind的两条路线的差异2.1 PRM与ORM的两大学派分支的差异2.2 DeepSeek-R1的两阶段训练概述 1 DeepSeek的CoT思维链的优势 DeepSeek跟之前…...
分享在职同时准备系统分析师和教资考试的时间安排
(在职、时间有限、同时备考系统分析师考试和小学信息技术教资面试),以下是详细的备考计划,确保计划的可行性和通过性。 一、总体安排 时间分配: 每周周末(2天)用于系统分析师考试备考。工作日晚…...
浅谈Java Spring Boot 框架分析和理解
Spring Boot是一个简化Spring开发的框架,它遵循“约定优于配置”的原则,通过内嵌的Tomcat、Jetty或Undertow等容器,使得开发者能够快速构建独立运行的、生产级别的基于Spring框架的应用程序。Spring Boot包含了大量的自动配置功能,…...
【开发心得】CentOS7编译Redis7.4.2打包RPM完整方案
概述 由于最近客户需要解决redis版本升级问题,故而全网寻找安全版本,redis7.4.x版本求而为果,只能自己编译了。 截止发文时间2025-02-12 最新稳定版的redis版本号为7.4.2 Security fixes (CVE-2024-46981) Lua script commands may lead t…...
【网络安全】常见网络协议
1. 网络协议概述 网络协议是网络上两个或多个设备使用的一组规则,用于描述传输顺序和数据结构。网络协议充当数据包中信息附带的指令。这些指令告诉接收设备如何处理数据。协议就像一种通用语言,让世界各地的设备能够相互通信和理解。 尽管网络协议在网…...
电路笔记(元器件):AD 5263数字电位计(暂记)
AD5263 是四通道、15 V、256位数字电位计,可通过SPI/I2C配置具体电平值。 配置模式: W引脚作为电位器的抽头,可在A-B之间调整任意位置的电阻值。也可将W与A(或B)引脚短接,A-W间的电阻总是0欧姆,通过数字接口调整电位器…...
MongoDB 的使用场景
一、内容管理系统 1. 博客平台 文章内容、作者信息、标签、评论等数据结构多样,MongoDB 的无模式特性可轻松应对。比如 WordPress 等博客系统,使用 MongoDB 能灵活存储不同格式和长度的文章内容,以及与文章相关的各种元数据。 2. 新闻网站…...
MongoDB 是什么
MongoDB 是一款文档型数据库,属于 NoSQL 数据库范畴。 一、基本概念 MongoDB 以文档的形式存储数据,文档类似于 JSON 对象,由键值对组成,它以 BSON(Binary JSON)格式存储在磁盘上,这种格式支持…...
Python3操作MongoDB批量upsert
个人博客地址:Python3操作MongoDB批量upsert | 一张假钞的真实世界 代码如下: mongoClient MongoClient(mongodb://172.16.72.213:27017/) opsDb mongoClient.ops azScheduled opsDb.azScheduledFlowbulkOpers [] for flow in scheduledFlows.valu…...
相机模数转换
模拟图像是什么? 模拟图像是指连续变化的图像,它通常来源于现实世界的物理场景,并通过光学系统(如相机镜头)投射到感光介质上。模拟图像是连续的,这意味着它在空间和颜色值上都有无穷的细节。例如…...
C++20 新特性解析
1. 概念(Concepts) 概念是 C++20 引入的一项重要特性,它允许程序员定义类型约束,从而在编译时检查模板参数是否符合某些要求。概念提供了模板参数的限制,使得模板代码更加可读和易于维护。 示例代码: #include <iostream> #include <concepts>// 定义一个…...
C# ManualResetEvent 类 使用详解
总目录 前言 ManualResetEvent 是 C# 中用于线程同步的核心类之一,位于 System.Threading 命名空间下。它的核心功能是通过信号机制控制线程的执行顺序,允许一个或多个线程等待某个信号后再继续运行。与 AutoResetEvent 不同,ManualResetEve…...
动态规划——路径问题②
文章目录 931. 下降路径最小和算法原理代码实现 64. 最小路径和算法原理代码实现 174. 地下城游戏算法原理代码实现 931. 下降路径最小和 题目链接:931. 下降路径最小和 算法原理 状态表示: 经验题目要求:dp[i][j]表示到达[i,j]位置时&…...
ChatGPT macOS 桌面应用让你的编程体验更上一层楼
高效开发必备:ChatGPT macOS 桌面应用亮点盘点 ©作者|Ninja Geek 来源|神州问学 通过 macOS 版 ChatGPT 应用,已经能够更好的和你的生产力工具无缝配合工作。 大概在三四周之前,Anthropic 在 Claude 上推出了一项名为 Computer Use 的功…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
