# Вывод списка в цикле ```js //+ run var list = { value: 1, next: { value: 2, next: { value: 3, next: { value: 4, next: null } } } }; function printList(list) { var tmp = list; while (tmp) { alert( tmp.value ); tmp = tmp.next; } } printList(list); ``` Обратите внимание, что для прохода по списку используется временная переменная `tmp`, а не `list`. Можно было бы и бегать по списку, используя входной параметр функции: ```js function printList(list) { while(*!*list*/!*) { alert( list.value ); list = list.next; } } ``` ...Но при этом мы в будущем не сможем расширить функцию и сделать со списком что-то ещё, ведь после окончания цикла начало списка уже нигде не хранится. Поэтому и используется временная переменная -- чтобы сделать код расширяемым, и, кстати, более понятным, ведь роль `tmp` -- исключительно обход списка, как `i` в цикле `for`. # Вывод списка с рекурсией Рекурсивный вариант `printList(list)` следует простой логике: вывести текущее значение `(1)`, а затем пропустить через себя следующее `(2)`: ```js //+ run var list = { value: 1, next: { value: 2, next: { value: 3, next: { value: 4, next: null } } } }; function printList(list) { alert( list.value ); // (1) if (list.next) { printList(list.next); // (2) } } printList(list); ``` # Обратный вывод с рекурсией Обратный вывод -- почти то же самое, что прямой, просто сначала мы обрабатываем следующее значение, а потом -- текущее: ```js //+ run var list = { value: 1, next: { value: 2, next: { value: 3, next: { value: 4, next: null } } } }; function printReverseList(list) { if (list.next) { printReverseList(list.next); } alert( list.value ); } printReverseList(list); ``` # Обратный вывод без рекурсии ```js //+ run var list = { value: 1, next: { value: 2, next: { value: 3, next: { value: 4, next: null } } } }; function printReverseList(list) { var arr = []; var tmp = list; while (tmp) { arr.push(tmp.value); tmp = tmp.next; } for (var i = arr.length - 1; i >= 0; i--) { alert( arr[i] ); } } printReverseList(list); ``` **Обратный вывод без рекурсии быстрее.** По сути, рекурсивный вариант и нерекурсивный работают одинаково: они проходят список и запоминают его элементы, а потом выводят в обратном порядке. В случае с массивом это очевидно, а для рекурсии запоминание происходит в стеке (внутренней специальной структуре данных): когда вызывается вложенная функция, то интерпретатор сохраняет в стек текущие параметры. Вложенные вызовы заполняют стек, а потом он выводится в обратном порядке. При этом, при рекурсии в стеке сохраняется не только элемент списка, а другая вспомогательная информация, необходимая для возвращения из вложенного вызова. Поэтому тратится больше памяти. Все эти расходы отсутствуют во варианте без рекурсии, так как в массиве хранится именно то, что нужно. Преимущество рекурсии, с другой стороны -- более короткий и, зачастую, более простой код.