我想动态生成对象属性的访问权。
如果我尝试访问mydata[i].val.name
,我会somename
。
如果我尝试mydata[i] + bar[j]
(其中bar [j] ==='。val.name'),它会失败。
如何动态创建这样的东西?这样我可以使用用户生成的值访问对象的任何属性吗?
一些代码:
如果我有一个对象,我希望能够遍历其属性,收集我感兴趣的对象。理想情况下,我想要如下内容:
var processData = function (data, keys, values) {
var returnData = [], i, j, k;
var parsedData = JSON.parse(data);
var keys = keys || null;
var values = values || null;
var datalen = parsedData.length;
for (i = 0; i < datalen; i++) {
returnData[i] = {};
for(j = 0; j< keys.length; j++){
for(k = 0; k < values.length; k++){
returnData[i][keys[j]] = parsedData[i] + values;
}
}
}
return returnData;
};
然后像:
一样使用它var keys = ["foo","bar"];
var values = [".val.name", ".val.date"];
processData(data, keys, values);
但是这不起作用,在控制台中我看到foo="[object Object].val.name"
而不是预期的foo="ACME Industries"
。
答案 0 :(得分:1)
如果您尝试:
new Object() + '.john.doe'
它将以字符串形式连接,因此您将获得"[object Object].john.doe"
。
您应该创建一个可以处理动态属性名称的函数(并且有很多这样的函数)。您也可能希望将".foo.bar"
语法作为字符串(除非您打算使用eval()
)并且仅使用数组。
答案 1 :(得分:1)
如果你想坚持你的下标构造为带有点的字符串的模式,你必须滚动你自己的查找函数,如下所示:
function descend(object, sub) {
var handle = object,
stack = sub.split('.'),
history = [],
peek;
while (handle[stack[0]]) {
if (peek) {
history.push(peek);
}
peek = stack.shift();
handle = handle[peek];
}
if (stack.length > 0) {
history.push(peek);
throw "Traversal error, could not descend to '" + stack.join('.') + "' from '" + history.join('.') + "'.";
}
return handle;
}
var x = {
a: {
b: {
c: 15
},
d: 4
}
};
console.log(descend(x, "a"));
console.log(descend(x, "a.b"));
console.log(descend(x, "a.b.c"));
console.log(descend(x, "a.d"));
function processData(data, keys, values) {
if (keys.length !== values.length) {
throw "Mismatched keys and value lookups";
}
var i,
len = keys.length,
gathered = {},
k,
scratch,
v;
for (i = 0; i < len; i += 1) {
k = descend(data, keys[i]);
scratch = values[i].split('.');
scratch.shift();
v = descend(k, scratch.join('.'));
gathered[keys[i]] = v;
}
return gathered;
}
var data = {
foo: {
val: {
name: "ACME Industries"
}
},
bar: {
val: {
date: (new Date())
}
}
};
var keys = ["foo","bar"];
var values = [".val.name", ".val.date"];
processData(data, keys, values);
请注意:如果没有这种查找方式,这将不会像编码一样高效。
答案 2 :(得分:0)
如果我理解正确,你需要使用
mydata[i]["val"]["name"]
所以,我会用这样的东西:
var result =getItemByValuesPath(myData[i],values);
alert(result);
function getItemByValuesPath(item, values)
{
var result = item;
var vals = values.split(".");
for(var j=0; j<values.length; j++)
{
if(result==undefined)
{
return null;
}
result = result[values[j]];
}
}