什么是proxy代理?
1. 什么是proxy代理
代理(Proxy)是 JavaScript 中一种非常强大而灵活的功能。代理允许你拦截并覆盖对象的默认行为,提供了一种拦截、定制和扩展对象操作的机制。
简单说,就是在访问对象属性或者赋值时,可以做一些额外的操作。
代理通过使用 Proxy 对象来创建。
Proxy 接受两个参数:目标对象(被代理的对象)和一个处理程序对象(handler)。处理程序对象又分为了get()捕获器和set()捕获器。
先看一个简单的栗子,创建一个空代理,不会做任何的额外操作。
const target = {msg: 'hello'};const handler = {};const proxy = new Proxy(target, handler);//属性会访问同一个值console.log(target.msg)//helloconsole.log(proxy.msg)//hellotarget.msg = 'morning';console.log(target.msg)//morningconsole.log(proxy.msg)//morning// 严格相等可以用来区分代理对象和目标对象console.log(target === proxy); // false
要想定义额外的操作,要在handler中定义捕获器。通过代理对象访问属性,会触发get()捕获器; 通过代理对象给属性赋值。会触发set()捕获器。
const John = {name: 'John',age: 20};const handler = {// 这里就额外输出了属性名get: function (target, property, receiver) {console.log(`property: ${property}`);return Reflect.get(target, property, receiver);//获取对象的属性值},set: function (target, property, value, receiver) {if (property === 'age') {if (value < 18) {throw new Error('年龄必须大于等于 18');}}return Reflect.set(target, property, value, receiver);//设置对象的属性}}const proxy = new Proxy(John, handler);// 直接通过对象访问属性,不会触发代理的 get 捕获器console.log(John.name); // 输出 'John'// 通过代理对象访问属性,会触发代理的 get 捕获器console.log(proxy.name); // 输出 'property: name' 和 'John'proxy.age = 23;console.log(proxy.age);//输出 'property: age' 和 23proxy.age = 16;//Uncaught Error: 年龄必须大于等于 18
2. Reflect.get()
在JavaScript中,我们通常通过点符号(obj.property)或方括号(obj['property'])来访问对象的属性。而 Reflect.get() 也是获取对象的属性值。
Reflect.get(target, propertyKey, receiver)
target:目标对象,即从这个对象中获取属性值。propertyKey:属性键,即要获取的属性的键名。receiver:可选,如果提供,那么receiver将作为this值传递给目标对象的 getter 方法。如果省略,将使用target作为this值。
const person = { name: 'John', age: 30 };// 通过点符号
const name1 = person.name;// 通过方括号
const name2 = person['name'];//使用 Reflect.get 获取属性值
const name3 = Reflect.get(person, 'name');
3. Reflect.get()与常见获取对象属性值有什么不同?
相同点:当访问不存在属性时都会返回undefined
const person = { age: 30 };console.log(person.name); // 输出 undefined
console.log(Reflect.get(person, 'name')); // 输出 undefined
不同点:Reflect.get()会触发代理的捕获器,而用点符号、方括号去访问不会。
const person = { age: 30 };const handler = {get: function (target, property) {console.log(`property: ${property}`);return Reflect.get(target, property);}};console.log(Reflect.get(person, 'name')); // 输出 "property: name",并且返回 undefinedconsole.log(person.name); // 输出 undefined
4. proxy代理的应用
1. 拦截和定制对象操作
通过代理,你可以使用捕获器(例如 get、set、apply 等)来拦截和定制对象上的操作。也就是在操作执行前后执行自定义逻辑,比如记录日志、验证数据、实现观察者模式等。
const handler = {get: function(target, property, receiver) {console.log(`Getting property: ${property}`);return Reflect.get(target, property, receiver);},set: function(target, property, value, receiver) {console.log(`Setting property: ${property} to ${value}`);return Reflect.set(target, property, value, receiver);}
};const proxy = new Proxy({}, handler);
proxy.name = 'John'; // 输出 "Setting property: name to John"
console.log(proxy.name); // 输出 "Getting property: name" 和 "John"
2. 数据验证和保护
通过代理,可以实现对对象属性的更严格的验证,以确保数据的完整性和安全性。
const validator = {set: function(target, prop, value) {if (prop === 'age' && (typeof value !== 'number' || value <= 0)) {throw new Error('请输入正确的年龄!');}return Reflect.set(target, prop, value);}
};const person = new Proxy({}, validator);
person.age = 30; // 设置成功
person.age = 'thirty'; // 抛出错误:请输入正确的年龄!
3. 观察者模式
通过代理,可以实现观察者模式,即对对象的变化进行监听,并在变化发生时执行相应的操作。
function createObservable(obj, onChange) {return new Proxy(obj, {set: function(target, prop, value, receiver) {onChange(prop, value);return Reflect.set(target, prop, value, receiver);}});
}const user = { name: 'John', age: 30 };
const observedUser = createObservable(user, (prop, value) => {console.log(`Property ${prop} changed to ${value}`);
});observedUser.age = 31; // 输出 "Property age changed to 31"
4. 动态属性生成
通过代理,可以动态生成属性的值,而不是静态地存储它们。
const dynamicProperties = new Proxy({}, {get: function(target, prop, receiver) {if (!(prop in target)) {target[prop] = `Dynamic value for ${prop}`;}return Reflect.get(target, prop, receiver);}
});console.log(dynamicProperties.name); // 输出 "Dynamic value for name"相关文章:
什么是proxy代理?
1. 什么是proxy代理 代理(Proxy)是 JavaScript 中一种非常强大而灵活的功能。代理允许你拦截并覆盖对象的默认行为,提供了一种拦截、定制和扩展对象操作的机制。 简单说,就是在访问对象属性或者赋值时,可以做一些额外…...
opencv-python读取的图像分辨率太大不能完全显示
如果使用OpenCV-Python读取的图像分辨率太大,无法完全显示在屏幕上,可以考虑以下几种方法: 1.缩放图像:使用OpenCV的resize函数,将图像缩小到适合屏幕显示的大小。例如,可以将图像的宽度和高度都缩小到屏幕…...
【ArcGIS Pro微课1000例】0038:基于ArcGIS Pro的人口密度分析与制图
文章目录 一、人口密度二、人口密度分析1. 点密度分析2. 核密度分析三、结果比对一、人口密度 人口密度是指单位土地面积上居住的人口数,通常以每平方千米或每公顷内的常住人口为单位计算。人口密度同资源、经济密切结合,因此,科学准确地分析人口密度的分布情况,对合理制定…...
Python 安装Vue依赖包发生异常:npm ERR! notsup Required: {“node“:“^18.17.0 || >=20.5.0“}
异常: 原因:node和npm要求升级为高版本 解决:重新安装node环境 (1) 官网下载Node.js (2)双击安装node.js (3)运行查看...
TypeScript 项目 Airbnb 语法风格 ESLint 配置
TypeScript 项目 Airbnb 语法风格 ESLint 配置 1. 配置 安装: npm i -D eslint-config-airbnb-typescript typescript-eslint/eslint-plugin^6.0.0 typescript-eslint/parser^6.0.0配置: .eslintrc.js: module.exports {root: true,env: {node: true…...
怎么使用sentinel,以及所有的知识点
Sentinel是一个开源的流量控制和实时监控系统,主要用于保护企业级应用程序免受不良的请求。下面是使用Sentinel需要了解的知识点: 1. 什么是流量控制? 流量控制指的是限制应用程序的请求流量,防止过多的请求超出系统的承受范围。…...
中国一年有457万人确诊癌症!医生提示:这4种食物,再爱吃也要管住嘴
癌症是威胁人类生命健康的重大疾病,癌症的发生因素一直以来都是专家学者重点探索的课题。据世卫组织最新公布的数据显示,食物或与癌症发生之间存在着密切的联系,某些食物的摄入过多可能会增加患癌症的风险,所以我们应该警惕&#…...
小程序项目:springboot+vue基本微信小程序的宠物领养系统
项目介绍 当今科技发展迅速,交通环境也变得越来越复杂。人们的出行方式变得多元化,这给视障人士带来了一定的困扰。而导盲犬可以帮助视障人士外出行走,提高他们的生活质量。在我国,导盲犬的数量远远少于视障人士的数量。由于导盲…...
数据挖掘 K近邻
什么时候用K近邻? 交叉验证的时候。最常见的交叉验证方法是K折交叉验证,其中数据集被均匀分成K个子集,称为折,然后执行K次训练和测试,每次选择不同的折作为测试集,其余的作为训练集。最后,将K次…...
项目去除git版本控制
我 | 在这里 🕵️ 读书 | 长沙 ⭐软件工程 ⭐ 本科 🏠 工作 | 广州 ⭐ Java 全栈开发(软件工程师) 🎃 爱好 | 研究技术、旅游、阅读、运动、喜欢流行歌曲 ✈️已经旅游的地点 | 新疆-乌鲁木齐、新疆-吐鲁番、广东-广州…...
ICMPv6报文与邻居状态跟踪
ICMPv6报文 ICMPv6(Internet Control Message Protocol for the IPv6)是IPv6的基础协议之一。 在IPv4中,Internet控制报文协议ICMP(Internet Control Message Protocol)向源节点报告关于向目的地传输IP数据包过程中的错误和信息。它为诊断、信息和管理目的定义了一些消息…...
React中通过children prop或者React.memo来优化子组件渲染【react性能优化】
文章目录 前言未优化之前的代码问题解决方案一,通过children prop解决方案二,通过React.memo后言 前言 hello world欢迎来到前端的新世界 😜当前文章系列专栏:react.js 🐱👓博主在前端领域还有很多知识和…...
「Verilog学习笔记」含有无关项的序列检测
专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点,刷题网站用的是牛客网 timescale 1ns/1ns module sequence_detect(input clk,input rst_n,input a,output reg match);reg [8:0] a_tem ; always (posedge clk or negedge rst_n) begin if (~rs…...
k8s部署的java服务查看连接nacos缓存的配置文件
一、问题描述 k8s部署的java服务,使用nacos中的配置文件,需要在缓存中查看该服务具体是使用到了哪些配置文件 二、解决 参考文档: https://nacos.io/zh-cn/docs/system-configurations.html 文档描述如下: 进入java服务容器进入用户目录下的nacos&a…...
【matlab程序】matlab给风速添加图例大小
【matlab程序】matlab给风速添加图例大小 clear;clc;close all; % load 加载风速数据。 load(matlab.mat) % 加载颜色包信息 gray load(D:\matlab_work\函数名为colormore的颜色索引表制作\R_color_txt\R_color_single\gray89.txt); brown load(D:\matlab_work\函数名为color…...
微服务学习|初识MQ、RabbitMQ快速入门、SpringAMQP
初识MQ 同步通讯和异步通讯 同步通讯是实时性质的,就好像你用手机与朋友打视频电话,但是,别人再想与你视频就不行了,异步通讯不要求实时性,就好像你用手机发短信,好多人都能同时给你发短信,你…...
【开源】基于Vue.js的固始鹅块销售系统
项目编号: S 060 ,文末获取源码。 \color{red}{项目编号:S060,文末获取源码。} 项目编号:S060,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 鹅块类型模块2.3 固…...
SpringCloud微服务网关Gateway:gateway基本实现、断言工厂、过滤器工厂、浏览器同源策略、跨域问题解决方案
Gateway网关 Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0和Project Reactor 等响应式编程和事件流技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API路由管理方式 为什么…...
ArcGIS中如何建立土地利用规划数据库
一、建库步骤 - 收集土地利用规划资料,包括图件资料、数据资料和文本资料。 - 将收集到的数据进行整理和格式转换,使其符合ArcGIS 的数据格式要求。 - 在ArcGIS 中创建新的土地利用规划数据库,并定义相应的数据结构和字段。 - 将转换后的数据导入到新的土地利用规划数据库中…...
微信小程序 服务端返回富文本,图片无法显示
场景: 微信小程序开发中,需要从服务端拿取数据渲染到页面上,后台返回的富文本里,图片路径有时是没有带域名前缀的,导致图片无法正常显示。 解决方案: 在富文本返回时,用正则匹配&#…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
