Недавно я увидел this question, в котором OP хотел найти путь к объекту объекта, поэтому я ответил на него в psuedocode, заявив, что мне не хватило времени на на самом деле написать решение. Однако вопрос был настолько интересным для меня, что я все-таки пытался написать решение. Вот что я придумал до сих пор:Бесконечный цикл при попытке поиска объекта
function isEmpty(obj) {
for (var prop in obj) {
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
return false;
}
}
return true;
}
function Node(obj, parent, searchTarget) {
this.parent = parent;
this.obj = obj;
this.searchTarget = searchTarget;
this.searchNode = function() {
if(this.obj == this.searchTarget) {
//return this.reconstructPathRecursive();
}
if (!isEmpty(this.obj)) {
var children = [];
for (prop in this.obj) {
if (this.obj.hasOwnProperty(prop)) {
children.push(new Node(this.obj[prop], this, searchTarget));
}
}
var path;
for(var i = 0, len = children.length; i < len; i++) {
path = children[i].searchNode();
if(path) return path;
}
}
}
this.reconstructPathRecursive = function() {
var path = [this], curObj = this.parent;
while (curObj != undefined) {
path.push(curObj);
curObj = curObj.parent;
if(curObj == undefined) break;
}
return path;
}
this.findPath = function() {
return this.searchNode();
}
}
var myObj = {
nullRoot: "gotcha!",
path1: {
myFunc: function() {
alert("Success!");
}
}
}
function findFunctionPath(obj, func) {
return new Node(obj, undefined, func).findPath();
}
var thisFunc = myObj.path1.myFunc;
console.log("--");
console.log(findFunctionPath(myObj, thisFunc));
Идея заключается в том, что я бы назвал this.searchNode()
на объектах Node, которые представляли каждый из свойств объекта. searchNode()
будет называть себя на каждом из полученных узлов свойств, передавая текущий объект как parent
на каждом из дочерних узлов. Если бы я нашел функцию для поиска, я бы назвал reconstructPathRecursive()
, что в значительной степени делает это, используя родительское свойство на каждом из узлов.
Однако, я получаю «Максимальный размер стека вызовов». ошибка, когда я запускаю этот live test. Я предполагаю, что это означает, что я случайно написал бесконечный цикл. Где ошибка в моей логике, и где этот бесконечный цикл прокрался? console.log
показывает, что searchNode
вызывается снова и снова, тогда как я вызываю его только в том случае, если объект не пуст, и я не даю объекту ссылку на себя где-нибудь (я не думаю ...) , так что я действительно немного здесь.
Edit: Я обновил код немного изменить isEmpty
из функции узла в глобальной функции, так что я мог бы назвать его this.obj
в функции searchNode()
. Раньше он вызывал бы это только на узлах (которые всегда будут иметь как минимум два свойства, что приводит к бесконечному циклу), а не к объектам, на которые они ссылаются. Это исправлено, но ошибка сохраняется.
Другое редактирование: Найден и исправлена другая ошибка (см. Ответ Сатьяджита). Тем не менее, все еще получая бесконечный цикл.
Не могли бы вы рассказать о том, где я это делаю, пожалуйста? Я нигде не вижу. Я посмотрю, как я могу реализовать отслеживание того, что я уже посетил. Спасибо за помощь! –
@ElliotBonneville, проблема в том, что 'myObj' является циклическим. Вы не показываете, как вызывается «myObj», поэтому я не могу указать вам на код. –
Вы посетили jsFiddle, который я предоставил? Обновление ссылки на него сейчас. Кроме того, myObj - это еще один объект. Вы видите, как это происходит. Это всего лишь тестовый объект, поэтому я могу проверить свою функцию на нем. –