argomento di callback setTimeout

Prendiamo in considerazione questo pezzo di JavaScript:

function Person(name) { this.name = name; } Person.prototype.showName = function() { alert(this.name); } var mike = new Person("mike"); //mike.showName(); window.name = "window"; 

Non capisco la differenza tra il comportamento di

 setTimeout(mike.showName(), 5000); 

e

 setTimeout(function(){ mike.showName(); }, 5000); 

Perché il comportamento è diverso? Mi confonde davvero. Grazie.

La tua domanda non ha davvero niente a che fare con setTimeout . Devi semplicemente capire la differenza tra una chiamata di funzione e un riferimento a una funzione.

Considera questi quattro incarichi:

 var one = function() { mike.showName(); }; var two = mike.showName; var three = mike.showName(); var four = (function() { mike.showName(); })(); 

I primi due assegnano un riferimento a una funzione alle rispettive variabili. Gli ultimi due, tuttavia, chiamano le funzioni (questo è il motivo per cui i parens servono) e assegnano i loro valori di ritorno ai vars sul lato sinistro.

Come questo si riferisce a setTimeout:

La funzione setTimeout prevede come primo argomento un riferimento a una funzione, quindi one o two sopra sarebbe corretto, ma three e four no. Tuttavia, è importante notare che non è, in senso stretto, un errore passare il valore di ritorno di una funzione a setTimeout , anche se lo vedrete spesso.

Questo è perfettamente soddisfacente, ad esempio:

 function makeTimeoutFunc(param) { return function() { // does something with param } } setTimeout(makeTimeoutFunc(), 5000); 

Non ha nulla a che fare con come setTimeout riceve una funzione come argomento, ma lo fa .

Se la risposta accettata è troppo lunga per leggere:

 setTimeout(mike.showName(), 5000); 

Questo eseguirà qualunque mike.showName() restituisce dopo 5000 millisecondi.

 setTimeout(function(){ mike.showName(); }, 5000); 

Questo eseguirà la funzione anonima dopo 5000 millisecondi che chiama mike.showName() , la funzione effettiva .

Un altro modo per ottenere lo stesso effetto:

 setTimeout(mike.showName.bind(mike), 5000); 

Non è un problema di prestazioni. Uno dei modi in cui hai mostrato semplicemente non funziona (chiama la funzione immediatamente anziché quando scatta il timeout).

setTimeout(mike.showName(), 5000); eseguirà la funzione showName e showName suo valore di ritorno come callback di timeout che non funzionerà.

setTimeout(function(){ mike.showName(); }, 5000); crea una funzione anonima e la imposta come callout di timeout. Quando si showName() il timeout, la funzione viene chiamata e chiama la funzione showName() .

Fyi, setTimeout('mike.showName();', 5000); funzionerebbe anche Ma non farlo – è altrettanto brutto quanto usare eval() . Inoltre, rende il tuo codice meno leggibile poiché il codice nella stringa non può essere evidenziato dalla syntax.

setTimeout(mike.showName(), 5000); esegue mike.showName() immediatamente e passa il valore restituito a setTimeout()

setTimeout(function(){ mike.showName(); }, 5000); passa invece un puntatore alla funzione. In questo modo setTimeout può eseguire la funzione, piuttosto che il suo valore di ritorno.