@rebyatyonok
Новичок

Почему рекурсия не останавливается?

Есть JS объект неизвестной вложенности. То есть, внутри него, среди прочих свойств, есть еще объекты, а в них в свою очередь, есть еще объекты и т.д. Выглядит это как-то так:
var trunk = {
    listItem1: 1,
    listItem2: {
        subListItem: 1,
        subListItem2: {
            subsubListItem1: 1,
            subsubListItem2: 2
        }
    },
    listItem3: 3
}

Нужно с этим объектом сделать следующее: выцепить из него все свойства, значения которых равны 1, и написать путь до них след. образом: ListItem2 > subListItem2 > subsubListItem1. То есть пройтись по всему объекту и его подобъектам. Написал такую функцию:
function search(obj) {
    for (var key in obj) {
        if (obj[key] == "1") {
            console.log(key + '>')
        } else if (typeof obj[key] == "object") {
            console.log(this + '>');
            return search(this);
        } else {
            // "I dont need this"
        }
    }
};

То есть, функция проверяет значения. Сначала на равенство единице, затем проверяет, объект ли это, и если это ни то, ни другое - ничего не делает. Если это объект, мне необходимо зациклить функцию, чтоб она начала выполнять саму себя, и остановилась, когда ни объектов, ни единиц не осталось. Моя ошибка в том, что во время проверки на объект, она зацикливается до бесконечности с ошибкой "speechSythesis" и бесконечным алертом, или же "Maximum call stack size exceeded" в консоли (Chrome). В чем моя ошибка? Ответ хотелось бы подробный и с разъяснениями.
В идеале хотелось бы иметь функцию, которая (теоретически, тк практически компьютер вероятно зависнет) проверит объект с n количеством свойств n-вложенности.
  • Вопрос задан
  • 343 просмотра
Решения вопроса 1
return search(this) ?
вы вызываете функцию с текущим контекстом. А нужно вызвать с тем объектом, в котором хотите искать, т.е. obj[key]. Ну и return конечно не нужен. Т.к. иначе вы выйдете из цикла после первого попадания на объект.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
devellopah
@devellopah
я позволил себе добавить второй аргумент(чтобы наращивать строку, указывающую путь до свойства)
если ты не против, то можно примерно так

const trunk = {
    listItem1: 1,
    listItem2: {
        subListItem: 1,
        subListItem2: {
            subsubListItem1: 1,
            subsubListItem2: 2
        }
    },
    listItem3: 3
};

const ones = [];

traverse(trunk, 'root');

function traverse(obj, path) {
	for(let key in obj) {
		const newPath = path + ' > ' + key;
		
		if (obj[key].constructor.name === "Object") {
			
			// console.log(newPath);
	  	return traverse(obj[key], newPath);
	  }
	  
	  if(obj[key] == "1") {
	  	ones.push(newPath);
	  }
	  
	}
	
	console.log('properties\' pathes which value is equal to 1 \n\n' , ones);
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы