ES6 入门教程 15 Proxy 15.3 Proxy.revocable() 15.4 this 问题 15.5 实例:Web 服务的客户端

news2025/1/9 1:40:25

ES6 入门教程

ECMAScript 6 入门

作者:阮一峰

本文仅用于学习记录,不存在任何商业用途,如侵删

文章目录

      • ES6 入门教程
      • 15 Proxy
        • 15.3 Proxy.revocable()
        • 15.4 this 问题
        • 15.5 实例:Web 服务的客户端

15 Proxy

15.3 Proxy.revocable()

Proxy.revocable()方法返回一个可取消的 Proxy 实例。

let target = {};
let handler = {};

let {proxy, revoke} = Proxy.revocable(target, handler);

proxy.foo = 123;
proxy.foo // 123

revoke();
proxy.foo // TypeError: Revoked

在这里插入图片描述

Proxy.revocable()方法返回一个对象,该对象的proxy属性是Proxy实例,revoke属性是一个函数,可以取消Proxy实例。上面代码中,当执行revoke函数之后,再访问Proxy实例,就会抛出一个错误。

Proxy.revocable()的一个使用场景是,目标对象不允许直接访问,必须通过代理访问,一旦访问结束,就收回代理权,不允许再次访问。

15.4 this 问题

虽然 Proxy 可以代理针对目标对象的访问,但它不是目标对象的透明代理,即不做任何拦截的情况下,也无法保证与目标对象的行为一致。

主要原因就是在 Proxy 代理的情况下,目标对象内部的this关键字会指向 Proxy 代理。

const target = {
  m: function () {
    console.log(this === proxy);
  }
};
const handler = {};

const proxy = new Proxy(target, handler);

target.m() // false
proxy.m()  // true

在这里插入图片描述

上面代码中,一旦proxy代理targettarget.m()内部的this就是指向proxy,而不是target。所以,虽然proxy没有做任何拦截,target.m()proxy.m()返回不一样的结果。

下面是一个例子,由于this指向的变化,导致 Proxy 无法代理目标对象。

const _name = new WeakMap();

class Person {
  constructor(name) {
    _name.set(this, name);
  }
  get name() {
    return _name.get(this);
  }
}

const jane = new Person('Jane');
jane.name // 'Jane'

const proxy = new Proxy(jane, {});
proxy.name // undefined

上面代码中,目标对象janename属性,实际保存在外部WeakMap对象_name上面,通过this键区分。由于通过proxy.name访问时,this指向proxy,导致无法取到值,所以返回undefined

此外,有些原生对象的内部属性,只有通过正确的this才能拿到,所以 Proxy 也无法代理这些原生对象的属性。

const target = new Date();
const handler = {};
const proxy = new Proxy(target, handler);

proxy.getDate();
// TypeError: this is not a Date object.

在这里插入图片描述

上面代码中,getDate()方法只能在Date对象实例上面拿到,如果this不是Date对象实例就会报错。这时,this绑定原始对象,就可以解决这个问题。

const target = new Date('2015-01-01');
const handler = {
  get(target, prop) {
    if (prop === 'getDate') {
      return target.getDate.bind(target);
    }
    return Reflect.get(target, prop);
  }
};
const proxy = new Proxy(target, handler);

proxy.getDate() // 1

在这里插入图片描述

另外,Proxy 拦截函数内部的this,指向的是handler对象。

const handler = {
  get: function (target, key, receiver) {
    console.log(this === handler);
    return 'Hello, ' + key;
  },
  set: function (target, key, value) {
    console.log(this === handler);
    target[key] = value;
    return true;
  }
};

const proxy = new Proxy({}, handler);

proxy.foo
// true
// Hello, foo

proxy.foo = 1
// true

上面例子中,get()set()拦截函数内部的this,指向的都是handler对象。

15.5 实例:Web 服务的客户端

Proxy 对象可以拦截目标对象的任意属性,这使得它很合适用来写 Web 服务的客户端。

const service = createWebService('http://example.com/data');

service.employees().then(json => {
  const employees = JSON.parse(json);
  // ···
});

上面代码新建了一个 Web 服务的接口,这个接口返回各种数据。Proxy 可以拦截这个对象的任意属性,所以不用为每一种数据写一个适配方法,只要写一个 Proxy 拦截就可以了。

function createWebService(baseUrl) {
  return new Proxy({}, {
    get(target, propKey, receiver) {
      return () => httpGet(baseUrl + '/' + propKey);
    }
  });
}

同理,Proxy 也可以用来实现数据库的 ORM 层。

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

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

相关文章

BLDC的列子2

1.三相采样电流的采集以u相为举例。 采集下桥臂I-V的电压。在除以采样电阻。就可以得到采样电流。但由于I-V的电压比较小。 需要一个放大电路把电压放大ADC才采集的到。 放大后的电压是AMP_IU.用ADC去采集这个电压。从而算出I_V的电压。 在电机停止的时候也会有微小的电压。…

Azure 深入浅出[2] --- App Service的部署并查看应用Log

假设读者已经申请了Azure的免费订阅的账户。如果想部署一个前端NodeJS的服务到Azure的App Service应该如何部署并查看应用程序本身的日志呢?笔者在这边文章就带大家快速看一下。 1.环境准备 安装Visual Studio Code以及在Visual Studio Code里面安装Azure App Ser…

文件上传漏洞 | iwebsec

文章目录靶场搭建文件上传漏洞前端JS过滤绕过文件名过滤绕过Content-Type过滤绕过文件头过滤绕过.htaccess文件上传文件截断上传条件竞争文件上传靶场搭建 参考文章https://juejin.cn/post/7068931744547733517出现个小问题,我的端口冲突了,所以换了一个…

Linux-unbuntu修改apt源

本文介绍如何将ubuntu的apt源修改为清华大学的镜像源 主要是修改/etc/apt/source.list的文件,并且使用sudo apt-get update来刷新源 修改apt源 unbuntu安装好之后,apt的源是us的,这样下载速度比较慢 apt源的地址放在/etc/apt/source.list中…

SpringBoot SpringBoot 开发实用篇 4 数据层解决方案 4.14 ES 索引操作

SpringBoot 【黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)】 SpringBoot 开发实用篇 文章目录SpringBootSpringBoot 开发实用篇4 数据层解决方案4.14 ES 索引操作4.14.1 索引操作4.14.2 小结4 数据…

m基于OFDM数字电视地面广播系统中频域同步技术研究

目录 1.算法概述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法概述 OFDM技术的基本构架如下所示: 注意系统中的虚线部分就是你要做的OFDM的频域同步模块。我们的MATLAB代码就是参考这个系统结构进行设计的。其中虚线就是本课题要做的代码部分…

[附源码]java毕业设计停车场管理系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

day04 spring 声明式事务

day04 spring 声明式事务 1.JDBCTemplate 1.1 简介 为了在特定领域帮助我们简化代码,Spring 封装了很多 『Template』形式的模板类。例如:RedisTemplate、RestTemplate 等等,包括我们今天要学习的 JDBCTemplate。 1.2 准备工作 1.2.1 加…

Python之TCP网络编程

目录 1. python3编码转换 2. TCP网络应用程序开发 2.1 概述 2.2 开发流程 2.3 TCP客户端程序开发 2.4 TCP服务端程序开发 2.5 注意点 3. socket之send和recv原理 4. 案例 1. python3编码转换 1.网络传输是以二进制数据进行传输的。 2.数据转化用到了encode和decode函数…

ES6 入门教程 15 Proxy 15.2 Proxy 实例的方法 15.2.1 get()

ES6 入门教程 ECMAScript 6 入门 作者:阮一峰 本文仅用于学习记录,不存在任何商业用途,如侵删 文章目录ES6 入门教程15 Proxy15.2 Proxy 实例的方法15.2.1 get()15 Proxy 15.2 Proxy 实例的方法 拦截方法的详细介绍。 15.2.1 get() get方…

应急响应-进程排查

进程排查 进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。无论在Windows还是Linux中,主机在感染恶意程序后,恶意程序都会启动相应进程来完成恶意操作。 Window…

Android 深入理解View.post() 、Window加载View原理

文章目录背景:如何在onCreate()中获取View的宽高?View.post()原理Window加载View流程setContentView()ActivityThread#handleResumeActivity()总结扩展Window、Activity及View三者之间的关系是否可以在子线程中更新UI资料背景:如何在onCreate…

m认知无线电信号检测算法matlab仿真,能量检测,循环平稳检测以及自相关检测

目录 1.算法概述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法概述 频谱感测是认知无线电的一项关键技术。我们将频谱感知作为一个分类问题,提出一种基于深度学习分类的感知方法。我们归一化接收信号功率以克服噪声功率不确定性的影响。我们使…

postgresql源码学习(49)—— MVCC⑤-cmin与cmax 同事务内的可见性判断

一、 难以理解的场景 postgresql源码学习(十九)—— MVCC④-可见性判断 HeapTupleSatisfiesMVCC函数_Hehuyi_In的博客-CSDN博客 在前篇的可见性判断中有个一直没想明白的问题 —— 本事务插入的数据,什么场景可能会出现去查询获取快照后插入…

路面坑洼检测中的视觉算法

3D道路成像和路面坑洼检测的经典工作综述。论文链接:https://arxiv.org/pdf/2204.13590.pdf 计算机视觉算法在3D道路成像和路面坑洼检测中的应用已有二十多年的历史。这里先介绍了用于2D和3D道路数据采集的传感系统,包括摄像机、激光扫描仪和微软Kinect…

汉兰达汽车发动机怠速抖动故障诊断方案设计

目录 一、课题简介 1 1.1课题基本内容 1 1.2课题解决的主要问题 1 1.3课题设计思路 1 二、毕业设计成果 2 2.1汉兰达汽车发动机怠速抖动故障现象描述 2 2.2 汉兰达汽车发动机怠速抖动故障原因分析 2 2.3汉兰达汽车发动机怠速抖动故障诊断与排除 6 2.4维修结论与建议 12 三、毕业…

java sleep yield join区别

1、sleep:让出CPU调度,Thread类的方法,必须带一个时间参数。会让当前线程休眠进入阻塞状态并释放CPU(阿里面试题 Sleep释放CPU,wait 也会释放cpu,因为cpu资源太宝贵了,只有在线程running的时候&…

高效正则匹配工具

很多人都用过正则,但文章或许会给你一种全新的认识(思考) 以下内容适合高效率正则匹配(比较适合正则匹配场景较多的情况) 效率提升精华:本地缓存减少编译次数(对effective java的思考,以及对数据库连接中…

Java中的装包(装箱)和拆包(装包)

装箱和拆箱 在Java的学习中,我们有的时候会设计装箱和拆箱的概念(也就是常说的装包和拆包),这篇博客将详细讲解一下装箱和拆箱的概念及其用途。 装箱(装包):将基本数据类型转换成包装类类型 拆…

websocket给指定客户端推送消息

业务场景 最近有一个业务场景是要做实时语音转义,考虑到实时性,所以决定采用websocket实现。 业务场景是A客户端(手机)进行语音转义的结果实时同步到B客户端(pc),这就需要用到websocket将A转义的结果发送给服务端,服务端接收到A…