iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >ES6中的Proxy类如何使用
  • 609
分享到

ES6中的Proxy类如何使用

2023-07-06 04:07:03 609人浏览 泡泡鱼
摘要

这篇文章主要介绍了es6中的Proxy类如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇ES6中的Proxy类如何使用文章都会有所收获,下面我们一起来看看吧。Object在 ES5 中,我们可以定义一个对

这篇文章主要介绍了es6中的Proxy类如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇ES6中的Proxy类如何使用文章都会有所收获,下面我们一起来看看吧。

Object

ES5 中,我们可以定义一个对象,并且对其进行操作(添加或查找),如下代码所示:

const moment = {  age: 18,  address: "西安",};moment["hobby"] = "basketball";moment.hight = 1.59;console.log(moment.age); // 18

那如果我们要对该对象进行监听呢,我们希望可以监听到这个对象中的属性被设置或获取的过程,我们可以通过属性描述符中的存储属性来做到这个功能。

属性描述符

ES5 中,所有的属性都具备了属性描述符,具体使用如下图所示:

ES6中的Proxy类如何使用

就像上图所展示的一样,这个普通的对象属性对应的属性描述符,可不仅仅是一个18,它还包含另外三个特性,它们分别是:

  • writable;

  • enumerable;

  • configurable;

在创建普通户型时,属性描述符会使用默认值,我们可以使用 Object.defineProperty(...) 来添加一个新属性或者修改一个已有属性(当该属性 Configurable 的值为 true 时)并对特性进行设置,具体如下代码所示:

const moment = {  age: 18,  address: "西安",};Object.defineProperty(moment, "address", {  value: "肇庆",  writable: true,  configurable: true,  enumerable: true,});console.log(moment.address); // 肇庆

该方法接收三个参数,它们分别为:

  • 要定义属性的对象;

  • 要定义或修改的属性的名称或 Symbol;

  • 要定义或修改的属性描述符;

Getter和Setter

前面说了这么多基础的东西,但是还没有讲解是怎么接收到属性的变化的,在这里,属性描述符 Object.defineProperty 提供了两个属性,它们分别是 setget,两个属性的使用如下所示:

const moment = {  age: 18,  address: "西安",};Object.keys(moment).forEach((key) => {  let value = moment[key];  Object.defineProperty(moment, key, {    get: function () {      console.log(`监听到了对象的 ${key} 属性被访问了`);      return value;    },    set: function (params) {      console.log(`监听到了对象的 ${key} 属性被修改了`);      value = params;    },  });});moment.age = 22;const foo = moment.address;

当我们对 moment.age 进行赋值的时候,会调用 set 属性上的方法,最终会输出 监听到了对象的 age 属性被修改了

当我们对 moment.address 进行取值的时候,会调用 get 属性上的方法,最终会输出 监听到了对象的 address 属性被访问了

虽然这两个方法是能做到,但是如果我们想监听更加丰富的操作的时候是做不到的,例如新增属性,淡出属性,使用 Object.defineProperty(...) 是做不到的

ES6中的Proxy类如何使用

最终结果如上图所示,终端中的输出是对应上面画圈圈的代码执行。

那么 Proxy 的出现就很好的解决了这一痛点。

Proxy

ES6 中,新增了一个 Proxy 类,这个类从名字就可以看出来,是用于帮助我们创建一个代理的,它是一种由你创建的特殊对象,它封装另一个普通对象或者说挡在这个普通对象的前面,例如你要修改一个对象,它主要有以下的流程图:

ES6中的Proxy类如何使用

它就像一个关卡对你的操作进行拦截。

这个类的基本使用如下所示:

const moment = {  age: 18,  address: "西安",};const proxy = new Proxy(moment, {});console.log(proxy); // { age: 18, address: '西安' }

你会发现它返回的是同一个对象,但是内存地址不同,所以通过严格相等比较返回的值也就是 false

Peoxy的13种捕获器

Peoxy 总共有13个捕获器,但是常用的就那么几个,这里不低其全部讲解,具体可以查看 MDN官网

话不多说,直接上代码:

const moment = {  age: 18,  address: "西安",};function foo(x, y) {  return x + y;}const proxy = new Proxy(moment, {  has: function (target, prop) {    console.log(`使用 in 访问了 ${prop} 是否存在于 moment 对象`);  },  get: function (target, property, receiver) {    console.log(`通过读取 moment 对象中的 ${property} 属性`);  },  set: function (target, property, value, receiver) {    console.log(`通过设置 moment 对象中的 ${property} 属性为 ${value}`);  },});const fProxy = new Proxy(foo, {  apply: function (target, _, params) {    return target(...params) * 10;  },  construct: function (target, argumentsList, newTarget) {    console.log(target); // [Function: foo]    console.log(argumentsList); // [ 1, 2 ]    console.log(newTarget); // [Function: foo]    return {};  },});"age" in proxy; // 使用 in 访问了 age 是否存在于 moment 对象proxy.age; // 通过读取 moment 对象中的 age 属性proxy.address = "肇庆"; // 通过设置 moment 对象中的 address 属性为 肇庆console.log(foo(1, 2)); // 3console.log(fProxy(1, 2)); // 30new fProxy(1, 2);

在上面的代码中,target === momentreceiver === proxy 都返回 true,也就是说 target 为对应要修改的对象,而 receiverProxy 或者继承 Proxy 的对象。

操作 Proxy 的同时会修改 moment 对象。

可取消代理

普通对象总是陷入到目标对象,并且在创建之后不能改变,只要还保持着对这个代理的引用,代理的机制就将维持下去。

但是可能会存在这样的情况,比如你想要创建一个在你想要停止它作为代理时便可被停用的代理,解决的方案是创建可取消代理,具体代码如下所示:

const moment = {  age: 18,  address: "西安",};const { proxy, revoke } = Proxy.revocable(moment, {  get: function (target, key, receiver) {    console.log("get 捕获器");  },});proxy.address;revoke();proxy.address;

最终的输出如下图所示:

ES6中的Proxy类如何使用

一旦可取消代理被取消,任何对他的访问都会抛出 TypeError 错误。

Proxy的问题与不足

尽管现在 Proxy 已经做得很好了,但是在某些情况下,代理也不能与现在的 ECMAScript 机制很好地协同。

Proxy中的this

Peoxy 潜在的一个问题来源是 this 值,我们知道方法中的 this 通常执行调用这个方法的对象,具体代码如下所示:

const target = {  moment() {    return this === proxy;  },};const proxy = new Proxy(target, {});console.log(target.moment()); // falseconsole.log(proxy.moment()); // true

按照正常的理解这是没有问题的调用 Proxy 上的任何方法,而这个方法进而又会调用另一个方法,实际上都会调用 Proxy 内部的方法,这是符合预期的行为,但是,如果目标对象依赖于对象表示,那就可能碰到意料之外的问题。

举个例子:

const wm = new WeakMap();class User {  constructor(userId) {    wm.set(this, userId);  }  set id(userId) {    wm.set(this, userId);  }  get id() {    return wm.get(this);  }}

由于这个实现依赖 User 实例的对象标识,在这个实例被代理的情况下就会出现问题:

const user = new User(1);console.log(user.id); // 1const proxy = new Proxy(user, {});console.log(proxy.id); // undefined

这是因为 User 实例一开始使用目标对象作为 WeakMap 的键,代理对象却尝试从自身取得这个实例,要解决这个问题,就需要重新设置代理,把代理 User 实例改为代理 User 类本身,之后再创建代理的实例就会创建代理实例作为 WeakMap 的键了:

const UserProcess = new Proxy(User, {});const proxy = new UserProcess(1);console.log(proxy.id); // 1

Proxy与内部槽位

代理与内置引用类型的实例通常可以很好地协同,但有些 ECMAScript 内置类型可能会依赖代理无法控制的机制,结果导致在代理上调用某些方法会出错,具体代码如下所示:

const target = new Date();const proxy = new Proxy(target, {});console.log(proxy instanceof Date); // trueproxy.getDate(); // TypeError: this is not a Date object.

在上面的代码中,根据 ECMAScript 规范,Date 类型方法的执行依赖 this 值上的内部曹伟 [[NumberDate]],代理对象上不存在这个内部槽位,而且这个内部槽位的值也不能通过普通的 get()set() 操作访问到,于是代理拦截后本应该转发给目标对象的方法会抛出 TypeRrror 的错误。

关于“ES6中的Proxy类如何使用”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“ES6中的Proxy类如何使用”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网精选频道。

--结束END--

本文标题: ES6中的Proxy类如何使用

本文链接: https://www.lsjlt.com/news/357701.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • ES6中的Proxy类如何使用
    这篇文章主要介绍了ES6中的Proxy类如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇ES6中的Proxy类如何使用文章都会有所收获,下面我们一起来看看吧。Object在 ES5 中,我们可以定义一个对...
    99+
    2023-07-06
  • es6中的proxy如何使用
    本篇内容主要讲解“es6中的proxy如何使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“es6中的proxy如何使用”吧! 在e...
    99+
    2024-04-02
  • ES6中的Proxy有什么用
    这篇文章主要介绍了ES6中的Proxy有什么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。 创建一个简单的Pr...
    99+
    2024-04-02
  • ES6中Proxy使用场景有哪些
    小编给大家分享一下ES6中Proxy使用场景有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!ES6 中的箭头函数、数组解构、...
    99+
    2024-04-02
  • ES6中Proxy的作用是什么
    这篇文章主要介绍“ES6中Proxy的作用是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“ES6中Proxy的作用是什么”文章能帮助大家解决问题。创建一个简单的Proxylet tar...
    99+
    2023-06-17
  • ES6中Proxy有什么用
    这篇文章主要为大家展示了“ES6中Proxy有什么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“ES6中Proxy有什么用”这篇文章吧。具体如下:Proxy ...
    99+
    2024-04-02
  • JS中ES6代理Proxy怎么用
    这篇文章主要为大家展示了“JS中ES6代理Proxy怎么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“JS中ES6代理Proxy怎么用”这篇文章吧。proxy...
    99+
    2024-04-02
  • ES6中的class类怎么使用
    本篇内容主要讲解“ES6中的class类怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“ES6中的class类怎么使用”吧! 认识class定义类 我...
    99+
    2024-04-02
  • es6中let如何使用
    本篇内容介绍了“es6中let如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在es6中,let关键字用于声明变量;但是所声明的变量,...
    99+
    2023-07-04
  • es6中continue如何使用
    这篇“es6中continue如何使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“es6...
    99+
    2024-04-02
  • ES6之Proxy中get方法的示例分析
    这篇文章主要介绍了ES6之Proxy中get方法的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Proxy是在ES2015(ES6)...
    99+
    2024-04-02
  • 如何使用Proxy对象
    本篇内容介绍了“如何使用Proxy对象”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、聊一聊代理在日常工...
    99+
    2024-04-02
  • 如何使用Nginx resin的proxy功能
    本篇内容主要讲解“如何使用Nginx resin的proxy功能”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何使用Nginx resin的proxy功能”吧...
    99+
    2024-04-02
  • ES6的Promise如何使用
    本篇内容介绍了“ES6的Promise如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!所谓Promise,简单说就是一个容器,里面保存...
    99+
    2023-06-27
  • es6中的reduce()函数如何使用
    本文小编为大家详细介绍“es6中的reduce()函数如何使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“es6中的reduce()函数如何使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。在es6中,red...
    99+
    2023-07-05
  • ES6的Class类怎么使用
    本篇内容介绍了“ES6的Class类怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在ES6中,class (类)作为对象的模板被引入...
    99+
    2023-06-27
  • es6语法中Proxy和Reflect对比的示例分析
    这篇文章主要介绍es6语法中Proxy和Reflect对比的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!如下所示:{   //原始对象  l...
    99+
    2024-04-02
  • ES6中Object属性如何使用
    本篇文章为大家展示了ES6中Object属性如何使用,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。我们之前定义对象属性的方法var obj =&...
    99+
    2024-04-02
  • node中如何使用es6/7/8
    这篇文章主要为大家展示了“node中如何使用es6/7/8”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“node中如何使用es6/7/8”这篇文章吧。前言这几年...
    99+
    2024-04-02
  • ES6中如何使用Promise对象
    这篇文章主要介绍了ES6中如何使用Promise对象的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇ES6中如何使用Promise对象文章都会有所收获,下面我们一起来看看吧。在promise之前处理异步回调的方式...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作