2017-03-16 107 views
0

我正在试验ES6中的代理,试图在对象上创建无限可链接的代理(从https://jsonplaceholder.typicode.com/users获得),如果找不到prop,则返回空{}在嵌套对象上实现代理

我试图实现此功能高达第二级(例如user.address.geo)。 编辑:用于检查类型属性内容的更新代码

let users = [{ 
    "id": 1, 
    "name": "Leanne Graham", 
    "username": "Bret", 
    "email": "[email protected]", 
    "address": { 
     "street": "Kulas Light", 
     "suite": "Apt. 556", 
     "city": "Gwenborough", 
     "zipcode": "92998-3874" 
    }, 
    "phone": "1-770-736-8031 x56442", 
    "website": "hildegard.org" 
}, 
{ 
    "id": 2, 
    "name": "Ervin Howell", 
    "username": "Antonette", 
    "email": "[email protected]", 
    "address": { 
     "street": "Victor Plains", 
     "suite": "Suite 879", 
     "city": "Wisokyburgh", 
     "zipcode": "90566-7771" 
    }, 
    "phone": "010-692-6593 x09125", 
    "website": "anastasia.net" 
}]; 

我想出了下面的代码

var handler = { 
    get: function (target, name) { 
     return name in target ? 
      target[name] : {}; 
    } 
}; 

let pusers = users.map(item => { 
    let pitem = new Proxy(item, handler); 
    Reflect.ownKeys(pitem).map(prop => { 
     pitem[prop] = (typeof pitem[prop] == 'object') ? new Proxy(pitem[prop], handler) : pitem[prop]; 
    }) 
    return pitem; 
}); 

pusers.map(u => { 
    console.log(u.address); 
    console.log(u.contact.city) 
}); 

这段代码的输出是没有吸引力,它返回undefined,而不是一个空{}对象

{ street: 'Kulas Light', 
    suite: 'Apt. 556', 
    city: 'Gwenborough', 
    zipcode: '92998-3874' } 
undefined 

我做了这几次,仍然得到相同的结果。我错过了什么吗?

+1

[有没有这样的事,作为一个“JSON对象”](http://benalman.com/news/2010/03/theres-no-such-thing-as-a-json/) –

+0

'checkJSON' - 什么?这看起来非常令人费解,根本不清楚该功能应该做什么。 – Bergi

+0

检查值是否是类型对象:我从http://stackoverflow.com/questions/4295386/how-can-i-check-if-a-value-is-a-json-object – NikhilGoud

回答

1

您不希望使用map仅在代理中包装数组的元素。相反,你希望你的get处理程序返回的属性包中的所有对象:

const handler = { 
    get(target, name) { 
     const v = target[name]; 
     return typeof v == "object" ? new Proxy(v, handler) : v; 
    } 
}; 
let pusers = new Proxy(users, handler); 

每一个嵌套的对象访问将经过处理现在,包括像。

现在你只需要添加的默认值不存在的属性,我猜你会想将它们存储在相应的目标,让突变:

const handler = { 
    get(target, name) { 
     const v = name in target ? target[name] : (target[name] = {}); 
     return typeof v == "object" ? new Proxy(v, handler) : v; 
    } 
}; 
let pusers = new Proxy(users, handler); 
+0

拍摄,我没有真正考虑更改处理程序,只是将处理程序分配给obj数组,而不是显然是错误的。 感谢您的详细解释。 有一件事,所以这里代理将被动态应用对吗?同时访问道具。 – NikhilGoud

+0

是的,确切地说。请注意,这意味着'pusers [0]!= pusers [0]',因为它们是从不同处理函数调用创建的不同代理实例。如果你想避免这种情况,你需要将代理自己存储在某个地方(也许是'WeakMap')。 – Bergi