javascript的Proxy

1. 什么是Proxy

Proxy是ES6中新增的一个特性,它可以拦截对象的操作,提供了一个中间层来控制对目标对象的访问。简单来说,它可以对对象进行代理,从而实现对对象的监控、修改、过滤等操作。

2. 为什么出现Proxy

在JavaScript中,对象的属性可以被任意修改,这就会导致一些安全问题和难以调试的问题。Proxy的出现就是为了解决这些问题,它可以拦截对象的操作,从而实现对对象的监控和控制。

3. 怎么使用Proxy

使用Proxy需要创建一个Proxy对象,它接收两个参数:目标对象和一个处理程序对象。处理程序对象中定义了一些拦截器方法,用于拦截目标对象的操作。

下面是一个简单的例子:

let target = {name: 'Tom',age: 18
};let handler = {get(target, propKey) {console.log('get操作');return target[propKey];},set(target, propKey, value) {console.log('set操作');target[propKey] = value;}
};let proxy = new Proxy(target, handler);console.log(proxy.name); // 输出:get操作 Tom
proxy.age = 20; // 输出:set操作
console.log(proxy.age); // 输出:get操作 20

在上面的例子中,我们创建了一个目标对象target和一个处理程序对象handler,然后使用它们来创建了一个代理对象proxy。在代理对象中,我们定义了get和set拦截器方法,用于拦截目标对象的读取和修改操作。当我们对代理对象进行读取和修改操作时,会触发相应的拦截器方法。

4. 解决什么问题

使用Proxy可以解决一些安全问题和难以调试的问题,例如:

  • 对象的属性可以被任意修改,使用Proxy可以控制对对象的修改操作。
  • 对象的属性访问不够直观,使用Proxy可以实现对属性访问的监控和控制。
  • 对象的属性访问不够安全,使用Proxy可以实现对属性访问的过滤和检查。

5. Proxy的API和Proxy实例的讲解

Proxy提供了一些API和实例方法,用于实现对目标对象的拦截和控制。下面是一些常用的API和实例方法:

  • Proxy.revocable(target, handler):创建一个可撤销的代理对象。
  • Proxy.isRevoked(proxy):判断一个代理对象是否已经被撤销。
  • Proxy.apply(target, thisArg, args):拦截函数的调用操作。
  • Proxy.construct(target, args):拦截new操作符。
  • Proxy.defineProperty(target, propKey, propDesc):拦截Object.defineProperty()操作。
  • Proxy.deleteProperty(target, propKey):拦截delete操作。
  • Proxy.get(target, propKey, receiver):拦截属性读取操作。
  • Proxy.set(target, propKey, value, receiver):拦截属性设置操作。
  • Proxy.has(target, propKey):拦截in操作符。
  • Proxy.getOwnPropertyDescriptor(target, propKey):拦截Object.getOwnPropertyDescriptor()操作。
  • Proxy.getPrototypeOf(target):拦截Object.getPrototypeOf()操作。
  • Proxy.setPrototypeOf(target, proto):拦截Object.setPrototypeOf()操作。
  • Proxy.isExtensible(target):拦截Object.isExtensible()操作。
  • Proxy.preventExtensions(target):拦截Object.preventExtensions()操作。
  • Proxy.ownKeys(target):拦截Object.getOwnPropertyNames()和Object.getOwnPropertySymbols()操作。

1. Proxy构造函数

Proxy构造函数用于创建一个代理对象,它接收两个参数:目标对象和handler对象。其中,目标对象是被代理的对象,handler对象包含了一系列拦截器方法,用于拦截目标对象的各种操作。

下面是Proxy构造函数的基本使用流程和思路:

const target = {}; // 目标对象
const handler = {}; // handler对象const proxy = new Proxy(target, handler); // 创建代理对象

在上面的代码中,我们创建了一个空对象作为目标对象,并创建了一个空对象作为handler对象。然后,我们使用Proxy构造函数创建了一个代理对象proxy,它将目标对象target和handler对象绑定在一起。

2. handler对象

handler对象包含了一系列拦截器方法,用于拦截目标对象的各种操作。这些方法在代理对象proxy被访问时被调用,它们接收两个参数:目标对象和操作参数。

下面是handler对象的基本使用流程和思路:

const handler = {get(target, key) {console.log(`Getting ${key} from target`);return target[key];},set(target, key, value) {console.log(`Setting ${key} to ${value}`);target[key] = value;},// 其他拦截器方法
};const proxy = new Proxy({}, handler); // 创建代理对象

在上面的代码中,我们定义了两个拦截器方法get和set,它们分别用于拦截目标对象的读取和写入操作。当代理对象proxy被访问时,这些方法会被调用,并输出相应的信息。

3. Proxy实例的API基本使用流程和思路

除了上面提到的get和set方法之外,handler对象还包括了许多其他拦截器方法,用于拦截目标对象的各种操作。下面是一些常用的拦截器方法及其基本使用流程和思路:

  • get
    get方法会在读取属性时被调用,它接收三个参数:target、prop和receiver。其中,target表示被代理的对象,prop表示被访问的属性名,receiver表示操作发生的对象。在get方法中,我们可以返回任何值,以便代理对象继续执行后续操作。如果我们不想让属性被访问,可以抛出一个错误。
const handler = {get: function(target, prop, receiver) {console.log(`Getting ${prop}`);if (prop === 'password') {throw new Error('Access denied');}return Reflect.get(target, prop, receiver);}
};

在上面的代码中,我们对password属性进行了限制,如果访问该属性,就会抛出一个错误。

  • set
    set方法会在设置属性时被调用,它接收四个参数:target、prop、value和receiver。其中,target表示被代理的对象,prop表示要设置的属性名,value表示要设置的属性值,receiver表示操作发生的对象。在set方法中,我们可以对属性值进行修改,或者抛出一个错误以阻止属性值被设置。
const handler = {set: function(target, prop, value, receiver) {console.log(`Setting ${prop} to ${value}`);if (prop === 'password') {throw new Error('Access denied');}return Reflect.set(target, prop, value, receiver);}
};

在上面的代码中,我们对password属性进行了限制,如果设置该属性,就会抛出一个错误。

  • has
    has方法会在判断属性是否存在时被调用,它接收两个参数:target和prop。其中,target表示被代理的对象,prop表示要判断的属性名。在has方法中,我们可以返回一个布尔值,表示属性是否存在。
const handler = {has: function(target, prop) {console.log(`Checking if ${prop} exists`);return Reflect.has(target, prop);}
};

在上面的代码中,我们输出了一个日志,然后调用了Reflect.has方法来判断属性是否存在。

  • apply方法:用于拦截函数的调用操作
const handler = {apply(target, thisArg, args) {console.log(`Calling ${target.name} with arguments: ${args}`);return target.apply(thisArg, args);},
};function sum(a, b) {return a + b;
}const proxy = new Proxy(sum, handler);proxy(1, 2); // 输出 "Calling sum with arguments: 1,2"

在上面的代码中,我们定义了一个拦截器方法apply,它用于拦截函数的调用操作。当代理对象proxy被调用时,这个方法会被调用,并输出相应的信息。

  • getPrototypeOf方法:用于拦截获取目标对象的原型操作
const handler = {getPrototypeOf(target) {console.log(`Getting prototype of target`);return Object.getPrototypeOf(target);},
};const obj = {};
const proxy = new Proxy(obj, handler);Object.getPrototypeOf(proxy); // 输出 "Getting prototype of target"

在上面的代码中,我们定义了一个拦截器方法getPrototypeOf,它用于拦截获取目标对象的原型操作。当代理对象proxy被访问时,这个方法会被调用,并输出相应的信息。

  • has方法:用于拦截in操作符的操作。
const handler = {has(target, key) {console.log(`Checking if ${key} is in target`);return key in target;},
};const obj = { a: 1 };
const proxy = new Proxy(obj, handler);"a" in proxy; // 输出 "Checking if a is in target"

在上面的代码中,我们定义了一个拦截器方法has,它用于拦截in操作符的操作。当代理对象proxy被访问时,这个方法会被调用,并输出相应的信息。

  • deleteProperty方法:用于拦截delete操作符的操作。
const handler = {deleteProperty(target, key) {console.log(`Deleting ${key} from target`);delete target[key];},
};const obj = { a: 1 };
const proxy = new Proxy(obj, handler);delete proxy.a; // 输出 "Deleting a from target"

在上面的代码中,我们定义了一个拦截器方法deleteProperty,它用于拦截delete操作符的操作。当代理对象proxy被访问时,这个方法会被调用,并输出相应的信息。

6. Proxy的使用场景

使用Proxy可以实现很多功能,例如:

  • 实现数据绑定:可以通过拦截属性设置操作来实现数据绑定。
  • 实现数据校验:可以通过拦截属性设置操作来实现数据校验。
  • 实现数据缓存:可以通过拦截属性读取操作来实现数据缓存。
  • 实现缓存代理:可以通过拦截函数调用操作来实现缓存代理。

7. Proxy的注意事项

使用Proxy需要注意以下几点:

  • Proxy不支持原型继承,即代理对象不能继承原始对象的原型链。
  • Proxy不支持一些内置方法的代理,例如toString()、valueOf()等方法。
  • Proxy不支持直接修改代理对象,必须通过拦截器方法进行修改。
  • Proxy的拦截器方法中,必须返回一个合法的值,否则会报错。

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

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

相关文章

在re:Invent上IBM宣布与亚马逊云科技携手,Amazon RDS for DB2正式亮相

11月29日,IBM在亚马逊云科技re:Invent 2023上宣布,与亚马逊云科技合作推出Amazon Relational Database Service(Amazon RDS)for Db2。这项全新的完全托管云服务旨在简化客户在混合云环境中管理人工智能(AI)…

electron-vue运用及案例代码

前言 Electron是一个使用JavaScript, HTML和CSS构建跨平台桌面应用程序的开源库。它允许开发者使用纯web技术创建原生应用程序,这使得web开发者能够利用他们已经掌握的web技术来构建桌面应用。 以下是一个简单的Electron应用程序的代码示例: // 引入Electron的主模块 co…

MDK5改造之格式化以及文件函数注释插件和主题应用

MDK5插件以及主题应用 前言一、主题修改1、主题文件下载2、主题应用 二、插件安装以及使用1.下载插件2、插件使用步骤 前言 为了写代码的心应手,先对MDK5进行改造 提示:以下是本篇文章正文内容,下面案例可供参考 🎉参考了其他大师…

结合贝叶斯定理浅谈商业银行员工异常行为排查

1.贝叶斯定理的数学表达 贝叶斯方法依据贝叶斯定理。关于贝叶斯定理解释如下:首先我们设定在事件B条件下,发生事件A的条件概率,即 ,从数学公式上,此条件概率等于事件A与事件B同时发生的概率除以事件B发生的概率。 上述…

代码随想录训练营第五十二天1143.最长公共子序列1035.不相交的线53. 最大子序和

1143.最长公共子序列 题目链接 1143. 最长公共子序列 - 力扣(LeetCode) 讲解链接 代码随想录 (programmercarl.com) 给定两个数组,求最长公共子序列,此时dp数组需要用二维的,dp[i][j]表示下表i-1.j-1所能拥有的最长公共…

状态模式-C++实现

状态模式是一种行为型设计模式,它允许对象内部状态发生改变时改变其行为,它将行为封装在不同的状态对象中,在运行时通过切换不同的状态可以表现出不同的行为。 状态模式一般有三种角色: 1、状态接口:定义了状态对象所…

Fiddler抓包工具之Fiddler+willow插件应用

安装Fiddler的安装包地址:fillderwillow 解压后安装fiddler4和willow1.4.*版本。 安装成功后,启动fiddler后会出现willow插件按钮: 说明安装成功。 重定向 willow重定向 进入willow界面后,通过右键->Add Project ->Add Ru…

鸿蒙开发学习笔记

快速入门 配置网络权限 1.打开项目的 module.json5 文件 2.在module 里面写下面代码 3.这样就可以使用网络图片了 4.模拟器上就可以正常显示网络图片了 5.官方文档有相吸说明 6. 华为官方编辑工具使用技巧(内置文档),鼠标移动到标签上&…

对于Kotlin DSL的简单解析与使用

DSL(领域特定语言)是Kotlin所带来的强大语法特性之一,也是Java中所不存在的功能,JetBrain也基于DSL开发出了众多的开源库,Kotlin的开发者可以使用DSL来重构许多已有的代码,甚至有可能做到彻底抛弃HTML,XML,…

Mysql——》int(1)和 int(10)区别

推荐链接: 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…

【Python百宝箱】数据格式化大作战:探索Python强大的转换和验证库

前言 在现代数据处理和转换的领域中,Python成为了一种强大而灵活的工具。数据格式的转换和验证对于数据科学家、工程师和分析师而言是至关重要的任务。本文将介绍一系列Python库,它们能够处理各种数据格式,从JSON、XML到Excel和Pickle等&…

electron持久化cookie的方法,从session中获取

文章目录 1. 持久化方法2. 代码说明3. 补充 1. 持久化方法 session.defaultSession.cookies.get({}).then((cookies) > {// 恢复cookie现场cookies.forEach((cookiesItem) > {let { secure false, domain "", path "" } cookiesItem;BrowserWin…

零基础打靶—CTF4靶场

一、打靶的主要五大步骤 1.确定目标:在所有的靶场中,确定目标就是使用nmap进行ip扫描,确定ip即为目标,其他实战中确定目标的方式包括nmap进行扫描,但不局限于这个nmap。 2.常见的信息收集:比如平常挖洞使用…

Python标准库:math库【侯小啾python领航班系列(十六)】

Python标准库:math库【侯小啾python领航班系列(十六)】 大家好,我是博主侯小啾, 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ…

【每日一题】找出叠涂元素

文章目录 Tag题目来源题目解读解题思路方法一:哈希表 写在最后 Tag 【哈希表】【数组】【2023-12-01】 题目来源 2661. 找出叠涂元素 题目解读 从左往右遍历 arr 给矩阵 mat 上色,在上色的过程中矩阵的某一行或者某一列的全部被上色了,返回…

(C语言)找出1-99之间的全部同构数

同构数&#xff1a;它出现在平方数的右边。例&#xff1a;5是25右边的数&#xff0c;25是625右边的数&#xff0c;即5和25均是同构数。 #include<stdio.h> int main() {for(int i 1;i < 100;i ){if((i*i % 10 i) || (i*i % 100 i))printf("%d\t%d\n",i,…

第6章 异步爬虫

目录 1. 协程的基本原理1.1 案例引入1.2 基础知识阻塞非阻塞同步异步多进程协程 1.3 协程的用法1.4 定义协程1.5 绑定回调1.6 多任务协程1.7 协程实现1.8 使用aiohttp安装使用 2. aiohttp的使用2.1 基本介绍2.2 基本实例2.3 URL参数设置2.4 其他请求类型2.5 POST请求表单提交JS…

Java数据结构之《哈希查找》题目

一、前言&#xff1a; 这是怀化学院的&#xff1a;Java数据结构中的一道难度中等的一道编程题(此方法为博主自己研究&#xff0c;问题基本解决&#xff0c;若有bug欢迎下方评论提出意见&#xff0c;我会第一时间改进代码&#xff0c;谢谢&#xff01;) 后面其他编程题只要我写完…

ChatGPT成为“帮凶”:生成虚假数据集支持未知科学假设

ChatGPT 自发布以来&#xff0c;就成为了大家的好帮手&#xff0c;学生党和打工人更是每天都离不开。 然而这次好帮手 ChatGPT 却帮过头了&#xff0c;莫名奇妙的成为了“帮凶”&#xff0c;一位研究人员利用 ChatGPT 创建了虚假的数据集&#xff0c;用来支持未知的科学假设。…

HarmonyOS应用开发——程序框架UIAbility、启动模式与路由跳转

前言 UIAbility简单来说就是一种包含用户界面的应用组件&#xff0c;用于和用户进行交互。每一个UIAbility实例&#xff0c;对应于一个最近任务列表中的任务。 一个应用可以有一个UIAbility&#xff0c;也可以有多个UIAbility。一个UIAbility可以对应于多个页面&#xff0c;建议…