Ci sono già delle ottime risposte, ma ne sto pubblicando una nuova per enfatizzare la mia osservazione sul caso III di seguito su ciò che accade quando si ha una dichiarazione di ritorno esplicita in una funzione che si sta new
elaborando. Dai un'occhiata ai casi seguenti:
Caso I :
var Foo = function(){
this.A = 1;
this.B = 2;
};
console.log(Foo()); //prints undefined
console.log(window.A); //prints 1
Sopra è un semplice caso di chiamare la funzione anonima indicata da Foo
. Quando chiamate questa funzione, ritorna undefined
. Poiché non esiste un'istruzione di ritorno esplicita, l'interprete JavaScript inserisce forzatamente return undefined;
un'istruzione alla fine della funzione. Qui la finestra è l'oggetto di invocazione (contestuale this
) che ottiene nuovi A
e B
proprietà.
Caso II :
var Foo = function(){
this.A = 1;
this.B = 2;
};
var bar = new Foo();
console.log(bar()); //illegal isn't pointing to a function but an object
console.log(bar.A); //prints 1
Qui l'interprete JavaScript che vede la new
parola chiave crea un nuovo oggetto che funge da oggetto di invocazione (contestuale this
) della funzione anonima indicata da Foo
. In questo caso A
e B
diventare proprietà dell'oggetto appena creato (al posto dell'oggetto finestra). Poiché non si dispone di alcuna dichiarazione di ritorno esplicita, l'interprete JavaScript inserisce forzatamente una dichiarazione di ritorno per restituire il nuovo oggetto creato a causa dell'uso della new
parola chiave.
Caso III :
var Foo = function(){
this.A = 1;
this.B = 2;
return {C:20,D:30};
};
var bar = new Foo();
console.log(bar.C);//prints 20
console.log(bar.A); //prints undefined. bar is not pointing to the object which got created due to new keyword.
Anche in questo caso l'interprete JavaScript che vede la new
parola chiave crea un nuovo oggetto che funge da oggetto di invocazione (contestuale this
) della funzione anonima indicata da Foo
. Ancora una volta, A
e B
diventa proprietà sull'oggetto appena creato. Ma questa volta hai una dichiarazione di ritorno esplicita, quindi l'interprete JavaScript non farà nulla di proprio.
La cosa da notare nel caso III è che l'oggetto creato a causa della new
parola chiave si è perso dal radar. bar
indica in realtà un oggetto completamente diverso che non è quello creato dall'interprete JavaScript a causa della new
parola chiave.
Citando David Flanagan da JavaScripit: The Definitive Guide (6th Edition), cap. 4, Pagina # 62:
Quando viene valutata un'espressione di creazione di oggetti, JavaScript crea innanzitutto un nuovo oggetto vuoto, proprio come quello creato dall'inizializzatore di oggetti {}. Successivamente, invoca la funzione specificata con gli argomenti specificati, passando il nuovo oggetto come valore di questa parola chiave. La funzione può quindi utilizzarlo per inizializzare le proprietà dell'oggetto appena creato. Le funzioni scritte per essere utilizzate come costruttori non restituiscono un valore e il valore dell'espressione di creazione dell'oggetto è l'oggetto appena creato e inizializzato. Se un costruttore restituisce un valore oggetto, quel valore diventa il valore dell'espressione di creazione dell'oggetto e l'oggetto appena creato viene scartato.
--- Ulteriori informazioni ---
Le funzioni utilizzate nello snippet di codice dei casi precedenti hanno nomi speciali nel mondo JS come di seguito:
Caso I e II - Funzione di costruzione
Caso III - Funzione di fabbrica. Le funzioni di fabbrica non dovrebbero essere usate con la new
parola chiave che ho fatto per spiegare il concetto nel thread corrente.
Puoi leggere le differenze tra loro in questo thread.