Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/405.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript es6代理安全深度对象_Javascript_Node.js - Fatal编程技术网

Javascript es6代理安全深度对象

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];

我编写了一个小包装器,在使用代理访问不存在的属性时,返回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;
}
当属性缺少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声明自动定义 设置对象结构后,您可以轻松了解当前楼层,并为每个楼层添加条件说明
  • 可以通过他的访问器访问属性的路径

我在GitHub()上发布了一个库,允许您代理一个对象和该对象的任何嵌套子对象。它还有一些额外的功能:

  • 每当发生更改时,报告回指定的回调
  • 将阻止用户尝试代理代理
  • 保留已代理对象的存储,并将重用现有代理,而不是创建新代理(非常重要的性能影响)
  • 它是用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、 我试图实现你的建议,但我得到了一些不理想的结果,所以我假设我误解了什么