Zanim nauczysz się prototypów, koniecznie sprawdź te tutoriale:
- Obiekty JavaScript
- Funkcja konstruktora JavaScript
Jak wiesz, możesz stworzyć obiekt w JavaScript używając funkcji konstruktora obiektu. Na przykład,
// constructor functionfunction Person () { this.name = 'John', this.age = 23}// creating objectsconst person1 = new Person();const person2 = new Person();
W powyższym przykładzie, function Person()
jest funkcją konstruktora obiektu. Utworzyliśmy z niej dwa obiekty person1
i person2
.
Prototyp JavaScriptu
W JavaScript każda funkcja i obiekt ma domyślnie właściwość o nazwie prototyp. Na przykład,
function Person () { this.name = 'John', this.age = 23}const person = new Person();// checking the prototype valueconsole.log(Person.prototype); // { ... }
W powyższym przykładzie próbujemy uzyskać dostęp do właściwości prototypu funkcji Person
konstruktora.
Ponieważ właściwość prototypu nie ma w tej chwili żadnej wartości, pokazuje pusty obiekt { … }.
Dziedziczenie prototypu
W JavaScript, prototyp może być użyty do dodania właściwości i metod do funkcji konstruktora. A obiekty dziedziczą właściwości i metody z prototypu. Na przykład,
// constructor functionfunction Person () { this.name = 'John', this.age = 23}// creating objectsconst person1 = new Person();const person2 = new Person();// adding property to constructor functionPerson.prototype.gender = 'male';// prototype value of Personconsole.log(Person.prototype);// inheriting the property from prototypeconsole.log(person1.gender);console.log(person2.gender);
Output
{ gender: "male" }malemale
W powyższym programie dodaliśmy nową właściwość gender
do funkcji konstruktora Person
używając:
Person.prototype.gender = 'male';
Ten obiekt person1
i person2
dziedziczy m.in. właściwość gender
z właściwości prototype funkcji konstruktora Person
.
Więc, oba obiekty person1
i person2
mogą mieć dostęp do właściwości gender.
Uwaga: Składnia dodawania właściwości do funkcji konstruktora obiektu jest następująca:
objectConstructorName.prototype.key = 'value';
Prototyp jest używany do zapewnienia dodatkowej właściwości wszystkim obiektom utworzonym z funkcji konstruktora.
Dodaj metody do funkcji konstruktora używając prototypu
Możesz również dodać nowe metody do funkcji konstruktora używając prototypu. Na przykład,
// constructor functionfunction Person () { this.name = 'John', this.age = 23}// creating objectsconst person1 = new Person();const person2 = new Person();// adding a method to the constructor functionPerson.prototype.greet = function() { console.log('hello' + ' ' + this.name);}person1.greet(); // hello Johnperson2.greet(); // hello John
W powyższym programie, nowa metoda greet
jest dodawana do funkcji konstruktora Person
przy użyciu prototypu.
Zmiana prototypu
Jeżeli wartość prototypu zostanie zmieniona, wtedy wszystkie nowe obiekty będą miały zmienioną wartość właściwości. Wszystkie wcześniej utworzone obiekty będą miały poprzednią wartość. Na przykład,
// constructor functionfunction Person() { this.name = 'John'}// add a propertyPerson.prototype.age = 20;// creating an objectconst person1 = new Person();console.log(person1.age); // 20// changing the property value of prototypePerson.prototype = { age: 50 }// creating new objectconst person3 = new Person();console.log(person3.age); // 50console.log(person1.age); // 20
Uwaga: Nie powinieneś modyfikować prototypów standardowych wbudowanych obiektów JavaScript, takich jak ciągi, tablice, itp. Jest to uważane za złą praktykę.
JavaScript Prototype Chaining
Jeśli obiekt próbuje uzyskać dostęp do tej samej właściwości, która znajduje się w funkcji konstruktora i w prototypie obiektu, obiekt pobiera właściwość z funkcji konstruktora. Na przykład,
function Person() { this.name = 'John'}// adding property Person.prototype.name = 'Peter';Person.prototype.age = 23const person1 = new Person();console.log(person1.name); // Johnconsole.log(person1.age); // 23
W powyższym programie, nazwa właściwości jest zadeklarowana w funkcji konstruktora, a także we właściwości prototypu funkcji konstruktora.
Gdy program się wykonuje, person1.name
patrzy w funkcji konstruktora, aby sprawdzić, czy istnieje właściwość o nazwie name
. Ponieważ funkcja konstruktora ma właściwość name o wartości 'John'
, obiekt pobiera wartość z tej właściwości.
Gdy program się wykonuje, person1.age
szuka w funkcji konstruktora, czy istnieje właściwość o nazwie age
. Ponieważ funkcja konstruktora nie posiada właściwości age
, program zagląda do obiektu prototypu funkcji konstruktora i obiekt dziedziczy właściwość z obiektu prototypu (jeśli jest dostępny).
Uwaga: Można również uzyskać dostęp do właściwości prototypu funkcji konstruktora z obiektu.
function Person () { this.name = 'John'}// adding a prototypePerson.prototype.age = 24;// creating objectconst person = new Person();// accessing prototype propertyconsole.log(person.__proto__); // { age: 24 }
W powyższym przykładzie obiekt person
jest używany do uzyskania dostępu do właściwości prototypu za pomocą __proto__
. Jednakże, __proto__
został zdeprecjonowany i powinieneś unikać jego używania.