Javascript Proxy对象 简介

Javascript Proxy对象 简介

本文转载自:众成翻译
译者:eJayYoung
链接:http://www.zcfy.cc/article/4755
原文:https://blog.campvanilla.com/advanced-guide-javascript-proxy-objects-introduction-301c0fce9432

Javascript Proxy对象

改变你操作对象的方式

Proxies 是Javasript对象的中间件

…或者说至少是那种很早的版本。

ES6 中引入Proxies,让你可以自定义Object的基本操作。例如,get就是Object的基础操作方法。

const obj = {val: 10
};
console.log(obj.val);

这里,console.log()表达式在对象obj上执行get方法来获取val的值。

另一个对象的基本操作方法是 set

const obj = {val: 10
};
obj.val2 = 20;

这里,set方法用来给对象obj设置一个新的值。


如何创建Proxy?

const proxiedObject = new Proxy(initialObj, handler);

调用Proxy构造函数,new Proxy()将返回一个对象,不仅包含了initialObj里的值,而且其基本操作(如getset)现在可以通过handler对象来指定一些自定义逻辑。

我们写个例子来理解这个概念,

const handler = {get: function() {console.log('A value has been accessed');}
}const initialObj = {id: 1,name: 'Foo Bar'
}const proxiedObj = new Proxy(initialObj, handler);console.log(proxiedObj.name);

现在,如果我们没有构造一个Proxy对象,执行第14行的console.log(proxiedObj.name)会在控制台输出 “Foo Bar”。

不过现在我们定义了一个Proxy,并在第三行get方法中定义了一些自定义逻辑。

现在执行console.log(proxiedObj.name)会在控制台输出 “A value has been accessed”。

仔细看,你会发现控制台中实际上有两条记录。 “A value has been accessed” 和 undefined。 为什么?��

get运算符的默认实现是返回Object中存储的值。由于我们将它重写为只记录一条语句,该值永远不会返回,因此第14行的console.log()输出undefined

让我们来解决这个问题!

get运算符有两个参数 - 对象本身和被访问的属性。

const handler = {get: function(obj, prop) {console.log('A value has been accessed');return obj[prop]; // 返回访问的key在obj的值}
}const initialObj = {id: 1,name: 'Foo Bar'
}const proxiedObj = new Proxy(initialObj, handler);console.log(proxiedObj.name);

返回属性值


返回属性值 — 控制台的输出

好多了吧! ��

我们为get提供的自定义覆盖被称为“拦截器”(大概基于操作系统拦截的概念)。 handler对象基本上是一个包含一组“拦截”的对象,每当访问对象属性时都会被触发。

我们给set也添加一个“拦截器”。 我们将做同样的事情 - 任何时候设置一个值,我们将记录被修改的属性,以及为该键设置的值。

set操作符有三个参数 - 对象本身,被访问的属性和为该属性设置的值。

const handler = {get: function(obj, prop) {console.log('A value has been accessed');return obj[prop];},set: function(obj, prop, value) {console.log(`${prop} is being set to ${value}`);}
}const initialObj = {id: 1,name: 'Foo Bar'
}const proxiedObj = new Proxy(initialObj, handler);proxiedObj.age = 24

添加set “拦截器”

这里,在第18行进行的访问将触发第6行定义的功能,该功能将记录正在访问的属性和正在设置的值。

Set “拦截器” —— 控制台的输出


一个真实的例子

假设我们有一个定义叫person的对象

const person = {id: 1,name: 'Foo Bar'
};

如果我们想让这个对象的id属性是一个私有属性呢? 没人能够通过person.id访问这个属性,如果有人这样做,我们需要抛出一个错误。 我们将如何做到这一点?

让Proxies来拯救吧!����‍��

我们所需要做的就是给这个对象创建一个Proxy,并覆盖get运算符来阻止我们访问id属性!

const handler = {get: function(obj, prop) {if (prop === 'id') { // Check if the id is being accessedthrow new Error('Cannot access private properties!'); // Throw an error} else {return obj[prop]; // If it's not the id property, return it as usual}}
}const person = {id: 1,name: 'Foo Bar'
}const proxiedPerson = new Proxy(person, handler);console.log(proxiedPerson.id);

阻止访问私有属性

这里,在我们给get创建的“拦截器”,我们检查被访问的属性是否是id属性,如果是的话,我们会抛出一个错误。 否则,我们照常返回值。

私有属性 — 控制台输出


另一个极好的用例是校验。 通过设置set“拦截器”,我们可以在设置值之前添加自定义验证。 如果该值不符合验证,我们可以抛出一个错误!

const handler = {set: function(obj, prop, value) {if (typeof value !== 'string') {throw new Error('Only string values can be stored in this object!');} else {obj[prop] = value;}}
}const obj = {};const proxiedObj = new Proxy(obj, handler);console.log(proxiedObj); // This will log an empty object
proxiedObj.name = 'Foo Bar'; // This should be allowed
console.log(proxiedObj); // This will log an object with the name property setproxiedObj.age = 24; // This will throw an error.

自定义对象的属性校验

自定义校验 - 控制台输出


在上面的例子中,我们已经看到了getset“陷阱”。 实际上可以设置更多的“陷阱”。 你可以在这里找到整个列表。

Proxy对象只是在阅读关于它们的这篇文章之后才进入我的视野,我已经可以在我每天写的代码中看到它们的用处了!

如果你之前在项目或工作中使用过Proxies,我很乐意听到!��

~最后~


如果您觉得这篇文章对您有用,请点个赞��!

在什么地方卡住了,需要更多的帮助,还是只想打个招呼? 在Hashnode 给我直接发问题,或者在Twitter上Call我。 你也可以在Github上找到我。��

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

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

相关文章

App架构经验总结

原文地址:http://www.iteye.com/news/31472-------------------------------------------------------------架构因人而异,不同的架构师大多会有不同的看法;架构也因项目而异,不同的项目需求不同,相应的架构也会不同。…

python数字排序 循环_【python-leetcode448-循环排序】找到所有数组中消失的数字

问题描述:给定一个范围在 1 ≤ a[i] ≤ n ( n 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次。找到所有在 [1, n] 范围之间没有出现在数组中的数字。您能在不使用额外空间且时间复杂度为O(n)的情况下完成这个任务吗…

携程Docker实践

原文地址:http://www.iteye.com/news/31468 请点击原文阅读 ---------------------以下是原文---------------------- 从去年底开始,携程开始计划把Docker引入到携程的云平台,这是系统研发部一部分的工作任务,携程系统研…

mysql全文索引thinkphp_ThinkPHP5 使用迅搜 (XunSearch) 实现全文检索实例指导

前期准备入坑了一天,折腾的无语,个人观点:【文档太差,适合学习思路,不建议入坑】背景最近在整理全文检索解决方案注意到 xunsearch 的评价很高,在此记录一番场景描述此处作为对 xunsearch 的初次使用&#…

为何有些程序员总是想要“干掉”产品经理?

好了,我准备去和产品经理做斗争去了,请祝我好运吧!小编花了大量时间收集了很多干货编程学习资源,其中资源包括 算法,大数据,人工智能,Python,Android,iOS,Jav…

Spark算子篇 --Spark算子之combineByKey详解

一。概念 rdd.combineByKey(lambda x:"%d_" %x, lambda a,b:"%s%s" %(a,b), lambda a,b:"%s$%s" %(a,b))三个参数(都是函数)第一个参数:给定一个初始值,用函数生成初始值。第二个参数:c…

SecureCRT防止自动断开

今天在宁波连接上海的linux库,是外网访问内网,使用了nat123这个软件映射的。 发现SecureCRT连接后,过几分钟就自动断开,导致使用SecureCRT做跳转机的其他应用使用起来很不方便。 于是设置了下SecureCRT。

AI工程师职业规划和学习路线完整版

AI工程师职业规划和学习路线完整版 如何成为一名机器学习算法工程师 成为一名合格的开发工程师不是一件简单的事情,需要掌握从开发到调试到优化等一系列能 力,这些能力中的每一项掌握起来都需要足够的努力和经验。而要成为一名合格的机器学习算法工程师&…

oracle 多个with as

主要看多个with的格式 [sql] view plaincopy WITH T3 AS ( SELECT T1.ID, T1.CODE1, T2.DESCRIPTION FROM TB_DATA T1, TB_CODE T2 WHERE T1.CODE1 T2.CODE ), T4 AS ( SELECT T1.ID, T1.CODE2, T2.DESCRIPTION FROM TB_DATA T1, TB_CODE T2 WHERE T1.C…

mysql主键 命中率_mysql主键问题

MySQL主键一. MySQL主键设计原则MySQL主键应当是对用户没有意义的。MySQL主键应该是单列的,以便提高连接和筛选操作的效率(当然复合主键是可以的,只是不建议)永远也不要更新MySQL主键MySQL主键不应包含动态变化的数据,如时间戳、创建时间列、…

hadoop SecondNamenode

一、定义 * The Secondary Namenode is a helper to the primary Namenode. * The Secondary is responsible for supporting periodic checkpoints * of the HDFS metadata. The current design allows only one Secondary * Namenode per HDFs cluster. * The Secondary Nam…

高性能mysql 小查询_高性能MySql进化论(十一):常见查询语句的优化

总结一下常见查询语句的优化方式1 COUNT1. COUNT的作用 COUNT(table.filed)统计的该字段非空值的记录行数 COUNT(*)或者是COUNT(not nullable field) 统计的是全表的行数如果要是统计全表记录数,COUNT(*)效率会比COUNT(not nullable fie…

首席架构师徐海峰眼中的架构和出色的架构师

CSDN架构领域编辑采访了一些与会讲师,谈谈他们将在会上分享的内容、相关技术和程序人生,带你领略讲师风采。 本期我们采访的讲师是来自阅文集团首席架构师徐海峰,主要负责内容中心的网站架构和分布式存储、分布式计算工作。10年互联网开发经验…

hadoop-eclipse-plugin使用

下载hadoop安装包:http://www.carfab.com/apachesoftware/hadoop/common/hadoop-1.0.2/ 但是没有plugin,我到这个地方下载的:http://ishare.iask.sina.com.cn/f/23642243.html?fromlikecopy到你的eclipse_home的plugins下面。配置map/reduce…

java 记事本界面_JAVA/GUI程序之记事本

自上半年JAVA课程结束后,再也没有看过JAVA了,最近不是很忙,又简单的看了看,本博客纯属记录学习过程,请大神们别笑,其中错误是难免的,毕竟是新手写的博客。下面就进入我们的正题吧,复…

mapper-reducer word count 实例

统计一个文件里各单词的个数,假设这个文件很大。 原理如下图: 编写代码: WCMapper.java package zengmg.hadoop.mr.wordcount;import java.io.IOException;import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; …

MR程序的几种提交运行模式

MR程序的几种提交运行模式 本地模型运行 1/在windows的eclipse里面直接运行main方法,就会将job提交给本地执行器localjobrunner执行 ----配置path:D:\hadoop-2.7.2\bin ----配置hadoop_home:D:\hadoop-2.7.2 ----复制 hadoop.dll和winutil…

零点起飞学java视频_零点起飞学java (刘升华) 高清PDF_IT教程网

资源名称:零点起飞学java (刘升华) 高清PDF第1篇 java开发基础第1章 java概述( 教学视频:37分钟) 2第2章 基本数据类型及运算( 教学视频:52分钟) 14第3章 java程序流程控制( 教学视频:33分钟) 36第4章 类与对…

vector 修改 java_java对vector动态数组中的对象排序,以下代码有何问题,如何修改?...

展开全部package com.tx.collection;import java.util.Comparator;import java.util.Iterator;import java.util.Map;import java.util.Set;import java.util.TreeMap;import java.util.TreeSet;import java.util.Vector;public class Student {String name;int score;public S…

hadoop的序列化与java的序列化区别

java的序列化机制 java序列化时会把具体类的数据和类的继承结构信息都序列化传递。如下图hadoop的序列化机制 序列化类的数据,但是不序列化类的继承结构信息。 网络传递的时候就少了很多流量,hadoop也不需要类的继承关系,只要类的数据就够…