OOJS: Objektově orientovaný JavaVýukový program skriptu s příkladem
⚡ Chytré shrnutí
Objektově orientovaný JavaSkript modeluje entity reálného světa jako objekty, které nesou vlastnosti a metody. Tato stránka vysvětluje objektové literály, konstruktorové funkce, prototypy, třídy ES6, dědičnost a privátní pole s pomocí spustitelných příkladů, které můžete spustit a ověřit.
V čem je koncept OOPS JavaSkript?
Proměnné nebo pole často nestačí k simulaci reálných situací. JavaSkript umožňuje vytvářet objekty, které se chovají jako objekty ze skutečného života. Student nebo dům může být objekt s mnoha jedinečnými vlastnostmi. Pro usnadnění programování můžete na svých objektech vytvářet vlastnosti a metody. Pokud je vaším objektem student, bude mít vlastnosti jako křestní jméno, příjmení a ID a metody jako calculateRank nebo changeAddress. Pokud je vaším objektem dům, bude mít vlastnosti jako počet pokojů, barvu a umístění a metody jako calculateArea nebo changeOwner.
Objektově orientované programování v JavaScénář se tedy opírá o čtyři myšlenky, se kterými se na této stránce setkáte: skupinaping stav a chování do objektu, opětovné použití plánu prostřednictvím konstruktoru, sdílení metod prostřednictvím prototypu a omezení přímého přístupu k interním datům. Pokud s tímto jazykem začínáte, začněte s tímto úvod do JavaScénář a pak se sem vraťte.
Jak vytvořit objekt
Můžete vytvořit objekt takto:
var objName = new Object(); objName.property1 = value1; objName.property2 = value2; objName.method1 = function() { // line of code }
NEBO s použitím kratšího tvaru objektového literálu:
var objName = { property1: value1, property2: value2, method1: function() { // lines of code } };
Přístup k vlastnostem a metodám objektu
K vlastnosti objektu můžete přistupovat pomocí tečkové notace a metodu můžete volat přidáním závorek:
objectname.propertyname; // read a property objectname.methodname(); // call a method objectname["propertyname"]; // bracket notation, useful for dynamic keys
Zkuste tento příklad sami:
<html>
<head>
<title>Objects!!!</title>
<script type="text/javascript">
var student = new Object();
student.fName = "John";
student.lName = "Smith";
student.id = 5;
student.markE = 76;
student.markM = 99;
student.markS = 87;
student.calculateAverage = function()
{
return (student.markE + student.markM + student.markS)/3;
};
student.displayDetails = function()
{
document.write("Student Id: " + student.id + "<br />");
document.write("Name: " + student.fName + " " + student.lName + "<br />");
var avg = student.calculateAverage();
document.write("Average Marks: " + avg);
};
student.displayDetails();
</script>
</head>
<body>
</body>
</html>
Výstup:
Student Id: 5 Name: John Smith Average Marks: 87.33333333333333
💡 Tip: Výše uvedený příklad používá dokument.napsat protože běží uvnitř editoru na této stránce. V reálných projektech dává přednost konzole.log pro ladění nebo DOM metody, jako například textObsah, Protože dokument.napsat Vymaže stránku, když je volána po dokončení načítání.
OOPS konstruktor
Vytváření objektů jeden po druhém není tak užitečné, protože byste museli opakovat stejný kód pro každého studenta. Zde přichází na řadu konstruktor objektů. Konstruktor je běžná funkce, která se volá s nový klíčové slovo; definuje typ objektu, který lze znovu použít pro každou jednotlivou instanci.
Uvnitř konstruktoru, tento odkazuje na nově sestavovaný objekt, takže každá instance obdrží svou vlastní kopii předaných hodnot. Související hodnoty, jako například značky, jsou často uloženy v řada aby je bylo možné sečíst v jednom průchodu.
Zkuste tento příklad sami:
<html>
<head>
<script type="text/javascript">
function Student(first, last, id, english, maths, science)
{
this.fName = first;
this.lName = last;
this.id = id;
this.markE = english;
this.markM = maths;
this.markS = science;
this.calculateAverage = function()
{
return (this.markE + this.markM + this.markS)/3;
}
this.displayDetails = function()
{
document.write("Student Id: " + this.id + "<br />");
document.write("Name: " + this.fName + " " + this.lName + "<br />");
var avg = this.calculateAverage();
document.write("Average Marks: " + avg + "<br /><br />");
}
}
var st1 = new Student("John", "Smith", 15, 85, 79, 90);
var st2 = new Student("Hannah", "Turner", 23, 75, 80, 82);
var st3 = new Student("Kevin", "White", 4, 93, 89, 90);
var st4 = new Student("Rose", "Taylor", 11, 55, 63, 45);
st1.displayDetails();
st2.displayDetails();
st3.displayDetails();
st4.displayDetails();
</script>
</head>
<body>
</body>
</html>
Výstup:
Student Id: 15 Name: John Smith Average Marks: 84.66666666666667 Student Id: 23 Name: Hannah Turner Average Marks: 79 Student Id: 4 Name: Kevin White Average Marks: 90.66666666666667 Student Id: 11 Name: Rose Taylor Average Marks: 54.333333333333336
Procházet vlastnosti objektu
Syntaxe:
for (variablename in objectname) { // lines of code to be executed }
Pro/v smyčka se obvykle používá k procházení vlastností objektu. Můžete mu dát libovolný název. proměnlivý, ale název objektu se musí shodovat s objektem, který již existuje. Při každém průchodu proměnná obsahuje vlastnost klíč jako řetězec, takže hodnota se čte s notací v hranatých závorkách, například zaměstnanec[x].
Zkuste tento příklad sami:
<html>
<head>
<script type="text/javascript">
var employee={first:"John", last:"Doe", department:"Accounts"};
var details = "";
document.write("<b>Using for/in loops </b><br />");
for (var x in employee)
{
details = x + ": " + employee[x];
document.write(details + "<br />");
}
</script>
</head>
<body>
</body>
</html>
Výstup:
Using for/in loops first: John last: Doe department: Accounts
Je třeba si uvědomit dva body. Cyklus for/in také navštěvuje vyčíslitelné vlastnosti zděděné prostřednictvím řetězce prototypů, takže ochranný prvek, jako například Objekt.prototyp.hasOwnProperty.call(zaměstnanec, x) se často přidává. U objektů s prostým datem se Object.keys(zaměstnanec) or Object.entries(zaměstnanec) je obvykle přehlednější, protože oba vracejí pouze vlastnosti objektu.
Jaká je syntaxe třídy ES6 v JavaSkript?
ECMAScript 2015, běžně nazývaný ES6, přidal třída klíčové slovo. Třída je syntaktický cukr nad prototypovým systémem, který výše uvedená konstruktorová funkce již používá: nebyl zaveden žádný nový objektový model. Spuštění typ studenta na třídě stále vrací řetězec „function“ a každá metoda napsaná v těle třídy je nainstalována na Student.prototype, což znamená, že všechny instance sdílejí jednu kopii dané metody, místo aby každý objekt nesl svou vlastní.
Syntaxe také odstraňuje některé nedostatky. Těla tříd se vždy provádějí v striktním režimu a volají třídu bez nový vyvolá TypeError místo tichého znečištění globálního objektu a gettery, settery a statické členy mají vyhrazené místo pro uložení. Výsledkem je kratší kód, který vyjadřuje stejný záměr.
class Student { constructor(first, last, id, english, maths, science) { this.fName = first; this.lName = last; this.id = id; this.marks = [english, maths, science]; } calculateAverage() { const total = this.marks.reduce((sum, m) => sum + m, 0); return total / this.marks.length; } displayDetails() { console.log("Student Id: " + this.id); console.log("Name: " + this.fName + " " + this.lName); console.log("Average Marks: " + this.calculateAverage().toFixed(2)); } } const st1 = new Student("John", "Smith", 15, 85, 79, 90); st1.displayDetails(); console.log(typeof Student); console.log(st1.calculateAverage === Student.prototype.calculateAverage);
Výstup:
Student Id: 15 Name: John Smith Average Marks: 84.67 function true
Poslední dva řádky to dokazují: třída je stále funkcí a metoda na instanci je tentýž funkční objekt uložený na prototypu.
Konstruktorová funkce vs. třída ES6
| Vzhled | Funkce konstruktoru | Třída ES6 |
|---|---|---|
| Prohlášení | funkce Student(…) { } | třída Student { konstruktor(…) { } } |
| Umístění metody | Přiřazeno uvnitř funkce, takže každá instance dostane svou vlastní kopii, pokud nezapíšete do Student.prototype | Zapsáno v těle třídy a automaticky umístěno na prototyp |
| Volání bez nového | Běží tiše a tento je nedefinovaný nebo globální objekt | Okamžitě vyvolá chybu TypeError. |
| Zvedání | Deklarace funkcí jsou zvednuty a použitelné před definicí. | V časové mrtvé zóně do vyhodnocení |
| Přísný režim | Sleduje okolní scénář | Vždy přísný |
| Dědictví | Manuální: Object.create plus volání rodiči | rozšiřuje a skvělý |
| Soukromé údaje | Uzávěry nebo konvence pojmenování, jako například _váhy | Skutečně soukromá pole s # |
| Podkladový model | Prototypy | Prototypy (identické za běhu) |
Jak implementovat dědičnost pomocí extends a super
Dědičnost umožňuje specializovanému typu znovu použít vlastnosti a metody obecnějšího typu. Před ES6 to znamenalo ruční propojení řetězce prototypů ve třech samostatných krocích a bylo snadné na jeden z nich zapomenout.
function Person(fName, lName) { this.fName = fName; this.lName = lName; } Person.prototype.introduce = function () { return "I am " + this.fName + " " + this.lName; }; function Student(fName, lName, id) { Person.call(this, fName, lName); // 1. borrow the parent constructor this.id = id; } Student.prototype = Object.create(Person.prototype); // 2. link the chain Student.prototype.constructor = Student; // 3. repair constructor var st = new Student("Kevin", "White", 4); console.log(st.introduce()); console.log(st instanceof Person);
Výstup:
I am Kevin White true
Jedno rozšiřuje klíčové slovo provede všechny tři kroky za vás a skvělý poskytuje čistý způsob, jak dosáhnout nadřazeného objektu. Existují dvě různá využití skvělý:
- super(…) jako hovor spustí nadřazený konstruktor. Je platný pouze uvnitř odvozeného konstruktoru a musí být spuštěn před dotykem. tento, jinak je vyvolána chyba ReferenceError.
- super.method() protože vyhledávání vlastnosti volá nadřazenou verzi metody, kterou podřízená metoda přepsala, což je způsob, jakým rozšiřujete chování, místo abyste ho nahrazovali.
class Person { constructor(fName, lName) { this.fName = fName; this.lName = lName; } introduce() { return "I am " + this.fName + " " + this.lName; } } class Student extends Person { constructor(fName, lName, id) { super(fName, lName); // must run before "this" is used this.id = id; } introduce() { return super.introduce() + ", roll number " + this.id; } } const st = new Student("Hannah", "Turner", 23); console.log(st.introduce()); console.log(st instanceof Student, st instanceof Person); console.log(Object.getPrototypeOf(Student.prototype) === Person.prototype);
Výstup:
I am Hannah Turner, roll number 23 true true true
Třetí řádek je důležitý. Potvrzuje, že rozšiřuje vytvořil přesně ten prototyp, který odkazoval na manuální verzi sestavenou ručně, takže třídy nenahradily řetězení prototypů. Jednoduše skryly standard. Když je vlastnost načtena z st, engine se podívá na instanci a poté Student.prototype, pak Person.prototype, pak Objekt.prototypea zastaví se na první shodě; tato vyhledávací cesta je řetězec prototypů.
Warning️ Varování: Nikdy nepřiřazovat Student.prototype = Person.prototypeDíky tomu oba typy sdílejí jeden objekt, takže jakákoli metoda, kterou přidáte k podřízenému objektu, se přidá také k nadřazenému objektu. Použijte Objekt.vytvořit(Osoba.prototyp), nebo jednoduše použijte rozšiřuje.
Jak dosáhnout zapouzdření pomocí soukromých polí třídy
Zapouzdření znamená uchovatping vnitřní stav mimo dosah, takže se může změnit pouze metodami, které ovládáte. Po léta JavaVývojáři skriptů to zfalšovali úvodním podtržítkem, ale název jako _váhy je to pouze konvence a jakýkoli kód ji stále může přepsat. Moderní JavaSkript nabízí skutečné soukromí: pole, jehož název začíná na # je přístupný pouze uvnitř těla třídy, která jej deklaruje.
Soukromá pole přinášejí tři konkrétní výhody:
- Před použitím musí být deklarovány v těle třídy, což na jednom místě dokumentuje vnitřní stav typu.
- Jsou pro ně neviditelní Objektové klíče, JSON.stringifya for/in, aby se vnitřní stav nepřenášel do serializovaného výstupu.
- Dotyk do soukromého pole zvenčí třídy je syntaktická chyba zachycená ještě před spuštěním kódu, nikoli tichá chyba.
class BankAccount { #balance = 0; constructor(owner, opening) { this.owner = owner; this.#balance = opening; } deposit(amount) { if (amount <= 0) { return "Deposit must be positive"; } this.#balance += amount; return this.owner + " balance: " + this.#balance; } get balance() { return this.#balance; } } const acc = new BankAccount("John", 500); console.log(acc.deposit(250)); console.log(acc.deposit(-40)); console.log("Read via getter: " + acc.balance); console.log("Own keys: " + Object.keys(acc)); console.log("JSON: " + JSON.stringify(acc));
Výstup:
John balance: 750
Deposit must be positive
Read via getter: 750
Own keys: owner
JSON: {"owner":"John"}
Zůstatek se nikdy neobjeví Objektové klíče nebo v řetězci JSON a negativní vklad je metodou odmítnut namísto poškození pole. získat zůstatek() accessor zpřístupňuje zobrazení pouze pro čtení, což je obvyklý způsob, jak bezpečně publikovat soukromý stav.
Nyní, když objekty, prototypy, třídy, dědičnost a zapouzdření dávají smysl, pokračujte ve vytváření. Procvičte si základy s těmito... praktický JavaPříklady skriptového kódu, propracovat se interaktivní JavaCvičení se skripty, aplikovat třídy na algoritmy, jako například rychlé řazení v JavaScénář, uklidit výstup pomocí JavaFormátování řetězce skriptua podívejte se, jak statické typing změny designu objektu v TypeScript.

