2014-10-09 7 views
7

In JavaScript, le funzioni sono semplicemente oggetti che possono essere richiamati. Quindi qual è il modo più semplice per il corpo di una funzione di fare riferimento all'oggetto funzione reale?Funzione Self Reference

this può essere utilizzato per fare riferimento all'oggetto contenitore da cui viene chiamata una funzione (o più specificamente un metodo). Ma credo che this non si riferisca mai all'oggetto della funzione stessa.

Ovviamente, bind, call o apply potrebbe essere utilizzato per modificare il valore del this per la funzione. Oppure è possibile utilizzare bind per creare una versione della funzione a cui viene sempre assegnato un riferimento a se stesso come primo parametro.

Ma c'è un modo più semplice? Sospetto di no, ma potrei sbagliarmi.

+0

Il [nome della funzione] (http://jsfiddle.net/rfcrore8/) sarebbe il più semplice. – Teemu

risposta

12

Non riesco a pensare a un caso in cui un'espressione di funzione con nome non può sostituire un'espressione di funzione anonima. Quindi, vorrei suggerire la denominazione della funzione, se avete intenzione di chiamarlo da dentro di sé (per esempio, se avete intenzione di utilizzare la ricorsione):

function myFunc(someArg) { 
    ... 
    ... 
    myFunc(someNewArg); 
} 

Questo funziona anche se si tratta di un punto di riferimento:

var myFunc = function(someArg) { 
    ... 
} 

si può anche utilizzare un IIFE ricorsiva (espressione di una funzione immediatamente, invocata) se non si vuole inquinare lo spazio dei nomi:

(function myFunc(arg) { 
    ... 
    myFunc(someOtherArg); 
})(0); //some initial value 

Inoltre, fare qualcosa di simile:

someOtherFunction(function myFunc(arg) { 
    ... 
    myFunc(otherArg); 
}); 

Funziona anche e non inquinerà lo spazio dei nomi.

+0

perché non funziona in questo caso: '{a: function someFunc() {someFunc.foo =' bar '}}' –

1

arguments.callee all'interno di una funzione sarà un riferimento alla funzione stessa, ma non è esattamente una buona forma. Dovresti nominare la funzione, quindi puoi semplicemente usare il nome all'interno della funzione

+1

'arguments.callee' è [proibito] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee) in modalità rigorosa ES5; Non lo raccomanderei. –

+0

Cool, mi sono dimenticato di arguments.callee. Ma sì, se è deprecato/proibito, non è quello che sto cercando. :/ –

2

Vorrei dare un nome alle funzioni, quindi usarle per fare riferimento a esse. Se hai una funzione dichiarata o una variabile di funzione, allora ha già un nome.

function test1(){ 
    // test1(); 
} 

var test2 = function(){ 
    // test2(); 
}; 

Se si dispone di una funzione anonima, è possibile assegnargli un nome. Quel nome sarà solo all'interno della funzione.

someFunc(function test3(){ 
    // test3(); 
}); 
// test3 will be undefined here 
4

Questo è in realtà una frustrazione della mia, perché hai utilizzato per essere in grado di utilizzare arguments.callee che ottiene un riferimento alla funzione. Come qualcun altro ha menzionato, questo non è più possibile.

C'è un motivo emergente per questo ... e cioè per denominare la funzione da soli e assegnarla. Assomiglia a questo:

my_obj.myfunc = function foo(arg1, arg2) { 
    // do stuff 
    foo.call(this, new_arg1, new_arg2); 
} 

In questo modo è possibile fare riferimento alla funzione denominata e andare sulla propria attività. Si noti che è necessario utilizzare la sintassi .call se si desidera chiamarla come metodo (in modo che this abbia un significato), ma a parte questo, è piuttosto semplice.

Un'altra opzione è quella di fare un approccio veramente funzionale, dove si passa l'oggetto da operare a una funzione:

function foo(obj, arg1, arg2) { 
    // do stuff 
    // call recursively: 
    foo(obj, new_arg1, new_arg2); 
} 

// assign as method: 
my_obj.foo = function(arg1, arg2) { 
    foo(this, arg1, arg2); 
} 

Si potrebbe obiettare che questo è meglio e più flessibile. Penso che sia una questione di gusti, davvero.

+0

arguments.callee è stato rimosso principalmente a causa di problemi di ottimizzazione. Capisco il motivo per cui l'hanno rimosso, ma in qualche modo mi dà fastidio che tu possa ottenere un riferimento a qualsiasi cosa in JS ... tranne la funzione attualmente in esecuzione. Ci sono altri modi per realizzare ciò che ti serve adesso, ma sembra semplicemente sbagliato che tu non possa accedere alla funzione in esecuzione se è anonima. Inoltre mi infastidisce il fatto che con questa deprecazione si perde anche la possibilità di ottenere dal chiamante. Ma potrei lamentarmi tutto il giorno di questo. È così com'è. Quanto sopra copre la maggior parte dei casi in cui ne hai bisogno. – JayKuri