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

WHAT - JavaScript 中 Object.defineProperty() 和 Proxy 对比

目录

  • 一、Object.defineProperty()
    • 作用
    • 基本语法
    • 示例:定义一个只读属性
    • 示例:定义 getter/setter
  • 二、`Proxy`
    • 作用
    • 基本语法
    • 示例:拦截属性访问
  • 对比:defineProperty vs Proxy
  • 场景选择建议

在 JavaScript 中,Object.defineProperty()Proxy 都可以用来拦截/控制对象的属性访问与修改,但它们适用的场景、能力和语法上有较大差异。

一、Object.defineProperty()

作用

给对象的某个属性定义更精细的特性,比如只读、不可枚举、拦截 getter/setter。

基本语法

Object.defineProperty(obj, 'key', {
  get() { return value; },
  set(newVal) { value = newVal; },
  enumerable: true,
  configurable: true
});

示例:定义一个只读属性

const user = {};
Object.defineProperty(user, 'name', {
  value: 'Tom',
  writable: false // 不可更改
});

user.name = 'Jerry';
console.log(user.name); // Tom

示例:定义 getter/setter

const person = {};
let _age = 18;

Object.defineProperty(person, 'age', {
  get() {
    console.log('get age');
    return _age;
  },
  set(val) {
    console.log('set age:', val);
    _age = val;
  }
});

person.age = 20; // set age: 20
console.log(person.age); // get age → 20

二、Proxy

作用

创建一个对象的代理,可拦截几乎所有操作(读取、写入、删除、函数调用等)。

基本语法

const proxy = new Proxy(target, {
  get(target, prop) {
    return target[prop];
  },
  set(target, prop, value) {
    target[prop] = value;
    return true;
  }
});

示例:拦截属性访问

const user = { name: 'Tom' };

const proxy = new Proxy(user, {
  get(target, prop) {
    console.log(`读取属性:${prop}`);
    return target[prop];
  },
  set(target, prop, value) {
    console.log(`设置属性:${prop} = ${value}`);
    target[prop] = value;
    return true;
  }
});

proxy.name;          // 读取属性:name
proxy.age = 30;      // 设置属性:age = 30

更多关于 proxy 的内容可以阅读 Proxy 代理和 Reflect API

对比:defineProperty vs Proxy

特性Object.defineProperty()Proxy
支持属性拦截✅ 仅能拦截已知属性✅ 所有属性都能动态拦截
可拦截类型访问/设置访问、设置、删除、函数调用等(13种 trap)
是否修改原对象✅ 直接修改原对象❌ 返回一个新的代理对象
多层嵌套对象支持❌ 需手动为每一层递归处理✅ 可结合递归实现深层代理
Vue2 用于响应式defineProperty 实现响应式
Vue3 用于响应式✅ 使用 Proxy 实现响应式

场景选择建议

需求推荐方式
精准控制某个属性Object.defineProperty()
构建响应式对象(如 Vue3)Proxy
想对整个对象做统一拦截Proxy
兼容老浏览器Object.defineProperty()(IE9+)

如果你想自己实现一个响应式系统、双向绑定,或者拦截 API 调用,Proxy 更强大。如果只是限制某个属性或定义只读/计算属性,defineProperty 就足够。


文章转载自:
http://aphthongal.aaladrg.cn
http://asiatic.aaladrg.cn
http://bushmaster.aaladrg.cn
http://accepter.aaladrg.cn
http://cardholder.aaladrg.cn
http://cameralist.aaladrg.cn
http://bootable.aaladrg.cn
http://capital.aaladrg.cn
http://bedeck.aaladrg.cn
http://calvinist.aaladrg.cn
http://ammoniac.aaladrg.cn
http://cabana.aaladrg.cn
http://cannelure.aaladrg.cn
http://bryant.aaladrg.cn
http://beppu.aaladrg.cn
http://bere.aaladrg.cn
http://advanced.aaladrg.cn
http://brattish.aaladrg.cn
http://auriscopic.aaladrg.cn
http://balmoral.aaladrg.cn
http://acardia.aaladrg.cn
http://astringent.aaladrg.cn
http://chargehand.aaladrg.cn
http://champagne.aaladrg.cn
http://candiot.aaladrg.cn
http://breakbone.aaladrg.cn
http://cavitate.aaladrg.cn
http://analyzer.aaladrg.cn
http://brutalize.aaladrg.cn
http://anthelion.aaladrg.cn
http://www.dtcms.com/a/117560.html

相关文章:

  • 使用LangChain Agents构建Gradio及Gradio Tools(4)——Gradio Tools:gradio_tools库
  • 小刚说C语言刷题——第17讲 循环之for语句
  • ARM处理器内核全解析:从Cortex到Neoverse的架构与区别
  • 优选算法第七讲:分治
  • 关于如何在 Ansible 中安全使用 `rm -rf` 或类似操作的完整指南
  • C++第14届蓝桥杯b组学习笔记
  • go原子操作和锁的区别是什么?
  • rtthread 软件SPI驱动, 支持mode0~3,MSB,LSB
  • 【C语言】编译和链接
  • 企业级 ClickHouse Docker 离线部署实践指南20250407
  • 使用JDBC/MyBatis流式查询,解决大数据量查询程序OOM问题
  • Java 中使用 File 类创建文件
  • C++笔记-string(下)
  • C++类模板的运用
  • spring功能汇总
  • 动态规划-杨辉三角
  • Python字典实战: 三大管理系统开发指南(班级+会议+购物车)(附源码)
  • git修改已经push的commit的message
  • Spring Boot中Spring MVC相关配置的详细描述及表格总结
  • C4D XP 粒子动画云端渲染指南
  • 控制理论-传递函数
  • 【docker】
  • 前后端 Mock 技术实践指南【大模型总结】
  • 1、window 下SDL 下载使用, 测试环境搭建
  • 位运算题目:N 天后的牢房
  • [数据集]The Natural Scenes Dataset (NSD)介绍,申请及使用方法
  • 【蓝桥杯】算法笔记6
  • CubeMX配置STM32VET6实现网口通信(无操作系统版-附源码)
  • win11 nacos2.2.1 报错curl -X post 报错找不到和名称X匹配参数;不是命令
  • excel经验