JS:将字符串“foo[bar]”转换为代码 obj.foo.bar 的简单方法
JS: easy way to convert string "foo[bar]" into code obj.foo.bar?
我有一个变量obj
定义如下:
{user: {username: "AzureDiamond", password: "hunter2"}}
我有一个字符串str
可能定义为以下任何字符串:
- "用户"
- "用户[用户名]"
- "用户[密码]"
- "假的"
在JS(特别是node.js)中,是否有一种相对简单的方法来本质上/动态地执行以下操作?
str == "user"
时,返回{username: "AzureDiamon", password: "hunter2"}
str == "user[username]"
时,返回"AzureDiamond"str == "user[password]"
时,返回"猎人2"str == "fake"
时,返回null
编辑:这个问题更多的是找出是否有更简单或内置到 JS/node 中.js除了正则表达式匹配之外,我可以使用
解决方案
如果您确定 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并解决了这个问题。
编辑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);
尝试eval
函数。 它接受一个字符串,并像执行javascript代码一样执行该字符串。 例如:
var data = {user: {username: "AzureDiamond", password: "hunter2"}};
var str = "user['"password'"]";
console.log( eval("data." + str) );
// Prints "hunter2"
不过,您必须非常小心,因为根据str
的来源,人们基本上可以在您的服务器上远程运行代码。 在执行之前使用正则表达式验证字符串,以确保人们不会向您发送偷偷摸摸的信息并将您的服务器破解为位。
编辑:请注意,您还必须引用password
,以便在执行时将其视为字符串,而不是变量。
- jQuery"return{foo:bar,foo2:bar2}"-它是什么
- javascript getElementsByClassName("foo"||"bar
- 无法在 js 中打印 foobar 只能打印 foo 和 bar
- JS:将字符串“foo[bar]”转换为代码 obj.foo.bar 的简单方法
- 速记 if/else 语句 : foo?foo:bar vs foo ||酒吧
- can.routing :触发从 #!/foo/bar 到 #!/foo 的更改
- 聚合物 - 有人可以解释一下聚合物中使用的this.$.foo.bar JavaScript语法
- JavaScript国际化和列表(例如[foo,bar,blah]到“foo,bar和blah”)
- 给定一个函数pipe(foo, bar, baz)(1, 2, 3),你将如何实现它等效于javascript中的baz
- 定义对象时从foo获取值到bar
- Difference between "if (foo) bar();" and "foo
- Boolean(foo.bar)和!!之间的区别是什么!!foo.bar
- JS-import'中@的含义@foo/bar'
- foo的三元简写?foo:bar
- Scala的写作方式'foo[“bar”]'JavaScript
- 为什么 foo: { bar: 10} 在 Chrome 控制台中执行时打印 10 |Javascript
- 其中一个更快吗?foo & lt;Bar) if (foo >酒吧)
- 检查多个空值的最佳方法是什么?例如if(foo.bar.giz.mo.)X === 123)
- Javascript functions like "var foo = function bar() ...
- 什么是(foo?bar:fobar)||xyz;在javascript中执行