深度搜索但没有递归函数调用
函数递归具有内部堆栈限制并浪费内存。
添加的附加功能
搜索数组形式的递归对象保护;它当然不会占用太多内存,因为对象仅作为引用存储。
如果对象本身与值匹配,则返回 true。否则它将返回 '' 这将匹配为 false。
数组使用尖括号表示法。
编码
function globalSearch(startObject, value) {
var stack = [[startObject,'']];
var searched = [];
var found = false;
var isArray = function(test) {
return Object.prototype.toString.call( test ) === '[object Array]';
}
while(stack.length) {
var fromStack = stack.pop();
var obj = fromStack[0];
var address = fromStack[1];
if( typeof obj == typeof value && obj == value) {
var found = address;
break;
}else if(typeof obj == "object" && searched.indexOf(obj) == -1){
if ( isArray(obj) ) {
var prefix = '[';
var postfix = ']';
}else {
var prefix = '.';
var postfix = '';
}
for( i in obj ) {
stack.push( [ obj[i], address + prefix + i + postfix ] );
}
searched.push(obj);
}
}
return found == '' ? true : found;
}
问题
如果不将初始变量名传递给函数,我们就无法从一开始就返回完全限定的变量名。我想不出解决方案,如果有解决方案,我会感到惊讶。
带有空格的变量名作为对象的键是有效的,其他无效的变量名也是如此,它只是意味着必须使用尖括号来处理该值。我能想到几个解决方案。正则表达式检查每个变量名称以确保它有效,如果不是,则使用尖括号表示法。最重要的问题是 reg-ex 是一页长的。或者,我们只能使用尖括号,但这对于 OPs 的原始问题并不真实。
对数组“搜索”的 indexOf 调用对于非常大的对象可能有点重,但我还想不出替代方案。
改进
除了稍微清理一下代码之外,如果函数返回一个匹配数组也会很好。这也引发了另一个问题,即返回的数组不包含对递归对象的引用。也许该函数可以接受结果格式配置参数。