JavaScript: 转换字符串并拼接动态创建对象属性引用
JavaScript: Convert string and concatenate it to dynamically create an object property reference
我正在创建一个 API,其中值由服务器通过数据属性传递,因此 JS 可以用来检索信息...我的 JS 进行 AJAX 调用和 JSON 返回对象...
{
"data": {
"results": {
"type": [
{
"cars" : {
"brands": {
"ford" : {},
"honda" : {}
}
}
}
]
}
}
}
为了得到牌子,我直接输入
let brand = data.result.type[0].cars.brands.ford
这样我可以获得我需要的结果,但我需要通过加入路径的 2 个部分来动态构建此路径。就像我在问题开头所说的那样,一些信息是通过数据属性传递的,信息是 type[0].cars.brands.ford
...我需要在我的代码中将其加入 data.result
。我目前能够通过使用 eval()
获得所需的结果,例如
entry.querySelectorAll('[data-brand]').forEach((e) =>
let brand = eval('data.result.' + e.dataset.brand);
)
我知道你们中的许多人会说使用 eval()
不好,我很清楚这一点,但我找不到更好的方法来实现这一点,还有另一个问题,当品牌,比方说,nissan
不在 JSON 上时,我得到一个错误 TypeError: Cannot read property 'nissan' of undefined
...可以通过检查 属性 是否存在来避免这种情况,在继续代码之前,但我不知道如何在涉及 eval()
时进行这种测试。
所以...基本上,我需要的是动态构建 属性 路径的更好方法,可以测试该路径以查看 属性 是否存在...
提前致谢...
您可以查看 lodash get 方法,该方法允许您使用路径访问对象的值。
如果 lodash 对您来说太大了,请查看它们的实现。
const brand = e.dataset.brand.split(".").reduce((obj,id) => obj[id] || {}, data.results);
不支持括号,所以支持:
type.0.whatever.keys
到 return undefined for non existent keys (instead of an empty object):
const brand = e.dataset.brand.split(".").reduce((obj,id) => (obj || {} )[id], data.results);
您可以先检查data.result是否有属性,然后才使您的变量品牌:
if(data.result.hasOwnProperty(e.dataset.brand)){
let brand = data.result[e.dataset.brand];
}
您可以String#match to find all keys, then iterate the keys using Array#reduce,并从对象中获取键值:
const obj = {"data":{"results":{"type":[{"cars":{"brands":{"ford":{"name":"ford"},"honda":{"name":"honda"}}}}]}}};
const brand = 'data.results.type[0].cars.brands.ford';
const getPathValue = (src, path) => path.match(/[^.\[\]]+/g)
.reduce((p, k) => typeof p === 'object' ? p[k] : p, src);
const brandOBj = getPathValue(obj, brand);
console.log(brandOBj);
我正在创建一个 API,其中值由服务器通过数据属性传递,因此 JS 可以用来检索信息...我的 JS 进行 AJAX 调用和 JSON 返回对象...
{
"data": {
"results": {
"type": [
{
"cars" : {
"brands": {
"ford" : {},
"honda" : {}
}
}
}
]
}
}
}
为了得到牌子,我直接输入
let brand = data.result.type[0].cars.brands.ford
这样我可以获得我需要的结果,但我需要通过加入路径的 2 个部分来动态构建此路径。就像我在问题开头所说的那样,一些信息是通过数据属性传递的,信息是 type[0].cars.brands.ford
...我需要在我的代码中将其加入 data.result
。我目前能够通过使用 eval()
获得所需的结果,例如
entry.querySelectorAll('[data-brand]').forEach((e) =>
let brand = eval('data.result.' + e.dataset.brand);
)
我知道你们中的许多人会说使用 eval()
不好,我很清楚这一点,但我找不到更好的方法来实现这一点,还有另一个问题,当品牌,比方说,nissan
不在 JSON 上时,我得到一个错误 TypeError: Cannot read property 'nissan' of undefined
...可以通过检查 属性 是否存在来避免这种情况,在继续代码之前,但我不知道如何在涉及 eval()
时进行这种测试。
所以...基本上,我需要的是动态构建 属性 路径的更好方法,可以测试该路径以查看 属性 是否存在...
提前致谢...
您可以查看 lodash get 方法,该方法允许您使用路径访问对象的值。
如果 lodash 对您来说太大了,请查看它们的实现。
const brand = e.dataset.brand.split(".").reduce((obj,id) => obj[id] || {}, data.results);
不支持括号,所以支持:
type.0.whatever.keys
到 return undefined for non existent keys (instead of an empty object):
const brand = e.dataset.brand.split(".").reduce((obj,id) => (obj || {} )[id], data.results);
您可以先检查data.result是否有属性,然后才使您的变量品牌:
if(data.result.hasOwnProperty(e.dataset.brand)){
let brand = data.result[e.dataset.brand];
}
您可以String#match to find all keys, then iterate the keys using Array#reduce,并从对象中获取键值:
const obj = {"data":{"results":{"type":[{"cars":{"brands":{"ford":{"name":"ford"},"honda":{"name":"honda"}}}}]}}};
const brand = 'data.results.type[0].cars.brands.ford';
const getPathValue = (src, path) => path.match(/[^.\[\]]+/g)
.reduce((p, k) => typeof p === 'object' ? p[k] : p, src);
const brandOBj = getPathValue(obj, brand);
console.log(brandOBj);