首页 > 其他分享 >ES6 之 Proxy(代理)总结(二)

ES6 之 Proxy(代理)总结(二)

时间:2024-07-11 11:01:11浏览次数:20  
标签:ES6 console target 代理 let proxy 拦截 Proxy

ES6 引入了 Proxy 对象,它用于创建一个对象的代理,从而可以拦截并自定义对象的基本操作,如属性查找、赋值、枚举、函数调用等。

主要特性:

  • 拦截操作:可以拦截对象的各种操作,如获取属性、设置属性、属性是否存在等。
  • 自定义行为:通过拦截操作,可以自定义对象的行为。
  • 撤销代理:可以撤销代理,恢复对象的原始行为。

Proxy 支持的拦截操作一览,一共 13 种:

  • get(target, propKey, receiver):拦截对象属性的读取,比如 proxy.foo 和 proxy[‘foo’] 。
  • set(target, propKey, value, receiver):拦截对象属性的设置,比如 proxy.foo = v 或 proxy[‘foo’] = v ,返回一个布尔值。
  • has(target, propKey):拦截 propKey in proxy 的操作,返回一个布尔值。
  • deleteProperty(target, propKey):拦截 delete proxy[propKey] 的操作,返回一个布尔值。
  • ownKeys(target):拦截 Object.getOwnPropertyNames(proxy)
  • Object.getOwnPropertySymbols(proxy) 、 Object.keys(proxy) 、 for…in 循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而 Object.keys() 的返回结果仅包括目标对象自身的可遍历属性。
  • getOwnPropertyDescriptor(target, propKey):拦截 Object.getOwnPropertyDescriptor(proxy, propKey) ,返回属性的描述对象。
  • defineProperty(target, propKey, propDesc):拦截 Object.defineProperty(proxy, propKey, propDesc) 、 Object.defineProperties(proxy, propDescs) ,返回一个布尔值。
  • preventExtensions(target):拦截 Object.preventExtensions(proxy) ,返回一个布尔值。
  • getPrototypeOf(target):拦截 Object.getPrototypeOf(proxy) ,返回一个对象。
  • isExtensible(target):拦截 Object.isExtensible(proxy) ,返回一个布尔值。
  • setPrototypeOf(target, proto):拦截 Object.setPrototypeOf(proxy, proto) ,返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
  • apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如
    proxy(…args) 、 proxy.call(object, …args) 、 proxy.apply(…) 。
    construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如 new proxy(…args) 。

1:基本的属性拦截

let target = {};
let handler = {
    get: function(obj, prop) {
        return prop in obj ? obj[prop] : `Property ${prop} not found`;
    },
    set: function(obj, prop, value) {
        console.log(`Setting ${prop} with value ${value}`);
        obj[prop] = value;
        return true;
    }
};

let proxy = new Proxy(target, handler);

proxy.name = "Alice"; // 输出: Setting name with value Alice
console.log(proxy.name); // 输出: Alice
console.log(proxy.age);  // 输出: Property age not found

2:拦截in操作符

let target = { a: 1 };
let handler = {
    has: function(target, prop) {
        return prop in target || prop === 'extra';
    }
};

let proxy = new Proxy(target, handler);

console.log('a' in proxy); // 输出:true
console.log('extra' in proxy); // 输出:true
console.log('b' in proxy); // 输出:false

3:拦截属性的枚举

let target = { a: 1, b: 2 };
let handler = {
    ownKeys: function(target) {
        return ['a'];
    }
};

let proxy = new Proxy(target, handler);

console.log(Object.keys(proxy)); // 输出:['a']
for (let key in proxy) {
    console.log(key); // 只会输出:a
}

4:拦截对象的删除操作

let target = { a: 1, b: 2 };
let handler = {
    deleteProperty: function(target, prop) {
        if (prop === 'a') {
            console.log(`Property ${prop} cannot be deleted`);
            return false;
        }
        return true;
    }
};

let proxy = new Proxy(target, handler);

console.log(delete proxy.a); // 输出:Property a cannot be deleted,返回 false
console.log(delete proxy.b); // 返回 true

5:撤销代理

let target = {};
let proxy = new Proxy(target, {});

// 撤销代理,revoke 后 proxy 不再可用
let revoke = Proxy.revoke;
revoke(proxy);

// 尝试使用 proxy 将会导致 TypeError
console.log(proxy.foo); // TypeError: Proxy was revoked

6. 拦截函数的调用、 call 和 apply 操作

apply方法可以接受三个参数,分别是目标对象、目标对象的上下文对象( this )和目标对象的参数数组。

var handler = {
  apply (target, ctx, args) {
    return Reflect.apply(...arguments);
  }
};

例子

var twice = {
  apply (target, ctx, args) {
    return Reflect.apply(...arguments) * 2;
  }
};
function sum (left, right) {
  return left + right;
};
var proxy = new Proxy(sum, twice);
proxy(1, 2) // 6
proxy.call(null, 5, 6) // 22
proxy.apply(null, [7, 8]) // 30

上面代码中,每当执行 proxy 函数(直接调用或 call 和 apply 调用),就会被 apply 方法拦截。

另外,直接调用 Reflect.apply 方法,也会被拦截。

Reflect.apply(proxy, null, [9, 10]) // 38

7. construct方法用于拦截new命令

//拦截对象的写法
var handler = {
  construct (target, args, newTarget) {
    return new target(...args);
  }
};
var p = new Proxy(function () {}, {
  construct: function(target, args) {
    console.log('called: ' + args.join(', '));
    return { value: args[0] * 10 };
  }
});
(new p(1)).value
// "called: 1"
// 10

construct方法返回的必须是一个对象,否则会报错。

var p = new Proxy(function() {}, {
  construct: function(target, argumentsList) {
    return 1;
  }
});
new p() // 报错
// Uncaught TypeError: 'construct' on proxy: trap returned non-object ('1')

标签:ES6,console,target,代理,let,proxy,拦截,Proxy
From: https://blog.csdn.net/qq_35876316/article/details/140259427

相关文章

  • ES6 Reflect 详解(三)
    Reflect对象与Proxy对象一样,也是ES6为了操作对象而提供的新API。Reflect对象的设计目的有4个。将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只......
  • 影响代理IP质量的因素有哪些?
    代理IP的质量受到多个因素的影响,这些因素直接关系到用户的网络体验、访问速度、稳定性以及隐私保护等方面。以下是影响代理IP质量的主要因素!1.稳定性稳定性是评估代理IP质量的首要因素。优质的代理IP应该能够在长时间内保持稳定的连接速度和可用性,避免频繁的断线或连接不稳......
  • 深入了解代理IP常见协议:区别与选择
    代理服务器在网络使用中扮演着重要的角色,是您设备和互联网之间的中间层。它不仅可以增强网络访问的安全性和隐私保护,还可以提供许多灵活的应用。使用代理时,不同的协议类型对数据交换具有不同的规则和特征。常见的代理协议包括HTTP代理、HTTPS代理和SOCKS5代理。它们有什么区别......
  • 影响代理IP质量的因素有哪些?
    代理IP的质量受到多个因素的影响,这些因素直接关系到用户的网络体验、访问速度、稳定性以及隐私保护等方面。以下是影响代理IP质量的主要因素!1.稳定性稳定性是评估代理IP质量的首要因素。优质的代理IP应该能够在长时间内保持稳定的连接速度和可用性,避免频繁的断线或连接不稳......
  • 影响代理IP质量的因素有哪些?
    代理IP的质量受到多个因素的影响,这些因素直接关系到用户的网络体验、访问速度、稳定性以及隐私保护等方面。以下是影响代理IP质量的主要因素!1.稳定性稳定性是评估代理IP质量的首要因素。优质的代理IP应该能够在长时间内保持稳定的连接速度和可用性,避免频繁的断线或连接不稳......
  • 深入了解代理IP常见协议:区别与选择
    代理服务器在网络使用中扮演着重要的角色,是您设备和互联网之间的中间层。它不仅可以增强网络访问的安全性和隐私保护,还可以提供许多灵活的应用。使用代理时,不同的协议类型对数据交换具有不同的规则和特征。常见的代理协议包括HTTP代理、HTTPS代理和SOCKS5代理。它们有什么区别......
  • 影响代理IP质量的因素有哪些?
    代理IP的质量受到多个因素的影响,这些因素直接关系到用户的网络体验、访问速度、稳定性以及隐私保护等方面。以下是影响代理IP质量的主要因素!1.稳定性稳定性是评估代理IP质量的首要因素。优质的代理IP应该能够在长时间内保持稳定的连接速度和可用性,避免频繁的断线或连接不稳......
  • 深入了解代理IP常见协议:区别与选择
    代理服务器在网络使用中扮演着重要的角色,是您设备和互联网之间的中间层。它不仅可以增强网络访问的安全性和隐私保护,还可以提供许多灵活的应用。使用代理时,不同的协议类型对数据交换具有不同的规则和特征。常见的代理协议包括HTTP代理、HTTPS代理和SOCKS5代理。它们有什么区别......
  • RPC api与Rest api的区别 微服务 正反向代理
    参考链接:https://blog.csdn.net/weixin_43871785/article/details/129922143  RPC:本地化REST:国际化HTTP与RPC的关系就好比国际化与地方化的关系(可以认为标准的国际拳击手和随意的自由拳击手)。要进行跨企业服务调用时,往往都是通过HTTPAPI,虽然效率不高,但是通用,没有......
  • Linux (10) 配置HAProxy,实现负载均衡器的主备模式
    《WindowsAzurePlatform系列文章目录》 最近有1个客户需求,在这里记录一下。客户提出需要使用Azure负载均衡器(四层负载均衡器),实现主备模式。场景是负载均衡器后有2台虚拟机-平时100%的流量都发送到第一台虚拟机-如果第一台虚拟机发生......