Jaki jest sens metody prototypowej?

10

Czytam przez Javascript: The Good Parts i starałem się omijać sekcję dotyczącą prototypów .

Po krótkim wyszukiwaniu doszedłem do wniosku, że ma to dodawać właściwości do obiektów po deklaracji obiektów.

Używając tego skryptu lśniącego od w3schools, zauważyłem, że usunięcie linii dodającej właściwość prototypu nie miało żadnego efektu . Więc o co chodzi?


//Prototyping

function employee(name,jobtitle,born)
{
this.name=name;
this.jobtitle=jobtitle;
this.born=born;
}

var fred=new employee("Fred Flintstone","Caveman",1970);
employee.prototype.salary=null; //  <---  try removing this line
fred.salary=20000;

document.write (fred.salary);

Łagodny Fuzz
źródło
4
@Raynos dobrze powiedział, ale sugeruje też zastąpienie, np.
Dokumenty

Odpowiedzi:

13

Nie tak działa prototyp. Prototyp jest wykorzystywany w łańcuchu prototypów.

Ilekroć spróbujesz uzyskać właściwość dla obiektu, sprawdzi on obiekt pod kątem tej nazwy właściwości. Jeśli nie istnieje, zajrzy do prototypu.

Przykład:

var o = {
  "foo": "bar",
  "method": function() { ... }
};

var o2 = Object.create(o);
var o3 = Object.create(o);

console.log(o2.hasOwnProperty("foo")); // false
console.log(o2.foo); // "bar"
console.log(o2.__proto__ === o); // true
o.baz = "foobar";
console.log(o2.baz); // "foobar"

Tak więc celem prototypu jest po prostu ponowne użycie kodu i dziedziczenie.

Raynos
źródło
Okej, więc rozumiem teraz. Ale próbowałem dynamicznie dodać właściwość i to mi mówi prototype is undefined---o.prototype.newProp = "mutts nuts";
Łagodny Fuzz
3
@MildFuzz oto obiekt. .prototypeNieruchomość jest wykorzystywana na funkcje, zignoruj go. Po prostu zróbo.newProp = "mutts nuts"
Raynos
7

Kiedy to zrobiłeś fred.salary=20000, dodałeś atrybut wynagrodzenia tylko do freda. Podczas korzystania z prototypu wszyscy pracownicy, których będziesz odtąd tworzył, będą mieli atrybut wynagrodzenia.

Załóżmy, że masz 100 wystąpień pracowników i chcesz dodać do nich atrybut wynagrodzenia. Możesz to zrobić ręcznie, iterować każdego pracownika i dodać go. Lub możesz użyć prototypu i ustawić go dla wszystkich.

Prototyp jest przydatny, gdy chcesz funkcjonalność do czegoś, co już istnieje. Powiedz, że chcesz dodać niestandardową metodę do tablic. Zrobiłbyś coś takiego:

Array.prototype.my_custom_method = function() {...}

Odtąd wszystkie tablice, które utworzysz, będą miały tę metodę dostępną.

adivasile
źródło
3
Dziwi mnie, że nikt nie wspomniał, że ma to na celu zmniejszenie zużycia pamięci. Jeśli potrzebujesz zaimplementować złożony obiekt, który ma dużo kodu, nie chcesz, aby kod był powtarzany w każdej instancji obiektu. Oczywiście właściwości danych częściej różnią się w każdym przypadku, ale zwykle potrzebujesz tylko jednej kopii kodu, więc umieść ją w prototypie.
Dominic Cronin
1
IMO to jak dotąd najlepsza odpowiedź.
The Muffin Man,
5

Możesz rzucić okiem na ten artykuł .

Język oparty na prototypach ma pojęcie obiektu prototypowego, obiektu używanego jako szablon, z którego można uzyskać początkowe właściwości nowego obiektu. Każdy obiekt może określić własne właściwości, zarówno podczas jego tworzenia, jak i w czasie wykonywania. Ponadto każdy obiekt może być skojarzony jako prototyp innego obiektu, umożliwiając drugiemu obiektowi współdzielenie właściwości pierwszego obiektu.

Jeśli dodasz właściwość do obiektu, który jest używany jako prototyp dla zestawu obiektów, obiekty, dla których jest to prototyp, również otrzymają nową właściwość.

To jedna z głównych zalet języka opartego na prototypach w porównaniu do języka opartego na klasach.

W razie potrzeby łatwo jest uzyskać klasyczne dziedzictwo OO w JS, ale często trudno jest uzyskać prototypowy model dla języka, który domyślnie go nie implementuje.

Jose Faeti
źródło
3
+1 za artykuł dotyczący języków klasowych i prototypowych
adivasile,