Když jsem začal pracovat na projektu s Vue.js, došel jsem k poznání, že o JavaScriptu toho moc nevím. Od té doby jsem hledal JS, což mě pak přivedlo k objektově orientovanému programování v JavaScriptu. Dozvěděl jsem se o mnoha věcech, ale nejvíce jsem se potýkal s konceptem prototypů.
Doufám, že tímto blogovým příspěvkem to dokážu vysvětlit srozumitelným způsobem.
Malý úvod
Konstruktor je funkce, která vytváří nové objekty. V JavaScriptu to vypadá takto:
function Person(name, age) {
this.name = name;
this.age = age;
}
Syntaxe pro vytvoření nového objektu pomocí konstruktoru vypadá takto:
const me = new Person("Nicole", 19);
me
nyní má name
„Nicole“ a age
19. Snadné a jednoduché, jak byste očekávali.
Nyní si představte, že bychom chtěli vytvořit objekt Person
s vlastnostmi paže, ruce, prsty a jméno:
function Person(arms, hands, fingers, name) {
this.arms = arms;
this.hands = hands;
this.fingers = fingers;
this.name = name;
}
Když vytvoříte čtyři instance Person
, bude to vypadat takto:
const person1 = new Person(2, 2, 10, "Alice");
const person2 = new Person(2, 2, 10, "Bob");
const person3 = new Person(2, 2, 10, "Ursula");
const person4 = new Person(2, 2, 10, "Hanspeter");
Docela otravné a velmi se opakující... Tehdy se prototypy stanou užitečnými.
Prototypy
Prototypy se používají ke sdílení vlastností mezi všemi instancemi objektu. Vezměte si příklad shora:
Person.prototype = {
constructor: Person,
arms: 2,
hands: 2,
fingers: 10
}
Pomocí tohoto prototypového objektu vytvoříte čtyři instance Person
s konstruktorem vypadá mnohem čistěji a je také méně práce:
function Person(name) {
this.name = name;
}
const person1 = new Person("Alice");
const person2 = new Person("Bob");
const person3 = new Person("Ursula");
const person4 = new Person("Hanspeter");
Jak jsem řekl, mnohem menší a méně se opakující práce, ale všechny mají stejné vlastnosti jako ty vytvořené výše bez prototypu.
Nejen, že to vypadá čistěji, ale je snazší měnit hodnoty.
Řekněme, že jste – z nějakého opravdu hloupého důvodu – zadali 2 ruce pro každou osobu, ale program ve skutečnosti vytváří lidi pouze jednou rukou (proč bychom potřebovali vlastnosti paže a prsty, je teď zbytečné). Museli byste projít každým. svobodný . instance objektu a změnit nejen hodnotu 2 ruce, ale i 10 prstů. S pouhými čtyřmi instancemi byste museli provést osm změn. S prototypem budete muset vždy provést pouze dvě změny.
Není to nejlepší příklad, ale myslím, že to vystihuje podstatu věci.
Vlastnost jednoho prototypu vs objekt prototypu
Výše jsem použil prototyp objektu což je dobré, když by mělo být sdíleno mnoho vlastností. Pokud však existuje pouze jedna sdílená vlastnost, můžete ji zapsat takto:
Person.prototype.age = 30;
Není třeba ho dělat větší, než musí být.
Prototypové funkce
S prototypem je také možné uložit funkce jako vlastnosti.
Prototyp objektu:
Person.prototype = {
introduce: function() {
console.log(`Hello, my name is ${this.name}`);
}
}
Vlastnost jednoho prototypu:
Person.prototype.introduce = function(){
console.log(`Hello, my name is ${this.name}`);
}
konstruktor:osoba
Možná jste si všimli, že jsem definoval konstruktor v objektu prototypu. To je důležité, protože pokud nedefinujeme konstruktor, objekty budou mít Object
jako jeho konstruktor a ne Person
.
Dobře, teď tuto větu rozebereme, aby to bylo jasnější.
Máte konstruktor pro objekt.
function Person(name, age){
this.name = name;
this.age = age;
}
Poté pomocí tohoto konstruktoru vytvoříte objekt.
const me = new Person("Nicole", 19);
Konstruktor me
je Person
. Myslím, že mnohé je jasné.
me.constructor === Person
→ true
Když však vytvoříte prototypový objekt pro Person
a nedefinujte konstruktor me
bude mít konstruktor Object
.
Person.prototype = {
introduce: function() {
console.log(`Hello, my name is ${this.name}`);
}
}
const me = new Person("Nicole", 19);
console.log(me.constructor === Person);
console.log(me.constructor === Object);
→ false
true
Ale proč?
Řetězec prototypů
Abychom vysvětlili prototypový řetězec, zaměřme se nejprve pouze na objekty. Když vytvoříte objekt, můžete zkontrolovat jeho vlastnosti pomocí hasOwnProperty
.
Ale odkud to pochází? Nikdy jsme to nikde nedefinovali, přesto to můžeme použít. Odpověď je, že všechny objekty dědí od Object
který má své vlastní prototypové vlastnosti. Můžete to zkontrolovat vytvořením jednoduchého objektu a kontrolou jeho konstruktoru.
let exampleObject = {
something: "hi"
}
console.log(exampleObject.constructor === Object);
→ true
Všechny objekty tedy pocházejí z Object
, může používat jeho vlastnosti prototypu a mít Object
jako konstruktér. To dává smysl.
Nyní, když vytvoříte prototyp objektu , je to objekt, a proto dědí z Object
. Proto musíte definovat konstruktor nebo jinak své instance Person
bude mít konstruktor Object
.
Object.prototype
-zděděno-> Person.prototype ={}
-zděděno-> me
Děkuji
Abych byl upřímný, nečekal jsem, že tento článek bude tak dlouhý (nevím, co se stalo), takže pokud jste se dostali až sem, vážně, děkuji za přečtení.