2015-09-19 14 views
6

In http://eloquentjavascript.net/1st_edition/chapter6.html, c'è il seguente esempio:Come vengono gestiti i parametri durante il passaggio delle funzioni in Javascript?

function negate(func) { 
    return function(x) { 
    return !func(x); 
    }; 
} 
var isNotNaN = negate(isNaN); 
alert(isNotNaN(NaN)); 

Conoscendo solo Javascript di base e programmazione imperativa, Stumped da questo stile di programmazione. Qualcuno può aiutarmi a capire cosa succede durante il runtime.

Ho passato il codice e controllato le variabili e ho scoperto che il valore di x è NaN. Come fa a sapere che l'argomento isNaN deve essere passato come argomento x della funzione anonima? In primo luogo, perché il parametro attuale NaN di isNaN diventa isNaN (ad esempio, mentre isNaN si aspetta un argomento, perché lo prende dall'argomento di isNotNaN)?

+0

* "In primo luogo, perché il parametro attuale' NaN' di 'isNotNaN' diventano l'argomento' isNaN'" * A causa della terza linea:' func (x) '. 'func' è un riferimento a' isNaN' e 'x' è' NaN'. Questo non è molto diverso da qualsiasi altra funzione E.g. in 'function foo (x) {return bar (x); }; pippo (x) ',' pippo' passa 'x' a' bar'. L'unica differenza nel tuo esempio è che 'func' è determinato dinamicamente. –

+0

** nota ** questa funzione 'negate' funziona correttamente solo con funzioni che richiedono un solo parametro – Grundy

risposta

1

Il modo migliore per capire questo potrebbe essere vedere ciò che queste cose sono effettivamente uguali. Si noti come func diventa la funzione passata isNaN.

function negate(func) { 
    return function(x) { 
    return !func(x); 
    }; 
} 
var isNotNaN = negate(isNaN); 
/* 

isNotNaN = function(x){ 
    return !isNaN(x) 
} 

*/ 

alert(isNotNaN(NaN)); 
+0

Questo blocco di commenti è illuminante. Tuttavia, da dove viene invocato il valore di 'x' quando viene richiamato isNotNaN? –

+0

@OldGeezer: Nell'ultima riga: 'isNotNaN (NaN)'. Stai passando 'NaN', –

0

Si noti che negate accetta una funzione come argomento e restituisce una funzione. La funzione restituita chiamerà la funzione argomento, annullando il valore restituito. Pertanto, isNotNaN è una funzione. Quando viene chiamato, chiamerà la funzione originariamente passata a negate, in questo caso isNaN. Qualsiasi cosa tu chiami, isNotNaN, verrà passata a isNaN.

In sostanza, si è la configurazione di una funzione con un'altra funzione. Questo potrebbe essere più facile da vedere con un esempio più semplice (nessuna funzione argomento):

function addX(x) { 
    return function(y) { 
     return x+y; 
    }; 
} 

var add2 = addX(2); 
console.log(add2(2)); // 4 

var add3 = addX(3); 
console.log(add3(7)); // 10 

Ora, prendere questo un passo avanti e immaginare avete passato una funzione in addX invece di un valore.

A proposito, questo è chiamato currying.

0

È perché si imposta questa:

var isNotNaN = negate(isNaN); 

E quando si chiama isNotNaN (x) quindi è come si chiama negate (isNaN) (x). Puoi anche usare una funzione con nome invece di quella anonima, quindi diciamo:

function negate(func) { 
     return xValue.call(this, x); //to be in the context of the xValue function 
     }; 
    } 
    var isNotNaN = negate(isNaN); 
    alert(isNotNaN(NaN)); 

    function xValue(x) { 
     return !func(x); 
    } 

    But then you have to take care about the context. 
Problemi correlati