Вот несколько элегантный подход к созданию методов получения вложенных свойств:
const getProperty = property => {
const getter = o => {
if (o && typeof o === 'object') {
return Object.entries(o)
.map(([key, value]) => key === property ? value : getter(value))
.filter(Boolean)
.shift()
}
}
return getter
}
const test1 = {
location: {
state: {
className: 'test1'
}
}
}
const test2 = {
params: {
className: 'test2'
}
}
const test3 = {}
const getClassName = getProperty('className')
console.log(getClassName(test1))
console.log(getClassName(test2))
console.log(getClassName(test3))
Если вы хотите, чтобы циклические объекты не вызывали переполнение стека, я предлагаю использовать WeakSet
для отслеживания повторных ссылок на объекты:
const getProperty = property => {
const getter = (o, ws = new WeakSet()) => {
if (o && typeof o === 'object' && !ws.has(o)) {
ws.add(o)
return Object.entries(o)
.map(([key, value]) => key === property ? value : getter(value, ws))
.filter(Boolean)
.shift()
}
}
return getter
}
const test1 = {
location: {
state: {
className: 'test1'
}
}
}
const test2 = {
params: {
className: 'test2'
}
}
const test3 = {}
const test4 = {
a: {
b: {}
}
}
test4.a.self = test4
test4.a.b.self = test4
test4.a.b.className = 'test4'
const getClassName = getProperty('className')
console.log(getClassName(test1))
console.log(getClassName(test2))
console.log(getClassName(test3))
console.log(getClassName(test4))