当前位置: 首页 > 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 就足够。

相关文章:

  • 使用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 粒子动画云端渲染指南
  • 怎么做免费网站被收录/百度博客收录提交入口
  • 宝塔里面一个服务器做多个网站/培训机构排名前十
  • phpcms做网站页面开发/怎么分析一个网站seo
  • java做网站访问量并发/app推广引流方法
  • 网站备案服务/小视频关键词汇总
  • 帮客户做网站平台犯法吗/百度云网盘网页版