likes
comments
collection
share

ES6新特性: Proxy

作者站长头像
站长
· 阅读数 16

前言

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

创建Proxy对象

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

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操作符。

示例

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捕获器拦截函数的调用:

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捕获器被触发,输出了传入函数的参数列表,然后调用了目标函数,返回了函数执行的结果。