Javascript es6代理安全深度对象
我编写了一个小包装器,在使用代理访问不存在的属性时,返回undefined来代替typeError。代码如下:Javascript es6代理安全深度对象,javascript,node.js,Javascript,Node.js,我编写了一个小包装器,在使用代理访问不存在的属性时,返回undefined来代替typeError。代码如下: function proxify(event) { var proxy = new Proxy(event, { get: function (target, property) { if (property in target) { return target[property];
function proxify(event) {
var proxy = new Proxy(event, {
get: function (target, property) {
if (property in target) {
return target[property];
} else {
return '';
}
}
}
});
return proxy;
}
当属性缺少1层深度时,此选项有效。
例如,假设obj.something不存在:
obj.something.else
将返回未定义的
但是如果对象属性是深嵌套的
obj.something.else.deeper
我收到一个打字错误
我的问题是如何扩展上面的函数来处理深层嵌套对象
Thx您需要将返回值包装在代理函数中:
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({});
}
}
老实说,你最好使用或之类的东西。无法从第一个
getProp()
调用知道计算将深入多少层,因此它必须始终返回原语值或“truthy”Proxy
实例,以便拦截下一个属性访问(如果发生)。另一方面,\ get()
方法接受一个字符串,这样它可以从初始调用中立即知道您只想访问这么多级别 正如idbehold所说,必须返回原语值或新代理。
我认为您不需要loDash来实现这一点,是的,您可以管理嵌套代理的深度!(见我的最后一点。
但是,由于我不确定您想做什么,我想让您关注以下几点:
首次使用(模拟链):
目前的代码将模拟嵌套属性, 但不授予任何成员依赖关系(因为没有赋值,就没有保存) 在我看来,这没有意义,或者只限于非常具体的情况。 同样,这取决于你的目的是什么 第二种用法(深度赋值):
基本不可扩展赋值
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
可扩展到赋值
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
obj.something.other.deep
(坏方法)假设此任务:
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陷阱中检查值的类型是否为true对象,并代理每个根属性。其余深度将由getter陷阱自然转换
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;
};
var处理程序=
{
get:函数(目标、属性、接收者)
{
如果(!(目标中的属性))
目标[属性]=代理();
返回Reflect.get(目标、属性、接收者);
},
集合:函数(目标、属性、值、接收者)
{
//将代理扩展到附加的嵌套对象
if(({}).toString.call(值)=“[object]”)
价值=深度应用(接收者、财产、价值);
返回Reflect.set(目标、属性、值、接收者);
},
};
var deepApply=函数(接收器、属性、数据)
{
var proxy=proxy();
var props=Object.keys(数据);
变量大小=道具长度;
对于(变量i=0;i
管理深度
我邀请您阅读我的实际解决方案:
- 该级别可以通过proto声明自动定义 设置对象结构后,您可以轻松了解当前楼层,并为每个楼层添加条件说明
- 可以通过他的访问器访问属性的路径
- 每当发生更改时,报告回指定的回调
- 将阻止用户尝试代理代理
- 保留已代理对象的存储,并将重用现有代理,而不是创建新代理(非常重要的性能影响)
- 它是用ES5编写的,采用了的分叉版本,所以可以很容易地在较旧的浏览器中部署,并支持数组变异方法
var test = {testing:{}};
var p = ObservableSlim.create(test, true, function(changes) {
console.log(JSON.stringify(changes));
});
p.testing.blah = 42; // console: [{"type":"add","target":{"blah":42},"property":"blah","newValue":42,"currentPath":"testing.blah",jsonPointer:"/testing/blah","proxy":{"blah":42}}]
我不确定我的理解是否正确。你能展示一个使用func的例子吗?我在上面分享了。我做了一些测试,我同意。lodash uuuz.get现在似乎是一个好办法。我试图保留简单的点访问器语法,但不需要使用dice,你需要使用
obj。有些东西
返回另一个这样的代理,而不是字符串。@Bergi似乎没有一种确定属性的深度的方法。如果我知道父级不存在,我可以调用另一个代理。如果我缺少某些内容,我会喜欢一个示例。thx无法确定,这只是动态属性访问。您需要始终返回一个代理。@Bergi您可以演示如何作为“答案”吗?@Bergi我应该d、 我试图实现你的建议,但我得到了一些不理想的结果,所以我假设我误解了什么