Sporo czasu poświęciłem na tworzenie prostych widżetów dla projektów w następujący sposób:
var project = project || {};
(function() {
project.elements = {
prop1: val1,
prop2: val2
}
project.method1 = function(val) {
// Do this
}
project.method2 = function(val) {
// Do that
}
project.init = function() {
project.method1(project.elements.prop1)
project.method2(project.elements.prop2)
}
})()
project.init();
Ale zacząłem zmieniać format na następujący:
function Project() {
this.elements = {
prop1: val1,
prop2: val2
}
this.method_one(this.elements.prop1);
this.method_two(this.elements.prop2);
}
Project.prototype.method_one = function (val) {
//
};
Project.prototype.method_two = function (val) {
//
};
new Project();
To prawda, są to głupie przykłady, więc nie owijaj się wokół osi. Ale jaka jest różnica funkcjonalna i kiedy powinienem wybrać jedną lub drugą?
design-patterns
javascript
prototyping
JDillon522
źródło
źródło
project
deklarację do funkcji. ZaktualizowanoOdpowiedzi:
Pierwszą różnicę można streścić w następujący sposób:
this
odnosi się do wystąpienia klasy.prototype
odnosi się do definicji .Powiedzmy, że mamy następującą klasę:
Tak więc tutaj przywiązujemy się
this.number
do każdej instancji klasy i ma to sens, ponieważ każdyFlight
powinien mieć swój własny numer lotu.W przeciwieństwie,
prototype
definiuje pojedynczą właściwość, do której mogą mieć dostęp wszystkie instancje.Teraz, jeśli chcemy uzyskać numer lotu, możemy po prostu napisać następujący fragment kodu, a wszystkie nasze instancje otrzymają odniesienie do tego nowo prototypowanego obiektu.
Druga różnica dotyczy sposobu, w jaki JavaScript wyszukuje właściwość obiektu. Kiedy szukasz
Object.whatever
, JavaScript dociera aż do głównego obiektu (obiektu, który odziedziczył wszystko inne), a gdy tylko znajdzie dopasowanie, zwróci go lub wywoła.Ale dzieje się tak tylko w przypadku prototypowanych właściwości. Więc jeśli masz gdzieś na wyższych poziomach
this.whatever
, JavaScript nie uzna tego za dopasowanie i kontynuuje wyszukiwanie.Zobaczmy, jak to się dzieje w rzeczywistości.
Pierwsza uwaga, że [prawie] wszystko to Obiekty w JavaScript. Spróbuj tego:
Zobaczmy teraz, co jest w środku
Object
(zwróć uwagę na wielkie literyO
i.
na końcu). Po wejściu do Narzędzi programistycznych Google Chrome.
zobaczysz listę dostępnych właściwości w tym konkretnym obiekcie.Teraz zrób to samo dla
Function
:Możesz zauważyć
name
metodę. Po prostu uruchom go i zobaczmy, co się stanie:Teraz stwórzmy funkcję:
Zobaczmy też, czy mamy
name
tutaj metodę:Powinieneś dostać pusty ciąg, ale to dobrze. Nie powinieneś otrzymywać błędu ani wyjątku.
Teraz dodajmy coś do tego boskiego
Object
i zobaczmy, czy dostaniemy to również w innych miejscach?I proszę bardzo:
We wszystkich przypadkach powinieneś zobaczyć
"Okay!"
.Jeśli chodzi o zalety i wady każdej metody, można rozważyć prototypowanie jako „bardziej wydajny” sposób wykonywania zadań, ponieważ zachowuje on referencje w każdym przypadku, a raczej kopiuje całą właściwość w każdym obiekcie. Z drugiej strony jest to przykład Tightly Coupling, który jest dużym nie-nie, dopóki nie będziesz w stanie naprawdę uzasadnić przyczyny.
this
jest znacznie bardziej skomplikowany, ponieważ dotyczy kontekstu. W Internecie można znaleźć wiele dobrych zasobów za darmo.To powiedziawszy, oba sposoby są tylko narzędziami językowymi i to naprawdę zależy od ciebie i problemu, który próbujesz rozwiązać, aby wybrać to, co pasuje lepiej.
Jeśli potrzebujesz mieć właściwość odpowiednią dla każdej instancji klasy, użyj
this
. Jeśli potrzebujesz właściwości, aby działała tak samo w każdej instancji, użyjprototype
.Aktualizacja
Jeśli chodzi o przykładowe fragmenty, pierwszy jest przykładem Singletona , więc sensowne jest użycie go
this
w ciele obiektu. Możesz także ulepszyć swój przykład, czyniąc go tak modułowym (i nie zawsze musisz go również używaćthis
).Twój drugi fragment nie ma większego sensu, ponieważ najpierw go używasz,
this
a później próbujesz go zhakowaćprototype
, co nie działa, ponieważthis
ma wyższy priorytetprototype
. Nie jestem pewien, jakie były twoje oczekiwania wobec tego fragmentu kodu i jak działał, ale bardzo polecam, aby go przeredagować.Aktualizacja
Aby rozwinąć
this
kwestię pierwszeństwaprototype
, mogę pokazać przykład i wyjaśnić, jak można to wyjaśnić, ale nie mam żadnych zewnętrznych zasobów, aby je wykonać.Przykład jest bardzo prosty:
Wyjaśnienie jest, jak wiemy,
this
istotne w kontekście. Więc nie powstanie, dopóki kontekst nie będzie gotowy. Kiedy kontekst jest gotowy? Podczas tworzenia nowej instancji! Resztę powinieneś odgadnąć! Oznacza to, że chociaż istniejeprototype
definicja, alethis
bardziej sensowne jest nadanie pierwszeństwa, ponieważ chodzi o tworzenie nowej instancji w tym momencie.źródło
this
w głupim prototypowym przykładzie, ponieważthis
odnosi się do jego własnych właściwości, w tym metod. Nie uczę się najlepiej z czytania o kodzie, ale z patrzenia na kod. ( Kawałek MDN na ten temat , Object Playground (niesamowity) i kilka innych). Czy możesz wskazać coś, co wyjaśnia, co masz na myśli mówiąc „this
ma pierwszeństwo przedprototype
”? Chciałbym przyjrzeć się temu bardziej.