2015-04-16 2 views
0
function fibonacci(n) { 
    return (function(a, b, i) { 
     return (i < n) ? arguments.callee(b, a + b, i + 1) : a; 
    })(1, 1, 1); 
} 

Эй, я новичок, я мог бы понять математику логической частью этой функции, что я не понимаю, это параметр, проходящий прогресс, его проходит (1,1,1) к функции (abi), что кажется не очень нормальным.Javascript: О Return()() формат хвостовой рекурсии в функции Фибоначчи

function fibonacci(n) { 
    return (function(a, b, i) { 
     return (i < n) ? arguments.callee(b, a + b, i + 1) : a; 
    }) 
    regular function pass a parameter like the way function(1 1 1) 
} 

Я не могу понять это, я попытался абстрагировать в наконец формате

, но как это может передать параметр, я предполагаю, что это что-то о обратном вызове не может справиться вызов функции после него, который также работает в нем.

Итак, есть ли какие-то базовые вещи, которые я не знал? Как какой-то формат по умолчанию, как записи в MDN?

Thnx много.

+0

Это почти невозможно понять, о чем вы говорите. Что путает насчет передачи трех параметров функции, которая определяется как ожидающая 3 параметра? – Pointy

+0

Также обратите внимание, что использование аргументов.callee' - довольно плохая идея, поэтому вы должны быть подозрительными, где бы вы ни находили этот образец кода. – Pointy

+1

'return (function (a, b) {...}} (1,2);' эквивалентно функции foo (a, b) {...}; return foo (1,2); '. Мы просто заменили переменную ('foo') на само определение функции и удалили имя функции. Это не имеет никакого отношения к' return'. Упрощенный, но эквивалентный пример: вместо записи результата var var =/\ d /; var = pattern.test (value); 'вы можете напрямую использовать литерал выражения, не вводя новую переменную' pattern': 'var result = /\d/.test (value);'. –

ответ

1
return (function(a, b, i) { 
    return (i < n) ? arguments.callee(b, a + b, i + 1) : a; 
})(1, 1, 1); 

является анонимным выражение функция, которая немедленно вызывается. Скобка вокруг него are not required.

Использование arguments.callee является устаревшим, это было бы лучше было написано с именем функции выражения:

return (function recurse(a, b, i) { 
    return (i < n) ? recurse(b, a + b, i + 1) : a; 
})(1, 1, 1); 

что эквивалентно объявлением функции и вызов

function recurse(a, b, i) { 
    return (i < n) ? recurse(b, a + b, i + 1) : a; 
} 
return recurse(1, 1, 1); 
1

Вашей окончательная абстракция неправильно. Это не return()() но:

return  (function(){})() 

Обратите внимание, что () не принадлежит returnreturn, поскольку не является функцией. В этом случае () действуют как скобки для группировки. Точно так же, когда вы используете это нравится:

return (1+1)*2 

Здесь, добавив *2 позади () работ, так как скобка не является частью вызова функции, но вместо того, чтобы использовать в качестве оператора группировки. Или, точнее, оценщик выражений.

Вы видите, как (1+1)*2 работает в том, что () признается не являющимся частью вызова функции, поэтому его содержимое рассматривается как выражение. Так он обрабатывается как:

temporary_variable = 1+1; 
temporary_variable * 2; 

Таким же образом, (function(){})() анализируется как:

temporary_variable = function(){}; 
temporary_variable(); 

Таким образом, все это в основном делает это:

function f (n) { 
    temporary_variable = function (a,b,i) { 
     /* ... */ 
    } 
    return temporary_variable(1,1,1); 
} 
+0

Извините, кто редактировал мой ответ, но я действительно хотел подчеркнуть, что функции могут быть назначены переменные, как значения. Значения не могут быть присвоены значениям. Поэтому обозначение переменной «переменная» более показательно, чем называть ее «значение», – slebetman

Смежные вопросы