2015-04-17 8 views
6

grazie per il vostro tempo.Javascript i ++ troppa ricorsione, i + 1 ok in coda ricorsione

stavo imparando una funzione di Fibonacci e uno della risposta è qui sotto:

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

Come l'arguments.callee è vietato in modalità rigorosa dopo ES5, così ho sostituirlo con un nome di funzione. Dopo di che, ho visto la parte i + 1, e la sostituisco con un i ++, che risulta troppo ricorsione.

function x(n){ 
    return (function y(a, b, i){ 
     return (i < n) ? y(b, a + b, i++) : a; 
    })(1,1,1) 
} 
console.log(x(51)) 

Dopo alcuni debug, ho scoperto che l'i + 1 funziona correttamente, mentre i ++ no.

Quindi, ho usato i ++ nel posto sbagliato o non ho capito affatto i ++?

Ancora una volta.

+3

i + 1 doesnt modificare il valore di i, passa solo i + 1 come parametro. i ++ d'altra parte aumenta il valore di i. – doldt

+1

Si noti che ES5 non ottimizza la ricorsione della coda. Strumenti come Babel lo ottimizzeranno in un loop per te. Qui http://babeljs.io/repl/#?experimental=true&evaluate=true&loose=false&spec=false&playground=true&code=function%20fibonacci(n)%20%7B%0A%20%20%20%20return%20(function% 20f (a% 2C% 20b% 2C% 20i)% 20% 7B% 0A% 20% 20% 20% 20% 20% 20% 20% 20return% 20 (i% 20% 3C% 20n)% 20% 3F% 20f (b% 2C% 20a% 20% 2B% 20b% 2C% 20i% 20% 2B% 201)% 20% 3A% 20a% 3B% 0A% 20% 20% 20% 20% 7D) (1% 2C% 201% 2C% 201)% 3B% 0A% 7D% 0Aconsole.log (fibonacci (51)) –

risposta

6

i+1 significa "valore di ritorno che è uno più grande di i, non cambiano i "

i++ mezzi "incremento i per uno, ma restituire il valore originale"

++i significa "incremento i di uno e restituire il valore incrementato"

Quindi in th è il caso se si utilizza i+1 non si modifica il valore di i, ma si invia un valore maggiore di i come argomento. È inoltre possibile utilizzare ++i, se si desidera modificare anche il valore in i.

Esempi

i = 10 
a = i+1 
// a = 11, i = 10 

i = 10 
a = i++ 
// a = 10, i = 11 

i = 10 
a = ++i 
// a = 11, i = 11 

Lo stesso vale anche per i-1, i-- e --i

10

i++ incrementa un numero e restituisce il vecchio valore.

Ciò significa che si sta passando i dappertutto anziché i + 1.

È meglio passare semplicemente i + 1 poiché questo è il valore che si richiede, ma anche lo ++i funzionerà.

+0

È possibile utilizzare ++ i invece. – greenhoorn

+2

@greenhoorn: Si * potrebbe *, ma non avrebbe alcun senso. 'i' non viene successivamente utilizzato nella stessa chiamata, quindi non ha senso scriverci di nuovo. –

+0

@ T.J.Crowder questa non è una questione di senso o di senso, ha solo bisogno di passare un numero che è 1 maggiore di me. Se aumenti i o definisci una nuova variabile superiore a I, è solo questione di come codifichi. Se ho ragione, ++ ho anche bisogno di meno spazio di I + 1 (pochi bit ..) – greenhoorn

4

Questo perché solo l'uscita del i++ è lo stesso i + 1.

Ma quando si utilizza i++, si assegna anche il valore a i.

così

var i = 0; 
output i++; // 1 
output i; // still 1 

var i = 0; 
output i + 1; // 1 
output i; // 0