我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

需求是对某个实例化对象,使用Proxy进行修改。然后犯的错误是:混淆了类定义和实例化变量的区别,忽略了new Proxy()handler的多样性。得出的结论是:Proxy的真正生效对象是具体的变量本身,而不是作用在定义规范它的类或函数。

苏南大叔:JavaScript,Proxy作用于普通实例或者类时,有何不同? - proxy-class-object
JavaScript,Proxy作用于普通实例或者类时,有何不同?(图1-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔的编程经验文章。测试环境:chrome@131.0.6778.70nodejs@20.18.0

前置阅读

为了更好的理解本文,可以先理解一下类和实例化变量的区别。参考下面的文章:

然后,基于上述文章的内容,继续对其进行修改。修改的内容是:利用Proxy(),传入篡改其属性的handler。有关Proxy的内容,可以参考:

需求演示

本文的目标是,对类实例的某个属性进行更改。实例是通过类初始化的,作用结果是输出从sunan变成"苏南"。参考代码:

// 基本目标,需求演示,成功经验
var person = {
  who: "sunan",
};
var handler = {
  get: function (obj, prop) {
    if (prop == "who") {
      return "苏南";
    }
    return prop in obj ? obj[prop] : "default";
  },
};
var proxy_person = new Proxy(person, handler);
console.log(proxy_person.who); // 苏南

移植到类定义【错误演示】

Proxy()作用到类定义的时候,原来的handler就不能生效了。

// 想把成功经验转化到类上来,误解行为
function PersonFunction(who) {
  this.who = who;
}
class PersonClass {
  constructor(who) {
    this.who = who;
  }
}
var handler = {
  //和“成功经验”保持一致,但是作用到类上面的时候,就失效了
  get: function (obj, prop) {
    if (prop == "who") {
      return "苏南";
    }
    return prop in obj ? obj[prop] : "default";
  },
};
var PersonFunctionProxy = new Proxy(PersonFunction, handler);
var PersonClassProxy = new Proxy(PersonClass, handler);
var proxy_person2 = new PersonFunctionProxy("sunan");
var proxy_person3 = new PersonClassProxy("sunan");
console.log(proxy_person2.who); // sunan
console.log(proxy_person2.who); // sunan

Proxy曲线修改类【正确方案】

因为Proxy作用的对象,是某个实例,并不是这种更加虚无的类定义。作用于类定义的时候,在初始化的时候,做了第二次的Proxy,最终覆盖掉原实例。

// 对照组,两次proxy,通过临时proxy做桥梁
// 类的时候,修改construct(),为第二次proxy准备
// 对象的时候,和“成功经验”行为保持一致
var handler2 = {
  construct: function (target, args) {
    var obj_tmp = new target(...args);
    var obj_proxy = new Proxy(obj_tmp, {
      get: function (obj, prop) {
        if (prop == "who") {
          return "苏南";
        }
        return prop in obj ? obj[prop] : "default";
      },
    });
    return obj_proxy;
  },
};
var PersonFunctionProxy = new Proxy(PersonFunction, handler2); // 覆盖自己
var PersonClassProxy = new Proxy(PersonClass, handler2);
var proxy_person2 = new PersonFunctionProxy("sunan");
var proxy_person3 = new PersonClassProxy("sunan");
console.log(proxy_person2.who); // 苏南,实验成功
console.log(proxy_person2.who); // 苏南,实验成功

结语

proxy能作用于普通的变量,也可以作用于类定义。但是由于作用对象的实际属性不同,需求的实现的挂载点也是不同的。
本文也是为下一篇文章做铺垫的,所以,更多苏南大叔的相关经验文章,请参考:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   js