在嵌套对象上实现代理

时间:2017-03-16 17:10:28

标签: javascript proxy ecmascript-6

我正在尝试在ES6中使用Proxies,试图在一个对象上创建一个无限可链接的代理(来自https://jsonplaceholder.typicode.com/users),如果找不到支柱,它应返回空{}

我尝试将此功能实现到第二级(例如,user.address.geo)。 编辑:已更新道具值检查类型的代码

let users = [{
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "Sincere@april.biz",
    "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": "Shanna@melissa.tv",
    "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 个答案:

答案 0 :(得分: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);

现在,每个嵌套对象访问都将通过处理程序,包括pusers[0].contact.city

之类的内容

现在您只需要为不存在的属性添加默认值,我想您会希望将它们存储在相应的目标上以允许突变:

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