我的变量obj
定义如下:
{user: {username: "AzureDiamond", password: "hunter2"}}
我有一个字符串str
,可以定义为以下任何字符串:
JS(特别是node.js)中有一种相对简单的方法可以基本上/动态地执行以下操作吗?
str == "user"
时,请返回{username: "AzureDiamon", password: "hunter2"}
str == "user[username]"
时,返回“AzureDiamond”str == "user[password]"
时,返回“hunter2”str == "fake"
时,请返回null
编辑:这个问题更多的是要找出是否有更容易的东西或构建到JS / node.js中,除了正则表达式匹配之外我还可以使用。
答案 0 :(得分:4)
如果您确定str
的语法正确,则该函数可能如下所示:
function get_by_path(source, path){
var path_elements = path.split(']').join('').split('[');
for (var i=0; i < path_elements.length; i++){
source = source[path_elements[i]];
if (typeof source === 'undefined'){
return null;
}
};
return source;
};
这就是它的表现:
var data = {'user': {
'username': "AzureDiamond", 'password': "hunter2",
'details': {'address': {'street': "Happiness Street"}}
}};
get_by_path(data, 'user'); // gives user object
get_by_path(data, 'user[username]'); // gives "hunter2"
get_by_path(data, 'user[password]'); // gives "AzureDiamond"
get_by_path(data, 'fake'); // gives null
get_by_path(data, 'user[details][address][street]'); // gives "Happiness Street"
在脚本不使用正则表达式,也没有危险eval()
电话,只假定你的“路径的”将用一个字就没有支架和每一个部分(如果有的话)会括在方括号内的单词。如果在遍历的对象中找不到某个路径,则将返回null
。如果找到它,它将被返回(无论它是否是一些复杂的对象,字符串,null
,布尔或其他任何东西)。
脚本从解析您的路径开始。它通过删除右方括号(“]
”)并通过打开方括号(“[
”)拆分结果字符串来实现。这个过程如下:
"user" -> "user" -> ["user"]
"user[username]" -> "user[username" -> ["user", "username"]
"user[password]" -> "user[password" -> ["user", "password"]
"user[address][street]" -> "user[address[street" -> ["user", "address", "street"]
"fake" -> "fake" -> ["fake"]
因此,如您所见,最后您有一个路径元素数组。这些是逐个评估的。如果在任何级别都不能使适当的步骤更深入到数据参数的结构中,则返回null
。否则返回最后访问的元素。
证明它有效:http://jsfiddle.net/EJCgE/2/
编辑:由于字符串replace()
方法的工作原理,更复杂的路径(当有两个以上的级别时)存在一些问题。我已将代码更新为不包含jQuery并修复该问题。
EDIT2 :我已更新脚本以删除冗余行和一个冗余变量。
答案 1 :(得分:2)
这是直接从EXTJS3源代码中获取的,但我已多次使用它来做类似的事情。
createAccessor : function(){
var re = /[\[\.]/;
return function(expr) {
if(Ext.isEmpty(expr)){
return Ext.emptyFn;
}
if(Ext.isFunction(expr)){
return expr;
}
var i = String(expr).search(re);
if(i >= 0){
return new Function('obj', 'return obj' + (i > 0 ? '.' : '') + expr);
}
return function(obj){
return obj[expr];
};
};
}(),
你会像这样使用它:
var accessor = createAccessor(str);
var data = accessor(object);
答案 2 :(得分:0)
尝试使用eval
功能。它需要一个字符串,并执行该字符串,就像它是javascript代码一样。例如:
var data = {user: {username: "AzureDiamond", password: "hunter2"}};
var str = "user[\"password\"]";
console.log( eval("data." + str) );
// Prints "hunter2"
你必须非常小心,因为根据str
来自哪里,人们基本上可以远程地在你的服务器上运行代码。在执行之前使用正则表达式验证字符串,以确保人们无法向您发送偷偷摸摸的信息并将您的服务器破解为位。
编辑:请注意,您还必须引用password
,以便在执行时将其视为字符串,而不是变量。