【js】对象属性的拦截和Proxy代理与Reflect映射的用法与区别

news2024/11/24 14:13:46

csdn动态图标

✍️ 作者简介: 前端新手学习中。

💂 作者主页: 作者主页查看更多前端教学

🎓 专栏分享:css重难点教学   Node.js教学 从头开始学习   ajax学习

文章目录

  • 对象属性的拦截
    • 介绍
    • Set
    • Get
  • 对象的拦截
    • 介绍
    • 使用
    • 对象属性拦截和对象拦截区别
    • 练习题
  • 映射
    • 介绍
    • 优点
  • 总结

对象属性的拦截

介绍

在对象中,set 和 get 是属性的特性,用于定义属性的赋值和取值行为。它们允许您在属性被赋值或取值时执行自定义的逻辑。

Set

set 是一个对象属性的特性,用于定义属性的赋值行为。当给属性赋值时,set 方法会被调用,允许执行自定义的逻辑。

  let obj = {
            name:0,
            set changename(value){
                if (value >5) {
                     this.name =value;
                }
              
            }
        }
obj.changename=10  //10
obj.changename=4    //0
console.log(obj.name);

通过changename函数 在里面进行需要的条件判断来修改name值,给这个函数赋值的时候,就会触发这个set。
注意 函数名跟属性名不能一样,不然就要递归调用报栈溢出错误了,

Get

get 用于定义对象属性的获取行为。当访问对象的属性时,get 方法会被触发,并且可以在方法中执行相应的逻辑。


  let obj = {
            name:0,
            set changename(value){
                if (value >5) {
                   this.name =value;
                }
              
            },
            get changename(){
               return this.name =1
              
            },
        }
obj.changename=10  //10
obj.changename=4    //0
console.log(obj.changename); //1  (获取的时候会触发get)

假设 我们要访问一个属性,然后不管设置还有获取都需要对这个属性进行相应操作 ,我们就可以使用 很好的搭配使用set和get。 其实就相当于你针对一个属性写了两个不同的函数进行操作,只不过 set get 我们写的函数名称一样,便于易读浏览。

对象的拦截

介绍

Proxy 是 JavaScript 提供的一个内置对象,用于创建一个代理对象,可以拦截并自定义对目标对象的操作。通过使用 Proxy,我们可以对目标对象的属性访问、赋值、删除等操作进行拦截和处理。

使用

   let obj = {
        name: 0,
      };
      let handle = {
        set: function (target, name, value) {
          if (value > 5) {
            target[name] = value;
          }
        },
        get: function (target, name) {
          return (target[name] = 1);
        },
      };
      let proxy = new Proxy(obj, handle);
      proxy.changename = 10; //10
      proxy.changename = 4; //0
      console.log(proxy.changename); //1

通过proxy代理来访问 对象进行获取和赋值等操作。

对象属性拦截和对象拦截区别

区别就跟名字一样,对象属性拦截,是你在对象中给某个属性设置拦截操作,当它获取,和赋值的时候触发,对象拦截 是设置proxy代理,通过代理来访问,既然通过代理来访问对象属性,则任何操作,只要你对这个对象有操作,都会进行拦截判断,
也就是说 一个是针对对象里的一个属性,一个是针对整个对象。

练习题

   let obj = {
          name: 0,
          set changename(value) {
            if (value > 5) {
              this.name = value;
            }
          },
          get changename() {
            return (this.name += 1);
          },
        };
        let handle = {
          //target原对象,name是属性
          get: function (target, name) {
            target[name] += 1;
            //注意 get 一定要return
            return target[name];
          },
          //value传的值
          set: function (target, name, value) {
            if (typeof value == "number") {
              target[name] = value;
            }
          },
        };
        let proxy = new Proxy(obj, handle);
        proxy.changename = 10;
        proxy.changename = "4";
        console.log(proxy.changename); 
     

写了个题目 供大家练习,感觉有面试题那味儿了,大家看看自己得出的结果是多少。

揭晓答案: 13。
讲解:proxy.changename = 10; 走proxy里的set, set里进行判断是一个数值,然后调用obj对象进行赋值,赋值的时候会触发obj的set拦截,判断大于5,ok最后赋值成10.
第二次 赋值字符串4 set判断 不通过就没下文了,默认return 一个undefined。
然后就是最后的显示了,显示的时候会触发proxy里的get 然后执行这段代码

 target[name] += 1;

也就是

target[name] =target[name] +1;

target[name] +1里的target[name] ,就相当于get操作触发obj里的get,于是就会加一,10+1变成了11,然后是11加1。也就是十二。
然后return target[name]; 又试一次get 操作 就是12 +1 结果就变成了 13。

映射

介绍

Reflect 是一个内置的 JavaScript 对象,它提供了一组用于操作对象的方法。这些方法与对象的操作行为相对应,例如属性访问、函数调用、实例化等。
通俗来讲,我们可以使用这个对象,来进行日常的对象操作,比如取值,赋值等等一些操作,他同样可以完成并且有一些其他的优点,我们使用reflect一般都是搭配proxy使用。

比如像下面这样。

const obj = {
  foo: 42,
};

const value = Reflect.get(obj, 'foo');
console.log(value); // 输出: 42

优点

  1. 方便处理和调用目标对象的默认行为:Reflect 提供了与目标对象的默认行为相对应的方法,比如 Reflect.get、Reflect.set、Reflect.has 等。在 Proxy 的处理程序中使用 Reflect 可以方便地调用这些方法,从而实现对目标对象默认行为的处理和拦截。

  2. 更严谨的错误处理:Reflect 方法的返回值会更加准确地反映操作的结果,而不是像在使用目标对象的方法时可能会抛出异常。例如,Reflect.set 方法在赋值操作成功时会返回 true,失败时会返回 false,而不是抛出异常。

  3. 保持 Proxy 和目标对象的行为一致:Proxy 的目标对象可能是任意类型的对象,而 Reflect 提供了一致的方法,可以在 Proxy 的处理程序中对不同类型的目标对象进行操作,保持行为的一致性。

  4. 更清晰的代码逻辑:使用 Reflect 方法可以使代码更加简洁和易读,因为 Reflect 方法的命名和用法更加一致和直观,能够更清晰地表达代码的意图。

把它应用到我们上面的题。

 let obj = {
        name: 0,
        set changename(value) {
          if (value > 5) {
            this.name = value;
          }
        },
        get changename() {
          return (this.name += 1);
        },
      };
      let handle = {
        //target原对象,name是属性
        get: function (target, name) {
          target[name] += 1;
          //注意 get 一定要return
          return Reflect.get(target, name);
        },
        //value传的值
        set: function (target, name, value) {
          if (typeof value == "number") {
            Reflect.set(target, name, value)
          }
        },
      };
      let proxy = new Proxy(obj, handle);
      proxy.changename = 10;
      proxy.changename = "4";
      console.log(proxy.changename);
      ···

总结

  1. 对象属性的拦截(Object Property Interception):可以使用对象自身的 get 和 set 方法来拦截属性的获取和设置操作。通过在对象上定义这些方法,可以在属性访问过程中执行自定义的逻辑,例如验证、转换或拦截。

  2. 代理对象(Proxy Object):代理对象是一个代理目标对象的对象,通过代理对象可以拦截对目标对象的操作。代理对象使用 Proxy 构造函数创建,并提供了一组拦截器(handler)来定义拦截行为。

  3. Reflect 映射(Reflect Mapping):Reflect 是一个内置的对象,提供了一组与对象操作相关的方法,用于执行与目标对象相同的操作。Reflect 方法提供了一种更简洁、易读的方式来执行常见的对象操作,如获取属性值、设置属性值、调用函数等。

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

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

相关文章

【Python实战】Python采集地震信息

前言 昨天,我们这里发生了地震,不过,没有太大的问题,我就想着能不能把近几年发生地震的信息,收集下来,我们发现中国地震台网的官方微博会分布近几年发生地震的信息。我们可以直接在这里获取。 环境使用 python 3.9pycharm模块使用 requests模块介绍 requests requ…

每日一博 - 浅析事务隔离级别 MVCC机制

文章目录 DB四个隔离级别MVCC如何工作的 ?小结 DB四个隔离级别 数据库隔离允许事务执行,就像没有其他并发运行的事务一样。 下面的图说明了四个隔离级别。 Serializalble: 这是最高的隔离级别。并发交易保证按顺序执行。Repeatable Read: 事务开始时读…

Flutter 笔记 | Flutter 事件与通知

原始指针事件处理 命中测试 在移动端,各个平台或UI系统的原始指针事件模型基本都是一致,即:一次完整的事件分为三个阶段:手指按下、手指移动、和手指抬起,而更高级别的手势(如点击、双击、拖动等&#xf…

重学迭代器和生成器

重学迭代器和生成器 之前在 JavaScript 高级程序设计第 7 章 迭代器和生成器 学习笔记 其实包含过 iterator 和 generator 的学习笔记,不过依旧温故而知新,有了一些实际上手的经验后重新再回滚一边会有比较深刻的理解,而不是只是 cv 书上的内…

硬件基础常识【3】--详细说说贴片电容器,可能有你不知道的

目录 贴片电容介绍MLCC的制作过程电容失效的头号大敌电容失效的最主要原因电容的容值、耐压值与封装尺寸的关系 电容串并联串联并联 电容的等效电路选取电容的建议总结 贴片电容介绍 贴片电容相信干电子技术活的基本都使用过,他的全称为:多层片式陶瓷电…

基础学习——读txt数据、字符串转list或数组、画PR曲线、画Loss曲线

文章目录 字符串转数组字符串中的数组转列表转整数列表 读数据,然后画PR曲线读取txt数据关于PR曲线代码 读数据画Loss曲线读txt数据代码 字符串转数组 .split() 是Python中的一个字符串方法,它可以将一个字符串按照指定的分隔符分割成多个子字符串&…

智能工厂 | 联合汽车电子有限公司汽车驱动科技上海智能工厂

智能制造是我国加快建设制造强国的主攻方向,是上海城市数字化转型的重要抓手。智能工厂是推动智能制造的切入点和突破口,是制造业数字化转型的重要载体,以智能工厂为载体布局新赛道、触发新动能、带动新终端,从而实现制造业高质量…

scanf读取字符数组的注意点

起因&#xff1a;scanf的%c格式可以读取空格和回车 读取中间无空格隔开的二维字符数组时 #include<bits/stdc.h> using namespace std; char mp[10][10]; signed main() {for(int i1;i<3;i){for(int j1;j<3;j){scanf("%c",&mp[i][j]);}getchar();/…

Zookeeper集群 + Kafka集群

Zookeeper 概述 Zookeeper 定义 Zookeeper是一个开源的分布式的&#xff0c;为分布式框架提供协调服务的Apache项目。 Zookeeper 工作机制 Zookeeper从设计模式角度来理解&#xff1a;是一个基于观察者模式设计的分布式服务管理框架&#xff0c;它负责存储和管理大家都关心的…

液体压强、浮力与密度分析

如图所示&#xff0c;将甲、乙两个容器放在水平桌面上&#xff0c;甲、乙两容器的底面积为S甲&#xff0c;S乙&#xff0c;甲容器中盛有密度为p1的液体&#xff0c;乙容器中盛有密度为p2的液体。现将体积相等的A、B两个物体分别放入甲、乙两容器后&#xff0c;物体A悬浮&#x…

学习TypeScript快速入门

&#x1f341; 作者主页&#xff1a;&#x1f496;仙女不下凡&#x1f496; &#x1f341; 前言介绍&#xff1a;以下&#x1f447; 内容是根据“阿宝哥”的教材自学总结&#xff0c;定期更新欢迎持续关注&#xff01; &#x1f341; 学习前提&#xff1a;学习该文章之前需要…

数据在内存中的存储(1)——整形

目录 1、数据类型介绍 1.1、类型的基本归类 整形家族 浮点数家族 指针类型 空类型 构造类型 2、整形在内存中的存储 2.1、原码、反码、补码 2.2、大小端介绍 2.3、有符号与无符号 2.4、练习 例一 例二 例三 例四 例五 1、数据类型介绍 我们先来简单了解一下我们前面所学的基…

【腾讯云Finops Crane集训营】降本增效之 Crane 初体验

1. Crane 初识2. Crane 如何进行成本优化&#xff1f;3. Crane 快速上手体验3.1 安装 Prometheus 和 Grafana3.2 安装 Crane 和 Fadvisor3.3 验证安装是否成功3.4 访问 Dashboard 4. Crane 初体验 - 总结&建议5. 关于腾讯云 Finops Crane 集训营 最近有幸参加了腾讯云 Fino…

新星计划【Java微服务+云原生】赛道开启!

前排提醒&#xff1a;这里是新星计划2023【微服务云原生】学习方向的报名入口&#xff0c;一经报名&#xff0c;不可更换。 ↓↓↓报名入口&#xff1a;新星计划2023【微服务云原生】学习方向报名入口&#xff01;-CSDN社区 一、关于本学习方向导师 博客昵称&#xff1a;鹤冲…

opengl灯光基础:2.1 光照基础知识

光照&#xff1a; 光照以不同的方式影响着我们看到的世界&#xff0c;有时甚至是以很戏剧化的方式。当手电筒照射在物体上时&#xff0c;我们希望物体朝向光线的一侧看起来更亮。我们所居住的地球上的点&#xff0c;在中午朝向太阳时候被照得很亮&#xff0c;但随着地球的自转…

【使用VS开发的第一个QT项目——实现相机功能(包括QT下载、配置、摄像头程序)】

使用VS开发的第一个QT项目 一、QT(WIN10)安装1.首先下载QT(VS有对应的QT)2.安装QT 二、将QT加载到VS中三、QT设置1.在VS"Qt Vs Tools"→"QT Versions"中添加"msvc2017_64"qmake的路径2.在"General"→"QT Designer"中将"…

克里金插值(Kriging)在MATLAB中的实现【优化】

该部分是基于克里金插值&#xff08;Kriging&#xff09;在MATLAB中的实现&#xff08;克里金工具箱&#xff09;&#xff0c;由于在运行过程中有部分问题&#xff0c;基于此做的一些理解优化。 工具箱的下载见上面的链接&#xff0c;其提供了工具箱。 clc clearload(data_kr…

服务(第三十二篇)nginx做缓存服务器

nginx作为缓存服务配置语法 1、proxy_cache_path 配置语法&#xff08;即缓存路径配置语法&#xff09; Syntax&#xff1a;proxy_cache_path path [levelslevels] [use_temp_pathon|off] keys_zonename:size [inactivetime] [max_sizesize] [manager_filesnumber] [manager_s…

python爬虫笔记

Python爬虫笔记 一. Urllib 1. 基础请求 指定url请求返回值解码返回结果的一些操作 import urllib.request as req # 定义一个url url http://www.baidu.com# 发送请求获得相应 res req.urlopen(url)# read返回字节形式的二进制数据,需要用指定编码来解码 content res.r…

Allure测试报告定制全攻略,优化你的Web自动化测试框架!

目录 前言&#xff1a; 1. Allure测试报告简介 2. Web自动化测试框架简介 3. 封装Web自动化框架 3.1 安装Selenium 3.2 封装Selenium 3.3 定制Allure测试报告 3.3.1 适配翻译插件 3.3.2 定制测试报告样式 4. 示例代码 5. 总结 前言&#xff1a; 随着现在Web应用的普…