Измените вложенные объекты на тот же объект, значения которого являются объектами с родительскими объектами в качестве прототипа - PullRequest
3 голосов
/ 02 апреля 2019

Экспериментируя с идеей.Учитывая объект как:

T = {
  a: 2,
  b: 9,
  c: {
    a: 3,
    d: 6,
    e: {
      f: 12
    }
  }
}

Я хочу изменить его так, чтобы каждое значение, являющееся объектом, изменялось на один и тот же объект с родительским объектом в качестве прототипа.

Значение I 'я хотел бы иметь возможность иметь следующие выходные данные:

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

2 голосов
/ 03 апреля 2019

Это, кажется, работает нормально:

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));
    }
};
0 голосов
/ 03 апреля 2019

Если я не ошибаюсь, вы хотели сделать что-то вроде этого:

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)
}
...