当前位置:首页 > JavaScript

纯js实现代理

2026-01-31 00:45:47JavaScript

纯 JavaScript 实现代理

在 JavaScript 中,可以通过 Proxy 对象实现代理模式。Proxy 用于创建一个对象的代理,从而拦截和自定义对象的底层操作。

基本代理实现

创建一个简单的代理,拦截对象的属性访问和赋值操作:

const target = {
  name: 'Alice',
  age: 25
};

const handler = {
  get(target, property) {
    console.log(`Accessed property: ${property}`);
    return target[property];
  },
  set(target, property, value) {
    console.log(`Set property ${property} to ${value}`);
    target[property] = value;
    return true;
  }
};

const proxy = new Proxy(target, handler);

console.log(proxy.name); // 输出: Accessed property: name, Alice
proxy.age = 30; // 输出: Set property age to 30

验证代理

通过代理可以实现属性验证,确保赋值的合法性:

const validator = {
  set(target, property, value) {
    if (property === 'age' && typeof value !== 'number') {
      throw new TypeError('Age must be a number');
    }
    target[property] = value;
    return true;
  }
};

const validatedProxy = new Proxy(target, validator);

validatedProxy.age = 'thirty'; // 抛出 TypeError: Age must be a number

函数代理

代理也可以用于函数,拦截函数的调用:

function greet(name) {
  return `Hello, ${name}!`;
}

const functionHandler = {
  apply(target, thisArg, argumentsList) {
    console.log(`Called with arguments: ${argumentsList}`);
    return target.apply(thisArg, argumentsList);
  }
};

const proxiedGreet = new Proxy(greet, functionHandler);

console.log(proxiedGreet('Alice')); // 输出: Called with arguments: Alice, Hello, Alice!

隐藏私有属性

通过代理可以隐藏对象的私有属性:

const privateData = {
  _secret: 'confidential',
  publicInfo: 'Open to all'
};

const privacyHandler = {
  get(target, property) {
    if (property.startsWith('_')) {
      return undefined;
    }
    return target[property];
  },
  has(target, property) {
    return !property.startsWith('_') && property in target;
  }
};

const privateProxy = new Proxy(privateData, privacyHandler);

console.log(privateProxy._secret); // 输出: undefined
console.log(privateProxy.publicInfo); // 输出: Open to all
console.log('_secret' in privateProxy); // 输出: false

链式操作代理

通过代理可以实现链式操作:

const chainableTarget = {
  value: 1,
  add(num) {
    this.value += num;
    return this;
  },
  subtract(num) {
    this.value -= num;
    return this;
  }
};

const chainHandler = {
  get(target, property) {
    const value = target[property];
    if (typeof value === 'function') {
      return function(...args) {
        const result = value.apply(target, args);
        return result === target ? proxy : result;
      };
    }
    return value;
  }
};

const chainProxy = new Proxy(chainableTarget, chainHandler);

chainProxy.add(5).subtract(2).add(3);
console.log(chainProxy.value); // 输出: 7

注意事项

使用 Proxy 时需要注意以下几点:

纯js实现代理

  • 代理的行为完全由 handler 对象定义,未定义的陷阱会直接转发到目标对象。
  • Proxy.revocable() 可以创建可撤销的代理,通过调用返回的 revoke 函数可以取消代理。
  • 某些操作可能无法被代理拦截,如 Date.prototype.getTime()
  • 过度使用代理可能导致性能问题,特别是在频繁操作的热点代码中。

通过合理使用 Proxy,可以实现数据绑定、验证、日志记录、自动填充对象等多种高级功能。

标签: js
分享给朋友:

相关文章

js 实现vue

js 实现vue

实现 Vue 的核心功能 在 JavaScript 中实现 Vue 的核心功能需要模拟数据绑定、虚拟 DOM 和响应式系统。以下是一个简化版的实现思路: 响应式系统 通过 Object.define…

js实现倒计时

js实现倒计时

实现倒计时的基本方法 使用 JavaScript 实现倒计时功能可以通过 setInterval 或 setTimeout 结合日期计算来完成。以下是几种常见的实现方式: 使用 setInterva…

js 实现vue模板

js 实现vue模板

实现 Vue 模板的 JavaScript 方法 通过原生 JavaScript 可以实现类似 Vue 的模板渲染功能,主要包括数据绑定、指令处理和模板解析。以下是核心实现思路: 数据绑定与响应式…

js实现图片轮播

js实现图片轮播

实现基础图片轮播 使用HTML、CSS和JavaScript创建一个简单的图片轮播。HTML部分定义轮播容器和图片,CSS设置样式和动画效果,JavaScript处理轮播逻辑。 <div cl…

js实现二叉树

js实现二叉树

二叉树的基本概念 二叉树是一种树形数据结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树的常见操作包括插入、删除、遍历等。 二叉树的节点定义 在JavaScript中,二叉树的节点可…

js实现驼峰

js实现驼峰

实现驼峰命名的几种方法 使用正则表达式和字符串替换 通过正则表达式匹配字符串中的特定模式(如下划线或短横线),并将其后的字母转换为大写,同时移除分隔符。 function toCamelCase(s…