我想在Javascript中下载一个对象来寻找特定的字符串。不幸的是,这个对象是以这样的方式构建的,它不可能简单地使用源和Ctrl-F来表示该字符串,并且它也是以这样的方式构建的,即递归函数试图降低它可能会被困在其中永远。
基本上,这个对象包含自己。不只是一次,而是在很多地方。我不能简单地说“排除这些密钥”,因为对象是混淆的,因此我们整天都在这里列出密钥,一旦完成,我们就不会查看所有数据。
同样,我需要能够下降__proto__
和prototype
,因为有用的字符串也隐藏在那里。 (但仅限于功能和对象。)
虽然我更喜欢findStuff(object, /string/ig)
这样的东西,但这可能很难,所以任何只有区域的功能都清楚地标明控制流程一旦找到特定的对象(功能,字符串等)就会掉落
谢谢你,对不起这个问题的痛苦。
编辑:如果它有帮助,我试图遍历编译的Construct2运行时对象。我不会在这里发布完整的内容,因为它不适合任何pastebin,无论多么宽容,而且我也不想意外发布我无权提供的资源。 (不过不用担心,我不是想自己盗版,我只是想弄清楚一些面向用户的功能)
您可以使用WeakSet来跟踪已经遍历的对象:
function traverseOnce(obj, cb) {
const visited = new WeakSet();
(function traverse(obj) {
for(const [key, value] of Object.entries(obj)) {
if(typeof value === "object" && value !== null) {
if(visited.has(value)) continue;
visited.add(value);
cb(value);
traverse(value);
}
}
})(obj);
}
通过WeakSet,您可以获得O(1)查找时间,并且确保它永远不会泄漏。
适用于:
const nested = { other: { a: 1 } };
nested.self = nested;
traverseOnce(nested, console.log);
// nested: { other, self }
// other: { a: 1 }
您还可以使用符号来标记遍历的对象,因为用new WeakSet()
替换Symbol()
,用visited.has(value)
替换value[visited]
,用visuted.add(value)
替换value[visited] = true;
每当你遍历一个潜在的循环对象时,保留已经遍历过的对象的备忘录,如果你以前看过当前对象就会破坏标准技术。你可以使用Set
这样做。
保留已递归的对象列表,然后根据该列表检查每个新对象。
const data = {
foo: {
bar: 1
},
one: 1,
jaz: {
hello: {
x: 1
}
}
};
data.bar = data.foo;
data.foo.foo = data.foo;
data.jaz.hello.foo = data;
function search_for_1() {
const seen = [];
search(data);
function search(object) {
Object.values(object).forEach(value => {
if (typeof value === "object") {
if (seen.includes(value)) {
console.log("Seen this already");
} else {
seen.push(value);
search(value);
}
} else {
if (value === 1) {
console.log("Found 1");
}
}
});
}
}
search_for_1();