将嵌套对象更改为同一个对象,该对象的值是以父对象为原型的对象
2019-04-02
129
试验一个想法。给定一个对象,例如:
T = {
a: 2,
b: 9,
c: {
a: 3,
d: 6,
e: {
f: 12
}
}
}
我想对其进行变异,使每个对象值都更改为同一个对象,以父对象为原型。
这意味着我希望能够获得以下输出:
> T.c.b
9
> T.c.e.b
9
> T.c.e.a
3
> T.c.c.c
{a: 3, d: 6, e:[Object]}
我已经创建了以下函数,它们几乎按预期工作:
function chainer(object) {
for (const key in object) {
if (object[key] !== null && typeof (object[key]) === 'object') {
let Constructor = function () {
};
Constructor.prototype = object;
let objectValue = {...object[key]};
object[key] = new Constructor();
for (const savedKey in objectValue) {
object[key][savedKey] = objectValue[savedKey];
}
}
}
}
function chain(object) {
chainer(object);
for (const key in object) {
if (object[key] !== null && typeof (object[key]) === 'object') {
chainer(object[key]);
}
}
}
使用前面的示例,它可以按预期工作。尽管如此,当我尝试以下命令时:
T = {a:4, g:{g:{g:{g:{g:{g:{g:{}}}}}}}}
出现以下输出:
> T.a
4
> T.g.a
4
> T.g.g.a
4
> T.g.g.g.a
undefined
> T.g.g.g.g.a
undefined
我觉得很奇怪,它只能在一定程度上起作用,这让我认为也许这是一个我不知道的限制问题。
无论如何,我头晕目眩,没有主意了,有什么想法吗?
2个回答
这似乎工作正常:
ouroboros = (x, parent = null) => {
if (!x || typeof x !== 'object')
return x;
let r = Object.create(parent);
Object.entries(x).forEach(([k, v]) => r[k] = ouroboros(v, r));
return r;
};
//
T = ouroboros({x: 4, a: {b: {c: {d: {e: {}}}}}});
console.log(T.a.b.c.a.b.c.a.b.c.a.b.c.a.b.c.x);
或者,改变对象,而不是复制:
ouroboros = (x, parent = null) => {
if (x && typeof x === 'object') {
Object.setPrototypeOf(x, parent);
Object.values(x).forEach(v => ouroboros(v, x));
}
};
georg
2019-04-02
如果我没弄错的话,你想做这样的事情:
rec = function (o) {
return Object.keys(o).reduce((acc, key) => {
if (typeof acc[key] === "object") {
const kv = {...rec(acc[key]), ...o}
return {...acc, ...kv, get [key]() { return this}}
}
return acc;
},o)
}
Viktor Pelle
2019-04-02