2016-01-21 17 views
8

enter image description herea è una funzione, quindi cosa fa realmente `a.call.call`?

Questi codici vengono eseguiti su chrome devtool.

Sembra che b.call (uguale a a.call.call) chiami il primo argomento, che è una funzione, quindi passa il secondo argomento come this. Se il primo argomento non è una funzione, quindi lanciare l'errore not a function.

Qualcuno può spiegare come funziona <Function>.call.call?

+0

Il "[Warlords of Documentation] (http://meta.stackoverflow.com/q/303865/419956)" a.k.a. "NullReference" non è ancora qui, fino a quel momento la tua domanda è probabilmente un po 'troppo ampia. Fino ad allora, consiglierei altre risorse come [MDN] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Function/call). – Jeroen

+0

@jeroen Ho già letto quel documento su MDN, ma questo spiega solo come funziona la funzione 'call', e fornisce alcuni esempi. Quello che esattamente chiedo qui è 'call.call', il cui comportamento è diverso con' call'. E non riesco a ottenere il lavoro dietro 'call.call'. – tjfdfs

+1

Il primo argomento di '.call()' è l'oggetto che si desidera impostare come valore 'this' nella funzione su cui' call() 'deve operare. Se 'call()' è di per sé la funzione su cui operare perché hai incatenato '.call.call()' cosa fa con il valore 'this' fornito? Presume che è una funzione e prova a chiamarla. Ma la tua ultima riga di codice non passa una funzione, passa un oggetto vuoto. – nnnnnn

risposta

8

Lasciate che vi mostri un esempio.

function a() { console.log(1) } 

function b() { console.log(2) } 

a.call(b) // 1 

a.call.call(b) // 2 

a.call.call.call(b) // 2 

Perché?

Sappiamo a.call(b) mezzi invocano a() con questo valore b.

Così che a.call.call(b) mezzi invocare Function.prototype.call() con questo valore b, uguale a Function.prototype.call.call(b).

Ma Function.prototype.call.call() non è una funzione ordinaria Oggetto. Può essere invocato ma non ha proprietà. Esistono alcune regole univoche per invocarlo.

Function.prototype.call.call(a) // 1 

Function.prototype.call.call(b) // 2 

Infatti, Function.prototype.call.call(b) è un oggetto esotici, inoltre, un associato Oggetto Funzione esotici.

  • [Specificazione] Una funzione associata è un oggetto esotico che racchiude un altro oggetto funzione.

  • [Specificazione] La chiamata a una funzione associata genera generalmente una chiamata della sua funzione di avvolgimento.

Quindi Function.prototype.call.call(a) significa semplicemente a().

a.call.call(x) significa invocare x, ovvero x().

  • [Specifica] In Function.prototype.call(thisArg), se thisArg non è definito o nullo, verrà sostituito dall'oggetto globale.

a.call.call() significa a.call.call(undefined) significa a.call.call(window) mezzi invocano window.

tenta di richiamare window si otterrà Uncaught TypeError: window is not a function, quindi tenta di richiamare a.call.call() si otterrà Uncaught TypeError: a.call.call is not a function.

Spero che aiuti.

1

Partendo dalla cose di base,

Che cosa è .call? è una funzione disponibile all'interno di Function.prototype. In modo che possa essere chiamato su qualsiasi funzione, questo è esattamente il motivo per cui è possibile chiamare a.call.

Ora, cosa fa un .call? imposta il contesto this sulla funzione che hai chiamato .call su. così nel tuo caso, quando chiami a.call può impostare un contesto this sulla funzione a (tramite il primo parametro si passa alla funzione .call).

cosa è this all'interno della funzione .call? non è altro che la funzione che si chiama .call sul (nel tuo caso a),
così per semplicità si assume, all'interno del .call potrebbe essere chiamata la funzione come this() (e che non è altro che chiamare a()) - finora così buona

alla tua domanda

a.call.call 

cosa sta accadendo qui? il secondo .call (sto contando da sinistra a destra) chiama prima .call e imposta this per il primo .call, che non è altro che il primo parametro, che è una funzione.

ora il primo .call chiamerà this() (ricorda che questo è impostato dal secondo .call ed è il primo parametro che hai passato e questa è una funzione).

spero, potrei spiegare quello che intendevo spiegare.

lasciami dire perché ti sei confuso con a.call.call. è perché stai pensando a dove è finita la mia funzione a in tutta questa confusione? che non è in realtà coinvolto più presto yo chiamano secondo .call (qui this per primo .call è venuta dalla seconda .call che rende la vostra funzione a obsoleti in questo caso)

in voi caso .call.call avrebbe dovuto essere chiamato sul Function.prototype o Object o qualsiasi altra funzione (ricordate .call fa parte di Function.prototype e può essere chiamato su qualsiasi funzione)

così si dovrebbe aver fatto

Function.prototype.call.call(...) 

o anche

Object.call.call(...) 

Ora ero confuso su queste cose la scorsa settimana (non .call.call ma .call.bind), ho fatto una domanda qui, e qualcuno ha spiegato a me in molto dettagliata, si può trovare HERE

ho cercato di rispondere dalla mia comprensione alla domanda che ho posto.

dopo tutto questo è ciò che è così per

UPDATE:

si mette in discussione "Sembra b.call (lo stesso a.call.call) sta chiamando il primo argomento, che è una funzione, quindi passare il secondo argomento come questo.Se il primo argomento non è una funzione, quindi non lanciare un errore di funzione. "

tua ipotesi è corretta qui

+0

grazie! Leggerò la tua risposta e i collegamenti due volte per ottenere alcune idee. – tjfdfs

+0

e la tua ipotesi è corretta e, ho aggiornato la mia risposta per catturare che – Oxi

+0

Si prega di mettere in relazione questo con un esempio che sarà facile da capire. –

Problemi correlati