简体   繁体   English

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

[英]JavaScript: Convert string and concatenate it to dynamically create an object property reference

I'm creating an API where values are passed by the server via data attribute, so the JS can use to retrieve information... My JS makes a AJAX call and a JSON object is returned... 我正在创建一个API,其中服务器通过data属性传递值,因此JS可以用来检索信息...我的JS进行AJAX调用并返回JSON对象...

{
    "data": {
        "results": {
            "type": [
                {
                    "cars" : {
                        "brands": {
                            "ford" : {},
                            "honda" : {}
                        }
                    }
                }
            ]
        }
    }
}

In order to get the brand, I just type 为了获得品牌,我只要输入

let brand = data.result.type[0].cars.brands.ford

this way I can get the results I need, but I need to build this path dynamically, by joining 2 partials of the path. 这样,我可以获得所需的结果,但是我需要通过连接路径的2个部分来动态构建此路径。 Like I said in the beginning of the question, some info are passed via data attribute and the info is type[0].cars.brands.ford ... I need to join this to data.result in my code. 就像我在问题开头所说的那样,一些信息是通过data属性传递的,信息是type[0].cars.brands.ford ...我需要在我的代码data.result其加入data.result中。 I'm currently being able to get the desired result by using eval() , like so 我现在可以通过使用eval()来获得所需的结果,像这样

entry.querySelectorAll('[data-brand]').forEach((e) =>
    let brand = eval('data.result.' + e.dataset.brand);
)

I know many of you will say that using eval() is bad and I'm very aware of it, but I just could not find a better way to make this to happen and there is another issue, when the brand, let's say, nissan is not on the JSON, I get an error TypeError: Cannot read property 'nissan' of undefined ... One could avoid this, by checking if the property exist, before continuing the code, but I don't know how to do this kind of test when eval() is involved. 我知道你们中的许多人都会说使用eval()不好,我对此非常了解,但是我只是找不到更好的方法来实现这一目标,还有另一个问题,那就是品牌,例如, nissan不在JSON上,我收到一个错误TypeError: Cannot read property 'nissan' of undefined ...在继续代码之前,可以通过检查属性是否存在来避免这种情况,但是我不知道该怎么做涉及eval()时进行这种测试。

So... basically, what I need, is a better way to dynamically build the property path, that can be tested to see if the property exist... 所以...基本上,我需要的是一种动态构建属性路径的更好方法,可以对其进行测试以查看属性是否存在...

Thanks in advance... 提前致谢...

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

That doenst support brackets, so do: 这确实会支撑支架,所以:

type.0.whatever.keys

To return undefined for non existent keys (instead of an empty object): 要为不存在的键(而不是空对象)返回undefined:

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

You can check if data.result has the property first, and only then make your variable brand: 您可以先检查data.result是否具有该属性,然后才能设置变量品牌:

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

You can String#match to find all keys, then iterate the keys using Array#reduce , and get the key value from the object: 您可以使用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); 

You can check ie the lodash get method which allows you to access values of object using path. 您可以检查lodash get方法,该方法允许您使用路径访问对象的值。

If lodash is too big for you, just review their implementation. 如果lodash对您来说太大了,请查看其实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM