检查可读的深层对象的安全方法? [英] Safe way to check deep objects that's readable?
问题描述
我正在查看代码库,很遗憾看到很多代码如下:
I was looking at a codebase and unfortunately saw a lot of code like:
if (module && module.foo && module.foo.bar && module.foo.bar.baz)
<我开始谷歌搜索是否有一个lib或者什么使这个可以忍受;没找到,但我仍然确定存在于某处)。我写得很快但有点讨厌它,因为传递根对象和字符串分裂'。'是丑陋的;希望有更好的东西:
I started googling to see if there was a lib or something to make this tolerable; didn't find but I'm still sure exists somewhere). I wrote this quickly but sort of hate it since it's ugly to pass in the root object and a string to split on '.'; was hoping for something better:
<!DOCTYPE html>
<html>
<head>
<title>safe tests</title>
<script type="text/javascript">
function assert(condition, desc) {
var d = document, li = d.createElement("li");
li.className = condition ? "pass" : "fail";
li.appendChild(d.createTextNode(desc));
d.getElementById('results').appendChild(li);
}
</script>
<style type="text/css">
#results li.pass { color: green; }
#results li.fail{ color: red; }
</style>
</head>
<body>
<ul id="results"></ul>
<script type="text/javascript">
function safe(root, s) {
var split = s.split('.'), checked = root;
for (var i = 0, len = split.length; i < len; i++) {
if (checked[split[i]]) {
checked = checked[split[i]];
continue;
} else {
return false;
}
}
return true;
}
var foo = {
bar: {
baz: {
qux: 'yippie!'
}
}
}
assert(safe(foo, 'bar'), "finds first sub object");
assert(safe(foo, 'bar.baz'), "finds first and then second sub object");
assert(safe(foo, 'bar.baz.qux'), "finds first, second, third, sub object");
assert(!safe(foo, 'bar.baz.qux.NOT'), "rejects if not defined (end)");
assert(!safe(foo, 'NOPE.baz.qux.NOT'), "rejects if not defined (front)");
assert(!safe(foo, 'bar.NO.baz'), "rejects if not defined (middle)");
</script>
</body>
</html>
任何已经处理过这种精益的建议或图书馆?
Any suggestions or libraries that already handle this that are lean?
推荐答案
我认为方法:
if (module && module.foo && module.foo.bar && module.foo.bar.baz)
仍然是测试对象中有效路径的最佳选择。也就是说,我认为您可以使用类似的东西来测试有效的对象路径:
still remains the best to test for a valid path in a object. That said, I think you could use something like that to test a valid object path:
var safeObjectPath = function safeObjectPath( object, properties ) {
var path = [],
root = object,
prop;
if ( !root ) {
// if the root object is null we immediately returns
return false;
}
if ( typeof properties === 'string' ) {
// if a string such as 'foo.bar.baz' is passed,
// first we convert it into an array of property names
path = properties ? properties.split('.') : [];
} else {
if ( Object.prototype.toString.call( properties ) === '[object Array]' ) {
// if an array is passed, we don't need to do anything but
// to assign it to the internal array
path = properties;
} else {
if ( properties ) {
// if not a string or an array is passed, and the parameter
// is not null or undefined, we return with false
return false;
}
}
}
// if the path is valid or empty we return with true (because the
// root object is itself a valid path); otherwise false is returned.
while ( prop = path.shift() ) {
// Before it was used an if..else statement only, but it
// could generate an exception in case of inexistent
// object member. We can fix it using a try..catch
// statement. Thanks to @xecute for the contribution!
try {
if ( prop in root ) {
root = root[prop];
} else {
return false;
}
} catch(e) {
return false;
}
}
return true;
}
该函数将接受字符串或 array as properties
value。在内部,参数被转换为数组并测试路径。
The function will accept a string or an array as properties
value. Internally the parameter is converted to an array and tested for the path.
属性可以指定为'foo.bar.baz'
或 ['foo','bar','baz']
。
要测试一个有效的路径:
To test for a valid path:
safeObjectPath( module )
safeObjectPath( module, 'foo.bar.baz' )
safeObjectPath( module, [ 'foo', 'bar', 'baz' ] )
请,请注意第一个表单(没有属性
参数)将返回 true
(如果传递的根对象有效,当然)因为那个模块
是一个有效的路径(根)。
Please, note that the first form (the one without properties
parameter) will returns true
(if passed root object is valid, of course) since that module
is a valid path (the root).
用这个来测试它是可能的工作小提琴。
It's possibile to test it with this working fiddle.
我相信也可以考虑递归和/或可绑定版本。
编辑:我是前在我在Coderwall上发表的文章中,用更详细的分析来回答这个答案。
I've extended this answer with a more detailed analysis in my article published on Coderwall.
这是由性能测试 .com / users / 958632 / xecute> @ xecute (再次感谢您的努力)。
Here's a performance test built by @xecute (Thanks again for your efforts).
这篇关于检查可读的深层对象的安全方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!