Tak, pierwsza funkcja nie ma związku z instancją obiektu tej funkcji konstruktora , można ją traktować jak „metodę statyczną” .
W JavaScript funkcje są pierwszorzędnymi obiektami, co oznacza, że możesz traktować je jak każdy obiekt, w tym przypadku dodajesz tylko właściwość do obiektu funkcji .
Druga funkcja, w miarę rozszerzania prototypu funkcji konstruktora, będzie dostępna dla wszystkich instancji obiektów utworzonych za pomocą newsłowa kluczowego, a kontekst tej funkcji ( thissłowo kluczowe) będzie odnosił się do rzeczywistej instancji obiektu, w której ją wywołujesz.
Rozważ ten przykład:
// constructor functionfunctionMyClass(){var privateVariable;// private member only available within the constructor fnthis.privilegedMethod =function(){// it can access private members//..};}// A 'static method', it's just like a normal function // it has no relation with any 'MyClass' object instanceMyClass.staticMethod =function(){};MyClass.prototype.publicMethod =function(){// the 'this' keyword refers to the object instance// you can access only 'privileged' and 'public' members};var myObj =newMyClass();// new object instance
myObj.publicMethod();MyClass.staticMethod();
Ale dlaczego jest Function.prototype.method == Function.method?
Raghavendra
1
@Raghavendra to nie jest
Zorgatone
1
@Menda Twój link nie żyje
Eugen Sunic
19
Kiedy utworzysz więcej niż jedną instancję MyClass, nadal będziesz mieć tylko jedną instancję publicMethod w pamięci, ale w przypadku privilegedMethod skończysz tworzenie wielu instancji, a staticMethod nie będzie mieć związku z instancją obiektu.
Właśnie dlatego prototypy oszczędzają pamięć.
Ponadto, jeśli zmienisz właściwości obiektu nadrzędnego, to czy odpowiednia właściwość dziecka nie została zmieniona, zostanie zaktualizowana.
Dla uczniów wizualnych, którzy definiują funkcję bez .prototype
ExampleClass=function(){};ExampleClass.method =function(customString){
console.log((customString !==undefined)?
customString :"called from func def.");}ExampleClass.method();// >> output: `called from func def.` var someInstance =newExampleClass();
someInstance.method('Called from instance');// >> error! `someInstance.method is not a function`
Z tym samym kodem, jeśli .prototypejest dodany,
ExampleClass.prototype.method =function(customString){
console.log((customString !==undefined)?
customString :"called from func def.");}ExampleClass.method();// > error! `ExampleClass.method is not a function.` var someInstance =newExampleClass();
someInstance.method('Called from instance');// > output: `Called from instance`
Aby było to jaśniejsze,
ExampleClass=function(){};ExampleClass.directM =function(){}//M for methodExampleClass.prototype.protoM =function(){}var instanceOfExample =newExampleClass();ExampleClass.directM();✓ works
instanceOfExample.directM(); x Error!ExampleClass.protoM(); x Error!
instanceOfExample.protoM();✓ works
**** Uwaga dla powyższego przykładu, niektóreInstance.method () nie zostanie wykonane, ponieważ
ExampleClass.method () powoduje błąd i wykonanie nie może być kontynuowane.
Ale dla ilustracji i łatwego zrozumienia zachowałem tę sekwencję. ****
Wyniki wygenerowane z chrome developer console&
Kliknij powyższy link jsbin, aby przejść przez kod.
Przełącz komentowaną sekcję za pomocą +JS Bin
Zobacz, jak staticużyto słowa kluczowego do zadeklarowania metody statycznej isPerson.
Aby utworzyć obiekt Personklasy.
const aminu = new Person("Aminu", "Abubakar");
Za pomocą metody statycznej isPerson.
Person.isPerson(aminu); // will return true
Za pomocą metody instancji sayHi.
aminu.sayHi(); // will return "Hi Aminu"
UWAGA: oba przykłady są zasadniczo takie same, JavaScript pozostaje językiem bezklasowym. classWprowadzony w ES6 to przede wszystkim cukier syntaktyczny w stosunku do istniejącego prototypu na bazie modelu dziedziczenia.
„W ES6” opisujesz tylko cukier składniowy. To nie jest „ES2015” (proszę, żeby wszyscy przestali używać ES6, używali właściwego terminu ES2015). To po prostu inny sposób na zrobienie tego i moim zdaniem niewłaściwy sposób.
Karl Morrison,
2
@KarlMorrison Aminu nie napisał „sposobu robienia tego”, po prostu sam to napisałeś i zrobiłeś wyjątek. Twój pogląd może być sprawiedliwy w stosunku do ES6 vs. ES2015, ale w rozmowach ludzie często uciekają się do krótszej konwencji dotyczącej wydajności, więc myślę, że usunięcie go z pisania nie jest możliwe lub na pewno wskazane.
wuliwong
Dziękuję za część odpowiedzi dotyczącą ES6; to wiele wyjaśnia, szczególnie w połączeniu z powyższymi 2 odpowiedziami „publicznymi + uprzywilejowanymi”. Jestem jednak całkowicie zdezorientowany tym, że obj.constructor === Personjesteś trueprzykładem ... Coaaaat? W jaki sposób konstruktor instancji ===klasy może sam klasę ...? (To tak, jakby powiedzieć, że podzbiorem zbioru jest sam zbiór itp.)
Andrew
Ohhh ... czy to wszystko znaczy, że dosłownie, konstruktor jest wszystkim, czym naprawdę jest klasa JS pod koniec dnia? Cała reszta jest albo ułożona w konstruktorze, albo całkowicie w konstrukcji statycznej, odizolowanej od klasy, z wyjątkiem nazwy / pojęcia (i jak implikowane „to” jest oczywiście dostępne)? (Tak więc to, co uważałem za podzbiór zestawu, nie było tak naprawdę podzbiorem).
Kiedy utworzysz więcej niż jedną instancję MyClass, nadal będziesz mieć tylko jedną instancję publicMethod w pamięci, ale w przypadku privilegedMethod skończysz tworzenie wielu instancji, a staticMethod nie będzie mieć związku z instancją obiektu.
Właśnie dlatego prototypy oszczędzają pamięć.
Ponadto, jeśli zmienisz właściwości obiektu nadrzędnego, to czy odpowiednia właściwość dziecka nie została zmieniona, zostanie zaktualizowana.
źródło
Dla uczniów wizualnych, którzy definiują funkcję bez
.prototype
Z tym samym kodem, jeśli
.prototype
jest dodany,Aby było to jaśniejsze,
**** Uwaga dla powyższego przykładu, niektóreInstance.method () nie zostanie wykonane, ponieważ
ExampleClass.method () powoduje błąd i wykonanie nie może być kontynuowane.
Ale dla ilustracji i łatwego zrozumienia zachowałem tę sekwencję. ****
Wyniki wygenerowane z
chrome developer console
& Kliknij powyższy link jsbin, aby przejść przez kod. Przełącz komentowaną sekcję za pomocą +JS Bin
ctrl/
źródło
Tak, pierwszy jest
static method
również nazywanyclass method
, podczas gdy drugi toinstance method
.Rozważ następujące przykłady, aby zrozumieć to bardziej szczegółowo.
W ES5
W powyższym kodzie
isPerson
jest metoda statyczna, asayHi
metoda instancjiPerson
.Poniżej znajduje się sposób utworzenia obiektu z
Person
konstruktora.var aminu = new Person("Aminu", "Abubakar");
Za pomocą metody statycznej
isPerson
.Person.isPerson(aminu); // will return true
Za pomocą metody instancji
sayHi
.aminu.sayHi(); // will return "Hi Aminu"
W ES6
Zobacz, jak
static
użyto słowa kluczowego do zadeklarowania metody statycznejisPerson
.Aby utworzyć obiekt
Person
klasy.const aminu = new Person("Aminu", "Abubakar");
Za pomocą metody statycznej
isPerson
.Person.isPerson(aminu); // will return true
Za pomocą metody instancji
sayHi
.aminu.sayHi(); // will return "Hi Aminu"
UWAGA: oba przykłady są zasadniczo takie same, JavaScript pozostaje językiem bezklasowym.
class
Wprowadzony w ES6 to przede wszystkim cukier syntaktyczny w stosunku do istniejącego prototypu na bazie modelu dziedziczenia.źródło
obj.constructor === Person
jesteśtrue
przykładem ... Coaaaat? W jaki sposób konstruktor instancji===
klasy może sam klasę ...? (To tak, jakby powiedzieć, że podzbiorem zbioru jest sam zbiór itp.)