Dynamické vytváranie javascriptových objektov. Vytvorenie nového objektu. Použitie funkcie konštruktora

  • 14.05.2019

JavaScript je navrhnutý na základe jednoduchej objektovo orientovanej paradigmy. Objekt je súbor vlastností a vlastnosť je asociácia medzi názvom (alebo kľúč) a hodnotu. Hodnota vlastnosti môže byť funkcia, v tomto prípade je vlastnosť známa ako metóda. Okrem objektov, ktoré sú preddefinované v prehliadači, môžete definovať svoje vlastné objekty. Táto kapitola popisuje, ako používať objekty, vlastnosti, funkcie a metódy a ako vytvárať vlastné objekty.

Prehľad objektov

Objekty v JavaScripte, rovnako ako v mnohých iných programovacích jazykoch, možno prirovnať k objektom v reálnom živote. Pojem objektov v JavaScripte možno chápať s reálnymi reálnymi predmetmi.

V JavaScripte je objekt samostatnou entitou s vlastnosťami a typom. Porovnajte to napríklad s pohárom. Pohár je predmet s vlastnosťami. Pohár má farbu, dizajn, hmotnosť, materiál, z ktorého je vyrobený atď. Podobne môžu mať objekty JavaScript vlastnosti, ktoré definujú ich vlastnosti.

Objekty a vlastnosti

Objekt JavaScript má priradené vlastnosti. Vlastnosť objektu možno vysvetliť ako premennú, ktorá je pripojená k objektu. Vlastnosti objektu sú v podstate rovnaké ako bežné premenné JavaScriptu, s výnimkou pripojenia k objektom. Vlastnosti objektu definujú vlastnosti objektu. K vlastnostiam objektu pristupujete pomocou jednoduchého bodkového zápisu:

ObjectName.propertyName

Rovnako ako všetky premenné jazyka JavaScript, názov objektu (ktorý môže byť normálnou premennou) aj názov vlastnosti rozlišujú veľké a malé písmená. Vlastnosť môžete definovať tak, že jej priradíte hodnotu. Vytvorme napríklad objekt s názvom myCar a priraďme mu vlastnosti s názvom značka, model a rok takto:

Var myCar = nový objekt (); myCar.make = "Ford"; myCar.model = "Mustang"; myCar.year = 1969; myCar.color; // nedefinované

K vlastnostiam objektov JavaScript je možné pristupovať alebo ich nastaviť aj pomocou zápisu zátvoriek (ďalšie podrobnosti nájdete v časti Prístupové prvky vlastností). Objekty sa niekedy nazývajú asociatívne polia, pretože každá vlastnosť je spojená s hodnotou reťazca, ktorú možno použiť na prístup k nej. K vlastnostiam objektu myCar teda môžete pristupovať napríklad takto:

MyCar ["make"] = "Ford"; myCar ["model"] = "Mustang"; myCar ["rok"] = 1969;

Názov vlastnosti objektu môže byť akýkoľvek platný reťazec JavaScript alebo čokoľvek, čo sa dá skonvertovať na reťazec, vrátane prázdneho reťazca. K akémukoľvek názvu vlastnosti, ktorý nie je platným identifikátorom JavaScript (napríklad názov vlastnosti, ktorý má medzeru alebo spojovník alebo ktorý začína číslom), je možné pristupovať iba pomocou zápisu v hranatých zátvorkách. Tento zápis je tiež veľmi užitočný, keď majú byť názvy vlastností určované dynamicky (keď názov vlastnosti nie je určený až do behu). Príklady sú nasledovné:

// štyri premenné sa vytvoria a priradia naraz, // oddelené čiarkami var myObj = new Object (), str = "myString", rand = Math.random (), obj = new Object (); myObj.type = "Syntax bodiek"; myObj ["dátum vytvorenia"] = "Reťazec s medzerou"; myObj = "Hodnota reťazca"; myObj = "Náhodné číslo"; myObj = "Objekt"; myObj [""] = "Dokonca aj prázdny reťazec"; console.log (myObj);

Upozorňujeme, že všetky kľúče v notácii s hranatými zátvorkami sa skonvertujú na reťazec, pokiaľ nejde o symboly, keďže názvy vlastností objektov JavaScript (kľúče) môžu byť iba reťazce alebo symboly (v určitom okamihu sa ako návrh polí triedy pridajú aj súkromné ​​názvy. postupuje, ale nebudete ich používať s formulárom). Napríklad vo vyššie uvedenom kóde, keď je kľúč obj pridaný do myObj, JavaScript zavolá metódu obj.toString () a použije tento výsledný reťazec ako nový kľúč.

K vlastnostiam môžete pristupovať aj pomocou hodnoty reťazca, ktorá je uložená v premennej:

Var propertyName = "make"; myCar = "Ford"; propertyName = "model"; myCar = "Mustang";

Použitie funkcie konštruktora

Prípadne môžete vytvoriť objekt pomocou týchto dvoch krokov:

  1. Definujte typ objektu napísaním funkcie konštruktora. Existuje silná konvencia, z dobrého dôvodu, používať veľké začiatočné písmeno.
  2. Vytvorte inštanciu objektu s novým.

Ak chcete definovať typ objektu, vytvorte pre typ objektu funkciu, ktorá špecifikuje jeho názov, vlastnosti a metódy. Predpokladajme napríklad, že chcete vytvoriť typ objektu pre autá. Chcete, aby sa tento typ objektu volal Car, a chcete, aby mal vlastnosti pre značku, model a rok. Ak to chcete urobiť, napíšte nasledujúcu funkciu:

Funkcia Auto (značka, model, rok) (this.značka = značka; tento.model = model; tento.rok = rok;)

Všimnite si použitie tohto na priradenie hodnôt k vlastnostiam objektu na základe hodnôt odovzdaných funkcii.

Teraz môžete vytvoriť objekt s názvom mycar takto:

Var mycar = nové auto ("Eagle", "Talon TSi", 1993);

Tento príkaz vytvorí mycar a priradí mu špecifikované hodnoty pre jeho vlastnosti. Potom hodnota mycar.make je reťazec "Eagle", mycar.year je celé číslo 1993 atď.

Môžete vytvoriť ľubovoľný počet objektov Car volaním na nové. Napríklad,

Var kenscar = nové auto ("Nissan", "300ZX", 1992); var vpgscar = nové auto ("Mazda", "Miata", 1990);

Objekt môže mať vlastnosť, ktorá je sama osebe iným objektom. Predpokladajme napríklad, že definujete objekt s názvom osoba takto:

Funkcia Osoba (meno, vek, pohlavie) (toto.meno = meno; toto.vek = vek; toto.pohlavie = pohlavie;)

a potom vytvorte inštanciu dvoch nových objektov osoby takto:

Var rand = nová osoba („Rand McKinnon“, 33, „M“); var ken = nová osoba („Ken Jones“, 39, „M“);

Potom môžete prepísať definíciu auta tak, aby zahŕňala vlastnosť vlastníka, ktorá zahŕňa objekt osoby, a to takto:

Funkcia Auto (značka, model, rok, majiteľ) (this.značka = značka; tento.model = model; tento.rok = rok; tento.majiteľ = majiteľ;)

Na vytvorenie inštancie nových objektov potom použijete nasledovné:

Var car1 = nové auto ("Eagle", "Talon TSi", 1993, rand); var car2 = nové auto ("Nissan", "300ZX", 1992, ken);

Všimnite si, že namiesto odovzdávania doslovného reťazca alebo celočíselnej hodnoty pri vytváraní nových objektov, vyššie uvedené príkazy odovzdávajú objekty rand a ken ako argumenty pre vlastníkov. Potom, ak chcete zistiť meno vlastníka auta2, máte prístup k nasledujúcej vlastnosti:

Meno.majiteľa auta

Všimnite si, že vždy môžete pridať vlastnosť k predtým definovanému objektu. Napríklad vyhlásenie

Car1.color = "black";

pridá farbu vlastnosti k autu1 a priradí mu hodnotu „čierna“. To však nemá vplyv na žiadne iné objekty. Ak chcete pridať novú vlastnosť ku všetkým objektom rovnakého typu, musíte vlastnosť pridať do definície typu objektu Auto.

Pomocou metódy Object.create

Pozri tiež

  • Ak sa chcete ponoriť hlbšie, prečítajte si podrobnosti o objektovom modeli JavaScriptu.
  • Ak sa chcete dozvedieť o triedach ECMAScript 2015 (nový spôsob vytvárania objektov), ​​prečítajte si kapitolu Triedy JavaScriptu.

Objekty

Objekt je základným dátovým typom v jazyku JavaScript. Objekt je zložená hodnota: kombinuje množinu hodnôt (jednoduché hodnoty alebo iné objekty) a umožňuje ukladať a získavať tieto hodnoty podľa názvu.

Objekt je neusporiadaná kolekcia vlastností, z ktorých každá má názov a hodnotu. Názvy vlastností sú reťazce, takže možno povedať, že objekty mapujú reťazce na hodnoty. Toto mapovanie reťazcov na hodnoty možno nazvať inak: možno už poznáte takú základnú dátovú štruktúru, ako je hash, slovník alebo asociatívne pole. Objekt je však viac než len jednoduché mapovanie reťazcov na hodnoty.

Okrem svojich vlastných vlastností môžu objekty JavaScriptu dediť aj vlastnosti z iných objektov známych ako prototypy. Objektové metódy sú typickými predstaviteľmi zdedených vlastností a " dedičnosť prostredníctvom prototypov„Je to kľúčová vlastnosť jazyka JavaScript.

Objekty v JavaScripte sú dynamické – zvyčajne vám umožňujú pridávať a odstraňovať vlastnosti – možno ich však použiť aj na napodobňovanie statických objektov a „štruktúr“, ktoré sa nachádzajú v programovacích jazykoch so statickým typom. Môžu byť tiež použité (okrem skutočnosti, že objekty mapujú reťazce na hodnoty) na reprezentáciu množín reťazcov.

Akákoľvek hodnota v JavaScripte, ktorá nie je reťazcom, číslom, true, false, null alebo undefined, je objekt. A dokonca aj reťazce, čísla a neobjektové booleany sa môžu správať ako nemenné objekty (majú objekty String, Number wrapper atď.).

Objekty sú meniteľné hodnoty a operácie s nimi sa vykonávajú podľa odkazu, nie podľa hodnoty. Ak premenná x odkazuje na objekt a výrok var y = x; , do premennej y sa zapíše odkaz na rovnaký objekt, nie jeho kópia. Akékoľvek zmeny vykonané na objekte pomocou premennej y sa prejavia aj v premennej x.

Vlastnosť má meno a hodnotu. Názov vlastnosti môže byť ľubovoľný reťazec vrátane prázdneho reťazca, ale objekt nemôže mať dve vlastnosti s rovnakým názvom. Hodnota vlastnosti môže byť akákoľvek hodnota platná v JavaScripte alebo (v ECMAScript 5) funkcia čítania alebo zápisu (alebo oboje).

Okrem mien a hodnôt má každá vlastnosť priradený súbor hodnôt, ktoré sa nazývajú vlastnosti vlastnosti :

    Atribút zapisovateľný určuje, či je hodnota nehnuteľnosti zapisovateľná.

    Atribút spočítateľné určuje dostupnosť názvu vlastnosti pre enumeráciu v slučke for / in.

    Atribút konfigurovateľné určuje možnosť prispôsobenia, t.j. odstránenie vlastnosti a zmena jej atribútov.

Pred štandardom ECMAScript 5 boli všetky vlastnosti objektov, ktoré boli vytvorené programom, zapisovateľné, sčítateľné a konfigurovateľné. ECMAScript 5 poskytuje možnosť prispôsobiť atribúty vašich vlastností.

Okrem vlastností má každý objekt tri objektový atribút :

    Atribút trieda obsahuje reťazec s názvom triedy objektu a definuje typ objektu.

    Vlajka rozšíriteľná(v ECMAScript 5) označuje možnosť pridať nové vlastnosti objektu.

Nakoniec, nasleduje popis niektorých výrazov, ktoré nám pomôžu rozlíšiť medzi tromi širokými kategóriami objektov v JavaScripte a dvoma typmi vlastností:

Objekt základného jazyka

Je to objekt alebo trieda objektov definovaná špecifikáciou ECMAScript. Polia, funkcie, dátumy a regulárne výrazy (napríklad) sú objekty základného jazyka.

Runtime objekt

Je to objekt definovaný runtime (ako je webový prehliadač), kde je vložený interpret JavaScript. Objekty HTMLElement, ktoré predstavujú štruktúru webovej stránky v JavaScripte na strane klienta, sú objekty runtime. Objekty runtime môžu byť aj objekty hostiteľského jazyka, napríklad keď modul runtime definuje metódy, ktoré sú bežnými objektmi funkcií hostiteľského jazyka JavaScript.

Vlastný objekt

Akýkoľvek objekt vytvorený spustením kódu JavaScript.

Vlastný majetok

Ide o vlastnosť, ktorá je definovaná priamo na tomto objekte.

Zdedený majetok

Toto je vlastnosť definovaná prototypom objektu.

Vytváranie objektov

Objekty je možné vytvárať pomocou objektových literálov, nového kľúčového slova a (v ECMAScript 5) funkcií Object.create ().

Objektové literály

Najjednoduchší spôsob, ako vytvoriť objekt, je zahrnúť objektový literál do vášho programu. Objektový literál je čiarkami oddelený zoznam vlastností (páry názov/hodnota) uzavretý v zložených zátvorkách. Názov vlastnosti môže byť identifikátor alebo reťazcový literál (prázdny reťazec je povolený). Hodnota vlastnosti môže byť akýkoľvek výraz platný v JavaScripte — hodnota výrazu (môže to byť jednoduchá hodnota alebo objekt) sa stane hodnotou vlastnosti.

Nižšie uvádzame niekoľko príkladov vytvárania objektov:

Var prázdna = (); // Objekt bez vlastností var point = (x: 0, y: 0); // Dve vlastnosti var bod2 = (x: bod.x, y: bod.y + 1); // Zložitejšie hodnoty ​​var site = ("url site": "www..NET Framework", // a spojovníky, preto použite úvodzovky autor: (// Hodnota tejto vlastnosti je meno: "Alexandr", // objekt. Všimnite si, že priezvisko: "Frolov" // názvy týchto vlastností bez úvodzoviek.));

ECMAScript 5 (a niektoré implementácie ECMAScript 3) vám umožňuje používať vyhradené slová ako názvy vlastností bez úvodzoviek. Vo všeobecnosti však názvy vlastností, ktoré zodpovedajú vyhradeným slovám, musia byť citované v ECMA-Script 3. V ECMAScript 5 sa ignoruje posledná čiarka za poslednou vlastnosťou v objektovom literáli. Väčšina implementácií ECMAScript 3 tiež ignoruje koncové čiarky, ale IE ich interpretuje ako chyby.

Objektový literál je výraz, ktorý vytvára a inicializuje nový objekt vždy, keď sa tento výraz vyhodnotí. Hodnota každej vlastnosti sa prepočíta pri vyhodnotení doslovnej hodnoty. To znamená, že s jediným objektovým literálom môžete vytvoriť veľa nových objektov, ak literál vložíte do tela cyklu alebo funkcie, ktorá sa bude volať viackrát, a že hodnoty vlastností týchto objektov sa môžu líšiť od navzájom.

Vytváranie objektov pomocou operátora new

Operátor new vytvorí a inicializuje nový objekt. Za týmto príkazom musí nasledovať názov funkcie. Takto použitá funkcia sa nazýva konštruktor a používa sa na inicializáciu novovytvoreného objektu. Základný JavaScript obsahuje mnoho vstavaných konštruktorov na vytváranie objektov základného jazyka. Napríklad:

Var o = nový objekt (); // Vytvorenie nového prázdneho objektu: rovnako ako () var a = new Array (); // Vytvorenie prázdneho poľa: rovnaké ako var d = new Date (); // Vytvorenie objektu Date reprezentujúceho aktuálny čas var r = new RegExp ("js"); // Vytvorenie objektu RegExp pre operácie porovnávania vzorov

Okrem týchto vstavaných konštruktorov je možné definovať vlastné funkcie konštruktorov na inicializáciu novovytvorených objektov. Ako sa to robí, je popísané v nasledujúcom článku.

Object.create ()

Štandard ECMAScript 5 definuje metódu Object.create (), ktorá vytvorí nový objekt a použije svoj prvý argument ako prototyp pre tento objekt. Okrem toho Object.create () môže mať druhý voliteľný argument popisujúci vlastnosti nového objektu.

Object.create () je statická funkcia, nie metóda volaná relatívne k nejakému konkrétnemu objektu. Ak chcete zavolať túto funkciu, stačí jej odovzdať požadovaný objekt prototypu:

// obj zdedí vlastnosti x a y var obj = Object.create ((x: 1, y: 2));

Ak chcete vytvoriť objekt, ktorý nemá prototyp, môžete zadať hodnotu null, ale v tomto prípade novovytvorený objekt nezdedí žiadne vlastnosti ani základné metódy, ako napríklad toString () (čo znamená, že tento objekt nemožno použiť vo výrazoch s operátorom +):

// obj2 nededí ani vlastnosti, ani metódy var obj2 = Object.create (null);

Ak váš program potrebuje vytvoriť obyčajný prázdny objekt (ktorý je napríklad vrátený doslovným () alebo novým výrazom Object ()), zadajte Object.prototype ako prvý argument:

// obj3 je ako objekt vytvorený // pomocou () alebo nového objektu () var obj3 = Object.create (Object.prototype);

Schopnosť vytvárať nové objekty s ľubovoľnými prototypmi (inými slovami, schopnosť vytvárať „dedičov“ z akýchkoľvek objektov) je výkonný nástroj, ktorý je možné simulovať v ECMAScript 3 pomocou funkcie uvedenej v príklade nižšie:

// zdediť () vráti novovytvorený objekt, ktorý zdedí vlastnosti // prototypového objektu p. Používa funkciu ECMAScript 5 Object.create () //, ak je definovaná, inak sa použije starší trik. function inherit (p) (if (p == null) throw TypeError (); // p nemôže byť null, ak (Object.create) // Ak je definovaný Object.create () ... return Object.create (p ) ; // použite it.var t = typeof p; // V opačnom prípade zistite typ a skontrolujte, či (t! == "objekt" && t! == "funkcia") throw TypeError (); funkcia f () () ; // Definujte prázdny konštruktor. F.prototype = p; // Zapíšte do jeho prototypovej vlastnosti // odkaz na objekt p. Vráťte nové f (); // Použite f () na vytvorenie // " dedič" objektu p.)

Implementácia funkcie zdediť () bude dávať väčší zmysel, keď sa v ďalšom článku zoznámime s konštruktormi. Zatiaľ predpokladajme, že vracia nový objekt, ktorý zdedí vlastnosti objektu v argumente. Všimnite si, že funkcia zdediť () nie je úplnou náhradou za Object.create (): neumožňuje vytváranie objektov bez prototypu a neprijíma voliteľný druhý argument ako Object.create ().

Získavanie a zmena vlastností

Hodnotu vlastnosti môžete získať pomocou operátorov bodka (.) a hranatých zátvoriek (). Naľavo od operátora musí byť výraz, ktorý vracia objekt. Pri použití bodkového operátora musí byť napravo jednoduchý identifikátor, ktorý sa zhoduje s názvom vlastnosti. Pri použití hranatých zátvoriek musí byť v hranatých zátvorkách uvedený výraz, ktorý vráti reťazec obsahujúci názov požadovanej vlastnosti:

// Jednoduchý objekt var user = (login: "kot86", meno: "Alexandr", vek: 26); var login = user.login; // Získanie vlastnosti "login" objektu používateľa var name = user.name; // Získanie vlastnosti "name" objektu používateľa var age = user ["vek"]; // Získanie vlastnosti "vek" objektu používateľa

Na vytvorenie novej vlastnosti alebo zmenu hodnoty existujúcej vlastnosti sa tiež používajú operátory bodka a hranaté zátvorky, ako pri operáciách na čítanie hodnôt vlastností, ale samotný výraz je umiestnený naľavo od operátora priradenia:

User.age = 28; // Zmeňte hodnotu vlastnosti "vek" user ["login"] = "kot84"; // Zmeňte hodnotu vlastnosti "login" user ["priezvisko"] = "Frolov"; // Vytvorenie novej vlastnosti "priezvisko"

V ECMAScript 3 nemôže byť identifikátor za bodkou vyhradené slovo: nemôžete napísať volanie vlastnosti o.for alebo o.class, pretože for je kľúčové slovo a class je slovo vyhradené na budúce použitie.

Ak má objekt vlastnosti, ktorých názvy sa zhodujú s vyhradenými slovami, na prístup k nim musíte použiť zápis v hranatých zátvorkách: o ["pre"] a o ["trieda"]. ECMAScript 5 túto požiadavku zmierňuje (ako to už urobili niektoré implementácie ECMAScript 3) a umožňuje použitie rezervovaných slov za bodkovým operátorom.

Prototypy

Každý objekt v JavaScripte má priradený druhý objekt (alebo nulový, ale oveľa menej často). Tento druhý objekt sa nazýva prototyp a prvý objekt zdedí od prototypu jeho vlastnosti.

Všetky objekty vytvorené pomocou objektových literálov majú rovnaký prototypový objekt, na ktorý možno odkazovať v programe JavaScript, ako je Object.prototype.

Objekty vytvorené pomocou kľúčového slova new a volania konštruktora preberajú hodnotu vlastnosti prototypu funkcie konštruktora ako svoj prototyp. Preto objekt vytvorený výrazom new Object () zdedí vlastnosti objektu Object.prototype, ako keby bol vytvorený pomocou literálu v zložených zátvorkách (). Podobne prototyp objektu vytvoreného novým výrazom Array () je Array.prototype a prototyp objektu vytvoreného novým výrazom Date () je Date.prototype.

Object.prototype je jeden z mála objektov, ktorý nemá prototyp: nemá žiadne zdedené vlastnosti. Ostatné prototypové objekty sú najbežnejšie objekty, ktoré majú svoje vlastné prototypy.

Všetky vstavané konštruktory (a väčšina vlastných konštruktérov) dedia z prototypu Object.prototype. Napríklad Date.prototype dedí vlastnosti z Object.prototype, takže objekt Date vytvorený novým Date () dedí vlastnosti z Date.prototype aj Object.prototype. Táto súvisiaca sekvencia prototypových objektov sa nazýva prototypový reťazec.

Dedičnosť

Objekty v JavaScripte majú mnoho "vlastných vlastností" a môžu tiež zdediť mnoho vlastností z prototypového objektu. Aby ste to pochopili, musíte si pozorne preštudovať mechanizmus prístupu k vlastnostiam. Príklady v tejto časti používajú funkciu zdediť () uvedenú vyššie na vytvorenie objektov so špecifickými prototypmi.

Predpokladajme, že váš program pristupuje k vlastnosti x obj. Ak objekt obj nemá vlastnú vlastnosť s týmto názvom, vykoná sa pokus nájsť vlastnosť x v prototype objektu obj. Ak objekt prototypu nemá vlastnú vlastnosť s týmto názvom, ale má svoj vlastný prototyp, vykoná sa pokus o lokalizáciu vlastnosti v prototype prototypu. Toto pokračuje, kým sa nenájde vlastnosť x alebo kým sa nedosiahne objekt bez prototypu. Ako vidíte, atribút prototypu objektu vytvára reťazec alebo prepojený zoznam objektov, z ktorých sa dedia vlastnosti.

Var obj = (); // obj zdedí metódy Object.prototype obj.x = 1; // a má vlastnú vlastnosť x. var p = zdediť (obj); // p zdedí vlastnosti z obj a Object.prototype p.y = 2; // a má vlastnú vlastnosť y. var q = zdediť (p); // q zdedí vlastnosti z p, obj a Object.prototype q.z = 3; // a má vlastnú vlastnosť z. var s = q.toString (); // toString dedí z Object.prototype var d = q.x + q.y // Výsledok 3: x a y dedí z obj a p

Teraz predpokladajme, že program priraďuje nejakú hodnotu vlastnosti x objektu obj. Ak obj už má vlastnú vlastnosť (nie zdedenú) s názvom x, potom operácia priradenia jednoducho zmení hodnotu existujúcej vlastnosti. V opačnom prípade sa v obj vytvorí nová vlastnosť s názvom x. Ak obj predtým zdedil vlastnosť x, zdedená vlastnosť je teraz skrytá novovytvorenou vlastnosťou s rovnakým názvom.

Priradenie k vlastnosti skontroluje prítomnosť tejto vlastnosti v reťazci prototypov, aby sa zaistilo, že priradenie je platné. Napríklad, ak obj zdedí vlastnosť x len na čítanie, priradenie zlyhá. Ak je však priradenie platné, vlastnosť sa vždy vytvorí alebo upraví na pôvodnom objekte a nikdy nie na reťazci prototypu. Skutočnosť, že mechanizmus dedenia funguje pri čítaní vlastností, ale nefunguje pri zápise nových hodnôt, je kľúčovou vlastnosťou jazyka JavaScript, pretože vám umožňuje selektívne prepísať zdedené vlastnosti:

Var unitcircle = (r: 1); // Objekt, z ktorého je vlastnosť zdedená var c = inherit (unitcircle); // c zdedí vlastnosť r c.x = 1; c.y = 1; // c definuje dve vlastné vlastnosti c.r = 2; // c prepíše zdedenú vlastnosť console.log (unitcircle.r); // => 1: objekt prototypu sa nezmenil

Existuje jedna výnimka z tohto pravidla, keď operácia priradenia vlastnosti zlyhá alebo má za následok vytvorenie / úpravu vlastnosti na pôvodnom objekte. Ak objekt obj zdedí vlastnosť x a k tejto vlastnosti sa pristupuje prostredníctvom metód prístupového objektu, potom sa namiesto vytvorenia novej vlastnosti x v objekte obj zavolá metóda na zápis novej hodnoty. Všimnite si však, že zapisovač sa volá relatívne k obj a nie relatívne k prototypu, kde je vlastnosť definovaná, takže ak zapisovač definuje nejaké vlastnosti, vytvoria sa v obj a reťazec prototypu zostane opäť nezmenený.

Chyby prístupu k vlastnostiam

Výrazy prístupu k vlastnostiam nie vždy vrátia alebo nemenia hodnotu vlastnosti. Táto časť popisuje situácie, v ktorých zlyhajú operácie čítania alebo zápisu na vlastnosti.

Pokus o prístup k vlastnosti, ktorá neexistuje, sa nepovažuje za chybu. Ak sa vlastnosť x nenájde medzi vlastnými alebo zdedenými vlastnosťami obj, výraz volania pre obj.x vráti nedefinované.

Pokúšanie sa o prístup k vlastnosti neexistujúceho objektu sa však považuje za chybu. Hodnoty null a undefined nemajú žiadne vlastnosti a pokusy o prístup k vlastnostiam týchto hodnôt sa považujú za chybu:

// Jednoduchý objekt var user = (login: "kot86", meno: "Alexandr", vek: 26); var a = user.password; // undefined: no property // Vyvolá TypeError. // undefined nemá žiadnu vlastnosť length var len = user.password.length;

Ak si nie ste istí, že user a user.password sú objekty (alebo sa správajú ako objekty), nemôžete použiť výraz user.password.length, pretože by to mohlo spôsobiť výnimku. Nižšie sú uvedené dva spôsoby obrany proti tomuto druhu výnimky:

// Vizuálnejší a priamočiarejší spôsob var len = undefined; if (user) (if (user.password) len = user.password.length;) // Kratšia alternatíva špecifickejšia pre JavaScript // ​​na získanie dĺžky vlastnosti hesla var len = user && user.password && user.password.length ;

Pokusy nastaviť hodnotu vlastnosti na iné hodnoty nie sú vždy úspešné: niektoré vlastnosti sú len na čítanie a neumožňujú meniť ich hodnoty. Niektoré objekty navyše neumožňujú pridávať k nim nové vlastnosti. Najzaujímavejšie však je, že takéto zlyhania spravidla nevedú k udeleniu výnimky:

// Vlastnosti prototypu vstavaných konštruktorov sú určené len na čítanie Object.prototype = 0; // Priradenie nebude vyvolávať výnimky; // Hodnota Object.prototype sa nezmení

Táto historická chyba JavaScriptu bola opravená v prísnom režime, ako je definované štandardom ECMAScript 5. Akýkoľvek neúspešný pokus o zmenu hodnoty vlastnosti v prísnom režime bude mať za následok chybu typu.

Pravidlá na určenie, kedy bude pokus o vykonanie operácie priradenia úspešný a kedy zlyhá, sú jednoduché a priamočiare, no ťažko sa dajú vyjadriť dostatočne stručnou formou. Pokus o priradenie hodnoty vlastnosti p objektu obj zlyhá v nasledujúcich prípadoch:

    Obj má svoju vlastnú vlastnosť len na čítanie p: nemôžete zmeniť hodnotu vlastnosti len na čítanie. (Všimnite si však metódu defineProperty (), ktorá predstavuje výnimku umožňujúcu zmenu vlastných hodnôt vlastností iba na čítanie.)

    Obj má zdedenú vlastnosť len na čítanie p: zdedené vlastnosti len na čítanie nemožno prepísať vašimi vlastnými vlastnosťami s rovnakým názvom.

    Obj nemá vlastnú vlastnosť p; obj nededí vlastnosť p s prístupovými objektmi a rozšíriteľný atribút obj je nepravdivý. Ak vlastnosť p v obj neexistuje a nie je pre ňu definovaná žiadna metóda zápisu, operácia priradenia sa pokúsi pridať vlastnosť p do obj. Ale keďže objekt obj nie je rozšíriteľný, pokus o pridanie novej vlastnosti k nemu zlyhá.

Odstránenie vlastností

Operátor vymazať odstráni vlastnosť z objektu. Jeho jediným operandom musí byť výraz prístupu k vlastnosti. Môže sa to zdať prekvapujúce, ale operátor vymazania nemá žiadny vplyv na hodnotu vlastnosti – pôsobí na samotnú vlastnosť:

// Jednoduchý objekt var user = (login: "kot86", meno: "Alexandr", vek: 26); delete user.login; // Objekt používateľa teraz nemá prihlasovaciu vlastnosť delete user ["meno"]; // Teraz objekt používateľa nemá vlastnosť názvu

Operátor vymazania vymaže iba svoje vlastné vlastnosti a neodstráni zdedené. (Ak chcete odstrániť zdedenú vlastnosť, musíte ju odstrániť v prototypovom objekte, v ktorom je definovaná. Táto operácia ovplyvní všetky objekty, ktoré zdedia daný prototyp.)

Výraz delete vráti hodnotu true, ak bola vlastnosť úspešne vymazaná, alebo keď operácia vymazania nezmenila objekt (napríklad pri pokuse o vymazanie neexistujúcej vlastnosti). Výraz delete tiež vráti hodnotu true, keď sa tomuto operátoru odovzdá výraz, ktorý nie je výrazom prístupu k vlastnosti:

Obj = (x: 1); // obj má vlastnú vlastnosť x a zdedí toString delete obj.x; // Vymaže x a vráti true delete obj.x; // Neurobí nič (x neexistuje) a vráti true delete obj.toString; // Neurobí nič (toString nie je jeho vlastná vlastnosť) a vráti true delete 1; // Nezmyselné, ale vráti sa pravda

Operátor vymazania nevymaže neprispôsobiteľné vlastnosti, atribút konfigurovateľnéčo je nepravdivé. (Môže však odstrániť užívateľské vlastnosti nerozšíriteľných objektov.) Neprispôsobiteľné vlastnosti sú vstavané vlastnosti objektu, ako aj globálne vlastnosti objektu vytvorené pomocou príkazov deklarácie premenných a funkcií. Pokus o odstránenie neprispôsobiteľnej vlastnosti v prísnom režime vyvolá výnimku TypeError. V neprísnom režime (a v implementáciách ECMAScript 3) operátor vymazania v takýchto prípadoch jednoducho vráti hodnotu false:

Delete Object.prototype; // Nedá sa odstrániť - nekonfigurovateľná vlastnosť var x = 1; // Deklarovanie globálnej premennej delete this.x; // Túto vlastnosť nemožno vymazať function f () () // Deklarovanie globálnej funkcie delete this.f; // Táto vlastnosť sa tiež nedá odstrániť

Kontrola existencie vlastností

Objekty v JavaScripte možno považovať za množiny vlastností a často je užitočné mať možnosť skontrolovať, či patria do množiny – na kontrolu vlastnosti s daným názvom v objekte. Takúto kontrolu môžete vykonať pomocou operátora v pomocou metód hasOwnProperty () a propertyIsEnumerable () alebo jednoducho odkazom na nehnuteľnosť.

Operátor in vyžaduje, aby mu bol v ľavom operande odovzdaný názov vlastnosti (ako reťazec) a v pravom operande objekt. Vráti hodnotu true, ak má objekt svoju vlastnú alebo zdedenú vlastnosť s týmto názvom:

Var obj = (x: 1) "x" v obj; // true: obj má vlastnú vlastnosť "x" "y" v obj; // false: obj nemá v obj vlastnosť "y" "toString"; // true: obj zdedí vlastnosť toString

Metóda hasOwnProperty () objektu kontroluje, či má objekt svoju vlastnú vlastnosť so zadaným názvom. Pre zdedené vlastnosti vráti false:

Var obj = (x: 1) obj.hasOwnProperty ("x"); // true: obj má svoju vlastnú vlastnosť "x" obj.hasOwnProperty ("y"); // false: obj nemá vlastnosť "y" obj.hasOwnProperty ("toString"); // false: toString je zdedená vlastnosť

Metóda propertyIsEnumerable () ukladá ďalšie obmedzenia v porovnaní s metódou hasOwnProperty (). Vráti hodnotu true, iba ak je špecifikovaná vlastnosť natívnou vlastnosťou, ktorej atribút enumerable je pravdivý. Vlastnosti vstavaných objektov nie sú spočítateľné. Vlastnosti generované bežným JavaScriptovým programom sú spočítateľné, pokiaľ nebola použitá jedna z nižšie uvedených metód ECMAScript 5 na to, aby vlastnosti neboli spočítateľné.

Často namiesto operátora in stačí použiť jednoduchý výraz prístupu k vlastnostiam a použiť operátor! == na testovanie nerovnosti s nedefinovanou hodnotou:

Var obj = (x: 1) obj.x! == nedefinované; // true: obj má vlastnosť "x" obj.y! == undefined; // false: obj nemá žiadnu vlastnosť "y" obj.toString! == undefined; // true: obj zdedí vlastnosť toString

Operátor in však rozlišuje situácie, ktoré sú nerozoznateľné pri použití vyššie uvedeného triku na volanie majetku. Operátor in rozlišuje neprítomnosť vlastnosti od vlastnosti, ktorá nie je definovaná.

Vyčíslenie vlastností

Namiesto kontroly jednotlivých vlastností je niekedy potrebné prejsť všetky dostupné vlastnosti alebo získať zoznam všetkých vlastností objektu. Zvyčajne sa na to používa slučka for / in, ale štandard ECMAScript 5 poskytuje dve pohodlné alternatívy.

Príkaz for / in loop vykoná telo cyklu pre každú vymenovanú vlastnosť (vlastnú alebo zdedenú) špecifikovaného objektu, pričom priradí názov vlastnosti premennej cyklu. Vstavané metódy zdedené objektmi sú nespočítateľné a vlastnosti, ktoré pridáte k objektom pomocou vášho programu, sú spočítateľné (pokiaľ ste nepoužili funkcie opísané nižšie na to, aby boli vlastnosti nespočítateľné). Napríklad:

// Jednoduchý objekt s tromi vymenovanými vlastnosťami var user = (login: "kot86", meno: "Alexandr", vek: 26); user.propertyIsEnumerable ("toString"); // false, toString - vstavaná metóda pre (n v užívateľovi) console.log (n);

Niektoré knižnice pridávajú do objektu Object.prototype nové metódy (alebo iné vlastnosti), aby ich bolo možné dediť a sprístupniť všetkým objektom. Pred štandardom ECMAScript 5 však neexistoval spôsob, ako urobiť tieto dodatočné metódy nevyčísliteľnými, takže boli dostupné na výpočet v cykloch for / in. Ak chcete vyriešiť tento problém, možno budete musieť filtrovať vlastnosti vrátené slučkou for / in. Nižšie sú uvedené dva príklady implementácie tohto filtrovania:

For (n v používateľovi) (if (! User.hasOwnProperty (n)) pokračovať; console.log (n);) pre (n v používateľovi) (if (typ používateľa [n] === "funkcia") pokračovať; console.log (n);)

Okrem cyklu for / in ECMAScript 5 definuje dve funkcie, ktoré vymenúvajú názvy vlastností. Prvý, Object.keys (), vráti pole vlastných vymenovateľných názvov vlastností objektu.

Druhá funkcia ECMAScript 5 vykonávajúca enumeráciu vlastností je Object.getOwnPropertyNames ()... Funguje ako funkcia Object.keys (), ale vracia názvy všetkých natívnych vlastností zadaného objektu, nielen vymenovaných. Implementáciám ECMAScript 3 chýba schopnosť implementovať takúto funkčnosť, pretože ECMAScript 3 neposkytuje možnosť získať nespočítateľné vlastnosti objektov.

Metódy čítania a zápisu vlastností

Vyššie bolo povedané, že vlastnosť objektu má názov, hodnotu a množinu atribútov. V ECMAScript 5 môže byť hodnota prepísaná jednou alebo dvoma metódami známymi ako metódy čítať (získať) a záznamy (setter)... Vlastnosti, pre ktoré sú definované metódy čítania a zápisu, sa niekedy označujú ako vlastnosti s prístupovými metódami na ich odlíšenie od údajových vlastností, ktoré predstavujú jednoduchú hodnotu.

Keď sa program pokúša získať hodnotu vlastnosti pomocou prístupových metód, interpret zavolá metódu read (bez argumentov). Hodnota vrátená touto metódou sa stane hodnotou výrazu prístupu k vlastnosti. Keď sa program pokúša zapísať hodnotu do vlastnosti, interpret zavolá metódu zápisu a odovzdá jej hodnotu napravo od operátora priradenia. Táto metóda je zodpovedná za „nastavenie“ hodnoty nehnuteľnosti. Hodnota vrátená metódou write sa ignoruje.

Na rozdiel od údajových vlastností vlastnosti prístupového objektu nemajú zapisovateľný atribút. Ak má vlastnosť metódy čítania aj zápisu, ide o čítanie/zápis. Ak má vlastnosť metódu len na čítanie, je len na čítanie. A ak vlastnosť má iba metódu zápisu, je to len zápis (to nie je možné pre vlastnosti s údajmi) a pokusy o načítanie hodnoty takejto vlastnosti sa vždy vrátia nedefinované.

Najjednoduchší spôsob, ako definovať vlastnosť pomocou prístupových metód, je použiť rozšírenú syntax na definovanie literálov objektu:

Var obj = (// Normálna vlastnosť s údajmi data_prop: hodnota, // Vlastnosť s metódami prístupového objektu je definovaná ako pár funkcií get accessor_prop () (/ * telo funkcie * /), set accessor_prop (hodnota) (/ * telo funkcie * /));

Vlastnosti prístupového objektu sú definované ako jedna alebo dve funkcie, ktorých názvy sa zhodujú s názvom vlastnosti a nahrádzajú kľúčové slovo funkcie get a / alebo set.

Všimnite si, že na oddelenie názvu vlastnosti od funkcie, ktorá riadi prístup k vlastnostiam, nemusíte použiť dvojbodku, ale aj tak musíte použiť čiarku za telom funkcie, aby ste oddelili metódu od iných metód alebo vlastností údajov.

Ako príklad uvažujme nasledujúci objekt predstavujúci karteziánske súradnice bodu v rovine. Na reprezentáciu súradníc X a Y má obvyklé vlastnosti údajov, ako aj vlastnosti s metódami prístupu, ktoré vám umožňujú získať ekvivalentné polárne súradnice bodu:

Var p = (// x a y sú bežné vlastnosti čítania/zápisu x: 1.0, y: 1.0, // r je vlastnosť čítania/zápisu s dvomi prístupovými objektmi. // Nezabudnite pridať čiarky za prístup k metódam get r () (návrat Math.sqrt (this.x * this.x + this.y * this.y);), set r (newvalue) (var oldvalue = Math.sqrt (this.x * this.x + this.y * this.y); var ratio = nová hodnota / stará hodnota; this.x * = pomer; this.y * = pomer;), // theta je vlastnosť len na čítanie s jednou metódou čítania get theta () (návrat Math.atan2 (toto.y, toto.x);));

Všimnite si použitie kľúčového slova this v metódach čítania a zápisu vyššie. Interpret bude tieto funkcie volať ako metódy objektu, v ktorom sú definované, t.j. v tele funkcie to bude odkazovať na bodový objekt. To umožňuje metóde čítania vlastnosti r odkazovať na vlastnosti x a y, ako napríklad this.x a this.y.

Vlastnosti prístupového objektu sa dedia rovnakým spôsobom ako normálne vlastnosti údajov, takže objekt p definovaný vyššie možno použiť ako prototyp pre iné bodové objekty. Nové objekty môžu definovať svoje vlastné vlastnosti x a y a zdedia vlastnosti r a theta.

Atribúty objektu

Všetky objekty majú atribúty prototyp, class a rozšíriteľné. Všetky tieto atribúty sú popísané v podsekciách nižšie.

Atribút prototypu

Atribút prototypu objektu definuje objekt, z ktorého sa dedia vlastnosti. Je dôležité pochopiť, že keď sa vo vašom kóde vyskytne odkaz na prototyp, označuje bežnú vlastnosť objektu, nie atribút prototypu.

Atribút prototypu sa nastavuje pri vytváraní objektu. Pre objekty vytvorené pomocou literálov je prototypom Object.prototype. Prototyp objektu vytvorený pomocou operátora new je hodnotou vlastnosti prototypu konštruktora. A prototyp objektu vytvorený pomocou Object.create () sa stane prvým argumentom tejto funkcie (ktorá môže byť nulová).

Štandard ECMAScript 5 poskytuje možnosť definovať prototyp akéhokoľvek objektu, ak ho prenesiete do metódy Object.getPrototypeOf ()... V ECMAScript 3 neexistuje žiadna ekvivalentná funkcia, ale často môžete definovať prototyp objektu obj pomocou výrazu obj.constructor.prototype.

Objekty vytvorené pomocou operátora new zvyčajne zdedia vlastnosť konštruktér ktorý odkazuje na funkciu konštruktora použitú na vytvorenie objektu. A ako je uvedené vyššie, funkcie konštruktora majú vlastnosť prototypu, ktorá definuje prototyp objektov vytvorených pomocou tohto konštruktora.

Všimnite si, že objekty vytvorené pomocou objektových literálov alebo Object.create () dostávajú vlastnosť konštruktora, ktorá odkazuje na konštruktor Object (). Constructor.prototype teda odkazuje na skutočný prototyp pre objektové literály, ale to zvyčajne neplatí pre objekty vytvorené volaním Object.create ().

Ak chcete zistiť, či je jeden objekt prototypom (alebo článkom v reťazci prototypov) iného objektu, použite metódu isPrototypeOf ()... Ak chcete zistiť, či p je prototypom obj, napíšte výraz p.isPrototypeOf (obj). Napríklad:

Var p = (x: 1); // Definujte objekt prototypu. var obj = Object.create (p); // Vytvorte objekt s týmto prototypom. p.isPrototypeOf (obj); // => true: obj dedí p Object.prototype.isPrototypeOf (p); // => true: p zdedí Object.prototype

Atribút triedy

Atribút triedy objektu je reťazec obsahujúci informácie o type objektu. Ani ECMAScript 3, ani ECMAScript 5 neposkytujú možnosť zmeniť tento atribút a poskytujú iba nepriame spôsoby určenia jeho hodnoty. Štandardne metóda toString () (zdedená z Object.prototype) vracia reťazec, ako je tento:

Preto na určenie triedy objektu môžete skúsiť zavolať metódu toString () tohto objektu a extrahovať podreťazec od ôsmeho po predposledný znak z výsledku. Trik je v tom, že mnohé metódy zdedia iné, užitočnejšie implementácie metódy toString () a aby ste zavolali správnu verziu metódy toString (), musíte vykonať nepriame volanie pomocou metódy Function.call ().

Nižšie uvedený príklad definuje funkciu, ktorá vracia triedu akéhokoľvek objektu, ktorý jej bol odovzdaný:

// Názov triedy objektu function classof (obj) (if (obj === null) return "Null"; if (obj === undefined) return "Undefined"; return Object.prototype.toString.call (obj) .slice (8, -1);)

Do tejto funkcie classof () môžete odovzdať akúkoľvek hodnotu JavaScriptu. Čísla, reťazce a booleany sa správajú ako objekty, keď sa na ne zavolá metóda toString () a hodnoty null a nedefinované hodnoty sa spracovávajú oddelene.

Rozšíriteľný atribút

Rozšíriteľný atribút objektu určuje, či možno objektu pridať nové vlastnosti. V ECMAScript 3 boli všetky vstavané a používateľom definované objekty implicitne rozšíriteľné a rozšíriteľnosť runtime objektov bola špecifická pre implementáciu. V ECMAScript 5 sú všetky vstavané a používateľom definované objekty rozšíriteľné, pokiaľ neboli skonvertované na nerozšíriteľné objekty a rozšíriteľnosť objektov runtime je stále špecifická pre implementáciu.

Štandard ECMAScript 5 definuje funkcie na získanie a zmenu atribútu rozšíriteľnosti objektu. Ak chcete zistiť, či je možné objekt rozšíriť, mali by ste ho odovzdať metóde Object.isExtensible ()... Aby bol objekt nerozšíriteľný, musíte ho odovzdať metóde Object.preventExtensions ()... Všimnite si, že akonáhle sa objekt stane nerozšíriteľným, nedá sa znova rozšíriť. Všimnite si tiež, že volanie preventExtensions () ovplyvňuje iba rozšíriteľnosť samotného objektu. Ak do prototypu nerozšíriteľného objektu pridáte nové vlastnosti, nerozšíriteľný objekt tieto nové vlastnosti zdedí.

Účelom rozšíriteľného atribútu je umožniť „fixáciu“ objektov v špecifickom stave, čím sa zabráni vykonaniu zmien. Atribút extensible object sa často používa v spojení s atribútmi konfigurovateľných a zapisovateľných vlastností, takže ECMAScript 5 definuje funkcie, ktoré uľahčia súčasné nastavenie týchto atribútov.

Metóda Object.seal () funguje ako metóda Object.preventExtensions (), ale nielenže robí objekt nerozšíriteľným, ale robí aj všetky vlastnosti tohto objektu nedostupnými pre prispôsobenie. To znamená, že do objektu nemožno pridať nové vlastnosti a existujúce vlastnosti nemožno odstrániť ani nakonfigurovať. Existujúce zapisovateľné vlastnosti sa však stále dajú zmeniť.

Po volaní Object.seal () sa objekt nemôže vrátiť do predchádzajúceho stavu. Ak chcete zistiť, či bola na objekte zavolaná metóda Object.seal (), môžete túto metódu zavolať Object.isSealed ().

Metóda Object.freeze () poskytuje ešte pevnejšiu fixáciu predmetov. Okrem toho, že objekt je nerozšíriteľný a jeho vlastnosti sa nedajú konfigurovať, sú všetky vlastnosti natívnych údajov iba na čítanie. (Toto neplatí pre vlastnosti objektu s metódami prístupového objektu, ktoré majú metódy zápisu; tieto metódy sa budú stále volať príkazmi priradenia.) Ak chcete zistiť, či bola volaná metóda Object.freeze () objektu, môžete zavolať Object.isFrozen ().

Je dôležité pochopiť, že Object.seal () a Object.freeze () ovplyvňujú iba objekt, ktorý im je odovzdaný: neovplyvňujú prototyp tohto objektu. Ak váš program potrebuje úplne odovzdať objekt, pravdepodobne budete musieť odovzdať aj objekty v reťazci prototypu.

Serializácia objektov

Serializácia objektov je proces konverzie objektov na reťazcovú reprezentáciu, ktorú možno neskôr použiť na ich obnovenie. ECMAScript 5 poskytuje vstavané funkcie na serializáciu a obnovu objektov JavaScript JSON.stringify () a JSON.parse ()... Tieto funkcie používajú formát výmeny údajov JSON. Názov JSON pochádza z „JavaScript Object Notation“ (JavaScript Object Notation) a syntax tohto zápisu je podobná syntaxi objektových literálov a polí v JavaScripte:

Var obj = (x: 1, y: (z :)); // Definovanie testovacieho objektu var s = JSON.stringify (obj); // s == "(" x ": 1," y ":(" z ":))" var p = JSON.parse (s); // p je kópia obj

Syntax formátu JSON je len podmnožinou syntaxe jazyka JavaScript a nemožno ju použiť na vyjadrenie všetkých možných hodnôt povolených v JavaScripte. Podporované a môžu byť serializované a rekonštruované: objekty, polia, reťazce, koncové číselné hodnoty, true, false a null. Hodnoty NaN, Infinity a -Infinity sú serializované na null. Objekty dátumu sú serializované do reťazcov dátumu ISO, ale JSON.parse () ich ponecháva v reťazcovom vyjadrení a neobnovuje pôvodné objekty Date.

Objekty Function, RegExp a Error a nedefinované hodnoty nie je možné serializovať ani opraviť. Funkcia JSON.stringify () serializuje iba vymenované natívne vlastnosti objektu. Ak hodnotu vlastnosti nemožno serializovať, vlastnosť sa jednoducho vylúči z reprezentácie reťazca. JSON.stringify () aj JSON.parse () majú voliteľný druhý argument, ktorý možno použiť na prispôsobenie procesu serializácie a/alebo obnovy, napríklad definovaním zoznamu vlastností, ktoré sa majú serializovať, alebo funkcie na prevod hodnôt ​v čase serializácie.

Posledná aktualizácia: 08.04.2018

Objektovo orientované programovanie je dnes jednou z dominantných paradigiem vo vývoji aplikácií a v JavaScripte vieme naplno využiť aj OOP. Objektovo orientované programovanie má zároveň určité zvláštnosti vo vzťahu k JavaScriptu.

Objekty

V predchádzajúcich témach sme pracovali s primitívnymi údajmi – číslami, reťazcami, no nie vždy údaje predstavujú primitívne typy. Napríklad, ak v našom programe potrebujeme opísať podstatu človeka, ktorý má meno, vek, pohlavie a podobne, tak prirodzene nedokážeme znázorniť podstatu človeka vo forme čísla, resp. reťazec. Potrebujeme niekoľko riadkov alebo čísel, aby sme osobu správne opísali. V tomto ohľade bude osoba pôsobiť ako zložitá komplexná štruktúra, ktorá bude mať samostatné vlastnosti - vek, výška, meno, priezvisko atď.

JavaScript používa objekty na prácu s takýmito štruktúrami. Každý objekt môže uchovávať vlastnosti, ktoré popisujú jeho stav a metódy, ktoré popisujú jeho správanie.

Vytvorenie nového objektu

Existuje niekoľko spôsobov, ako vytvoriť nový objekt.

Prvým spôsobom je použiť konštruktor Object:

Var user = nový objekt ();

V tomto prípade má objekt názov užívateľ. Je definovaná ako každá bežná premenná pomocou kľúčového slova var.

Nový výraz Object () predstavuje volanie konštruktora, funkcie, ktorá vytvára nový objekt. Operátor new sa používa na volanie konštruktora. Volanie konštruktora je vlastne ako volanie bežnej funkcie.

Druhým spôsobom vytvorenia objektu je použitie zložených zátvoriek:

Používateľ var = ();

Dnes je bežnejší druhý spôsob.

Vlastnosti objektu

Po vytvorení objektu v ňom môžeme definovať vlastnosti. Ak chcete definovať vlastnosť, za názvom objektu zadajte názov vlastnosti oddelený bodkou a priraďte mu hodnotu:

Používateľ var = (); user.name = "Tom"; user.age = 26;

V tomto prípade sú deklarované dve vlastnosti, meno a vek, ktorým sú priradené zodpovedajúce hodnoty. Potom môžeme použiť tieto vlastnosti, napríklad zobraziť ich hodnoty v konzole:

Console.log (používateľské meno); console.log (user.age);

Vlastnosti môžete definovať aj pri definovaní objektu:

Var user = (meno: "Tom", vek: 26);

V tomto prípade sa na priradenie hodnoty vlastnosti použije znak dvojbodka a za definíciou vlastnosti sa použije čiarka (namiesto bodkočiarky).

Okrem toho je k dispozícii skrátený spôsob definovania vlastností:

Názov var = "Tom"; var vek = 34; var user = (meno, vek); console.log (meno používateľa); // Tom console.log (user.age); // 34

V tomto prípade sú názvy premenných zároveň názvami vlastností objektu. A týmto spôsobom môžete vytvárať zložitejšie štruktúry:

Názov var = "Tom"; var vek = 34; var user = (meno, vek); var učiteľ = (používateľ, kurz: "JavaScript"); console.log (teacher.user); // (meno: "Tom", vek: 34) console.log (teacher.course); // JavaScript

Objektové metódy

Metódy objektu definujú jeho správanie alebo akcie, ktoré vykonáva. Metódy sú funkcie. Napríklad definujme metódu, ktorá zobrazí meno a vek osoby:

Používateľ var = (); user.name = "Tom"; user.age = 26; user.display = function () (console.log (user.name); console.log (user.age);); // zavolajte metódu user.display ();

Rovnako ako pri funkciách, metódy sú najprv definované a potom volané.

Metódy možno definovať aj priamo pri definovaní objektu:

Var user = (meno: "Tom", vek: 26, displej: function () (console.log (toto.meno); console.log (tento.vek);));

Rovnako ako pri vlastnostiach je metóde priradený odkaz na funkciu pomocou dvojbodky.

Ak chcete odkazovať na vlastnosti alebo metódy objektu v rámci tohto objektu, použite kľúčové slovo this. Znamená to odkaz na aktuálny objekt.

Môžete tiež použiť skrátený spôsob definovania metód, keď sa vynechá dvojbodka a slovo funkcia:

Var user = (meno: "Tom", vek: 26, displej () (console.log (this.name, this.age);), move (place) (console.log (this.name, "goes to" , miesto);)); user.display (); // Tom 26 user.move ("obchod"); // Tom ide do obchodu

Syntax poľa

Existuje aj alternatívny spôsob, ako definovať vlastnosti a metódy pomocou syntaxe poľa:

Používateľ var = (); užívateľ ["meno"] = "Tom"; používateľ ["vek"] = 26; užívateľ ["zobraziť"] = funkcia () (console.log (používateľ.meno); console.log (používateľ.vek);); // zavolajte metódu user ["display"] ();

Každá vlastnosť alebo názov metódy je uzavretá v úvodzovkách a hranatých zátvorkách a potom je tiež priradená hodnota. Napríklad používateľ ["vek"] = 26.

Pri odkazovaní na tieto vlastnosti a metódy môžete použiť buď bodkový zápis (user.name), alebo môžete použiť toto: user ["meno"]

Reťazce ako vlastnosti a metódy

Treba tiež poznamenať, že názvy vlastností a metód objektu sú vždy reťazce. To znamená, že by sme mohli prepísať predchádzajúcu definíciu objektu takto:

Var user = ("meno": "Tom", "vek": 26, "zobrazenie": function () (console.log (user.name); console.log (user.age);)); // zavolajte metódu user.display ();

Na jednej strane medzi týmito dvoma definíciami nie je žiadny rozdiel. Na druhej strane sú prípady, kedy omotávanie šnúrkou môže pomôcť. Ak sa napríklad názov vlastnosti skladá z dvoch slov oddelených medzerou:

Var user = (meno: "Tom", vek: 26, "celé meno": "Tom Johns", "zobraziť informácie": function () (console.log (user.name); console.log (user.age) ;)); console.log (používateľ ["celé meno"]); používateľ ["zobraziť informácie"] ();

Iba v tomto prípade, aby sme sa odvolávali na takéto vlastnosti a metódy, musíme použiť syntax polí.

Odstránenie vlastností

Vyššie sme videli, ako môžete dynamicky pridávať nové vlastnosti k objektu. Vlastnosti a metódy však môžeme vymazať aj pomocou operátora delete. A rovnako ako pri pridávaní, môžeme vlastnosti odoberať dvoma spôsobmi. Prvým spôsobom je použiť bodkovú notáciu:

Odstrániť objekt.vlastnosť

Alebo použite syntax poľa:

Odstrániť objekt ["vlastnosť"]

Napríklad odstránime vlastnosť:

Používateľ var = (); user.name = "Tom"; user.age = 26; user.display = function () (console.log (user.name); console.log (user.age);); console.log (meno používateľa); // Tom vymaže user.name; // zmazať vlastnosť // alternatívna možnosť // zmazať užívateľa ["meno"]; console.log (meno používateľa); // nedefinované

Po odstránení bude vlastnosť nedefinovaná, takže pri pokuse o prístup k nej program vráti hodnotu nedefinovaná.

Zdravím všetkých, ktorí čítajú túto publikáciu. Dnes vás chcem previesť kľúčovým jazykovým nástrojom – objektmi JavaScriptu. Dovoľte mi pripomenúť, že js je cross-browser a funguje vo všetkých operačných systémoch (windows, mac os atď.). Na rozdiel od objektovo orientovaných programovacích jazykov sa v js implementácia objektov výrazne líši od bežnej funkčnosti a variácií používania inštancií, napríklad v C #.

Preto sa po prečítaní aktuálneho článku naučíte hlavné rozlišovacie znaky skriptovaných objektov, naučíte sa ich vytvárať, aktualizovať a odstraňovať. Dotknem sa aj témy vlastností, metód a konštruktorov, poviem si o užitočných príkazoch a samozrejme niečo málo o dedičnosti. Myslím, že je čas začať sa učiť!

Čo je objekt v JavaScripte a aké funkcie má?

V js sú objekty jednoduché asociatívne polia (nazývané aj hash).

Čo je to asociatívne pole?

Ide o dátovú štruktúru, ktorá uchováva určité množstvo informácií týkajúcich sa a popisujúcich konkrétny prvok. Všetky údaje sú štruktúrované a prepojené ako "kľúč => hodnota".

Napríklad musíte opísať autá. Potom vytvoríte objekt avto a opíšete jeho charakteristiky v poli. Rozhodol som sa popísať značku auta (názov), jeho farbu (farbu) a cenu (cena). Nižšie prikladám implementačný kód pre opísanú úlohu.

1 2 3 4 5 var avto = (názov: "BMW 116i", farba: "čierna", cena: 588000);

var avto = (názov: "BMW 116i", farba: "čierna", cena: 588000);

Tu vidíte jeden zo spôsobov, ako vytvoriť objekt s názvom „avto“. Názov, farba a cena sú kľúče, ktoré sú dostupné počas písania aplikácie.

S týmto príkladom som predbehol, takže teraz si všetko pekne rozoberieme.

Existuje niekoľko spôsobov, ako vytvoriť objekt:

var avto = (); alebo var avto = nový objekt ();

V oboch prípadoch sa vytvorí prázdny objekt so známym názvom, ale prvá možnosť sa používa oveľa častejšie, pretože je kratšia a pohodlnejšie na písanie.

Všetko o vlastnostiach

Teraz musíme vyplniť prázdny objekt parametrami. Na to je potrebné pridať vlastnosti, ktoré som vyššie nazval aj kľúče. Opäť existujú dva spôsoby, ako deklarovať vlastnosti.

Chcem upozorniť, že JavaScript nemá striktný rámec na vytváranie a inicializáciu takýchto parametrov. V kóde sa môžu objaviť nové vlastnosti, rovnako ako ich možno vymazať a aktualizovať.

Môžete teda vytvoriť všetky kľúče naraz alebo ich deklarovať, keď budú k dispozícii. A aj keď sa v priebehu písania programu odvolávate na neexistujúce kľúče, nedôjde k žiadnej chybe. V tomto prípade sa vráti „nedefinované“.

Prvý spôsob.

Vytváranie a prístup k vlastnostiam prostredníctvom bodky. Ak chcete implementovať túto možnosť, musíte napísať názov objektu a potom mu priradiť názov kľúča cez bodku a potom priradiť nejakú hodnotu cez znamienko rovnosti:

avto.name = “BMW 116i”

Ale týmto spôsobom pridáte k existujúcim kľúčom ešte jeden prvok:

Táto metóda sa používa, keď je už známy názov vlastnosti a je potrebné vykonať určité akcie s hodnotami.

Druhý spôsob.

Nič sa nelíši od prvého, ak porovnáte ich účel. Táto metóda má však malú výhodu. Pre túto možnosť sa používajú hranaté zátvorky:

avto [“názov”] = “BMW 116i”

Príjemným doplnkom je možnosť vytvárať názvy vlastností vo forme ľubovoľného reťazca. Napríklad,

avto [“názov auta”] = “BMW 116i”

Práca s kľúčmi cez hranaté zátvorky sa používa vtedy, keď niektoré parametre zadáva používateľ a ukladá ich do premenných alebo keď nie sú vopred známe názvy vlastností. Používateľ sa napríklad pýta na cenu vybraného auta. Volaný prvok sa zapíše do premennej a ako odpoveď sa odovzdá cena:

var avto = (); avto.name = "BMW_116i"; avto.cena = 588000; var key = "cena"; // bola požadovaná cena auta alert (avto);

Teraz prejdime k odstraňovaniu vlastností. Všetko je tu veľmi jednoduché. Ak chcete odstrániť, použite príkaz vymazať... Ak teda do posledného príkladu nižšie pridáte nasledujúce 2 riadky:

zmazať avto.cena;

výstraha (avto);

Potom, keď sa výstraha vyvolá druhýkrát, dialógové okno sa vráti ako „nedefinované“.

Pár slov o kompaktnosti

V súčasnej fáze som vám povedal, ako vytvoriť objekt a opísať jeho vlastnosti. K tomu som pripojil testovacie prípady, ale tí najpozornejší z vás, milí čitatelia, si všimli, že prvý programový kód sa trochu líši od všetkých ostatných.

A to všetko preto, že používa kompaktnú reprezentáciu údajov. Toto je veľmi populárna metóda na deklarovanie kľúčov, pretože je kratšia na písanie a ľahšie sa vizuálne číta.

Pozrime sa na naše vlastnosti

V JavaScripte môžete rýchlo opakovať generované vlastnosti. Na tento účel bol poskytnutý špeciálny mechanizmus, lepšie známy ako cyklu.

Ak ste oboznámení s inými programovacími jazykmi, potom viete, že slučky sa najčastejšie vytvárajú pomocou slova pre, potom je v zátvorke napísaná podmienka pre vyčíslenie prvkov.

V js to vyzerá ako slučka pre každý z jazyka C #. Pozrite si celkový pohľad na štruktúru:

for (var obj v objekte) (// iterovať cez)

kde obj je zodpovedný za názov vymenovaných kľúčov,

objekt – pre svoje hodnoty.

A teraz je tu pre vás konkrétny príklad.

1 2 3 4 5 6 7 8 var avto = (názov: "BMW 116i", farba: "čierna", cena: 588000); pre (var obj v objekte) (upozornenie (obj + ":" + objekt))

var avto = (názov: "BMW 116i", farba: "čierna", cena: 588000); pre (var obj v objekte) (upozornenie (obj + ":" + objekt))

Je čas zoznámiť sa s metódami

Skriptovací jazyk zabezpečuje vytváranie metód. Ide o absolútne jednoduchý mechanizmus, pomocou ktorého môžete kedykoľvek pridať metódu alebo metódy k akémukoľvek objektu, ktoré rozšíria možnosti vytvorených asociatívnych polí. Nazývajú sa aj funkčné vlastnosti.

Samotný Js je do určitej miery veľmi dynamický a úžasný. Takto môžete vytvárať prvky rôznych typov. Pri učení tohto jazyka si nemusíte pamätať zložité konštrukcie, pretože mnohé reklamy sú si navzájom veľmi podobné.

Ak chcete vytvoriť metódu, musíte deklarovať objekt a potom začať písať príkaz, ktorý je presne ako vytváranie vlastností. Za „=“ sa však už nezapisuje hodnota, ale funkcia kľúčového slova (premenná). A potom, v zložených zátvorkách, je zoznam akcií.

Tu je implementácia tohto mechanizmu:

var avto = () avto.name = “BMV” avto.year = 1999 avto.drive = funkcia (k) (upozornenie (“Vozidlo prešlo” + n + “km”)) avto.drive (300) avto.drive ( 450)

Ako vidíte, tento príklad obsahuje vlastnosti a metódy, ktorých volania sú na začiatku identické.

Má JS aj konštruktérov?

Áno Pane! V tomto jazyku všetko, čo používa kľúčové slovo " Nový“, Automaticky sa stáva konštruktorom. Takže vyššie ste videli deklaráciu prázdneho objektu v tvare: avto = new Object () ;. Toto je konštruktér.

Pre prehľadnosť zvážte riadky nižšie.

var bob = nový objekt ();

bob.name = "Bob Smith";

To však nie je celý arzenál možností. V js si môžete vytvoriť svoje vlastné konštruktory a potom ich použiť na deklarovanie nových objektov.

Chcem teda „vyrobiť“ konštruktéra na mieru pre už pôvodné autá. Upozorňujeme, že názov musí byť napísaný veľkými písmenami. Toto je charakteristický znak funkcií. Na tento účel napíšem nasledujúcu implementáciu softvéru:

funkcia Avto (názov, cena) (

this.name = meno;

this.price = cena;

Teraz, keď vytvoríte neobmedzený počet objektov a použijete na ne tento konštruktor, všetky budú patriť do rovnakej triedy. Napríklad:

var car1 = nové Avto ("BMW", 650000);

var car2 = nové Avto ("Audi", 520000);

Okrem toho môžu byť metódy vytvorené vo vnútri konštruktora.

Vlastnosti dedičnosti v JavaScripte

Typicky je v mnohých jazykoch dedičnosť založená na triedach, ktoré môžu dediť jedna od druhej. Potom môžete počuť výrazy ako „trieda predkov“, „trieda dieťaťa“ atď.

V js je však všetko inak. Predmety sa tu dedia.

Celé dedičstvo je založené na internom odkaze medzi objektmi, ktorý je známy ako „prototyp“. Ak metóde priradíte „.prototype“ cez bodku a potom napíšete názov prototypu, potom všetky objekty vybranej metódy zdedia tento prototyp.

Prejdime k príkladu.

function Transport (name) (this.name = name this.canDrive = true) var transport = new Transport ("avto") // vytvoril dopravný objekt function Bike (name) (this.name = name) Bike.prototype = transport / / označujeme, že všetky nové objekty tejto triedy budú používať transport bike1 = new Bike ("for_sport") bike2 = new Bike ("for_child") console.log (bike1.name) console.log (bike2.name) console . log (bike1.canDrive)

V tomto bode asi končím. Povedal som vám o základných aspektoch skriptovacieho jazyka. To sú však len povrchné poznatky. Ďalej pôjdeme hlbšie. Medzitým sa nezabudnite pridať do radov mojich odberateľov a zdieľať odkaz na článok so svojimi priateľmi. Veľa štastia!

Čau Čau!

S pozdravom Roman Chueshov

Čítať: 97 krát

V tomto článku chcem čo najúplnejšie a najdôslednejšie hovoriť o tom, čo je objekt v JavaScripte, aké sú jeho schopnosti, aké vzťahy možno medzi objektmi vytvoriť a aké metódy „natívneho“ dedenia z toho vyplývajú, ako to všetko ovplyvňuje výkon a čo to všetko robí :)

Článok NEPOVEDÁ ani slovo o: emulácii tradičnej paradigmy triedneho objektu, syntaktického cukru, obalov a rámcov.

Náročnosť látky sa bude od začiatku do konca článku zvyšovať, takže pre profíkov sa môžu prvé časti zdať nudné a triviálne, no ďalej to bude oveľa zaujímavejšie :)

Objekty v JavaScripte

Mnoho článkov obsahuje frázu „V JavaScripte je všetko objekt“. Technicky to nie je úplne pravda, ale na nováčikov to robí ten správny dojem :)

V skutočnosti je veľa v jazyku objektom a dokonca aj to, čo objektom nie je, môže mať niektoré zo svojich schopností.

Je dôležité pochopiť, že slovo „objekt“ sa tu nepoužíva v zmysle „predmetu určitej triedy“. Objekt v JavaScripte je primárne len súbor vlastností (ak je to pre niekoho jednoduchšie, môžete to nazvať asociatívne pole alebo zoznam), ktoré pozostávajú z párov kľúč – hodnota. Okrem toho kľúčom môže byť iba reťazec (aj pre prvky poľa), ale hodnota môže byť ľubovoľný typ údajov uvedený nižšie.

V JavaScripte je ich teda 6 základné typyúdaje sú Nedefinované (neoznačuje žiadnu hodnotu), Null, Boolean (logická hodnota), String (reťazec), Číslo (číslo) a Objekt (objekt).
Navyše, prvých 5 je primitívny dátové typy, ale objekt nie je. Okrem toho možno bežne predpokladať, že typ objektu má „podtypy“: pole (Array), funkciu (Function), regulárny výraz (RegExp) a ďalšie.
Toto je trochu zjednodušený popis, ale v praxi zvyčajne postačuje.

Okrem toho sú primitívne typy String, Number a Boolean nejakým spôsobom spojené s neprimitívnymi "podtypmi" Object: String, Number a Boolean.
To znamená, že napríklad reťazec „Hello, world“ môže byť vytvorený ako primitívna hodnota, tak aj ako objekt typu String.
Stručne povedané, robí sa to tak, že programátor môže používať metódy a vlastnosti pri práci s primitívnymi hodnotami, ako keby to boli objekty. Viac o tom si môžete prečítať v príslušnej časti tohto článku.

Práca podľa referencie

Odkaz je prostriedok na prístup k objektu pod rôznymi názvami. Práca s akýmikoľvek predmetmi sa vykonáva výlučne pomocou odkazu.
Ukážme si to na príklade:
test = funkcia () (upozornenie („Ahoj!“)) // Vytvorte funkciu (upozornenie ("Ahoj!")) (A funkcia, ako si pamätáme, je plnohodnotný objekt) a urobte z testovacej premennej odkaz na ňu
test_link = test; // test_link teraz tiež odkazuje na našu funkciu
test (); // Ahoj!
test_link (); // Ahoj!


Ako vidíme, prvý aj druhý odkaz poskytujú rovnaký výsledok.
Je potrebné si uvedomiť, že nemáme žiadnu funkciu s názvom test a že testovacia premenná nie je nejaký „hlavný“ alebo „hlavný“ odkaz a „test_link“ je vedľajší odkaz.

Naša funkcia, ako každý iný objekt, je len oblasťou v pamäti a všetky odkazy na túto oblasť sú absolútne ekvivalentné. Okrem toho objekt nemusí mať vôbec žiadne referencie – v tomto prípade sa nazýva anonymný a môže byť použitý iba bezprostredne po vytvorení (napríklad odovzdaný funkcii), inak k nemu nebude možné pristupovať a čoskoro bude budú zničené garbage collectorom.(garbage collection), čo je to, čo vymaže objekty bez odkazov.

Pozrime sa, prečo je také dôležité pochopiť toto:

test = (podpora: "nejaký text") // Vytvorenie objektu s vlastnosťou prop
test_link = test; // Vytvorte ďalší odkaz na tento objekt

Upozornenie (test.prop); // nejaký text

// Zmena vlastnosti objektu
test_link.prop = "novýtext";

Upozornenie (test.prop); // nový text
upozornenie (test_link.prop); // nový text
/ * Dalo by sa povedať, že majetok sa sem-tam zmenil – ale nie je.
Objekt je jeden. Vlastnosť sa v ňom teda raz zmenila a odkazy stále ukazujú tam, kam smerujú. * /

// Pridajte novú vlastnosť a odstráňte starú
test.new_prop = "ahoj";
zmazať test.prop;

Upozornenie (test_link.prop); // undefined - táto vlastnosť už neexistuje
upozornenie (test_link.new_prop);

// Odstráňte odkaz
vymazať test;
upozornenie (test.new_prop);
/ * V tomto bode skript vyhodí chybu, pretože test už neexistuje a test.new_prop o to viac neexistuje * /
upozornenie (test_link.new_prop); // Ahoj
/ * ale tu je všetko v poriadku, pretože sme nezmazali samotný objekt, ale iba odkaz naň. Teraz na náš objekt ukazuje jeden odkaz test_link * /

// Vytvorenie nového objektu
test = test_link; // Najprv znova vytvorte testovací odkaz
test_link = (prop: "nejaký text") // A tu je nový objekt

Upozornenie (test_link.prop); // nejaký text
výstraha (test.prop); // nedefinované
/ * Vytvorenie nového objektu preruší prepojenie a teraz test a test_link ukazujú na rôzne objekty.
V skutočnosti sa to rovná odstráneniu odkazu test_link a jeho opätovnému vytvoreniu, ale už ukazuje na iný objekt * /
upozornenie (test.new_prop); // ahoj - teraz test obsahuje odkaz na náš úplne prvý objekt


* Tento zdrojový kód bol zvýraznený pomocou Zvýrazňovača zdrojového kódu.

Toto správanie objektov často vyvoláva veľa otázok pre začínajúcich vývojárov, takže dúfam, že tento text prinesie trochu jasnosti. Ak chceme vytvoriť skutočne novú, nezávislú kópiu objektu a nie odkaz, potom jediný spôsob, ako to urobiť, je vytvoriť nový objekt a skopírovať tam požadované vlastnosti.

Za zmienku stojí aj fakt, že práca s objektmi podľa referencií okrem vyššie spomenutých vtipných efektov poskytuje aj značnú úsporu pamäte, čo je dôležité, keď je jeden objekt hojne využívaný na rôznych miestach programu.

Primitívne hodnoty

Ako som spomenul vyššie, dátové typy String a Number môžu byť objekty aj primitívne hodnoty.
obj = nový reťazec ("ahoj"); // Vytvorenie reťazca ako objektu
jednoduché = "ahoj"; // Vytvorte primitívnu hodnotu

Upozornenie (obj); // Ahoj
výstraha (jednoduchá); // ahoj - zatiaľ je všetko predvídateľné

Upozornenie (dĺžka objektu); // 6 - objekt typu String má vlastnosť length, ktorá ukladá dĺžku reťazca
výstraha (jednoduchá.dĺžka); // 6
/ * Hoci simple nie je objekt, môžeme pristupovať k rovnakej množine vlastností ako objekt String. To je celkom praktické */

Obj.prop = "text";
simple.prop = "text";

Upozornenie (obj.prop); // text - kedze obj je obycajny objekt, tak mu kludne mozeme dat este jednu vlastnost
výstraha (jednoduchá.prop); // undefined - ale simple nie je objekt a toto číslo nám nebude fungovať

* Tento zdrojový kód bol zvýraznený pomocou Zvýrazňovača zdrojového kódu.


To isté platí pre Number aj Boolean (okrem toho, že nemajú vlastnosť dĺžky, ale existuje množstvo ďalších úžasných vlastností).
Používanie reťazcov a čísel ako objektov nemá praktický význam. primitívne hodnoty sú pohodlnejšie na prácu, ale zároveň si zachovávajú všetky potrebné funkcie. Pre úplnosť je však potrebné tento mechanizmus pochopiť.

Nezamieňajte si použitie primitívnych hodnôt s použitím literálov – napríklad bez ohľadu na to, či vytvoríme pole ako „test = nové pole ()“ alebo ako „test =“, výsledkom bude stále rovnaký objekt . Nedostaneme žiadne primitívne hodnoty.

Vytváranie a používanie objektov

Takže na rozdiel od jazykov, kde je implementovaná paradigma trieda-objekt, nemusíme najskôr vytvoriť triedu a potom vytvoriť objekt triedy. Okamžite môžeme vytvoriť objekt, čo urobíme v nasledujúcom príklade:
test = (
simple_property: "Dobrý deň",
vlastnosť_objektu: (
user_1: "Petya",
user_2: "Vasya"
},
vlastnosť_funkcie: funkcia (používateľ) (
alert (toto .simple_property + "," + toto .object_property);
}
}

Test.function_property ("user_1"); // Ahoj Peťo.

* Tento zdrojový kód bol zvýraznený pomocou Zvýrazňovača zdrojového kódu.


Pred nami je testovací objekt, ktorý má 3 vlastnosti, ktorých názvy, dúfam, hovoria samy za seba. Najviac nás na nej zaujíma vlastnosť function_property, ktorá obsahuje funkciu. Takúto funkciu možno nazvať metódou objektu.

Naša funkcia používa dvakrát kľúčové slovo this, čo je ukazovateľ (t. j. odkaz) na objekt, z ktorého sa funkcia volá. Teda this.simple_property = test.simple_property = "Ahoj" a this.object_property = test.object_property = "Peter".

Malo by byť jasné, že sa to vždy vzťahuje na objekt, z ktorého je funkcia volaná, a nie na objekt, ku ktorému patrí. Aj keď v tomto príklade ide o rovnaký objekt, nie je to vždy tak.

test.vlastnost_funkcie ("user_1"); // Ahoj Peťo.

Test2 = nový objekt (); // Iná forma vytvorenia nového objektu, podobná test2 = ()

Test.function_property.call (test2, "user_1"); //chyba
/ * Metóda volania vám umožňuje volať funkciu v mene iného objektu. V tomto prípade zavoláme metódu function_property testovaného objektu a tá už neukazuje na testovaný objekt, ale na objekt test2. A odvtedy nemá vlastnosť object_property, potom keď sa pokúsite získať this.object_property, skript zobrazí chybu * /

// skús napraviť situáciu
test2.simple_property = "Dobrý deň";
test2.vlastnosť_objektu = test.vlastnosť_objektu; // V tomto prípade použijeme špecifikovanie objektu odkazom, aby sa neduplikoval kód

Test.function_property.call (test2, "user_1"); // Pekný deň, Petya.


* Tento zdrojový kód bol zvýraznený pomocou Zvýrazňovača zdrojového kódu.

Z príkladu by tiež malo byť zrejmé, že neexistujú žiadne jasné kroky na vytvorenie a používanie objektu. Objekt je možné kedykoľvek akýmkoľvek spôsobom upraviť – pred, po a dokonca aj počas používania. To je tiež dôležitý rozdiel od „tradičného“ OOP.

Konštruktér

Vo vyššie uvedenom príklade sme vytvorili 2 objekty, ktoré majú určité podobnosti. Boli prítomné vlastnosti simple_property aj object_property. Je zrejmé, že pri písaní skutočného kódu často vzniká úloha vytvoriť identické alebo len podobné objekty. A samozrejme, nemusíme každý takýto objekt vytvárať ručne.

Na pomoc nám príde konštruktér. Konštruktor v JavaScripte nie je súčasťou triedy (pretože neexistujú žiadne triedy), ale iba samostatnou funkciou. Najbežnejšia funkcia.

make_me = funkcia (_name) (
výstraha ("Bol som spustený");
toto .meno = _meno;

}


/ * Pozrime sa, čo sa tu deje. Tlmočník vidí nového operátora a skontroluje, čo je napravo od neho. Pretože make_me je funkcia a možno ju použiť ako konštruktor, potom sa v pamäti vytvorí nový objekt a vykoná sa funkcia make_me, ktorá ukazuje na tento nový objekt. Ďalej sa k tomuto objektu pridá vlastnosť name, ktorej je priradená hodnota z argumentu _name, a metóda show_name. Tiež (neviem presne v akom momente, ale to je jedno) detská premenná začína ukazovať na náš nový, práve narodený objekt * /

Upozornenie (meno dieťaťa); //Vasya
dieťa.meno_zobrazenia (); //Vasya


dieťa2.názov_zobrazenia (); //Peter

Child2.show_name = funkcia () (upozornenie ( "Nepoviem svoje meno");} // Nezabudnite, že svoje objekty môžeme kedykoľvek zmeniť
dieťa2.názov_zobrazenia (); // Nepoviem svoje meno

Child.show_name (); // Vasya - deti sa navzájom nijako neovplyvňujú


* Tento zdrojový kód bol zvýraznený pomocou Zvýrazňovača zdrojového kódu.

Konštruktéra môžete tiež porovnať s otcom - porodí dieťa, obdaruje ho určitými vlastnosťami, ale hneď po stvorení sa dieťa stáva úplne nezávislým od rodiča a môže sa veľmi líšiť od svojich bratov.
Ak si pripomenieme popis dátových typov na začiatku článku, potom je jasné, že Object a jeho podtypy (Function, Array a iné) sú vlastne konštruktory, ktoré dávajú vytvorenému objektu možnosti funkcie, poľa atď.

Takže toto je oveľa lepšie. Teraz máme možnosť vytvárať objekty podľa určitého vzoru. Nie je však všetko v poriadku. Po prvé, každý objekt, ktorý vytvoríme, a všetky jeho vlastnosti a metódy majú v pamäti samostatné miesto, hoci sa v mnohých ohľadoch opakujú. Po druhé, čo ak chceme zachovať spojenie medzi rodičom a dieťaťom a byť schopní zmeniť všetky detské objekty naraz. Na pomoc nám príde prototyp.

Prototyp

Tak ako každé dieťa má otca a matku (aspoň biologicky), tak aj každý objekt v JavaScripte. A ak otec, ako sme sa rozhodli, pracuje ako dizajnér, tak matka je len prototyp. Pozrime sa, ako sa to stane:
make_me = funkcia (_name) (
výstraha ("Bol som spustený");
toto .meno = _meno;
toto .show_name = funkcia () (upozornenie (toto .meno);)
}
/*
Keď tlmočník vidí kľúčové slovo funkcie, skontroluje kód napravo od neho a odvtedy všetko je ok - vytvorí nový objekt v pamäti, čo je aj naša funkcia. Potom sa automaticky (bez účasti programátora) pre túto funkciu vytvorí vlastnosť prototypu, ktorá odkazuje na prázdny objekt. Ak by sme to urobili ručne, vyzeralo by to takto: make_me.prototype = new Object ();

Potom sa daný objekt (na ktorý ukazuje vlastnosť prototypu) automaticky pridá aj s vlastnosťou konštruktora smerujúcou späť na funkciu. Ukazuje sa, že ide o kruhový odkaz.

Teraz tento objekt, ktorý možno opísať ako (konštruktor: ... tu je odkaz na funkciu ...) - je prototypom funkcie.
*/

// Objekt je skutočne objekt
upozornenie (typeof make_me.prototype.constructor); // Funkcia je naša funkcia
alert (make_me.prototype.constructor === make_me); // pravda

// Pridajte novú metódu do prototypu funkcie make_me

Dieťa = new make_me ("Vasya"); // spustili ma
/ * Teraz, okrem všetkého opísaného v predchádzajúcom príklade, sa v podradenom objekte vytvorí ďalšia skrytá vlastnosť [], ktorá ukazuje na rovnaký objekt ako make_me.prototype. Pretože vlastnosť je skrytá, nemôžeme si jej hodnotu prezerať ani ju meniť - hrá však dôležitú úlohu pri ďalšej práci * /

Upozornenie (meno dieťaťa); //Vasya
dieťa.meno_zobrazenia (); //Vasya

Child.set_name ("Kolya");
/ * Najprv interpret hľadá metódu set_name na podradenom objekte. Keďže tam nie je, pokračuje v hľadaní dieťaťa. [] Majetok, nájde ho tam a spustí ho. * /
dieťa.meno_zobrazenia (); // Kolja - teraz sa Vasja volá Kolja :)

Make_me.prototype.show_name2 = funkcia () (upozornenie ("Ahoj," + tento .name;) //T.k. prototyp je obyčajný predmet, môžeme ho meniť aj za chodu

Child2 = new make_me ("Petya");
dieťa2.názov_zobrazenia2 (); // Ahoj Peťo
dieťa.meno_zobrazenia2 (); // Ahoj Kolja - zmeny v prototype sa týkajú nielen novovytvorených objektov, ale aj všetkých starých

Child2.show_name2 = funkcia () (upozornenie ( "Nepoviem svoje meno");} // Samotný objekt môžeme ešte zmeniť, pričom nová metóda show_name2 v tomto objekte (a iba v ňom) akoby „prepíše“ starú metódu z prototypu
dieťa2.názov_zobrazenia2 (); // Nepoviem svoje meno - pretože teraz máme vlastnú metódu show_name2, potom sa zavolá a v prototype sa nevyhľadá

Child.show_name2 (); // Dobrý deň, Kolja - všetko je stále tu

Make_me.prototype = (prop: "ahoj") // Skúsme znova vytvoriť prototyp

Upozornenie (child.prop); // nedefinované
dieťa.meno_zobrazenia2 (); //Ahoj Kolja
/ * Ak si pamätáte, čo je práca s odkazom, potom je všetko jasné. Opätovné vytvorenie prototypu preruší spojenie a teraz vlastnosť [] objektu child a child2 ukazuje na jeden objekt (ktorý bol prototypom funkcie make_me) a vlastnosť make_me.prototype na iný objekt, ktorý je novým prototyp funkcie make_me * /

Child3 = new make_me ("Oleg");
upozornenie (child3.prop); // ahoj - podľa očakávania


* Tento zdrojový kód bol zvýraznený pomocou Zvýrazňovača zdrojového kódu.

Ako vidno z príkladu, zatiaľ čo otec zostáva verný matke (t. j. zatiaľ čo prototyp funkcie zostáva rovnaký), všetky deti závisia od matky a sú citlivé na všetky jej zmeny. Len čo sa však rodičia rozvedú (dizajnér zmení prototyp za iný), deti sa hneď rozhádžu kto kam a už s nimi nie je žiadne spojenie.

Trochu o terminológii
Kým sa neporuší primárne spojenie medzi konštruktorom a prototypom, môžeme pozorovať nasledujúci obrázok:

make_me = funkcia (_name) (
výstraha ("Bol som spustený");
toto .meno = _meno;
toto .show_name = funkcia () (upozornenie (toto .meno);)
}

Make_me.prototype.set_name = function (_name) (toto .name = _name;)
dieťa = new make_me ("Vasya");

Upozornenie (typeof make_me.prototype); // objekt - funkcia má vlastnosť prototypu
výstraha (typ dieťaťa.prototyp); // undefined - vytvorený objekt NEMÁ ŽIADNU vlastnosť prototypu
upozornenie (child.constructor.prototype === make_me.prototype); // true - ale objekt má vlastnosť konštruktor, ktorá ukazuje na funkciu konštruktora make_me, ktorá má zase vlastnosť prototypu


* Tento zdrojový kód bol zvýraznený pomocou Zvýrazňovača zdrojového kódu.

Ako som si všimol po prečítaní mnohých fór na túto tému, hlavné problémy ľudia majú, keď si pomýlia prototypovú vlastnosť funkcie a skrytú vlastnosť [] objektu vytvoreného s touto funkciou.
Obe tieto vlastnosti sú odkazmi na rovnaký objekt (pokiaľ nie je prerušené primárne spojenie medzi prototypom a konštruktorom), no napriek tomu ide o odlišné vlastnosti s rôznymi názvami, jednu z nich má k dispozícii programátor a iný nie je.

Vždy je potrebné jasne pochopiť, že ak hovoríme o prototype konštruktora, tak toto je vždy vlastnosť prototypu a ak o prototype vytvoreného objektu, tak ide o skrytú vlastnosť [].

Dedičnosť

Teraz vieme, že každý objekt má skrytú referenciu prototypu a každý prototyp je bežný objekt.
Tí najvnímavejší čitatelia už zacítili vôňu rekurzie :)
Skutočne, odvtedy prototyp je obyčajný objekt, potom má zase prepojenie na svoj prototyp atď. Takto je implementovaná hierarchia prototypu.
vták = funkcia () () // Toto je konštruktér vtákov
bird.prototype.cry = funkcia () (upozornenie ("Cree!");) // Vták môže kričať
bird.prototype.fly = function () (upozornenie ("Letím!");) // a letieť

Kačica = funkcia () ()
kačica.prototyp = nový vták ();
duck.prototype.cry = funkcia () (upozornenie ("Kvakanie!");) // Kačica inak kričí
duck.prototype.constructor = kačica; // Vynúti nastavenie vlastnosti prototype.constructor na hodnotu duck, pretože inak sa bude vzťahovať na vtáka

Billy = nová kačica (); // Billy je naša kačica
billy.fly (); //Letím! - Billy vie lietať, pretože je vták
billy.cry (); //Kvakať! - Billy kričí kvákanie, pretože je kačica


* Tento zdrojový kód bol zvýraznený pomocou Zvýrazňovača zdrojového kódu.

Týmto spôsobom môžete implementovať hierarchiu akejkoľvek úrovne vnorenia.

Problém s hviezdičkou

Teraz, keď o tom všetkom vieme toľko, skúsme zistiť, koľko sa toho v týchto troch riadkoch deje.
make_me = funkcia () ()
dieťa = new make_me ();
upozornenie (child.toString ()); // výstupy

* Tento zdrojový kód bol zvýraznený pomocou Zvýrazňovača zdrojového kódu.

Na prvom riadku vytvoríme novú funkciu a premennú make_me, ktorá ukazuje na túto funkciu. Tým sa vytvorí prototyp funkcie make_me.prototype, ktorý obsahuje vlastnosť konštruktor smerujúcu na make_me.
Ale to nie je všetko :)
Pretože funkcia make_me je tiež objekt, potom to má zase otec a mama, t.j. konštruktér a prototyp. Jeho konštruktor je natívnou funkciou jazyka Function () a jeho prototypom je objekt obsahujúci metódy call, apply atď. - práve vďaka tomuto prototypu môžeme tieto metódy použiť v akejkoľvek funkcii. To dáva funkcii make_me vlastnosť [], ktorá ukazuje na Function.prototype.

Prototyp konštruktora Function je zase objekt, ktorého konštruktorom je (prekvapenie!) Object (tj Function.prototype. []. Konštruktor === Object) a prototypom je objekt obsahujúci štandardné vlastnosti a metódy objektu, ako napríklad toString, hasOwnProperty a iné (inými slovami - Function.prototype. [] ["hasOwnProperty"] - to je presne tá istá metóda, ktorú môžeme použiť vo všetkých odvodených objektoch - a to je presne tá vlastná metóda tohto objektu a nie zdedená). Takto zaujímavým spôsobom zistíme, že od Object sú odvodené všetky druhy objektov.

Môžeme pokračovať ďalej? Ukazuje sa, že nie. Object.prototype obsahuje základné vlastnosti objektu práve preto, že nemá vlastný prototyp. Object.prototype. [] = Null; V tomto bode sa cesta prototypovým reťazcom za účelom nájdenia vlastnosti alebo metódy zastaví.

Ďalšou zaujímavosťou je, že konštruktorom objektu je funkcia. Tie. Objekt. []. Konštruktor === Funkcia.
Existuje ďalší kruhový odkaz - konštruktor pre Object je Funkcia a konštruktor pre Function.prototype je Object.

Vráťme sa k nášmu príkladu. Už sme pochopili, ako sa funkcia vytvára, teraz prejdime k druhému riadku. Tam vytvoríme podriadený objekt, ktorého konštruktorom je funkcia make_me a prototypom je make_me.prototype.

No, v treťom riadku vidíme, ako tlmočník postupuje v reťazci, od dieťaťa k dieťaťu. [] (Aka make_me.prototype), potom k dieťaťu. []. [] (Aka Object.prototype), a už tam nájde metóda toString, ktorá sa spustí na vykonanie.

Nečistoty

Mohlo by sa zdať, že dedenie prostredníctvom prototypov je jediným možným spôsobom JavaScriptu. To nie je pravda.
Máme čo do činenia s veľmi flexibilným jazykom, ktorý neposkytuje ani tak pravidlá, ako možnosti.

Napríklad, ak chceme, nemôžeme vôbec používať prototypy, ale programovať pomocou konceptu mixinov. Na to nám prídu vhod naši starí dobrí priatelia – konštruktéri.

// Toto je ľudský konštruktér
muž = funkcia () (
toto .live = funkcia () (upozornenie ("žijem");) // Človek vie, ako žiť
táto .chôdza = funkcia () (upozornenie ("Idem");) // Človek môže chodiť
}

// Toto je básnikov konštruktér
básnik = funkcia () (
this .kill = function () (upozornenie ( "Básnik zabil človeka");} // Básnik môže zabiť človeka
toto .live = funkcia () (upozornenie („som mŕtvy“);) // To spôsobí smrť osoby
}

Vladimír = nový človek (); // Vladimír je muž
vladimir.live (); // Žijem - on žije
vladimir.walk (); // Chodím - on chodí

Poet.call (vladimir); // Spustite konštruktor básnika pre objekt vladimir
vladimir.kill (); // Básnik zabil muža
vladimir.live (); //Som mŕtvy

// A teraz zameranie
človek.hovor (vladimir);
vladimir.live (); //Žijem


* Tento zdrojový kód bol zvýraznený pomocou Zvýrazňovača zdrojového kódu.

Čo vidíme na tomto príklade? Po prvé, je to schopnosť dediť z viacerých objektov, ktoré nie sú v rovnakej hierarchii. V príklade sú 2 z nich, ale môže ich byť toľko, koľko chcete.
Po druhé, ide o absenciu akejkoľvek hierarchie. Prevažujúce vlastnosti a metódy sú určené výlučne poradím, v ktorom sú volané konštruktory.
Po tretie, ide o možnosť meniť objekt ešte dynamickejšie a ide o samostatný objekt, a nie o všetkých potomkov, ako pri zmene prototypu.

Aktualizované: Uzávierky a súkromné ​​nehnuteľnosti

Aby som nenafúkol tento už aj tak dosť veľký článok, dávam odkaz na príspevok Uzávierky v JavaScripte, kde sa o tom píše dosť podrobne.

Čo s tým všetkým teraz robiť

Ako som povedal vyššie, svojvoľná modifikácia jednotlivých objektov a použitie konštruktorov a mixinov a flexibilita prototypov sú len nástroje, príležitosti, ktoré umožňujú programátorovi vytvárať kód, ktorý je hrozný a zároveň krásny vo všetkých ohľadoch. Dôležité je len pochopiť, aké úlohy riešime, akými prostriedkami, aké ciele dosahujeme a akú cenu za to platíme.

Navyše, otázka ceny je dosť netriviálna, najmä ak hovoríme o vývoji pre verzie Internet Explorer 6 a 7.
1. Pamäť – tu je všetko jednoduché. Vo všetkých prehliadačoch zaberá dedenie na prototypoch niekoľkonásobne menej pamäte ako pri vytváraní metód pomocou konštruktérov. Navyše, čím viac metód a vlastností máme, tým väčší je rozdiel. Je však potrebné pripomenúť, že ak nemáme tisíc rovnakých objektov, ale iba jeden, spotreba pamäte bude v každom prípade malá, pretože tu je potrebné zvážiť ďalšie faktory.
2. Čas procesora - tu sú hlavné jemnosti spojené s prehliadačmi od spoločnosti Microsoft.
Na jednej strane objekty, kde sú metódy a vlastnosti vytvárané prostredníctvom konštruktora, môžu byť vytvárané mnohonásobne (v niektorých prípadoch desiatky či stokrát) pomalšie ako prostredníctvom prototypu. Čím viac metód, tým pomalšie. Ak vám teda IE počas inicializácie skriptu na pár sekúnd zamrzne – je dôvod rýpať týmto smerom.

Na druhej strane, vlastné metódy objektu (vytvorené pomocou konštruktora) sa môžu vykonávať o niečo rýchlejšie ako prototypové. Ak zúfalo potrebujete urýchliť vykonávanie metódy v tomto prehliadači, musíte to vziať do úvahy. Majte na pamäti, že zrýchlené je volanie metódy (t. j. jej hľadanie v objekte), a nie jej vykonávanie. Ak teda samotná metóda beží na sekundu, nevšimnete si zvláštne zvýšenie výkonu.

V iných prehliadačoch sú pozorované podobné problémy, kde je čas na vytváranie objektov a volanie ich metód približne rovnaký pre oba prístupy.

P.S. Zvyčajne v článkoch tohto druhu autor ponúka nejaký obal, buď sa snaží implementovať dedičnosť triednych objektov na základe prototypu, alebo len syntaktický cukor pre prototypové dedičstvo. Nerobím to zámerne, pretože Myslím si, že človek, ktorý rozumie zmyslu tohto článku, je schopný napísať si pre seba akýkoľvek obal a mnoho ďalších zaujímavých vecí :)

Štítky: Pridať štítky