Изменить ссылки объектов на другой объект в глубоко вложенном объекте - PullRequest
0 голосов
/ 08 мая 2018

Как установить ссылки на объекты одного типа с ссылкой на другой объект в глубоко вложенном объекте?

// Following is the class
class Ab{ a: number; }

let x = new Ab();
x.a = 10;

// Now I have an object something like this
let obj  = {
    b: 'hello',
    c: new Ab(),
    d: {
        x: 5,
        y: new Ab(),
        z: {
           p: new Ab()
        } 
    }
} 

Теперь я смогу изменить все ссылки нового Ab (), установленного на x object.

let obj  = {
    b: 'hello',
    c: x, // reassign the x reference
    d: {
        x: 5,
        y: x,
        z: {
           p: x
        } 
    }
} 

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

lodash.cloneDeepWith(obj, val => {
    // please do not worry/consider these logic this condition is working
    if (Object.getPrototypeOf(val) === tc) {
       // Actual problem is here
       // reassigning is not changing the original reference of obj
       val = x;
    }
});

Существуют ли какие-либо решения, которые бывают быстрее и проще? Любая помощь приветствуется.

1 Ответ

0 голосов
/ 08 мая 2018

Следующий код будет рекурсивно изменять каждый объект в зависимости от типа экземпляра:

const changeObjects = (obj, replacement, className) => {
  Object.keys(obj).forEach((key) => {
    if (obj[key] instanceof className) {
      obj[key] = replacement;
    } else if (typeof obj[key] === 'object') {
      changeObjects(obj[key], replacement, className);
    }
  });
}

changeObjects(obj, x, Ab);

Этот код должен работать с примером, который вы привели, без создания глубокого клона. Если вы хотели клонировать замену и не имели циклических ссылок, вы также можете сделать это:

obj[key] = Object.assign({}, replacement);

при назначении замены.

Я не уверен, что это квалифицируется как проще, но это немного быстрее и выполняет ту работу, которая вам необходима.

...