Получить путь к доступному значению во вложенном объекте

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

Он должен работать как наблюдатель, который возвращает доступ к пути.

Ниже моя реализация.

function wrap(o, fn, scope = []) {
  const handler = {
    set(target, prop, value, receiver) {
      fn('set value in scope: ', scope.concat(prop))
      target[prop] = value
      return true
    },
    get(target, prop, receiver) {
      fn('get value in scope: ', scope.concat(prop))
      return o[prop]
    },
    ownKeys() {
      fn('keys in scope: ', scope)
      return Reflect.ownKeys(o)
    }
  }

  return new Proxy(
    Object.keys(o).reduce((result, key) => {
      if (isObject(result[key])) {
        result[key] = wrap(o[key], fn, scope.concat(key))
      } else {
        result[key] = o[key]
      }
      return result
    }, {}),
    handler
  )
}

function isObject(obj) {
  return typeof obj === 'object' && !Array.isArray(obj)
}

const obj = wrap({
  a0: {
    a1: {
      a2: 0
    },
    b1: {
      b2: 0
    }
  },
  b0: 0
}, console.log)


// set value:
obj.b0 = 1

// get value:
console.log('value: ' + obj.a0.a1.a2)

// list keys:
console.log('keys: ', Object.keys(obj.a0))

  • Первый журнал должен вернуться set value in scope: ['b0']
  • второй должен вернуться get value in scope: ['a0', 'a1', 'a2'] а также value: 0
  • последний должен вернуться keys in scope: ['a0'] и ключи obj.a0

Спасибо за любую помощь!

1 ответ

Решение

Вы сделали несколько ошибок:

get(target, prop, receiver) {
    fn('get value in scope: ', scope.concat(prop))
    return o[prop]
},

Это return target[prop] вернуть завернутую версию. а также

if (isObject(result[key])) {
    result[key] = wrap(o[key], fn, scope.concat(
} else {
    result[key] = o[key]
}

его isObject(o[key]) проверить исходный объект

И ничего не трогая, ваш второй журнал будет выглядеть так:

get value in scope: ['a0'] 
get value in scope: ['a0', 'a1'] 
get value in scope: ['a0', 'a1', 'a2'] 
value: 0
Другие вопросы по тегам