当前位置:首页 > 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实现图片上传

js实现图片上传

图片上传的基本实现 使用HTML的<input type="file">元素配合JavaScript的File API可以实现图片上传功能。HTML部分需要创建一个文件选择输入框和一个用于…

js如何实现继承

js如何实现继承

原型链继承 通过将子类的原型指向父类的实例实现继承。子类实例能够访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Parent…

js 实现vue

js 实现vue

Vue.js 的基本实现 在 JavaScript 中实现 Vue.js 的核心功能,可以通过数据绑定、响应式系统和虚拟 DOM 来实现。以下是实现 Vue.js 核心功能的简化版本。 数据响应式系…

js实现换肤

js实现换肤

使用CSS变量实现换肤 通过CSS变量可以轻松实现主题切换功能。CSS变量在根元素中定义,通过JavaScript动态修改这些变量值。 :root { --primary-color: #349…

js实现点击显示和隐藏

js实现点击显示和隐藏

实现点击显示和隐藏的JavaScript方法 使用classList.toggle切换类名 通过添加/移除CSS类控制元素的显示与隐藏,需提前在CSS中定义隐藏样式(如display: none)。…

js实现路由

js实现路由

js实现路由的方法 在JavaScript中实现路由功能可以通过多种方式完成,以下是几种常见的方法: 使用原生JavaScript实现路由 通过监听window.onhashchange事件来实现基…