理解 Proxy 和 Object.defineProperty:提升你的 JavaScript 技能(上)

在这里插入图片描述

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6
🍨 阿珊和她的猫_CSDN个人主页
🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》
🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入门到实战全面掌握 uni-app》

文章目录

  • 引言
    • 介绍 Proxy 和 Object.defineProperty 的背景和重要性
  • Proxy 的基本概念和用法
    • 解释 proxy 的作用和工作原理
    • 展示如何创建一个 proxy 对象
    • 探讨 proxy 的一些常见用例,如数据拦截、属性访问控制等

引言

介绍 Proxy 和 Object.defineProperty 的背景和重要性

在 JavaScript 中,Proxy 对象和 Object.defineProperty()方法都是用于操作对象的属性和方法的工具。它们提供了一种更高级、更灵活的方式来控制对象的行为。

  • Proxy 对象是在 ES6 中引入的,它可以用于创建一个代理对象,该代理对象可以拦截对原始对象的操作,并可以自定义对这些操作的响应。这使得可以在不修改原始对象的情况下,对对象的访问进行额外的处理,例如数据验证、日志记录、性能监测等。

  • Object.defineProperty()方法则是在 ES5 中引入的,它可以用于直接定义对象的属性,包括属性的可枚举性、可写性、可配置性以及值的获取和设置函数。通过使用 Object.defineProperty(),可以在对象上添加新属性,或者修改现有属性的行为。

这两个工具的重要性在于它们提供了一种更细粒度的控制对象的方式。在一些场景下,直接修改对象的属性可能会带来一些问题,例如不可预测的副作用、命名冲突等。而使用 Proxy 和 Object.defineProperty(),可以在不影响其他代码的情况下,对对象的行为进行定制,从而提高代码的可维护性和扩展性。

此外,Proxy 对象还可以与其他 JavaScript 特性(如迭代器、生成器等)结合使用,提供更强大的功能。而 Object.defineProperty()方法则常用于创建不可变对象、实现响应式编程等领域。

总的来说,Proxy 对象和 Object.defineProperty()方法是 JavaScript 中非常重要的工具,它们为开发人员提供了更多的灵活性和控制力,有助于编写更高效、更可靠的代码。

Proxy 的基本概念和用法

解释 proxy 的作用和工作原理

Proxy 是 JavaScript 中的一个对象,它可以用于创建一个代理对象,该代理对象可以拦截对原始对象的操作,并可以自定义对这些操作的响应。

Proxy 的作用主要有以下几个方面:

  1. 数据拦截:可以拦截对对象的访问,例如读取属性、写入属性、调用方法等,并可以在这些操作之前或之后进行额外的处理,例如数据验证、日志记录、性能监测等。

  2. 虚拟属性:可以通过 Proxy 对象为原始对象添加新的属性,这些属性实际上并不存在于原始对象上,而是通过 Proxy 对象来实现的。

  3. 方法拦截:可以拦截对对象方法的调用,并可以在调用方法之前或之后进行额外的处理,例如参数验证、错误处理等。

在这里插入图片描述

Proxy 的工作原理基于 JavaScript 的原型链和委托机制。当创建一个 Proxy 对象时,需要传递一个目标对象作为参数,proxy 对象会拦截对目标对象的操作,并根据需要进行相应的处理。

具体来说,

  • 当对 proxy 对象进行操作时,JS 会首先检查 proxy 对象的自有属性,如果找到了相应的属性或方法,则直接执行;
  • 如果没有找到,则会通过原型链和委托机制来查找目标对象上的属性或方法,并执行相应的操作。

在这个过程中,proxy 对象可以通过拦截器函数来干预对目标对象的操作,从而实现自定义的行为。

需要注意的是,Proxy 对象是在 ES6 中引入的,对于一些旧版本的浏览器可能需要使用 polyfill 来实现。此外,Proxy 对象的性能可能会受到一定的影响,因此在实际应用中需要根据具体情况进行权衡。

展示如何创建一个 proxy 对象

以下是一个简单的示例,展示如何创建一个 Proxy 对象:

const target = { name: 'John' };

const proxy = new Proxy(target, {
  // 定义属性的获取行为
  get: (target, key) => Reflect.get(target, key) + '!',

  // 定义属性的设置行为
  set: (target, key, value) => Reflect.set(target, key, value.toUpperCase())
});

console.log(proxy.name); 
proxy.name = 'JACK';
console.log(proxy.name); 

在这个示例中,我们创建了一个 Proxy 对象,它拦截了对 target 对象的属性操作。具体来说:

  1. get() 方法中,我们使用 Reflect.get() 来获取原始对象的属性值,并在返回之前对其进行了一些额外的操作(在这里,我们只是在属性值后面添加了一个感叹号)。

  2. set() 方法中,我们使用 Reflect.set() 来设置原始对象的属性值,并在设置之前对其进行了一些额外的操作(在这里,我们将新的值转换为大写)。

通过使用 Proxy 对象,我们可以在不修改原始对象的情况下,对对象的操作进行拦截和自定义。这对于一些高级应用场景非常有用,例如数据验证、日志记录、性能监测等。

探讨 proxy 的一些常见用例,如数据拦截、属性访问控制等

以下是一些 Proxy 对象常见的用例:

  1. 数据拦截:可以使用 Proxy 对象来拦截对对象的访问,例如读取属性、写入属性、调用方法等。通过拦截这些操作,可以进行额外的数据处理、验证、日志记录等。

    const target = { name: 'John' };
    
    const proxy = new Proxy(target, {
      // 拦截属性的读取操作
      get: (target, key) => Reflect.get(target, key) + '!',
    
      // 拦截属性的写入操作
      set: (target, key, value) => Reflect.set(target, key, value.toUpperCase())
    });
    
    console.log(proxy.name); 
    proxy.name = 'JACK';
    console.log(proxy.name); 
    
  2. 属性访问控制:可以使用 Proxy 对象来控制对对象属性的访问,例如禁止访问某些属性、只读属性等。

    const target = { name: 'John', age: 25 };
    
    const proxy = new proxy(target, {
      // 拦截属性的读取操作
      get: (target, key) => {
        if (key === 'age') {
          return Reflect.get(target, key);
        }
        throw new Error('无权访问该属性');
      }
    });
    
    console.log(proxy.name); 
    console.log(proxy.age); 
    try {
      console.log(proxy.password); 
    } catch (error) {
      console.error(error.message); 
    }
    
  3. 方法拦截:可以使用 Proxy 对象来拦截对对象方法的调用,例如修改方法的行为、添加额外的参数等。

    const target = {
      sayHello: function() {
        console.log('Hello, ' + this.name);
      }
    };
    
    const proxy = new proxy(target, {
      // 拦截方法的调用操作
      apply: (target, thisArg, argumentsList) => {
        Reflect.apply(target, thisArg, argumentsList);
        console.log('方法执行完毕');
      }
    });
    
    proxy.sayHello(); 
    
  4. 虚拟属性:可以使用 Proxy 对象来为对象添加虚拟属性,这些属性实际上并不存在于原始对象上,而是通过代理对象来实现。

    const target = { name: 'John' };
    
    const proxy = new proxy(target, {
      // 拦截属性的读取操作
      get: (target, key) => {
        if (key === 'age') {
          return Reflect.get(target, key) + 1;
        }
        return Reflect.get(target, key);
      }
    });
    
    console.log(proxy.age); 
    

这些只是 Proxy 对象的一些常见用例,实际上,Proxy 对象可以用于许多其他场景,根据具体的需求来定制拦截行为。需要注意的是,Proxy 对象的性能可能会受到一定的影响,因此在实际应用中需要根据情况进行权衡。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【01分数规划】ABC324F

[ABC324F] Beautiful Path - 洛谷 思路 首先看到这个形式很容易想到 01 分数规划&#xff0c;即去二分答案&#xff0c;然后就是转化成 是否存在一个路径使得 sigma b - mid * sigma c > 0 显然只需要改变一下边权&#xff0c;跑一遍最长路即可 #include <bits/stdc.h…

html 中vue3 的setup里调用element plus的弹窗 提示

引入Elementplus之后&#xff0c;在setup&#xff08;&#xff09;方法外面导入ElMessageBox const {ElMessageBox} ElementPlus 源码 &#xff1a; <!DOCTYPE html> <html> <head><meta charset"UTF-8"><!-- import Vue before Elemen…

运筹优化 | 模拟退火求解旅行商问题 | Python实现

"""模拟退火旅行商""" import random import numpy as np import math import time import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False location np.loadtxt(city_location.t…

python-爬取壁纸

代理池的&#xff0c;防止IP 被封 找到图片真实地址 现在看到的只是图片的预览地址 (previews) 1.检查&#xff1a; 2.鼠标变为箭头时查看网页源代码 关于怎样在源代码中找到图片的真实地址 ??? 为什么在源代码界面 ctrl f 时候搜索的是 .png ??? 首先图片地址是以 .j…

OpenStack网络详解

本文主要解释了OpenStack在安装完毕——创建网段与dhcp——创建虚拟机的过程中&#xff0c;系统中多出来的这一堆网卡到底分别连接哪两部分的网卡&#xff0c;以及哪些设备是虚拟出来的。 拓扑 红色代表ovs与网桥 蓝色代表命名空间或者虚机 绿色代表网卡 网络概况 openstack安…

【Mars3d-ModelEntity】实现gltf模型不随地图缩放而改变大小

需求场景&#xff1a; 1.实现gltf模型不随地图缩放而改变大小 相关代码&#xff1a; const graphic new mars3d.graphic.ModelEntity({ name: "警车", position: [116.346929, 30.861947, 401.34], style: { url: "//data.mars3d.cn/gltf/mars/jingche/jingc…

SpringBoot进行自然语言处理,利用Hanlp进行文本情感分析

. # &#x1f4d1;前言 本文主要是SpringBoot进行自然语言处理&#xff0c;利用Hanlp进行文本情感分析&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风…

[Unity+文心知识库]使用百度智能云搭建私有知识库,集成知识库API,打造具备知识库的AI二次元姐姐

1.简述 最近从百度智能云的官方技术支持那边了解到&#xff0c;目前百度千帆大模型平台提供有在线的知识库功能&#xff0c;能够在线上传自己的私人知识库文档&#xff0c;并且配置文心一言模型作为文本生成的引擎&#xff0c;构建自己的私有知识库。之前自己搭建知识库都是用的…

bugku--源代码

查看源代码 发显URL编码 解码 在拼接这一串 拿着去提交就行啦

【Vue】vue增加导航标签

系列文章 【C#】WebAPI&#xff0c;在Windows IIS平台部署 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/126539836 【Vue】vue&#xff0c;在Windows IIS平台部署 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/13385…

docker compose部署wordpress

准备机器&#xff1a; 192.168.58.151 &#xff08;关闭防火墙和selinux&#xff09; 安装好docker服务 &#xff08;详细参照&#xff1a;http://t.csdnimg.cn/usG0s 中的国内源安装docker&#xff09; 部署wordpress: 创建目录&#xff1a; [rootdocker ~]# mkdir…

Selenium库自动化测试入门

前言 为什么要学selenium&#xff1f;&#xff1f;前面已经学了requests库我们会发现 对于绝大多数动态渲染的网页来说&#xff0c;用requests进行爬虫比较繁琐。 所以我们还是要学习一下selenium库&#xff0c;以帮助我们更高效的爬取网页。 环境&#xff1a; pychar 202…

flutter调试器查看不了副页面(非主页面/子页面)

刚接触flutter&#xff0c;写了两个页面&#xff0c;通过按钮&#xff0c;可以从主页面跳转到副页面&#xff0c;副页面我自己写的一个独立的dart文件&#xff0c;在主页面的代码中导入使用。但是当我运行代码后&#xff0c;点击跳转的时候&#xff0c;却发现查看不到对应的副页…

Linux驱动入门 —— 利用引脚号操作GPIO进行LED点灯

目录 一、字符设备驱动程序框架 编写驱动程序的步骤&#xff1a; 对于 LED 驱动&#xff0c;我们想要什么样的接口&#xff1f; LED 驱动能支持多个板子的基础&#xff1a;分层思想 二、Linux驱动如何指向一个GPIO 直接通过寄存器来操作GPIO 利用引脚号操作GPIO IMX6UL…

STM32的看门狗(WDG)

WDG&#xff08;Watchdog&#xff09;看门狗 看门狗可以监控程序的运行状态&#xff0c;当程序因为设计漏洞、硬件故障、电磁干扰等原因&#xff0c;出现卡死或跑飞现象时&#xff0c;看门狗能及时复位程序&#xff0c;避免程序陷入长时间的罢工状态&#xff0c;保证系统的可靠…

基于C/C++的rapidxml加载xml大文件 - 下部分

下载地址: RapidXml (sourceforge.net)https://rapidxml.sourceforge.net/ 将源码添加到自己的工程中 示例测试大文件耗时: 总共293w行数据&#xff0c;大概耗时不到1s。

Paper Reading: (U2PL) 基于不可靠伪标签的半监督语义分割

目录 简介目标/动机方法Pseudo-LabelingUsing Unreliable Pseudo-Labels 补充知识InfoNCE LossOHEM 实验Comparison with Existing AlternativesAblationEffectiveness of Using Unreliable Pseudo-LabelsAlternative of Contrastive Learning 总结附录U2PL 与 negative learni…

【C语言程序设计】数组程序设计

目录 前言 一、数组的定义和初始化 二、数组的基本操作 三、数组的高级应用 四、程序设计 4.1 程序设计第一题 4.2 程序设计第二题 4.3 程序设计第三题 总结 &#x1f308;嗨&#xff01;我是Filotimo__&#x1f308;。很高兴与大家相识&#xff0c;希望我的博客能对你有所帮助…

论文阅读《DPS-Net: Deep Polarimetric Stereo Depth Estimation》

论文地址&#xff1a;https://openaccess.thecvf.com/content/ICCV2023/html/Tian_DPS-Net_Deep_Polarimetric_Stereo_Depth_Estimation_ICCV_2023_paper.html 概述 立体匹配模型难以处理无纹理场景的匹配&#xff0c;现有的方法通常假设物体表面是光滑的&#xff0c;或者光照是…

设计模式(2)--对象创建(4)--原型

1. 意图 用原型实例指定创建对象的种类&#xff0c;并且通过拷贝这些原型创建新的对象。 2. 两种角色 抽象原型(Prototype)、具体原型(Concrete Prototype) 3. 优点 3.1 对客户隐藏了具体的产品类 3.2 可以在运行时刻增加和删除产品 3.3 可以极大地减少系统所需要的类的数目 …