JavaScript基础 -- 代理与反射

JavaScript Proxy() 构造函数、Proxy对象 Proxy()构造函数用于创建Proxy对象。 阅读详情

在了解 Proxy 和 Reflect 前,需要先了解属性描述符的作用

属性描述符

属性描述符(Property Descriptor) 本质上是一个 JavaScript 普通对象,用于描述一个属性的相关信息,共有以下几种属性:

  • value:属性值

  • configurable:该属性的描述符是否可以修改

  • enumerable:该属性是否可以被枚举

  • writable:该属性是否可以被重新赋值

  • 存取器属性:属性描述符中如果配置了 get 和 set 中的任何一个,则该属性变成了存取器属性

    • get()读值函数:get 方法得到的返回值作为属性值
    • set(newVal)存值函数:newVal 参数为赋值的值

存取器属性最大的意义,在于可以控制属性的读取和赋值,在函数里可以进行各种操作

PS: value 和 writable 属性不能与 get 和 set 属性二者不可共存,二者只能选其一


常见的方法如下:

1)查看某个对象的属性描述符,使用以下这两种方法:

Object.getOwnPropertyDescriptor(对象, 属性名) //得到一个对象的某个属性的属性描述符
Object.getOwnPropertyDescriptors(对象) //得到某个对象的所有属性描述符

2)为某个对象添加属性时 或 修改属性时,配置其属性描述符,使用以下这两种方法:

Object.defineProperty(对象, 属性名, 描述符) //设置一个对象的某个属性
Object.defineProperties(对象, 多个属性的描述符) //设置一个对象的多个属性

Reflect

Reflect 是一个内置的 JS 对象,它提供了一系列方法,可以让开发者通过调用这些方法,访问一些 JS 底层功能。由于它类似于其他语言的反射,因此取名为 Reflect

ES6 认为对属性内存的控制、原型链的修改、函数的调用等等,这些都属于底层实现,需要将它们提取出来,形成一个正常的 API,并高度聚合到某个对象中,于是就造就了 Reflect 对象。因此,Reflect 对象中有很多的 API 都可以使用过去的某种语法或其他 API 实现

主要有以下API,其他更多的API

在这里插入图片描述

Proxy

ES6 新增的代理和反射为开发者提供了拦截并向基本操作嵌入额外行为的能力。具体地说,可以给目标对象(target)定义一个关联的代理对象,而这个代理对象可当作一个抽象的目标对象来使用。 因此在对目标对象的各种操作影响到目标对象之前,我们可以在代理对象中对这些操作加以控制,并且最终也可能会改变操作返回的结果

在这里插入图片描述

创建空代理

最简单的代理是空代理,即除了作为一个抽象的目标对象,什么也不做。 默认情况下,在代理对象上执行的所有操作都会无障碍地传播到目标对象。因此,在任何可以使用目标对象的地方,都可以通过同样的方式来使用与之关联的代理对象

代理是使用 Proxy 构造函数创建的,这个构造函数接收两个参数:目标对象和处理程序对象,缺少其中任何一个参数都会抛出 TypeError

要创建空代理,可以传一个简单的对象字面量作为处理程序对象

const target = {
 id: 'target'
} //target:目标对象
const handler = {} //handler:是一个普通对象,其中可以重写底层实现
//创建空对象
const proxy = new Proxy(target, handler)

// id 属性会访问同一个值
console.log(target.id) // target
console.log(proxy.id) // target

// 给目标属性赋值会反映在两个对象上 因为两个对象访问的是同一个值
target.id = 'foo'
console.log(target.id) // foo
console.log(proxy.id) // foo
// 给代理属性赋值会反映在两个对象上 因为这个赋值会转移到目标对象
proxy.id = 'bar'
console.log(target.id) // bar
console.log(proxy.id) // bar

// hasOwnProperty()方法在两个地方  也都会应用到目标对象
console.log(target.hasOwnProperty('id')) // true
console.log(proxy.hasOwnProperty('id')) // true

// Proxy.prototype 是 undefined   因此不能使用 instanceof 操作符
console.log(target instanceof Proxy) // TypeError: Function has non-object prototype
console.log(proxy instanceof Proxy) // TypeError: Function has non-object prototype

// 严格相等可以用来区分代理和目标
console.log(target === proxy) // false

定义捕获器

使用代理的主要目的是可以定义捕获器(trap),捕获器就是在处理程序对象中定义的“基本操作的拦截器”

每个处理程序对象可以包含 0 个或多个捕获器,每个捕获器都对应一种基本操作,可以直接或间接在代理对象上调用。每次在代理对象上调用这些基本操作时,代理可以在这些操作传播到目标对象之前先调用捕获器函数,从而拦截并修改相应的行为

PS:捕获器是从操作系统中借用的概念。在操作系统中,捕获器是程序流中的一个同步中断,可以暂停程序流,转而执行一段子例程,之后再返回原始程序流

所有捕获器都可以访问相应的参数,基于这些参数可以重建被捕获方法的原始行为。比如,get() 捕获器会接收到目标对象、要查询的属性和代理对象三个参数

只有在代理对象上执行操作才会触发捕获器,在目标对象上执行仍然会产生正常的行为

const target = {
  foo: "bar",
}
const handler = {
  // 捕获器在处理程序对象中以方法名为键
  get(trapTarget, property, receiver) {
    //trapTarget - 目标对象
    //property   - 要查询的属性
    //receiver   - 代理对象
    return "handler override"
  },
}
const proxy = new Proxy(target, handler)
console.log(target.foo) // bar
console.log(proxy.foo) // handler override

捕获器不变式

使用捕获器几乎可以改变所有基本方法的行为,但也不是没有限制

根据 ECMAScript 规范,每个捕获的方法都知道目标对象上下文、捕获函数签名,而捕获处理程序的行为必须遵循“捕获器不变式”(trap invariant),捕获器不变式因方法不同而异,但通常都会防止捕获器定义出现过于反常的行为

比如,如果目标对象有一个不可配置且不可写的数据属性,那么在捕获器返回一个与该属性不同的值时,会抛出 TypeError:

const target = {}
Object.defineProperty(target, "foo", {
  configurable: false,
  writable: false,
  value: "bar",
})
const handler = {
  get() {
    return "water"
  },
}
const proxy = new Proxy(target, handler)
console.log(proxy.foo) // TypeError

可撤销代理

有时候可能需要中断代理对象与目标对象之间的联系,Proxy 也暴露了 revocable() 方法,这个方法支持撤销代理对象与目标对象的关联,后续可直接调用撤销函数 revoke() 来撤销代理,撤销代理这个操作是不可逆的

撤销代理之后再调用代理会抛出 TypeError,撤销函数和代理对象是在实例化时同时生成的:

const target = {
  foo: "bar",
}
const handler = {
  get() {
    return "intercepted"
  },
}
const { proxy, revoke } = Proxy.revocable(target, handler)
console.log(proxy.foo) // intercepted
console.log(target.foo) // bar
revoke()
console.log(proxy.foo) // TypeError

代理的问题与不足

代理是在 ES6 现有基础上构建出来的一套新API,很大程度上,代理作为对象的虚拟层可以正常使用,但在某些情况下,代理也不能与现在的 ES 机制很好地协同

代理中的this

方法中的 this 通常指向调用这个方法的对象:

const target = { 
    thisValEqualsProxy() { 
        return this === proxy 
    } 
}
const proxy = new Proxy(target, {})
console.log(target.thisValEqualsProxy()) // false(this 指向目标对象)
console.log(proxy.thisValEqualsProxy()) // true(this指向代理) 

在多数情况下,这是符合预期的,但如果目标对象依赖于对象标识,那么代理对象可能无法正确访问目标对象的标识,导致错误

以下这个例子:通过 WeakMap 保存私有变量

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 实例的对象标识,在这个实例被代理的情况下就会出问题。 User 实例的 this 是原对象,代理调用时 this 指向代理,导致 WeakMap 查不到键

const user = new User(123)
console.log(user.id) // 123(正常)

const proxy = new Proxy(user, {})
console.log(proxy.id) // undefined(WeakMap 键为原对象,代理无法读取) 

要解决这个问题,就需要重新配置代理,改为代理类而非实例,使代理后的实例成为 WeakMap 的键

const UserClassProxy = new Proxy(User, {})
const proxyUser = new UserClassProxy(456) // 代理实例的 `this` 指向自身
console.log(proxyUser.id) // 456(WeakMap 键为代理实例)

代理与内部槽位

某些内置类型(如 Date、Array)的方法依赖内部槽位,而代理无法访问或修改这些槽位,导致方法调用失败

比如下面这个例子,代理拦截后本应转发给目标对象的方法会抛出 TypeError

  • Date 的 getDate() 依赖内部槽位 [[NumberDate]],代理对象无此槽位,而且这个内部槽位的值也不能通过普通的 get() 和 set() 操作访问到
  • 即使proxy instanceof Date返回true,代理仍无法转发内部槽位操作
const target = new Date()
const proxy = new Proxy(target, {})

console.log(proxy instanceof Date) // true
proxy.getDate() // TypeError: 'this' is not a Date object

代理捕获器与代理方法

get()

get()捕获器会在获取属性值的操作中被调用,对应的反射 API 方法为 Reflect.get()

1)返回值

  • 返回值无限制

2)拦截的操作

  • proxy.property
  • proxy[property]
  • Object.create(proxy)[property]
  • Reflect.get(proxy, property, receiver)

3)捕获器处理程序参数

  • target:目标对象
  • property:引用的目标对象上的字符串键属性
  • receiver:代理对象或继承代理对象的对象

4)捕获器不变式

  • 如果 target.property 不可写且不可配置,则处理程序返回的值必须与 target.property 匹配
  • 如果 target.property 不可配置且[[Get]]特性为 undefined,处理程序的返回值也必须是 undefined
const myTarget = {}
const proxy = new Proxy(myTarget, {
  get(target, property, receiver) {
    console.log("get()")
    return Reflect.get(...arguments)
  },
})
proxy.foo // 触发get()捕获器

set()

set()捕获器会在设置属性值的操作中被调用,对应的反射 API 方法为 Reflect.set()

1)返回值

  • 返回 true 表示成功;返回 false 表示失败,严格模式下会抛出 TypeError

2)拦截的操作

  • proxy.property = value
  • proxy[property] = value
  • Object.create(proxy)[property] = value
  • Reflect.set(proxy, property, value, receiver)

3)捕获器处理程序参数

  • target:目标对象
  • property:引用的目标对象上的字符串键属性
  • value:要赋给属性的值
  • receiver:接收最初赋值的对象

4)捕获器不变式

  • 如果 target.property 不可写且不可配置,则不能修改目标属性的值
  • 如果 target.property 不可配置且[[Set]]特性为 undefined,则不能修改目标属性的值。 在严格模式下,处理程序中返回 false 会抛出 TypeError
const myTarget = {}
const proxy = new Proxy(myTarget, {
  set(target, property, value, receiver) {
    console.log("set()")
    return Reflect.set(...arguments)
  },
})
proxy.foo = "bar" // 触发set()捕获器

has()

has()捕获器会在 in 操作符中被调用,对应的反射 API 方法为 Reflect.has()

1)返回值

  • has()必须返回布尔值,表示属性是否存在,返回非布尔值会被转型为布尔值

2)拦截的操作

  • property in proxy
  • property in Object.create(proxy)
  • with(proxy) {(property);}
  • Reflect.has(proxy, property)

3)捕获器不变式

  • 如果 target.property 存在且不可配置,则处理程序必须返回 true
  • 如果 target.property 存在且目标对象不可扩展,则处理程序必须返回 true
const myTarget = {}
const proxy = new Proxy(myTarget, {
  has(target, property) {
    console.log("has()")
    return Reflect.has(...arguments)
  },
})
"foo" in proxy //触发 has()捕获器

deleteProperty()

deleteProperty()捕获器会在 delete 操作符中被调用,对应的反射 API 方法为 Reflect.deleteProperty()

1)返回值

  • deleteProperty()必须返回布尔值,表示删除属性是否成功,返回非布尔值会被转型为布尔值

2)拦截的操作

  • delete proxy.property
  • delete proxy[property]
  • Reflect.deleteProperty(proxy, property)

3)捕获器不变式

  • 如果自有的 target.property 存在且不可配置,则处理程序不能删除这个属性
const myTarget = {}
const proxy = new Proxy(myTarget, {
  deleteProperty(target, property) {
    console.log("deleteProperty()")
    return Reflect.deleteProperty(...arguments)
  },
})
delete proxy.foo // 触发deleteProperty()捕获器

apply()

apply()捕获器会在调用函数时中被调用,对应的反射 API 方法为 Reflect.apply()

1)返回值

  • 返回值无限制

2)拦截的操作

  • proxy(…argumentsList)
  • Function.prototype.apply(thisArg, argumentsList)
  • Function.prototype.call(thisArg, …argumentsList)
  • Reflect.apply(target, thisArgument, argumentsList)

3)捕获器处理程序参数

  • target:目标对象
  • thisArg:调用函数时的 this 参数
  • argumentsList:调用函数时的参数列表

4)捕获器不变式

  • target 必须是一个函数对象
const myTarget = () => {}
const proxy = new Proxy(myTarget, {
  apply(target, thisArg, ...argumentsList) {
    console.log("apply()")
    return Reflect.apply(...arguments)
  },
})
proxy() // 触发apply()捕获器

construct()

construct()捕获器会在 new 操作符中被调用,对应的反射 API 方法为 Reflect.construct()

1)返回值

  • construct()必须返回一个对象

2)拦截的操作

  • new proxy(…argumentsList)
  • Reflect.construct(target, argumentsList, newTarget)

3)捕获器处理程序参数

  • target:目标构造函数
  • argumentsList:传给目标构造函数的参数列表
  • newTarget:最初被调用的构造函数

4)捕获器不变式

  • target 必须可以用作构造函数
const myTarget = function () {}
const proxy = new Proxy(myTarget, {
  construct(target, argumentsList, newTarget) {
    console.log("construct()")
    return Reflect.construct(...arguments)
  },
})
new proxy() // 触发construct()捕获器

其他捕获器可参考:MDN-Proxy

手把手配置:用Synopsys VDK为英飞凌TC4x系列MCU做虚拟原型开发 本文详细介绍了如何使用Synopsys VDK为英飞凌TC4x系列MCU进行虚拟原型开发,涵盖开发环境搭建、关键外设虚拟化配置、AUTOSAR栈集成及虚拟调试与性能调优全流程。通过虚拟原型技术,开发者可提前6-12个月启动软件开发,显著提升汽车电子项目的开发效率。 阅读详情

相关推荐

AI漫剧制作全流程零基础实操指南:从剧本到剪辑

AI漫剧是一种利用AI工具将剧本、分镜、出图、配音、剪辑整合为流水线的短视频内容形式。其技术原理基于文生图、图生图与文本转语音模型的组合,核心挑战在于角色一致性控制与分镜批量出图。这项技术大幅降低了视频制作门槛,使个人创作者无需演员和设备即可产出剧情向短内容,广泛应用于短视频平台的情景剧、玄幻、甜宠等题材。本文给出了一套零基础可照做的全流程实操方案,覆盖剧本提示词、分镜表、出图选型、配音合成与剪辑模板,帮助你快速跑通AI漫剧制作链路。

weixin_29048309的博客 531

使用new Proxy,自定义object的setter 和getter,Proxy 和 Object.defineProperty 的区别,Reflect 对象是啥

proxy

有一棵树的博客 3050

服务器冗余电源维修图纸,冗余热备份电源的电路图设计

在设计某高可靠性计算机系统时,要求其配套电源采取冗余设计。一般来说,可以采取的方案有容量冗余、冗余冷备份方式、并联均流的N+1备份方式、冗余热备份方式。容量冗余是指电源的最大负载能力大于实际负载,也就是“大马拉小车”,其缺点是不利于提高电源的效率,而且对提高电源的可靠性意义不大。冗余冷备份方式是指电源由两个或多个功能相同的单元模块组成,电源启动后由其中一个单元模块向设备供电,当工作单元发生故障时,...

weixin_39671509的博客 1995

new Proxy()代理

new Proxy()代理

qq_36453396的博客 1万+

导带、价带

价带是电子的“束缚态”能量区间,决定材料的化学性质;导带是电子的“自由态”能量区间,直接决定材料的导电能力;禁带宽度则是区分金属、半导体与绝缘体的核心参数。通过调控能带结构(如掺杂、应变工程),可设计出具有特定电学和光学特性的功能材料,推动电子信息、能源转换等领域的技术革新。

weixin_51552564的博客 5119

微信中调起支付宝支付

微信中调用支付宝支付,首先我们知道微信是不能直接调用支付宝的,所以我们需要使用一个中间页提示用户在浏览器中打开,然后进行网页支付或打开app支付。以下为详细唤起支付宝的步骤、业务代码以及相关页面图。 如有问题欢迎评论留言,看到定回复哦^_^\(^o^)/~ 一、微信中唤起支付宝,有几个步骤: 1、中间页引导用户在浏览器中打开去唤起支付宝。 2、浏览器中打开支付宝或app中打开支付宝。 3...

han_calligrapher的博客 2万+

Vue 55 ,Vue2 和 vue3 中双向数据绑定的原理,JavaScript的 Object.defineProperty 和 ES6的 Proxy 对象代理,使用详细

⭐Object.defineProperty大家都知道,是一个强大且常用的方法,用于定义对象属性,允许我们精确地控制属性的行为,包括读取、写入和删除等操作; Proxy是ES6中一种用于创建代理对象的特殊对象,它允许我们拦截并自定义目标对象的操作,例如属性访问、赋值、函数调用等。Proxy提供了一种机制,可以在目标对象上设置拦截器,从而拦截对目标对象的操作。

AI Agent 全栈架构师(AI + GIS + Backend)& 数字芯片系统架构师(FPGA),NorthCity Smile的博客(NcSmile,博主域名:https://ncmile.blog.youkuaiyun.com) 2381

思岚A1 上手教程

前言 寒假在家闲着也是闲着,索性就向是实验室借了一个思岚 A1激光雷达,来进一步完成自己的实验室实习项目。经过一个月在Linux上和ROS上的摸爬滚打,我已经对机器人开发和SLAM有了初步了解,现在就写个上手教程吧(以防自己以后忘了)。 Basic Support 硬件 一台电脑 思岚 A1激光雷达 软件 安装Virtual Box虚拟机 在虚拟机安装Ubuntu 16操作系统 在Ubuntu 16搭建ROS kinetic 简要步骤 1.现在w..

ajxdhe的博客 6386

JavaScript之proxy详解

proxy在目标对象的外层搭建了一层拦截,外界对目标对象的某些操作,必须通过这层拦截proxy对象是obj对象的原型,obj对象本身并没有time属性,所以根据原型链,会在proxy对象上读取该属性,导致被拦截。

subsistent的博客 1213

Solidworks曲面建模学习(三)——样条曲线

本文主要演示平面的空间样条曲线的一些绘制。

东东不熬夜的博客 6505

Impala>Impala安装部署

文章目录1.安装前提2.下载安装包、依赖包3.虚拟机新增磁盘(可选)4.配置本地yum源5.安装Impala6.修改Hadoop、Hive配置7.修改impala配置8.启动、关闭impala服务 1.安装前提 集群提前安装好hadoop,hive。 hive安装包scp在所有需要安装impala的节点上,因为impala需要引用hive的依赖包。 hadoop框架需要支持C程序访问接口,查看下...

qq_44509920的博客 838

js的代理与反射

在 JS 运行时,能够知道这个对象的成员,并能够调用这些成员,这种动态获取信息、动态调用对象方法的功能称为反射。反射 API 范围很广,可以用于代理中的捕获处理程序。大多的反射 API 方法在 Object 类型上都有对应的方法。相比 Object 直接操作,反射更适合用于细粒度的对象控制。

weixin_43418929的博客 255

机器人控制算法九之 位姿描述与空间变换

机器人控制算法九之 位姿描述与空间变换

yohnyang的博客 1034

JavaScript重难点突破:代理与反射

详细解释并列举了JavaScript中代理与反射部分的知识点和内容,结合图像和API共同编写

sententias的博客 790

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

JS代理与反射

JS代理与反射前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 提示:以下是本篇文章正文内容,下面案例可供参考 一、pandas是什么? 示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。 二、使用步骤 1.引入库 代码如下(示例): import numpy as np impor

weixin_41979384的博客 1816

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

JavaScript --- 代理与反射

引言: 代理与反射听起来像是javaScript不同于其他语言的独有特性,从某些方面来说,代理类似C++的指针,但这里先不讨论它的定义。接下来给出几个例子,就很容易理解了 创建空代理 let target = { name: 'lihua', age: 18, array: [1, 2, 6] } let handler = {} let proxy = new Proxy(target, handler) //证明proxy与target的属性引用的是同一块地址,哪怕是原始.

JKR10000的博客 920

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

JS学习笔记(八)代理与反射

JS学习笔记(八)代理与反射 文章目录JS学习笔记(八)代理与反射一、代理1.1 创建空代理1.2 定义捕获器1.3 捕获器参数和反射API1.4 可撤销代理1.5 实用反射API1.5.1 反射API与对象API1.5.2 状态标记1.5.3 用一等函数替代操作符二、代理捕获器与反射方法2.1 get()1. 返回值2. 拦截的操作3. 捕获器不变式2.2 set()1. 返回值2. 拦截的操作2.3 has()1. 返回值2. 拦截的操作2.4 defineProperty()1. 返回值2. 拦截的操

MARTIAN的博客 976

JavaScript红宝书第九章:代理与反射

本文主要讲解代理与反射,那么好,本文正式开始。捕获器是代理的重要概念之一,它作用是可以在设置捕获的某个路径中进行程序处理。实现捕获。举例:比如我们想要让目标对象输出时候输出1.get(){return 1;//target 1代理就是对数据的劫持,并且劫持的过程中加一些操作,反射,就是对象方法的复制API。可以从头到尾复刻对象的某个API方法。以上就是,全部内容。

lplovewjm的博客 2105

js 代理与反射 Proxy

代理基础 Proxy:创建空代理,可撤销代理,实用反射API,代理另一个代理,代理的问题与不足。代理捕获器与反射方法:get()、set()、has()、defineProperty()、getOwnPropertyDescriptor()、deleteProperty()、ownKeys()、getPrototypeOf()、setPrototypeOf()、isExtensible()、preventExtensions()、apply()、construct()。代理模式:跟踪属性访问、隐藏属性、属性

逆水寒 306

理解javascript代理基础和反射

理解javascript代理基础 这里的代理是对于对象的代理,这个代理其实和对象属性的访问器属性差不多,可以类比去理解 一、创建空代理——就是设置代理的第二个参数是一个空的对象字面量 <script> let target = { id:"201902091" } let handler ={} let proxy = new Proxy(target,handler); console.log(target.id); console.

weixin_47450807的博客 459

Javascript中的代理和反射

ECMAScript 6 新增的代理与反射为开发者提供了拦截并向基本操作(如属性查找、赋值、枚举、函数调用等)嵌入额外行为的能力。也就是,可以给目标对象定义一个关联的代理对象,而这个代理对象可以作为抽象的目标来使用。

qq_45265059的博客 454

js 代理与反射简介

js 代理与反射简介 代理与反射提供了拦截并向基本操作嵌入额外行为的能力。 在对目标对象的各种操作影响目标对象之前,可以在代理对象中对这些操作加以控制。 // 目标对象 const target = { name: 'zhangsan', age: 12, } // 处理器 const handler = { // get 捕获器 /** * * @param {*} trapTarget - 目标对象 * @param {*} proper

lihaogn的博客 410

js 深入理解代理和反射

代理和反射提供了拦截并向基本操作嵌入额外行为的能力。具体地说,可以给目标对象定义一个关联的代理对象,而这个代理对象可以作为抽象的目标对象来使用。在对目标对象的各种操作影响目标对象之前,可以在代理对象中对这些操作加以控制对刚刚接触这个主题的开发者而言,代理是一个比较模糊的概念,而且还夹杂着很多新术语。其实只要看几个例子,就很容易理解了。使用代理的主要目的是可以定义捕获器(trap)。捕获器就是在处理程序对象中定义的“基本操作的拦截器”。

weiweiliude2的专栏 1039

JavaScript 代理与反射

JavaScript 代理与反射

sinat_35607202的博客 1196

js逆向基础11-多态代理反射常用方法

多态的最根本好处在于,你不必再向对象询问“你是什么类型”而后根据得到的答案调用对象的某个行为--你只管调用该行为就是了,其他的一切多态机制都会为你安排妥当。多态的实际含义是:同一操作作用于不同对象上,可以产生不同的解释和不同的执行结果。function makeSound (animal) { if (animal instanceof Cat) { console.log('喵喵喵~') } else if (animal instanceof Dog) { console.log('汪汪汪!

qq_68630379的博客 1058

js高级-代理与反射

每个处理程序对象可以包含零个或多个捕获器,每个捕获器都对应一种基本操作,可以直接或间接在代理对象上调用。每次在代理对象上调用这些基本操作时,代理可以在这些操作传播到目标对象之前先调用捕获器函数,从而拦截并修改相应的行为。根据 ECMAScript 规范,每个捕获的方法都知道目标对象上下文、捕获函数签名,而捕获处理程序的行为必须遵循“捕获器不变式”。它可以用作目标对象的替身,但又完全独立于目标对象。处理程序对象:一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理的行为。

m0_53614495的博客 362
上一篇: 从前端视角看设计模式之行为型模式篇
下一篇: JavaScript基础 -- 函数
ZoeLandia
博客等级 码龄6年 734粉丝 183原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值