ES6新特性: Proxy

前言

Proxy是ES6引入的一个元编程特性,它允许你创建一个代理对象,用于拦截并自定义 JavaScript 对象的基本操作。通过代理对象,你可以拦截并重定义对象的基本操作,比如属性查找、赋值、枚举等。Proxy的核心思想是在目标对象和代码之间建立一个拦截层,使得可以对目标对象的操作进行拦截和监视。

创建Proxy对象

创建Proxy对象的基本语法如下:

js 复制代码
let proxy = new Proxy(target, handler);
  • target:要代理的目标对象。
  • handler:一个对象,定义了代理对象的行为,包括捕获器(handlers)等。

Proxy的Handler对象

Handler对象是一个包含了代理行为的集合。它定义了当在代理对象上进行操作时应该如何响应这些操作。Handler对象可以定义各种捕获器(handlers),这些捕获器对应了不同的操作。一些常见的捕获器有:

  • get(target, property, receiver):拦截对象属性的读取操作。
  • set(target, property, value, receiver):拦截对象属性的设置操作。
  • has(target, property):拦截in操作符。
  • deleteProperty(target, property):拦截delete操作符。
  • apply(target, thisArg, argumentsList):拦截函数的调用。
  • construct(target, argumentsList, newTarget):拦截new操作符。

示例

js 复制代码
let target = {
    name: "John",
    age: 30
};

let handler = {
    get: function(target, prop, receiver) {
        console.log(`Getting property "${prop}"`);
        return target[prop];
    },
    set: function(target, prop, value, receiver) {
        console.log(`Setting property "${prop}" to ${value}`);
        target[prop] = value;
    }
};

let proxy = new Proxy(target, handler);

console.log(proxy.name); // Output: Getting property "name"  John

proxy.age = 40; // Output: Setting property "age" to 40

这段代码使用了Proxy来创建一个代理对象,代理了一个名为target的普通对象。该target对象有两个属性,nameage

接着,定义了一个handler对象,其中包含了两个捕获器:getset

  • get捕获器用于拦截对代理对象属性的读取操作。在这个示例中,它会在控制台打印出正在读取的属性名,然后返回target对象上对应属性的值。
  • set捕获器用于拦截对代理对象属性的设置操作。它会在控制台打印出被设置的属性名和值,然后将值赋给target对象上对应的属性。

最后,通过new Proxy(target, handler)创建了一个代理对象proxy,并将target对象和handler对象传入,用于定义代理对象的行为。

当我们尝试访问代理对象的name属性时,get捕获器被触发,输出了属性名并返回了target对象上name属性的值,即"John"。当我们尝试设置代理对象的age属性时,set捕获器被触发,输出了被设置的属性名和值,然后将值赋给了target对象的age属性,即将其从30修改为40。

apply

apply捕获器用于拦截函数的调用操作。当你通过代理对象调用被代理的函数时,apply捕获器会被触发,允许你自定义函数调用的行为。

下面是apply捕获器的详细解释:

参数:

  • target:被代理的目标函数。
  • thisArg:调用函数时绑定的this值。
  • argumentsList:一个类数组对象,包含了调用函数时传入的参数列表。

功能:

apply捕获器允许你定义在调用被代理函数时所执行的行为。你可以在这个捕获器内部执行任意操作,然后再调用目标函数并返回结果。这使得你可以在函数调用前后执行一些逻辑,或者修改传入的参数。

示例:

下面是一个示例,演示了如何使用apply捕获器拦截函数的调用:

js 复制代码
let targetFunction = function(a, b) {
    return a + b;
};

let handler = {
    apply: function(target, thisArg, argumentsList) {
        console.log(`Calling function with arguments {argumentsList}`);
        return target(...argumentsList); // 调用目标函数
    }
};

let proxy = new Proxy(targetFunction, handler);

console.log(proxy(3, 5)); // Output: Calling function with arguments 3,5  8

在这个例子中,我们创建了一个简单的目标函数targetFunction,它接收两个参数并返回它们的和。

然后,我们定义了一个handler对象,其中包含了一个apply捕获器。在apply捕获器中,我们输出了传入函数的参数列表,并调用了目标函数target,并将结果返回。

最后,我们通过new Proxy()创建了一个代理对象proxy,并将目标函数和handler对象传入,用于定义代理对象的行为。

当我们通过代理对象调用函数时,apply捕获器被触发,输出了传入函数的参数列表,然后调用了目标函数,返回了函数执行的结果。

相关推荐
ssshooter7 分钟前
Promise 和 async/await 被 try-catch 包裹时的行为差异
前端·javascript·面试
肖志-AI全栈12 分钟前
从零讲透 Ajax:XHR、Fetch、JSON 序列化到异步编程全链路
前端·ajax·json
yyt36304584114 分钟前
KlineChartQuant Tooltip 高频交互 200FPS 性能优化完整复盘
前端·经验分享·性能优化·typescript·vue·交互·chrome devtools
2601_9637713743 分钟前
WordPress SEO Guide: Boost Rankings Without Technical Jargon
前端·php
李顿波1 小时前
Chrome 扩展程序 MV3 架构组件概览
前端·chrome·浏览器插件
KingCodeHan1 小时前
ESLint 完全指南:从入门到精通
前端
GHL2842710901 小时前
安装chrome浏览器
前端·chrome
kisshyshy1 小时前
从0到1彻底理解流式输出:先读懂Vue的“乐高积木”,再拧开LLM的“数据水龙头”
javascript·vue.js·人工智能
谙忆10241 小时前
WebCodecs 实战:用 ImageDecoder 和 VideoFrame 在浏览器里做硬件加速的帧处理
前端
JerrySir1 小时前
密码没泄露,2FA 也没失效:Chrome 146 为什么还要让 Cookie“搬不走”?
前端