JavaScript:转换字符串并将其连接以动态创建对象属性引用

时间:2017-10-18 15:15:33

标签: javascript json object ecmascript-6 eval

我正在创建一个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()时,我不知道如何进行此类测试。

所以...基本上,我需要的是动态构建属性路径的更好方法,可以测试该属性是否存在...

提前致谢...

4 个答案:

答案 0 :(得分:0)

const brand = e.dataset.brand.split(".").reduce((obj,id) => obj[id] || {}, data.results);

那是最重要的支持括号,所以:

type.0.whatever.keys

要为不存在的键(而不是空对象)返回undefined:

const brand = e.dataset.brand.split(".").reduce((obj,id) => (obj || {} )[id], data.results);

答案 1 :(得分:0)

您可以先检查data.result是否具有该属性,然后再创建您的变量品牌:

if(data.result.hasOwnProperty(e.dataset.brand)){
    let brand = data.result[e.dataset.brand];
}

答案 2 :(得分:0)

您可以String#match查找所有密钥,然后使用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);




答案 3 :(得分:-1)

您可以检查lodash get方法,该方法允许您使用路径访问对象的值。

如果lodash对你来说太大了,那就回顾一下它们的实现。