【问题标题】:Node.js: Create a watchdog for an object with ProxyNode.js:使用 Proxy 为对象创建看门狗
【发布时间】:2018-08-12 23:46:52
【问题描述】:

编辑:它是一个对象代理,另见答案但是不明白为什么 console.log( watchDog ) 会产生这么多与 http 和路径相关的东西,不了解关联。


我想关注一个对象的变化,但是代理对象似乎是一个代理服务器对象。

我为测试该功能所做的工作:

var myObject = {},
    watchDog = new Proxy( myObject, {
                            set: function (target, key, value) 
                            {
                                console.log(key, 'changed to ', value );
                                target[key] = value;
                            }
                          }); 
 myObject.test = 1;

它永远不会被触发,因为它似乎不是一个对象代理。当我转储代理对象的内容 (console.log( watchDog );) 时,它会显示大量内容,如下所示:

   .............
   .............
   .............  
   { http_parser: '2.8.0',
           node: '8.11.3',
           v8: '6.2.414.54',
           uv: '1.19.1',
           zlib: '1.2.11',
           ares: '1.10.1-DEV',
           modules: '57',
           nghttp2: '1.32.0',
           napi: '3',
           openssl: '1.0.2o',
           icu: '60.1',
           unicode: '10.0',
           cldr: '32.0',
           tz: '2017c' },
        arch: 'ia32',
        platform: 'win32',
        release:
         { name: 'node',
           lts: 'Carbon',
           sourceUrl: 'https://nodejs.org/download/release/v8.11.3/node-v8.11.3.tar
    gz',
           headersUrl: 'https://nodejs.org/download/release/v8.11.3/node-v8.11.3-he
    ders.tar.gz',
           libUrl: 'https://nodejs.org/download/release/v8.11.3/win-x86/node.lib' }

        argv:
         [ 'F:\\Program Files (x86)\\nodejs\\node.exe',
           'L:\\Utils\\codebeat\\SerialInputDevice\\server\\app.js' ],
        execArgv: [],
        env:
         { ALLUSERSPROFILE: 'C:\\ProgramData',
           APPDATA: 'C:\\Users\\User\\AppData\\Roaming',
           CLASSPATH: '.;C:\\Program Files (x86)\\Java\\jre7_32\\lib\\ext\\QTJava.z
    p',
           CommonProgramFiles: 'C:\\Program Files (x86)\\Common Files',
           'CommonProgramFiles(x86)': 'C:\\Program Files (x86)\\Common Files',
           CommonProgramW6432: 'C:\\Program Files\\Common Files',

 ..............
 ..............

 etc.

所以这不是对象代理。如何创建对象代理而不是代理服务器对象?

另见

【问题讨论】:

  • 你能详细说明你的情况吗?为什么您需要关注对象更改以及为什么要更改 myObject 而不是 watchDog?这在代码中并不清楚。
  • @estus :另请参阅下面的答案和 cmets。
  • 我看到了。不清楚您为什么坚持观看 myObject 而不是使用 watchDog。 无法观察更改而不是包装它? 可以使用 Proxy 篡改原型链并观察 myObject 本身,但这可能会产生不良后果。这取决于这个对象是什么以及它是如何使用的。
  • @estus,感谢您的回复。好吧,我记得观察并观察哪些从 js 中删除。由于对过去的了解,我使用了 myObject 而不是代理,我认为它是相同的,但事实并非如此。现在我明白为什么叫proxy了,proxy是对象的访问管理器,而对象是保存信息的容器。我尝试做的是创建一个在初始化一次后无法更改的对象。这正在工作。
  • 我想念 Object.observe,但仅此而已。是的,如果代理按原样工作,请不要再观望。 Object.observe 的唯一真正替代方案是轮询,它效率低下而且是异步的。正如我所提到的,对于普通对象的原型链可以被篡改,例如obj.__proto__ = new Proxy({}, ...)。如果对象不是普通的或具有现有承诺,则可能无法按预期工作。

标签: javascript node.js object proxy


【解决方案1】:

使用现有代码示例:

watchDog.test = 5

确实产生输出。原始的myObject 没有被修改,而是在它周围创建了一个“shell”,可用于在允许与原始对象交互之前拦截交互。

在 Chrome 中(我刚刚尝试过),这会输出 test changed to 5。但是set() 的文档说明了返回值:

set 方法应该返回一个布尔值。返回 true 表示分配成功。如果 set 方法返回 false,并且赋值发生在严格模式代码中,则会抛出 TypeError。

示例代码显示了不同值的返回。该代码使用Reflect.set() 来处理返回的真实性。试试这个:

var myObject = {},
    watchDog = new Proxy( myObject, {
                            set: function (target, key, value) 
                            {
                                console.log(key, 'changed to ', value );
                                target[key] = value;
                                return Reflect.set(...arguments);
                            }
                        }); 
watchDog.test = 1;

【讨论】:

  • 欣赏快速的答案,但代理是观察另一个对象的变化。无论如何都试过了,这就是发生的事情: TypeError: 'set' on proxy: trap returned falsish for property 'test' 此外,无论如何,它是服务器代理而不是对象代理,我可以做些什么来创建和对象代理服务器代理对象。
  • return Reflect... 来自 MDN 示例,用于寻址 TypeError
  • 我想我马上就能搞定,感谢您的耐心;-) Return true 成功了。所以我需要使用代理来检测更改,而不是对象本身?现在我理解了“代理”这个名字(之前它是 watch 或 observe),但它不是手表,看门狗。我需要将其用作主要对象并返回此看门狗对象,对吗?所以 myObject 只是一个容器,而 watchDog 是对象的管理器。那不一样。无法查看更改而不是包装它?
  • 听起来你走在正确的轨道上。 Javascript 不是我的强项,但据我所知,代理是最接近你想要的。
  • 嗨,Alex,它现在正在工作,感谢您的帮助!你知道为什么 console.log(watchDog) 输出这么多 http 和路径的东西吗(见我的问题)?
猜你喜欢
  • 2012-08-06
  • 1970-01-01
  • 2011-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多