Istnieją już bardzo świetne odpowiedzi, ale zamieszczam nową, aby podkreślić moją obserwację w przypadku III poniżej, co dzieje się, gdy masz wyraźną instrukcję return w funkcji, którą new
wymyślasz. Spójrz na poniższe przypadki:
Przypadek I :
var Foo = function(){
this.A = 1;
this.B = 2;
};
console.log(Foo()); //prints undefined
console.log(window.A); //prints 1
Powyżej jest zwykły przypadek wywołania wskazanej funkcji anonimowej Foo
. Gdy wywołujesz tę funkcję, ona zwraca undefined
. Ponieważ nie ma wyraźnej instrukcji return, interpreter JavaScript na siłę wstawia return undefined;
instrukcję na końcu funkcji. Tutaj okno jest obiektem wywołania (kontekstowym this
), który otrzymuje nowe A
i B
właściwości.
Przypadek 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
Tutaj interpreter JavaScript, widząc new
słowo kluczowe, tworzy nowy obiekt, który działa jako obiekt wywołania (kontekstowy this
) wskazywanej przez anonimową funkcję Foo
. W takim przypadku A
i B
stają się właściwościami nowo utworzonego obiektu (zamiast obiektu okna). Ponieważ nie masz żadnej wyraźnej instrukcji return, interpreter JavaScript zdecydowanie wstawia instrukcję return, aby zwrócić nowy obiekt utworzony z powodu użycia new
słowa kluczowego.
Przypadek 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.
Tutaj znowu interpreter JavaScript, widząc new
słowo kluczowe, tworzy nowy obiekt, który działa jak obiekt wywołania (kontekstowy this
) wskazanej przez anonimową funkcję Foo
. Ponownie A
i B
stań się właściwościami nowo utworzonego obiektu. Ale tym razem masz wyraźną instrukcję return, więc interpreter JavaScript nie zrobi nic własnego.
W przypadku III należy zauważyć, że obiekt tworzony z powodu new
słowa kluczowego został utracony z radaru. bar
wskazuje na zupełnie inny obiekt, który nie jest tym, który interpreter JavaScript utworzył z powodu new
słowa kluczowego.
Cytując Davida Flanagana z JavaScripit: The Definitive Guide (wydanie 6), rozdz. 4, strona # 62:
Kiedy ocenia się wyrażenie tworzenia obiektu, JavaScript najpierw tworzy nowy pusty obiekt, tak jak ten utworzony przez inicjator obiektu {}. Następnie wywołuje określoną funkcję z określonymi argumentami, przekazując nowy obiekt jako wartość tego słowa kluczowego. Funkcja może następnie użyć tego do zainicjowania właściwości nowo utworzonego obiektu. Funkcje napisane do użycia jako konstruktory nie zwracają wartości, a wartością wyrażenia tworzenia obiektu jest nowo utworzony i zainicjowany obiekt. Jeśli konstruktor zwróci wartość obiektu, wartość ta staje się wartością wyrażenia tworzenia obiektu, a nowo utworzony obiekt jest odrzucany.
--- Informacje dodatkowe ---
Funkcje używane we fragmencie kodu powyższych przypadków mają specjalne nazwy w świecie JS, jak poniżej:
Przypadek I i II - funkcja konstruktora
Przypadek III - funkcja fabryczna. Funkcje fabryczne nie powinny być używane ze new
słowem kluczowym, które zrobiłem, aby wyjaśnić tę koncepcję w bieżącym wątku.
O różnicy między nimi możesz przeczytać w tym wątku.