Proxy-Reflect使用详解

news2024/11/24 12:00:35

1 监听对象的操作

2 Proxy类基本使用

3 Proxy常见捕获器

4 Reflect介绍和作用

5 Reflect的基本使用

6 Reflect的receiver

Proxy-监听对象属性的操作(ES5)

通过es5的defineProperty来给对象中的某个参数添加修改和获取时的响应式。

单独设置defineProperty是只能一次设置一个响应式的,但是可以通过遍历还为每个参数添加响应式。这样子有个缺点就是如果对象里面有新添加的参数,那就没办法做到响应式了。

这里proxy的捕获器直接操作原对象了,不好,需要结合reflect来修改对象才是最好的,比较严谨。

<body>
  
  <h2 class="name"></h2>

  <script>

    const obj = {
      name: "why",
      age: 18,
      height: 1.88
    }

    // 需求: 监听对象属性的所有操作
    // 监听属性的操作
    // 1.针对一个属性
    // let _name = obj.name
    // Object.defineProperty(obj, "name", {
    //   set: function(newValue) {
    //     console.log("监听: 给name设置了新的值:", newValue)
    //     _name = newValue
    //   },
    //   get: function() {
    //     console.log("监听: 获取name的值")
    //     return _name
    //   }
    // })

    // 2.监听所有的属性: 遍历所有的属性, 对每一个属性使用defineProperty
    const keys = Object.keys(obj)
    for (const key of keys) {
      let value = obj[key]
      Object.defineProperty(obj, key, {
        set: function(newValue) {
          console.log(`监听: 给${key}设置了新的值:`, newValue)
          value = newValue
        },
        get: function() {
          console.log(`监听: 获取${key}的值`)
          return value
        }
      })
    }

    // console.log(obj.name)
    // obj.name = "kobe"
    console.log(obj.age)
    obj.age = 17
    console.log(obj.age)



    // 什么是响应式?
    // const nameEl = document.querySelector(".name")
    // nameEl.textContent = obj.name
    // obj.name = "kobe"
    // obj.name = "james"



  </script>

</body>

Proxy-监听对象属性的操作(ES6

通过创建代理,修改代理来做到响应式。捕获器里面可以放置set和get方法等等。总共有13个。

这里proxy的捕获器直接操作原对象了,不好,需要结合reflect来修改对象才是最好的,比较严谨。

 

  const obj = {
      name: "why",
      age: 18,
      height: 1.88
    }


    // 1.创建一个Proxy对象
    const objProxy = new Proxy(obj, {
  //  这里都是捕获器的内容
      set: function(target, key, newValue) {
        console.log(`监听: 监听${key}的设置值: `, newValue)
        target[key] = newValue
      },
      get: function(target, key) {
        console.log(`监听: 监听${key}的获取`)
        return target[key]
      }
    })

    // 2.对obj的所有操作, 应该去操作objProxy
    // console.log(objProxy.name)
    // objProxy.name = "kobe"
    // console.log(objProxy.name)
    // objProxy.name = "james"

    objProxy.address = "广州市"
    console.log(objProxy.address)

Proxy-其他捕获器的监听方法

set、get、delete、in捕获器的使用。这里proxy的捕获器直接操作原对象了,不好,需要结合reflect来修改对象才是最好的,比较严谨。

  const obj = {
      name: "why",
      age: 18,
      height: 1.88
    }


    // 1.创建一个Proxy对象
    const objProxy = new Proxy(obj, {
      set: function(target, key, newValue) {
        console.log(`监听: 监听${key}的设置值: `, newValue)
        target[key] = newValue
      },
      get: function(target, key) {
        console.log(`监听: 监听${key}的获取`)
        return target[key]
      },

      deleteProperty: function(target, key) {
        console.log(`监听: 监听删除${key}属性`)
        delete obj.name
      },

      has: function(target, key) {
        console.log(`监听: 监听in判断 ${key}属性`)
        return key in target
      }
    })

    delete objProxy.name

    console.log("age" in objProxy)

Proxy-监听函数对象的操作

apply、constructor的使用。这里proxy的捕获器直接操作原对象了,不好,需要结合reflect来修改对象才是最好的,比较严谨。

  function foo(num1, num2) {
      console.log(this, num1, num2)
    }

    const fooProxy = new Proxy(foo, {
      apply: function(target, thisArg, otherArgs) {
        console.log("监听执行了apply操作")
        target.apply(thisArg, otherArgs)
      },
      construct: function(target, otherArray) {
        console.log("监听执行了new操作")
        console.log(target, otherArray)
        return new target(...otherArray)
      }
    })

    // fooProxy.apply("abc", [111, 222])
    new fooProxy("aaa", "bbb")

Reflect-和Object的区别之一

reflect操作对象类型会比直接使用object的好。object有的,reflect都有。

 "use strict"

    const obj = {
      name: "why",
      age: 18
    }

    Object.defineProperty(obj, "name", {
      configurable: false
    })
    // Reflect.defineProperty()

    // 1.用以前的方式进行操作
    // delete obj.name
    // if (obj.name) {
    //   console.log("name没有删除成功")
    // } else {
    //   console.log("name删除成功")
    // }

    // 2.Reflect
    if (Reflect.deleteProperty(obj, "name")) {
      console.log("name删除成功")
    } else {
      console.log("name没有删除成功")
    }

Reflect-和Proxy共同完成代理

不要直接对原对象进行操作,可以通过reflect来做到,并且有很多好处。

  const obj = {
      name: "why",
      age: 18
    }

    const objProxy = new Proxy(obj, {
      set: function(target, key, newValue, receiver) {
        // target[key] = newValue
        // 1.好处一: 代理对象的目的: 不再直接操作原对象
        // 2.好处二: Reflect.set方法有返回Boolean值, 可以判断本次操作是否成功
        const isSuccess = Reflect.set(target, key, newValue)

        if (!isSuccess) {
          throw new Error(`set ${key} failure`)
        }
      },
      get: function(target, key, receiver) {

      }
    })

    // 操作代理对象
    objProxy.name = "kobe"
    console.log(obj)

Reflect-和Reflect设置receiver

1

 const obj = {
      _name: "why",
      set name(newValue) {
        console.log("this:", this) // 默认是obj
        this._name = newValue
      },
      get name() {
        return this._name
      }
    }


    // obj.name = "aaaa"

    // console.log(obj.name)
    // obj.name = "kobe"

    const objProxy = new Proxy(obj, {
      set: function(target, key, newValue, receiver) {
        // target[key] = newValue
        // 1.好处一: 代理对象的目的: 不再直接操作原对象
        // 2.好处二: Reflect.set方法有返回Boolean值, 可以判断本次操作是否成功
        /*
           3.好处三:
             > receiver就是外层Proxy对象
             > Reflect.set/get最后一个参数, 可以决定对象访问器setter/getter的this指向
        */
        console.log("proxy中设置方法被调用")
        const isSuccess = Reflect.set(target, key, newValue, receiver)

        if (!isSuccess) {
          throw new Error(`set ${key} failure`)
        }
      },
      get: function(target, key, receiver) {
        console.log("proxy中获取方法被调用")
        return Reflect.get(target, key, receiver)
      }
    })


    // 操作代理对象
    objProxy.name = "kobe"
    console.log(objProxy.name)

Reflect-和construct结合的反射

1

  function Person(name, age) {
      this.name = name
      this.age = age
    }

    function Student(name, age) {
      // Person.call(this, name, age)
      const _this = Reflect.construct(Person, [name, age], Student)
      return _this
    }

    // const stu = new Student("why", 18)
    const stu = new Student("why", 18)
    console.log(stu)
    console.log(stu.__proto__ === Student.prototype)

 

 

 

 

 

 

 

 

 

 

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

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

相关文章

AppStorage, OnboardingView 的示例

1. AppStorage 数据简单存储的实现 /// 应用程序数据简单存储 struct AppStorageBootcamp: View {//State var currentUserName: String?AppStorage("name") var currentUserName: String?var body: some View {VStack(spacing: 20) {Text(currentUserName ?? &…

Ghostscript开源PDF库中发现关键漏洞

在Linux中广泛使用的PostScript语言和PDF文件开源解释器Ghostscript被发现存在严重远程代码执行漏洞。 该漏洞被标记为CVE-2023-3664&#xff0c;CVSS v3评级为9.8&#xff0c;影响10.01.2之前的所有Ghostscript版本&#xff0c;10.01.2是三周前发布的最新版本。 据Kroll公司…

深入理解netfilter和iptables

目录 Netfilter的设计与实现 内核数据包处理流 netfilter钩子 钩子触发点 NF_HOOK宏与Netfilter裁定 回调函数与优先级 iptables 内核空间模块 xt_table的初始化 ipt_do_table() 复杂度与更新延时 用户态的表&#xff0c;链与规则 conntrack Netfilter(结合iptable…

基于C语言设计的足球信息查询系统

完整资料进入【数字空间】查看——baidu搜索"writebug" 需求分析与概要设计 2.1 项目说明 我们小组的选题主要是面向足球爱好者&#xff0c;在普通社交软件的基础之上&#xff0c;围绕足球的主题展开设计&#xff0c;以便于他们能够更好的交流相关的话题&#xff…

高效编程的捷径:HbuilderX的独特之处

目录 引言HbuilderX的功能HbuilderX的优点HbuilderX的缺点总结 HBuilderX 官网 引言 在当今科技发展日新月异的时代&#xff0c;软件开发已成为一个极富挑战性且高需求的领域。为了在竞争激烈的市场中脱颖而出&#xff0c;程序员们需要掌握一系列高效编程的技巧和工具。在这个过…

谈一谈LLM在推荐域的一些理解

作者&#xff1a;陈祖龙(葬青) 一、前言 最近大模型真的很火&#xff0c;从个人到公司&#xff0c;各行各业都在学习大模型、总结大模型和尝试应用大模型。大模型其实不是一个新的产物&#xff0c;已经在NLP发展了很多年。ChatGPT的诞生&#xff0c;经验的效果震惊了所有人&…

ES系列--es初探

一、前言 一般传统数据库&#xff0c;全文检索都实现的很鸡肋&#xff0c;因为一般也没人用数据库存文本字段。进 行全文检索需要扫描整个表&#xff0c;如果数据量大的话即使对 SQL 的语法优化&#xff0c;也收效甚微。建 立了索引&#xff0c;但是维护起来也很麻烦&#xff0…

人工智能-电脑如何像人一样思考?

发展历史 在电影如 终结者、机械公敌 中&#xff0c;机器人为什么能够像人一样思考&#xff1f;其实这就是人工智能。人工智能多方面&#xff1a;例如人脸识别系统、肺部影响CT&#xff0c;手机中的美颜、垃圾邮件拦截、自动驾驶 。 上世纪30-50年代&#xff0c;随着计算机科…

服务器如何查库磁盘情况?

查库磁盘情况 du -h --max-depth1 ./ | sort -hr

九九乘法表案例

for循环嵌套 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</titl…

Linux5.15 Zookeeper集群 + Fafka集群

文章目录 计算机系统5G云计算第四章 LINUX Zookeeper集群 Fafka集群一、Zookeeper1.Zookeeper 概述1&#xff09;Zookeeper 定义2&#xff09;Zookeeper 工作机制3&#xff09;Zookeeper 特点4&#xff09;Zookeeper 数据结构5&#xff09;Zookeeper 应用场景6&#xff09;Zoo…

unittest与pytest自动化测试框架

引言 前面一篇文章已经介绍了python单元测试框架&#xff0c;大家平时经常使用的是unittest&#xff0c;因为它比较基础&#xff0c;并且可以进行二次开发&#xff0c;如果你的开发水平很高&#xff0c;集成开发自动化测试平台也是可以的。而这篇文章主要讲unittest与pytest的区…

大华相机接入web页面实现人脸识别

先看下效果&#xff0c;中间主视频流就是大华相机&#xff08;视频编码H.264&#xff09;&#xff0c;海康相机&#xff08;视屏编码H.265&#xff09; 前端接入视屏流代码 <!--视频流--><div id"col2"><div class"cell" style"flex: …

2023夏季营销报告新鲜出炉!(小红书平台)

夏季温度持续走高&#xff0c;大众需求也在升级。品牌如何借势和部署相关内容&#xff1f; 本期&#xff0c;千瓜推出《千瓜2023夏季营销策略数据报告&#xff08;小红书平台》&#xff08;本文非完整版报告&#xff09;&#xff0c;围绕七大行业&#xff08;美妆|个护|食品|家…

能翻译维吾尔语的软件有哪些?这几个可以用用看

能翻译维吾尔语的软件有哪些&#xff1f;在如今全球化的背景下&#xff0c;不同语言之间的沟通交流变得尤为重要。维吾尔语作为中国特有的少数民族语言之一&#xff0c;它的翻译需求日益增长。本文将介绍几款精选的维吾尔语翻译软件&#xff0c;帮助大家顺利实现跨语言沟通。 智…

creator 滑动循环展示图片 自动展示

import MyBaseView from "./MyBaseView";const { ccclass, property } cc._decorator;ccclass export default class ScrollCard extends MyBaseView {property({ tooltip: "是否自动展示" })Move_zidong: boolean true;property({ tooltip: "自动展…

【机器学习】特征降维 - 方差选择法VarianceThreshold

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 方差选择法 一、方差科普二、方差选择API三、获取数…

炎炎夏日,相约Polkadot Decoded 2023上海

​上周&#xff0c;Moonbeam现身胡志明&#xff0c;参与GM Vietnam峰会活动&#xff0c;并与Chainlink和AWS等知名公司的代表一同畅谈Web3。 这周&#xff0c;Moonbeam中文社区将出席Polkadot未来论坛上海站&#xff0c;与来自波卡生态中不同平行链的代表一同探讨波卡新一代生…

小区物业管理系统需求分析

小区物业管理系统核心在于加强管理&#xff0c;提升效率&#xff0c;降低成本。实现物业核心业务信息化&#xff0c;为员工提供流畅运营模式&#xff0c;为业主提供高品质服务&#xff0c;有助于公司做强做大&#xff0c;系统优势主要有以下几方面&#xff1a; • 服务数字化&a…

Systemd服务单元

Systemd服务单元 service服务文件基本格式自定义service文件systemctl定时重启service文件中的type systemctl管理service查看服务状态查看服务是否运行查看服务是否被启用 查看开机自启服务列表设置开机启动开机启动的原理&#xff1a; 取消开机启动启动/暂停/重启服务重新加载…