给定的数据类似于:
var data = [{id: 12345,
name:'my products',
items:[{
size: 'XXL',
sku: 'awe2345',
prices:[{type: 'rrp',prices: 10.99},
{type: 'sell_price', price: 9.99},
{type:'dealer', price:4.50}
]
},{
size: 'XL',
sku: 'awe2346',
prices:[{type: 'rep', prices: 10.99},
{type: 'sell_price', price: 9.99},
{type:'dealer', price:4.50}
]
}
]
}]
}]
有没有办法评估数据对象中元素的字符串表示?例如:“data[0].items[0].prices[0].rrp” ...不使用 eval()?
最佳答案
理想的解决方案是首先没有字符串表示。 认真地 问问自己是否更改现有代码以提供更理想输出中的内容。
但是,如果你不能,这应该做你想做的:
var path = "data[0].items[0].prices[0].rrp".split(/[\[\]\.]+/);
var next = window;
if (path[path.length - 1] == "") {
path.pop();
};
while (path.length && (next = next[path.shift()]) && typeof next == "object" && next !== null);
next;
为此创建一个函数:
function get(path) {
var next = window;
path = path.split(/[\[\]\.]+/);
if (path[path.length - 1] == "") {
path.pop();
};
while (path.length && (next = next[path.shift()]) && typeof next === "object" && next !== null);
return path.length ? undefined : next;
}
缺点:
data
必须在全局范围内才能工作(不能是局部变量)。 编辑: 要使用设置功能,您可以滥用 JavaScript 对象的传递引用性质,如下所示:
function set(path, value) {
var split = Math.max(path.lastIndexOf("["), path.lastIndexOf("."));
get(path.slice(0, split))[path.slice(split + 1).replace(/\]/, "")] = value;
}
提供有关其工作原理的一些解释:
getter 首先将输入拆分成一个数组,这样每个元素都是我们需要遍历
[data, 0, items, 0, prices, 0, rrp]
的成员。如果搜索字符串以“]”结尾,我们会在数组末尾得到一个额外的空元素,因此我们检查并删除它。然后我们做大循环;所以我们有元素要遍历(
while path.length
),将 next
变量设置为我们需要遍历 next = next[path.shift()]
的下一个对象成员。检查它是否是一个对象(否则它不会有任何成员要遍历),并检查它是否为空(因为 typeof null == "object")。循环执行后,我们将拥有链中的最后一个元素;所以退货吧。
setter 在搜索字符串中搜索最后一个对象引用,并使用
get()
函数检索该对象引用。然后它将返回的对象键设置为所需的值。如果我们没有这样做,我们就会设置一个值而不是一个引用,因此“真实”对象永远不会更新。关于javascript - 从字符串引用 Javascript 对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6898288/