Proxy 的 this 问题

虽然 Proxy 可以代理针对目标对象的访问,但它不是目标对象的透明代理,即不做任何拦截的情况下,也无法保证与目标对象的行为一致。主要原因就是在 Proxy 代理的情况下,目标对象内部的this关键字会指向 Proxy 代理。

  1. const target = {
  2. m: function () {
  3. console.log(this === proxy);
  4. }
  5. };
  6. const handler = {};
  7. const proxy = new Proxy(target, handler);
  8. target.m() // false
  9. proxy.m() // true

上面代码中,一旦proxy代理target.m,后者内部的this就是指向proxy,而不是target

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

  1. const _name = new WeakMap();
  2. class Person {
  3. constructor(name) {
  4. _name.set(this, name);
  5. }
  6. get name() {
  7. return _name.get(this);
  8. }
  9. }
  10. const jane = new Person('Jane');
  11. jane.name // 'Jane'
  12. const proxy = new Proxy(jane, {});
  13. proxy.name // undefined

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

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

  1. const target = new Date();
  2. const handler = {};
  3. const proxy = new Proxy(target, handler);
  4. proxy.getDate();
  5. // TypeError: this is not a Date object.

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

  1. const target = new Date('2015-01-01');
  2. const handler = {
  3. get(target, prop) {
  4. if (prop === 'getDate') {
  5. return target.getDate.bind(target);
  6. }
  7. return Reflect.get(target, prop);
  8. }
  9. };
  10. const proxy = new Proxy(target, handler);
  11. proxy.getDate() // 1

es6 Proxy 的 this 问题相关推荐

  1. ES6 Proxy 性能之我见

    ES6 Proxy 性能之我见 本文翻译自https://thecodebarbarian.com/thoughts-on-es6-proxies-performance Proxy是ES6的一个强力 ...

  2. es6 --- Proxy的属性(get、set除外)

    apply(): 拦截函数的调用.call和apply操作 var target = function () { return 'I am the target';}; var handler = { ...

  3. es6 --- Proxy实例的get方法

    写一个拦截函数,访问目标对象不存在属性时,会抛出不存在该属性的错误 如果存在该属性时,就返回其值. var person = {name: "张三" };var proxy = n ...

  4. 第十二节:ES6 Proxy代理 和 去银行存款有什么关系?

    ES:给开发者提供了一个新特性:Proxy,就是代理的意思.也就是我们这一节要介绍的知识点. 以前,ATM还没有那么流行的时候(暴露年纪),我们去银行存款或者取款的时候,需要在柜台前排队,等柜台工作人 ...

  5. ES6 Proxy和Reflect (上)

    Proxy概述 Proxy用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种"元编程"(meta programming),即对编程语言进行编程. Proxy可以理 ...

  6. es6 Proxy 简介

    Proxy 简介 Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种"元编程"(meta programming),即对编程语言进行编程. Proxy ...

  7. 深入实践 ES6 Proxy Reflect

    原文: https://zhuanlan.zhihu.com/p/60126477 引言 Vue中的数据绑定 Vue作为前端框架的三驾马车之一,在众多前端项目中具有极其重要的作用. Vue中具有一个重 ...

  8. ES6 Proxy 和 Reflect 的理解

    Vue中的数据绑定 ps:观察者模式 (下面有重点) Vue作为前端框架的三驾马车之一,在众多前端项目中具有极其重要的作用. Vue中具有一个重要的功能点--"数据绑定".使用者无 ...

  9. ES6 Proxy和Reflect

    目录 Proxy 概述 基本用法 Proxy 实例方法 1.get(target, propKey, receiver) 2.set(target, propKey, value, receiver) ...

  10. es6 proxy代理

    es6 新增构造函数 Proxy Proxy 构造函数,可以使用new 去创建,可以往里面插入两个参数,都是对象 let target = {} let handler = {} let proxy ...

最新文章

  1. 阿里大佬总结的算法进阶指南,助你进大厂!
  2. [转载]IT知识体系结构图
  3. ASP:关于生成HTML文件的新闻系统
  4. 牛客16654 谁拿了最多奖学金
  5. 从零开始理解JAVA事件处理机制(3)
  6. maven eclipse操作
  7. 25服务端_手把手教你使用 OpenResty 搭建高性能服务端!
  8. MongoDB的江湖传说
  9. centos 7的systemctl
  10. 文本聚类kmeans
  11. C语言期末试卷华师,2020华中师大计算机考研经验帖(已上岸)
  12. 【MD5加密算法能被破解么?】
  13. 悉尼大学商业数据科学与计算机学院,悉尼大学数据科学专业
  14. WinEdt字体大小修改
  15. 《A Traceable and Revocable Ciphertext-Policy Attribute-based Encryption Scheme Based》属性加密机制
  16. 计算机设备更新理由,电脑硬件明明升级了,为什么速度还这么慢?四种原因在背后作怪!...
  17. [重庆思庄每日技术分享]-oracle11g到ORACLE 816的dblink访问报 ORA-03150错误
  18. IT男真实的情感记录
  19. Java替换所有的字符串
  20. 聊一聊IT培训机构的那些事!

热门文章

  1. 基于samba实现win7与linux之间共享文件_阳仔_新浪博客
  2. Weblogic跨域session冲突解决办法
  3. Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析(9)...
  4. 在Struts2中实现文件上传(二)
  5. [Oracle]oracle概念和术语
  6. [建议]添加模板功能
  7. 大屏监控系统实战(15)-打包上线及总结
  8. android时间戳字体,Android获取当前时间戳?
  9. oracle 全局id,基于SnowFlake 全局ID 生成器 go-id-worker
  10. 天津理工大学计算机工程学院院长,王法玉