递归搜索全局变量及其属性中的值

Rav*_*afi 10 javascript arrays global-variables object

假设我想'StackOverflow'在所有声明的变量中搜索一个值window.我可以用这段代码做到:

function globalSearch(obj, value) {
    for(var p in obj)
        if(obj[p] == value)
            return(p);
}
globalSearch(window, 'StackOverflow');
Run Code Online (Sandbox Code Playgroud)

此代码将返回具有此值的变量的名称(或不返回任何内容).所以,如果我已经声明了一个带有值的变量'StackOverflow',它将成功找到它.

我的问题是我想更深入地搜索通过window对象(以及它自己的嵌套对象),以实现这样的结果:

var x = 'StackOverflow'                     // returns 'x'
var y = { a : 'StackOverflow' }             // returns 'y.a'
var z = { a : { b: 'StackOverflow' } }      // returns 'z.a.b'
Run Code Online (Sandbox Code Playgroud)

我对Object的继承方法有问题.有没有办法做到这一点?

tho*_*ter 17

深度搜索但没有递归函数调用

函数递归具有内部堆栈限制并浪费内存.

添加了其他功能

以搜索数组的形式提供递归对象保护; 当然,它不会消耗太多内存,因为对象仅存储为引用.

如果对象本身与值匹配,则返回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;
}
Run Code Online (Sandbox Code Playgroud)

问题

如果不将初始变量名称传递给函数,我们就无法从头开始返回完全限定的变量名称.我想不出解决方案,如果有的话,我会感到惊讶.

带空格的变量名作为对象的键是有效的,其他无效变量名也是如此,它只是意味着必须使用尖括号来处理该值.我能想到几个解决方案.正则表达式检查每个变量名称以确保它是有效的,如果不是,则使用尖括号表示法.最重要的问题是reg-ex是一个页面长.或者,我们只能使用尖括号,但这对于OP原始问题并不是真的.

对''搜索'数组的indexOf调用对于非常大的对象可能有点沉重,但我还不能想到另一种选择.

改进

除了清理代码之外,如果函数返回一个匹配数组也会很好.这也引发了另一个问题,即返回的数组不包含对递归对象的引用.也许该函数可以接受结果格式配置参数.

  • 使用窗口执行此操作:未捕获 DOMException:无法从“CSSStyleSheet”读取“cssRules”属性:无法访问 globalSearch 的规则(<anonymous>:27:32) (4认同)
  • 这是代码改进版本的要点:https://gist.github.com/stracker-phil/e5b3bbd5d5eb4ffb2acdcda90d8bd04f 该函数搜索所有出现的情况并将它们存储在数组中,此外它还允许搜索键名、正则表达式搜索,并且可以更好的处理DOM节点 (3认同)

JCO*_*611 5

这应该工作.它使用递归来实现结果.

function globalSearch(obj, value) {
    for(var p in obj)
        if(obj[p] == value){
            return(p);
        }else if(typeof obj[p] == "object" && obj[p] != obj){
           var te = globalSearch(obj[p], value);
           if(te!=false){ return p + "." + te }
        }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

  • 为窗口执行此操作:Uncaught RangeError: Maximum call stack size exceeded at Function.valueOf (<anonymous>) (3认同)