es6代理安全的深层对象

我在使用代理访问不存在的属性时,写了一个小封装来返回undefined而不是typeError。 这里是代码:

function proxify(event) { var proxy = new Proxy(event, { get: function (target, property) { if (property in target) { return target[property]; } else { return ''; } } } }); return proxy; } 

这是一个财产缺less1级深。 例如,假设obj.something不存在:

 obj.something.else 

将返回undefined

但是,如果对象属性深嵌套

 obj.something.else.deeper 

我收到一个typeError

我的问题是如何扩展上面的函数来深层嵌套对象?

谢谢

您需要将返回值包装在proxify函数中:

 function proxify(event) { return isPrimitive(event) ? event : new Proxy(event, { get: getProp }); } function isPrimitive(v) { return v == null || (typeof v !== 'function' && typeof v !== 'object'); } function getProp (target, property) { if (property in target) { return proxify(target[property]); } else { return proxify({}); } } 

诚实地说,你最好使用lodash的_.get()或者ramda的R.path() 。 没有办法从第一个getProp()调用中知道评估将要进行多less层,所以它必须总是返回一个原始值或一个“truthy” Proxy实例,以便下一个属性访问可以被拦截(if一个发生)。 另一方面, _.get() . _.get()方法需要一个string,以便从初始调用中立即知道您只是试图访问这么多级别。

如idbehold所说,你必须返回一个原始值或新的代理。 我认为你不需要loDash来做到这一点,是的,你可以pipe理嵌套代理的深度! (请参阅我的最后一点, deepProxy 。但是,由于我不确定你想要做什么,我想集中你的注意力几点:

第一次使用(模拟链):


 function proxify(event){ return isPrimitive(event) ? event : new Proxy(event,{ get: getProp }); } function isPrimitive(v){ return v == null || (typeof v !== 'function' && typeof v !== 'object'); } function getProp(target, property){ return (property in target) ? proxify(target[property]) : proxify({}); } 

这个代码,将模拟嵌套的属性,但不赋予任何成员的依赖(因为没有分配,然后不保存)。

 obj.something.else = 99; console.log(obj.something.else) // returning a new Proxy() 

海事组织,这是没有意义的,或保留给非常具体的情况。 再次,这取决于你的目的是什么。

第二次使用(深度分配):


基本不可扩展的分配

 function proxify(defprop={}) { return new Proxy(defprop, handler); }; var handler = { get: function(target, property, receiver) { if(!(property in target)) target[property] = proxify(); return Reflect.get(target, property, receiver); }, }; obj.something.else = 99; console.log(obj.something.else) // returning 99 

可扩展到分配

通过使用基本的可链接代理,如果你尝试设置一个新的对象(或嵌套的对象),你将只捕获这个新属性的根。 没有更多可能的链条,这是不适合的,不安全的。

请记住以下情况:

Cyph:但是如果对象属性深嵌套

obj.something.else.deeper

(坏道)假设这个任务:

 var deeper = {toto: "titi"}; obj.something.else = deeper; console.log(obj.something.else.toto) // will return "titi" obj.something.else.toto.something.else = {tutu: "tata"}; // will return a typeError Again 

(好方法)传播链能力你需要在setter陷阱中检查值的types作为一个真实的对象,并且对每个根属性进行插入。 其余的深度将被吸气阱自然转换。

 var handler = { get: function(target, property, receiver) { if(!(property in target)) target[property] = proxify(); return Reflect.get(target, property, receiver); }, set: function(target, property, value, receiver) { // extend proxify to appended nested object if(({}).toString.call(value) === "[object Object]") value = deepApply(receiver, property, value); return Reflect.set(target, property, value, receiver); }, }; var deepApply = function(receiver,property, data) { var proxy = proxify(); var props = Object.keys(data); var size = props.length; for(var i = 0; i < size; i++) { property = props[i]; proxy[property] = data[property]; } return proxy; }; 

pipe理深度


我邀请您阅读我的实际解决scheme: deepProxy

  • 在设置对象结构时,可以通过proto声明自动定义关卡。 然后你可以很容易地知道当前楼层,并为每个级别添加条件指令。
  • 财产的path可以从他的访问者那里得到。