一种在不知道其在嵌套 js 对象中的路径的情况下访问 属性 的方法
A way to access a property without knowing its path in a nested js object
有没有办法在不知道对象路径的情况下访问对象中的嵌套 属性?
例如我可以有这样的东西
let test1 = {
location: {
state: {
className: 'myCalss'
}
}
};
let test2 = {
params: {
className: 'myCalss'
}
};
'extract' className
属性 有什么巧妙的方法吗?
我有一个解决方案,但它很丑陋,而且它只适用于这两种情况,我想知道我是否可以做一些更灵活的事情
当然可以。试试这个。它递归遍历对象和 returns 第一个匹配项。您可以根据需要配置 for
循环以匹配全部或最后一个
let test1 = {
location: {
state: {
className: 'myCalss'
}
}
};
let test2 = {
params: {
className: 'myCalss'
}
};
function getClassName(obj) {
if(typeof obj === "object" && 'className' in obj) {
return obj.className
}
const keys = Object.keys(obj)
for(let i = 0; i < keys.length; i++) {
let key = keys[i]
let res = getClassName(obj[key])
if(res) return res
}
return null
}
console.log(getClassName(test1), getClassName(test2))
这里有一个创建嵌套 属性 吸气剂的优雅方法:
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))
有没有办法在不知道对象路径的情况下访问对象中的嵌套 属性? 例如我可以有这样的东西
let test1 = {
location: {
state: {
className: 'myCalss'
}
}
};
let test2 = {
params: {
className: 'myCalss'
}
};
'extract' className
属性 有什么巧妙的方法吗?
我有一个解决方案,但它很丑陋,而且它只适用于这两种情况,我想知道我是否可以做一些更灵活的事情
当然可以。试试这个。它递归遍历对象和 returns 第一个匹配项。您可以根据需要配置 for
循环以匹配全部或最后一个
let test1 = {
location: {
state: {
className: 'myCalss'
}
}
};
let test2 = {
params: {
className: 'myCalss'
}
};
function getClassName(obj) {
if(typeof obj === "object" && 'className' in obj) {
return obj.className
}
const keys = Object.keys(obj)
for(let i = 0; i < keys.length; i++) {
let key = keys[i]
let res = getClassName(obj[key])
if(res) return res
}
return null
}
console.log(getClassName(test1), getClassName(test2))
这里有一个创建嵌套 属性 吸气剂的优雅方法:
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))