【问题标题】:Is it possible to create a "before writing" Proxy for a Node.JS object?是否可以为 Node.JS 对象创建“在编写之前”代理?
【发布时间】:2018-01-15 07:12:48
【问题描述】:

给定一个像这样的对象:

var box = { number: 20 }

我想在它上面加上一个“写之前”Proxy(或等效的)。该代理将充当中间件并执行类型检查。

例如,在执行box.number = "30" 之后,它将验证typeof === "number"。既然不是,就会报错。

执行box.number = 30 不会触发代理。


我尝试过的:

  • This。仅适用于未定义的属性。
  • Watcher.JS 值被写入,然后中间件被执行(因为它是一个观察者)。中间件应首先执行。

我知道可以做到的:

  • 我知道我可以简单地事先检查变量的typeof。我正在寻找代理解决方案。
  • 自定义函数(getter 和 setter)。我想尝试代理,所有属性都有动态名称。

【问题讨论】:

  • 使用带有get/set函数的CRUD方法,可以在设置实际值之前进行任何检查,并根据结果返回true/false。

标签: javascript node.js proxy


【解决方案1】:

在我看来,考虑到您的需求,get/set 是一种更好的方法,它们的执行时间更快,并且代码更易于维护。

GETTERS/SETTERS 解决方案

自 ES5 到来以来就一直存在...

  • 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 来实现它。

【讨论】:

    【解决方案2】:

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

    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,你可以封装在一个函数中

    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
    

    更多信息:

    【讨论】:

      猜你喜欢
      • 2020-10-16
      • 1970-01-01
      • 2018-10-07
      • 2011-12-12
      • 2020-04-26
      • 2023-02-14
      • 1970-01-01
      • 1970-01-01
      • 2021-07-28
      相关资源
      最近更新 更多