【javaScript】Proxy与Object.defineProperty的区别

news2024/12/21 23:04:35

目录

    • 功能方面的区别:
      • Object.defineProperty对整个对象进行赋值,不会触发set拦截
      • Object.defineProperty对整个对象进行遍历,不会触发get拦截
      • Proxy自定义拦截行为
    • Proxy的优缺点
      • 优点:
      • 缺点

在这里插入图片描述

Proxy和Object.defineProperty都是JavaScript中用于实现对象属性拦截和代理的机制,但它们在功能和应用方面有一些区别。

功能方面的区别:

Object.defineProperty:它是ES5引入的属性定义方法,通过直接定义对象属性的特性(如可枚举性、可写性等),可以拦截属性的读取、写入和删除操作。但它只能拦截对象的属性访问,对于对象的整体操作(如对整个对象的赋值或属性遍历)并不会被拦截

Proxy:它是ES6引入的代理机制,可以对整个对象进行代理,拦截对象的各种操作,包括属性访问、赋值、删除、函数调用等。通过在代理对象上定义各种"陷阱"(trap)方法,可以自定义拦截行为,实现更细粒度的对象操作控制。

比如:

Object.defineProperty对整个对象进行赋值,不会触发set拦截

const obj = {};

Object.defineProperty(obj, 'name', {
  get() {
    console.log('访问name属性');
    return 'John';
  },
  set(value) {
    console.log('设置name属性');
    obj._name = value;
  }
});

// 访问name属性,触发get拦截
console.log(obj.name); // 输出: "访问name属性" 和 "John"

// 设置name属性,触发set拦截
obj.name = 'Alice'; // 输出: "设置name属性"

// 对整个对象进行赋值,不会触发set拦截
obj = { age: 25 }; // 抛出TypeError: Assignment to constant variable.

输出如下图所示:

在这里插入图片描述

Object.defineProperty对整个对象进行遍历,不会触发get拦截

const obj = { name: 'John', age: 25 };

Object.defineProperty(obj, 'name', {
  get() {
    console.log('访问name属性');
    return 'Alice';
  }
});

for (const key in obj) {
  console.log(key); // 输出: "name" 和 "age"
}

console.log(obj.name); // 输出: "访问name属性" 和 "Alice"

输出结果如下:

在这里插入图片描述

Proxy自定义拦截行为

const user = {
  name: 'John',
  age: 25,
};

const protectedUser = new Proxy(user, {
  set(target, property, value) {
    if (property === 'age') {
      throw new Error('age属性不可被修改');
    }

    return Reflect.set(target, property, value);
  },
  deleteProperty(target, property) {
    if (property === 'name') {
      throw new Error('name属性不可被删除');
    }

    return Reflect.deleteProperty(target, property);
  },
});

console.log(protectedUser.name); // 输出: "John"

protectedUser.name = 'Alice'; // 不会抛出错误,属性赋值成功

console.log(protectedUser.name); // 输出: "Alice"

protectedUser.age = 30; // 抛出错误,无法修改age属性

delete protectedUser.name; // 抛出错误,无法删除name属性

Proxy的优缺点

优点:

  • 更全面的拦截能力:Proxy可以拦截对象的更多操作,包括对属性的读取、赋值、删除等,以及函数的调用等,提供了更细粒度的拦截控制。
  • 可变性控制:Proxy可以用于控制对象的可变性,例如可以禁止对某些属性进行赋值或删除,从而实现更严格的对象保护和约束。

缺点

  • 兼容性问题:Proxy是ES6引入的新特性,旧版本的JavaScript环境可能不支持Proxy,因此在一些特定的环境或需求下,使用Proxy可能会导致兼容性问题。
  • 性能开销:相比Object.defineProperty,Proxy的拦截机制更为复杂,因此在某些情况下可能会引入一定的性能开销。但对于大多数应用场景来说,这种开销可以忽略不计。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/638659.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

亿发软件:中医药信息一体化解决方案,智慧中药房煎配系统

智慧中药房是中医药服务的一种新模式,随着中医药信息化建设逐渐兴起,湖南远跃顺应时代发展需求,深度分析中医药行业现状,充分发挥研发技术创新,融合运用互联网、物联网、大数据等技术创新成果,研发出中药信…

上市后首份年报,读书郎去年净利下滑94%

又是一年高考逐梦时,寒窗二十四年的读书郎如何克服“偏科”症? 近日,读书郎教育控股有限公司(下称“读书郎”,02385.HK)交出了上市后的首份年报。 3月29日,财报公布的首个交易日,其股价下跌0.27%&#xf…

起点,而非终点——我的创作纪念日

机缘 我注定遇见CSDN. 作为一位oier,在学习算法,查找题解的时候,第一个看到的,总是CSDN。 于是,我加入了CSDN这个家庭。 茫茫然然,带着无限的憧憬,我写下了第一篇文章:《你好,CSDN》 我的C…

什么是融合CDN?融合CDN的优势和常见的调度模式有哪些?

什么是融合CDN? 为了理解什么是融合CDN,我们先了解什么是CDN。CDN是一个地理分布的边缘服务器网络,其目标是提供更快、可靠的互联网内容交付。CDN通过在网络边缘缓存互联网内容来实现这一点,从而减少数据源和最终用户之间的物理距…

“入职半年,绩效背了C”,谈谈「绩效管理」的误区及对策

职场打工人上班吃维C,绩效却背C,苦C久矣! 又到年中“考核季”,被绩效考核折磨到“头秃”的职场打工人们,选择将情绪释放到社交平台。 一位朋友分享了自己绩效被打C的经历:“茶饭不思,感觉自己很…

数学建模经历-程序人生

引言 即将大四毕业(现在大三末),闲来无事(为了冲粽子)就写一篇记录数学建模经历的博客吧。其实经常看到一些大佬的博客里会有什么"程序人生"、"人生感想"之类的专栏,但是由于我只是一个小趴菜没什么阅历因此也就没有写过类似的博客…

一文详解IPv4与IPv6协议

前段时间的工作大多与通信协议相关,随着协议相关工作的不断深入,相关数据包的分析占据了不少工作时间。在数据报文分析中,发现大学期间IP协议内容已经重新还给了老师,相关知识完全没有了印象,这篇文章算是一篇复习文&a…

Day05 04-MySQL分库分表介绍

文章目录 第十七章 MySQL分库分表17.1 什么是分库分表17.2 为什么要分库分表17.3 垂直切分17.3.1 垂直分库17.3.2 垂直分表 17.4 水平切分17.4.1 水平分库17.4.2 水平分表17.4.3 常见的水平切分规则 第十七章 MySQL分库分表 17.1 什么是分库分表 MySQL数据库常见的优化方案中…

新的管理中心应用

大家好,才是真的好。 Notes/Domino 14 Drop1如约而至,让我们有了很多内容要写。首先是管理新特性,就像上篇和大家介绍的,感受最直接的就是新的管理中心应用AdminCentral。 以目前的Drop1环境来看,管理中心应用主要功…

plus.runtime.version总是13.8.4

引言 最近在uniapp中使用到了plus.runtime.version,但是在开发环境下一直无法获取到真正的版本号,他的值一直都是13.8.4,在全局进行搜索也没有发现哪里设置了13.8.4,后来查阅了相关资料才知道这并不是自己写错了。 场景复现&…

你知不知道ai如何绘画的

有没有想要自己能绘画一幅有艺术感的画呢?想自己也能将自己所想的事、物或景绘画出来呢?其实你不用担心你的绘画功底不行,因为现在有一门ai绘画的技术,它可以将你提供的信息用智能技术自动绘画,你也可以把它当做一门新…

数字IC前端学习笔记:仲裁轮询(一)

相关文章 数字IC前端学习笔记:LSFR(线性反馈移位寄存器) 数字IC前端学习笔记:跨时钟域信号同步 数字IC前端学习笔记:信号同步和边沿检测 数字IC前端学习笔记:锁存器Latch的综合 数字IC前端学习笔记&am…

【面试必问】Spring核心之面向切面编程(AOP)

tip:作为程序员一定学习编程之道,一定要对代码的编写有追求,不能实现就完事了。我们应该让自己写的代码更加优雅,即使这会费时费力。 💕💕 推荐:体系化学习Java(Java面试专题&#…

【数据结构】八大排序算法

目录 一、直接插入排序 二、希尔排序 三、选择排序 四、堆排序 五、冒泡排序 六、快速排序 1、递归版本 1.1 hoare 法 1.2 挖坑法 1.3 前后指针法 2、非递归版本 3、快速排序的优化 3.1 三数取中 3.2 小区间优化 七、归并排序 1、递归版本 2、非递归版本 八、计数排序 …

【Spring Security】的RememberMe功能流程与源码详解

文章目录 前言原理 基础版搭建初始化sql依赖引入配置类验证 源码分析 进阶版集成源码分析疑问1疑问2 鉴权 升级版集成初始化sql配置类验证 源码分析鉴权流程 扩展版 前言 之前我已经写过好几篇权限认证相关的文章了,有想复习的同学可以查看【身份权限认证合集】。今…

Ada Tutorial(3)SPARK2——Post condition + Loop Invariant 后置条件 + 循环不变量

文章目录 divmod循环不变量 v.s. 后置条件扩展思考 divmod -- divmod.adb package body DivMod with SPARK_Mode isprocedure DivMod(X : Positive; N : Positive; K : out Natural; Remainder : out Natural)isY : Natural : X;beginK : 0;while Y > N loopY : Y - N;K : …

MySQL 日期与时间函数

一、获取日期、时间 函数用法CURDATE(),CURRENT_DATE()返回当前日期,只包含年、月、日CURTIME() , CURRENT_TIME()返回当前时间,只包含时、分、秒NOW() , SYSDATE(),CURRENT_TIMESTAMP() , LOC…

为什么企业和品牌一定要创建百度百科词条呢?

在企业和品牌宣传推广方面,百度百科作为一个权威的知识平台,早已成为了宣传阶段非常重要的一环。本文伯乐网络传媒将从以下几个方面探讨为什么企业和品牌一定要创建百度百科词条。 一、提升企业和品牌知名度 在信息时代,信息的获取渠道变得更…

PySpark简单使用(零)

介绍 Spark是Apache基金会旗下的顶级开源项目,用于对海量数据进行大规模分布式计算。PySpark是Spark的Python实现,是Spark为Python开发者提供的编程入口,用于以Python代码完成Spark任务的开发PySpark不仅可以作为Python第三方库使用&#xf…

【深入浅出 Spring Security(九)】解决跨域问题和 Axios 所需配置

跨域 一、SpringMVC 跨域的解决方案CrossOrigin(注解的方式解决)addCorsMappings(实现WebMvcConfigurer接口,重写方法) 二、Spring Security 跨域的解决方案前后端跨域测试(前端相关配置) 啥是跨…