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

proxy对待原变量的属性的态度是:如果是原版的属性,那么不改变原变量属性,只改变代理自身。如果不是原版的属性,那么会透传给原变量。真心是贴心亲密无间好的合作伙伴啊。那么,本文中,将讨论的内容是proxy如何对待原变量的方法,如何给原变量添加新的方法。

苏南大叔:nodejs如何利用Proxy无中生有,给原变量添加新方法? - proxy新方法
nodejs如何利用Proxy无中生有,给原变量添加新方法?(图5-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验文章。本文继续讨探js中的proxy功能。测试环境:win10node@。本次在node环境下执行本文测试,不是在浏览器环境下了。

测试代码

在前文中,苏南大叔写了关于proxy对于setget的态度和处理方式。参考:

基于上一篇文章里面的代码,新的测试代码如下:

const sn = {
  hi: "hello",
  to: "苏南大叔",
  greeting: function (from) {
    console.log(from + ": " + this.hi + " " + this.to);
  },
};
const handler = {
  // 错误的定义方式1
  greetingFake: function (p) {
    console.log("无法执行的新方法");
  },
  // 错误的定义方式2
  greeting: function (p) {
    console.log("这个也无法覆盖");
    obj.greeting(...arguments);
  },
};
const ssnn = new Proxy(sn, handler);

// 正确的定义方式
ssnn.greetingNew = function (from) {
  console.log("greeting new");
  console.log(from + ": " + this.hi + " " + this.to);
};

苏南大叔:nodejs如何利用Proxy无中生有,给原变量添加新方法? - 正确的定义方式
nodejs如何利用Proxy无中生有,给原变量添加新方法?(图5-2)

proxy执行原变量方法

如果有原变量定义了一些方法,那么,这些方法必然是可以在新的代理变量里面被执行的。
所以下面的代码可以顺利执行:

sn.greeting("原始");
ssnn.greeting("代理");

输出:

原始: hello 苏南大叔
代理: hello 苏南大叔

proxy透传新方法

如果想在给原变量添加新的方法,那么,并不是在handler里面定义的。所以,下面的代码会报错。

sn.greetingFake("原始");      // ssnn.greetingFake is not a function
ssnn.greetingFake("代理");    // sn.greetingFake is not a function

苏南大叔:nodejs如何利用Proxy无中生有,给原变量添加新方法? - 调用方式
nodejs如何利用Proxy无中生有,给原变量添加新方法?(图5-3)

也可以侧面推断:原变量和新的代理变量,两者并不是简单的合并。否则在handler里面定义的新方法必然是可以生效的。它的新方法是下面这样生效的:

ssnn.greetingNew = function (from) {
  console.log("greeting new");
  console.log(from + ": " + this.hi + " " + this.to);
};

从代码的运行结果上看,这个新添加的方法是可以透传回原变量的,原变量也有了新的方法能力。

sn.greetingNew("原始");
ssnn.greetingNew("代理");

输出:

greeting new
原始: hello 苏南大叔
greeting new
代理: hello 苏南大叔

proxy覆盖原方法

对于原有的方法,是否可以改写呢?答案是可以。就是把生成新方法的代码,稍稍改动一下,使用同名函数即可。

ssnn.greeting = function (from) {
  console.log("greeting overwrite");
  console.log(from + ": " + this.hi + " " + this.to);
};

sn.greeting("原始");
ssnn.greeting("代理");

输出:

greeting overwrite
原始: hello 苏南大叔
greeting overwrite
代理: hello 苏南大叔

苏南大叔:nodejs如何利用Proxy无中生有,给原变量添加新方法? - 可以覆盖
nodejs如何利用Proxy无中生有,给原变量添加新方法?(图5-4)

特别强调

这种通过proxy添加的新方法,对于变量属性的获取,也是会遵守handler里面的定义的。比如:

const sn = {
  hi: "hello",
  to: "苏南大叔",
  greeting: function (from) {
    console.log(from + ": " + this.hi + " " + this.to);
  },
};
const handler = {
  get(obj, prop, receiver) {
    if (prop in obj) {
      if (prop === "hi") {
        return "hola";
      }
      return obj[prop];
    }
    return "无此属性";
  },
};
const ssnn = new Proxy(sn, handler);
ssnn.greetingNew = function (from) {
  console.log(from + ": " + this.hi + " " + this.to);
};
sn.greetingNew("原始");
ssnn.greetingNew("代理");

输出是:

原始: hello 苏南大叔
代理: hola 苏南大叔

苏南大叔:nodejs如何利用Proxy无中生有,给原变量添加新方法? - 特别注意事项
nodejs如何利用Proxy无中生有,给原变量添加新方法?(图5-5)

参考文献

结束语

本文的结论是这样的:proxy对待对象的方法的态度,和对待属性的态度是一致的。如果存在,则可继承也可以单独发挥。如果不存在,则可以透传回去,让本体具有相同能力。

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

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

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

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