可以为Node.JS对象创建一个“写前”代理吗?

ebdffaop  于 2023-06-05  发布在  Node.js
关注(0)|答案(2)|浏览(362)

给定一个像这样的对象:

var box = { number: 20 }

我想把一个“before writing”Proxy(或等价物)绑定到它。该代理将充当中间件并执行类型检查。
例如,在执行box.number = "30"之后,它将验证typeof === "number"。因为它不是,所以它会显示错误。
执行box.number = 30不会触发代理。
我尝试过的:

  • 此。仅适用于未定义的属性。
  • Watcher.JS写入值,然后执行中间件(因为它是一个监视器)。中间件应该首先执行。

我知道可以做到的是:

  • 我知道我可以事先简单地检查变量的typeof。我正在寻找一个代理解决方案。
  • 自定义函数(getters和setters)。我想用代理进行实验,所有属性都有动态名称。
m4pnthwp

m4pnthwp1#

在我看来,考虑到你的需要,get/set是一个更好的方法,它们在执行时间上更快,代码更容易维护。

Getters/Setters解决方案

自从ES 5问世以来,...

*getter是一个获取特定属性值的方法。
*setter是一个设置特定属性值的方法。

您可以在任何支持添加新属性的预定义核心对象或用户定义对象上定义getter和setter。定义getter和setter的语法使用对象文字语法。
+信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects

var box = { 
    _number : 0,
    get number(){ return this._number },
    set number(value){ 
        /* your verifications here */
        if( typeof value !== 'number' ) throw new Error('Invalid input')
        /* if validates , asign value */
        this._number = value;
    }
}
// test...
box.number = "1234"; // FAIL
box.number = 1234;   // OK
box.number;          // output = 1234

代理解决方案

自ES6起可用。如果性能对你来说很重要的话,可能不合适。使用 *GET/SET代理陷阱 * 获得与上一个示例相同的行为。

// your original object...
var box = {};
// create a proxy linked to your original object
var boxProxy = new Proxy( box , {
    get( obj, prop, receiver ){ return obj[prop] },
    set( obj, prop, value){ 
        /* check if the property trying to be written is 'number' */
        if( prop === 'number' ){
             /* your verifications here */
            if( typeof value  !== 'number' ) throw new Error('Invalid input')
            /* if validates , asign value */
            this._number = value;
        }
    } 
 });
// test...
boxProxy.number = "1234"; // FAIL
boxProxy.number = 1234;   // OK
boxProxy.number;          // output = 1234

在这两种情况下,如果你需要属性box._number是私有的和隐藏的,你可以使用closures来实现它。

hrirmatl

hrirmatl2#

这里有一个例子,你有一个验证码,和一个默认值

var box =Object.create({},{
number: {    
    get: function() { return this._number || 0; },
    set: function(value) {
      if(typeof value!='number') throw new Error('error')
      this._number=value
    }
}
})

如果你想隐藏私有的_number,你可以 Package 在一个函数中

var box=(function() {
    var _number
    var box =Object.create({},{
    number: {    
        get: function() { return _number || 0; },
        set: function(value) {
          if(typeof value!='number') throw new Error('error')
          _number=value
        }
    }
    })
    return box
})()

box.number=3

详细信息:

相关问题