当前位置:首页 > 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

验证代理

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

纯js实现代理

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!

隐藏私有属性

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

纯js实现代理

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 时需要注意以下几点:

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

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

标签: js
分享给朋友:

相关文章

js实现vue

js实现vue

Vue.js 的基本实现方法 在 JavaScript 中实现 Vue.js 的功能,可以通过直接引入 Vue 库或使用现代构建工具(如 Vite 或 Webpack)。以下是几种常见的实现方式:…

js实现轮播

js实现轮播

实现轮播图的基本思路 轮播图的核心逻辑是通过定时切换展示的图片或内容,通常结合左右滑动按钮和指示器(小圆点)增强交互性。以下是基于原生JavaScript的实现方法。 HTML结构 构建轮播图的H…

js实现动画

js实现动画

使用 CSS 动画与 JavaScript 控制 通过 JavaScript 动态添加或移除 CSS 类来触发动画。CSS 定义关键帧(@keyframes),JavaScript 通过 classL…

js实现拖拽

js实现拖拽

实现拖拽的基本步骤 通过监听鼠标事件(mousedown、mousemove、mouseup)实现拖拽功能。以下是核心代码逻辑: const draggableElement = document.…

js实现验证码

js实现验证码

使用Canvas生成图形验证码 在HTML中创建一个Canvas元素用于绘制验证码。通过JavaScript随机生成数字或字母组合,并添加干扰线、噪点等干扰元素增强安全性。 <canvas i…

js实现全选

js实现全选

实现全选功能的方法 在JavaScript中实现全选功能通常涉及监听全选复选框的点击事件,并根据其状态控制其他复选框的选中状态。以下是几种常见的实现方式: 基础DOM操作实现 通过获取所有目标复选框…