ES6 中的 Proxy 全面讲解

目录

[一、什么是 Proxy](#一、什么是 Proxy)

[二、常用的拦截操作(handler traps)](#二、常用的拦截操作(handler traps))

[1. get ------ 拦截对象属性的读取](#1. get —— 拦截对象属性的读取)

[2. set ------ 拦截对象属性的赋值](#2. set —— 拦截对象属性的赋值)

[3. has ------ 拦截 in 操作符](#3. has —— 拦截 in 操作符)

[4. deleteProperty ------ 拦截 delete 操作](#4. deleteProperty —— 拦截 delete 操作)

[5. apply ------ 拦截函数调用](#5. apply —— 拦截函数调用)

[6. construct ------ 拦截 new 操作](#6. construct —— 拦截 new 操作)

[三、Proxy 的应用场景](#三、Proxy 的应用场景)

[四、Proxy 与 Object.defineProperty 的区别](#四、Proxy 与 Object.defineProperty 的区别)


一、什么是 Proxy

Proxy 是 ES6 引入的一个强大功能,意思是"代理"。它可以用来拦截对象的操作,并在操作时进行自定义的逻辑处理。

你可以把 Proxy 理解成:

👉 在 对象 和 外部访问者 之间加了一层"代理层",所有对对象的操作都会先经过 Proxy,从而让我们有机会"改写"这些操作。

语法如下:

javascript 复制代码
let proxy = new Proxy(target, handler);
  • target:要代理的对象(可以是对象、数组、函数等)

  • handler:包含拦截方法的对象,不同的方法对应不同的拦截操作


二、常用的拦截操作(handler traps)

1. get ------ 拦截对象属性的读取

javascript 复制代码
const user = {
  name: "Tom",
  age: 18
};

const proxy = new Proxy(user, {
  get(target, prop) {
    if (prop === "age") {
      return target[prop] + " 岁"; 
    }
    return target[prop];
  }
});

console.log(proxy.name); // Tom
console.log(proxy.age);  // 18 岁

👉 在读取 age 时被拦截,返回了一个自定义的字符串。


2. set ------ 拦截对象属性的赋值

javascript 复制代码
const user = {};

const proxy = new Proxy(user, {
  set(target, prop, value) {
    if (prop === "age") {
      if (typeof value !== "number") {
        throw new TypeError("年龄必须是数字!");
      }
    }
    target[prop] = value;
    return true; // 必须返回 true 表示赋值成功
  }
});

proxy.age = 20; 
console.log(proxy.age); // 20

proxy.age = "abc"; // 报错:年龄必须是数字!

👉 可以在设置属性时做数据校验,非常适合做表单验证。


3. has ------ 拦截 in 操作符

javascript 复制代码
const user = { name: "Tom", password: "123456" };

const proxy = new Proxy(user, {
  has(target, prop) {
    if (prop === "password") {
      return false; // 隐藏 password 属性
    }
    return prop in target;
  }
});

console.log("name" in proxy);     // true
console.log("password" in proxy); // false

👉 可以用来隐藏敏感信息。


4. deleteProperty ------ 拦截 delete 操作

javascript 复制代码
const user = { name: "Tom" };

const proxy = new Proxy(user, {
  deleteProperty(target, prop) {
    if (prop === "name") {
      console.log("name 属性不能被删除!");
      return false;
    }
    return true;
  }
});

delete proxy.name; // name 属性不能被删除!
console.log(proxy.name); // Tom

5. apply ------ 拦截函数调用

javascript 复制代码
function sum(a, b) {
  return a + b;
}

const proxy = new Proxy(sum, {
  apply(target, thisArg, args) {
    console.log("拦截函数调用,参数是:", args);
    return target(...args) * 2; // 返回值改为原函数结果的两倍
  }
});

console.log(proxy(1, 2)); // 6

6. construct ------ 拦截 new 操作

javascript 复制代码
class Person {
  constructor(name) {
    this.name = name;
  }
}

const ProxyPerson = new Proxy(Person, {
  construct(target, args) {
    console.log("正在创建实例,参数:", args);
    return new target(...args);
  }
});

const p = new ProxyPerson("Tom");
// 正在创建实例,参数: [ 'Tom' ]

三、Proxy 的应用场景

  1. 数据验证(如 set 中校验数据类型)

  2. 隐藏属性(如 has、get 中屏蔽敏感数据)

  3. 调试/日志记录(在 get/set 时记录日志)

  4. 自动填充默认值(属性不存在时返回默认值)

  5. 函数增强(apply 中扩展函数功能)

  6. Vue3 响应式实现(Vue3 底层用 Proxy 实现数据劫持)


四、Proxy 与 Object.defineProperty 的区别

在 Vue2 中,响应式是通过 Object.defineProperty 实现的,而 Vue3 改用了 Proxy。

  • Object.defineProperty 只能监听对象的属性,不能监听对象本身

  • Proxy 能直接代理整个对象,不需要对每个属性单独处理

  • Proxy 能监听更多操作(如 in、delete、函数调用 等)

因此,Proxy 更加灵活、强大,也逐渐成为未来的主流。


相关推荐
子兮曰4 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰4 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万4 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝4 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋4 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁4 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95274 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大4 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师4 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学5 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端