递归搜索全局变量及其属性中的值 [英] Recursively search for a value in global variables and its properties

查看:42
本文介绍了递归搜索全局变量及其属性中的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Let's say that I want to search for a value, like 'StackOverflow', in all declared variables in window. I can do it with this code:

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

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

This code will return the name of a variable that have this value (or returns nothing). So, if I have declared a variable with value 'StackOverflow', it will successfully find it.

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

My problem is that I want to go deeper and search thru window's objects (and its own nested objects) too, to achieve a result like this:

var x = 'StackOverflow'                     // returns 'x'
var y = { a : 'StackOverflow' }             // returns 'y.a'
var z = { a : { b: 'StackOverflow' } }      // returns 'z.a.b'

我在继承对象的方法方面遇到了问题.有没有办法做到这一点?

I'm having problems with inherited methods of Objects. Is there a way to do this?

推荐答案

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

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

Functional recursion has internal stack limits and wastes memory.

添加了其他功能

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

Recursive object protection in the form of a searched array; It doesn't use up too much memory of course as the objects are only stored as references.

如果对象本身与值匹配,则返回 true.否则它会返回 '' 匹配到 false.

Return true if the the object itself matches the value. Otherwise it would return '' which would match to false.

数组使用尖括号表示法.

Arrays use angle-bracket notation.

代码

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;
}

问题

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

Without passing the initial variable name into the function, we can't return the fully qualified variable name from the beginning. I can't think of a solution and I would be surprised if there was one.

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

Variable names with spaces are valid as the key to an object, as are other invalid variable names, it just means that the value must be addressed using angle-brackets. There are a couple of solutions I can think of. Regex check each variable name to make sure it's valid and use angle-brackets notation if it is not. The overriding problem with this is that the reg-ex is a page long. Alternatively, we could only use angle-brackets but this isn't really true to the OPs original question.

对searched"数组的 indexOf 调用在非常大的对象上可能有点繁重,但我还想不出替代方法.

The indexOf call on the array 'searched' might be a bit heavy on very large objects but I can't yet think of an alternative.

改进

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

Apart from cleaning up the code a little, it would also be nice if the function returned an array of matches. This also raises another issue in that the returned array would not contain references to recursive objects. Maybe the function could accept a result format configuration parameter.

这篇关于递归搜索全局变量及其属性中的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆