Вызов JavaScript в сравнении с функциями возврата
Прежде чем перейти к сути моего вопроса, вот код, который идет перед рассматриваемой областью.
function arrayToList(array) {
var list = null;
for (var i = array.length - 1; i >= 0; i--)
list = {value: array[i], rest: list};
return list;
}
function listToArray(list) {
var array = [];
for (var node = list; node; node = node.rest)
array.push(node.value);
return array;
}
Теперь кто-нибудь может объяснить разницу между вызовом функции и возвратом функции. Когда я вызываю свою функцию, я получаю неопределенный результат. Однако, если я верну свою функцию, ответ будет правильным. Может кто-нибудь объяснить мне разницу между этими двумя?
С возвратом:
function nth(list, n) {
if (!list)
return undefined;
else if (n == 0){
return list.value;
}
else
return nth(list.rest, n - 1);
}
Без возврата:
function nth(list, n) {
if (!list)
return undefined;
else if (n == 0){
return list.value;
}
else
nth(list.rest, n - 1);
}
Спасибо за вашу помощь!
2 ответа
Во втором фрагменте ничего не возвращается в else
ветка. Вы рекурсивно вызываете свою функцию. Функция будет возвращать значение, но только для вызывающего себя. Возвращаемое значение отбрасывается, и в результате ничего не возвращается на место, где функция была первоначально отозвана.
В первом (рабочем) фрагменте возвращаемое значение передается снова и снова на внешние слои рекурсии.
Кстати, ни в одном из случаев вы не "возвращаете функцию". В обоих случаях вы вызываете функцию, но в первом случае вы также возвращаете ее возвращаемое значение (передавая его вызывающей стороне), тогда как во втором случае возвращаемое значение игнорируется.
Ниже версия с отдельными функциями, которая, возможно, более понятна, чем эта рекурсия.
function h() {
return "Hello world";
}
function a() {
return h(); // Calls h() and returns the value that was returned from h() to the caller.
}
function b() {
h(); // Also calls h(), but does nothing with its return value. b() itself returns nothing.
}
alert("a returns: " + a()); // Hello world
alert("b returns: " + b()); // Undefined
Если вы ничего не вернете, переменная, ожидающая вызова функции, будет неопределенной. Когда вы возвращаете вызов функции, вы возвращаете результат этого выполнения. Когда вы просто выполняете функцию, вы не возвращаете результаты этого выполнения. Позвольте мне показать вам пример: скрипка
Если вы пытаетесь вернуть функцию, которая будет вызвана позже, чем это может быть сделано, но вам нужно вернуть имя функции без скобок. Смотрите здесь: скрипка
Вот полный пример кода со всем упомянутым выше:
function doWork(){
writeResult('doWork Starting');
return 1;
}
function myFunctionWithReturn() {
writeResult('myFunctionWithReturn Starting');
return doWork();
}
function myFunctionWithoutReturn(){
writeResult('myFunctionWithoutReturn Starting');
doWork();
}
function myFunctionWithFunctionReturned() {
writeResult('myFunctionWithFunctionReturned Starting');
return myCallback;
}
function myCallback() {
return 'Callback was called!';
}
function writeResult(message) {
document.getElementById("result").innerHTML += "</br>" + message;
}
writeResult('Starting with return first...');
var result = myFunctionWithReturn();
writeResult('Result: ' + result);
writeResult('Now doing without return...');
result = myFunctionWithoutReturn();
writeResult('Result: ' + result);
writeResult('Now doing returning a function to call later...');
result = myFunctionWithFunctionReturned();
writeResult('Result: ' + result);
writeResult('Now calling the function that was returned...');
result = result();
writeResult('Result: ' + result);
writeResult('Done.');
<div id="result"></div>