Skapar dynamiskt JavaScript-objekt. Tar bort objektegenskaper


Hälsningar till alla som läser denna publikation... Idag vill jag leda dig genom ett viktigt språkverktyg - JavaScript-objekt. Låt mig påminna dig om att js är cross-browser och fungerar i alla operativsystem (windows, mac os, etc.). Till skillnad från objektorienterade programmeringsspråk, i js, skiljer sig implementeringen av objekt avsevärt från den vanliga funktionaliteten och variationerna av att använda instanser, till exempel i C #.

Därför, efter att ha läst den aktuella artikeln, kommer du att känna till de viktigaste utmärkande egenskaperna hos skriptobjekt, lära dig hur du skapar, uppdaterar och tar bort dem. Jag kommer också att beröra ämnet egenskaper, metoder och konstruktörer, jag ska prata om användbara kommandon och såklart lite om arv. Jag tycker att det är dags att börja lära sig!

Vad är ett objekt i JavaScript och vilka funktioner har det?

I js är objekt enkla associativa arrayer (även kallade hashes).

Vad är en associativ array?

Det är en datastruktur som lagrar en viss mängd information relaterad till och beskriver ett specifikt element. All data är strukturerad och länkad som "nyckel => värde".

Du behöver till exempel beskriva bilar. Sedan skapar du ett avto-objekt och beskriver dess egenskaper i en array. Jag bestämde mig för att beskriva bilens märke (namn), dess färg (färg) och kostnad (pris). Nedan har jag bifogat implementeringskoden för den beskrivna uppgiften.

1 2 3 4 5 var avto = (namn: "BMW 116i", färg: "svart", pris: 588 000);

var avto = (namn: "BMW 116i", färg: "svart", pris: 588 000);

Här ser du ett av sätten att skapa ett objekt som heter "avto". Namn, färg och pris är de nycklar som kan nås under ansökningsskrivning.

Med det här exemplet kom jag före mig själv, så nu ska vi analysera allt i ordning.

Det finns flera sätt att skapa ett objekt:

var avto = (); eller var avto = nytt objekt ();

I båda fallen skapas ett tomt objekt med känt namn, men det första alternativet används mycket oftare, eftersom det är kortare och bekvämare att skriva.

Allt om fastigheter

Nu måste vi fylla det tomma objektet med parametrar. För att göra detta måste du lägga till egenskaper, som jag också kallade ovanstående nycklar. Återigen finns det två sätt att deklarera egenskaper.

Jag vill påpeka att JavaScript inte har ett strikt ramverk för att skapa och initiera sådana parametrar. Nya egenskaper kan dyka upp i hela koden, precis som de kan tas bort och uppdateras.

Således kan du skapa alla nycklar på en gång eller deklarera dem när de blir tillgängliga. Och även om du, medan du skriver programmet, vänder dig till att inte befintliga nycklar, det blir inget fel. I det här fallet kommer "odefinierad" att returneras.

Det första sättet.

Skapa och komma åt egenskaper genom en punkt. För att implementera det här alternativet måste du skriva namnet på objektet och sedan tilldela nyckelns namn till det genom en punkt och sedan tilldela något värde genom likhetstecknet:

avto.name = "BMW 116i"

Men på detta sätt lägger du till ytterligare ett element till de befintliga nycklarna:

Denna metod används när namnet på egenskapen redan är känt och det är nödvändigt att utföra vissa åtgärder med värdena.

Andra sättet.

Inget annorlunda än det första om du jämför deras syfte. Men denna metod har liten fördel... För det här alternativet, använd hakparentes:

avto ["namn"] = "BMW 116i"

Ett trevligt tillägg är möjligheten att skapa egenskapsnamn i form av valfri sträng. Till exempel,

avto ["namn på bilen"] = "BMW 116i"

Att arbeta med nycklar inom hakparenteser används när vissa parametrar skrivs in av användaren och lagras i variabler eller när namnen på egenskaper inte är kända i förväg. Till exempel frågar användaren om kostnaden för den valda bilen. Elementet som anropades skrivs till variabeln och priset skickas som svar:

var avto = (); avto.name = "BMW_116i"; avto.price = 588000; var nyckel = "pris"; // bilens pris begärdes varning (avto);

Låt oss nu gå vidare till att ta bort egenskaper. Allt är väldigt enkelt här. För att radera, använd kommandot radera... Så om du lägger till följande två rader till det sista exemplet nedan:

ta bort avto.price;

alert (avto);

När sedan larmet anropas en andra gång kommer dialogen att returnera "odefinierat".

Några ord om kompakthet

I det aktuella skedet berättade jag hur man skapar ett objekt och beskriver dess egenskaper. Jag har bifogat testfall till detta, men de mest uppmärksamma av er, kära läsare, har märkt att den första programkod lite annorlunda än alla andra.

Och allt för att den använder en kompakt representation av data. Detta är en mycket populär metod för att deklarera nycklar eftersom den är kortare att skriva och lättare att läsa visuellt.

Låt oss iterera över våra fastigheter

I JavaScript kan du snabbt iterera över de genererade egenskaperna. För detta tillhandahölls en speciell mekanism, mer känd som cykel.

Om du är bekant med andra programmeringsspråk, då vet du att loopar oftast skapas med hjälp av ordet för, då skrivs inom parentes villkoret för att räkna upp element.

I js ser det ut som en loop för varje från språket C #. Kolla in den allmänna översikten av strukturen:

for (var obj i objekt) (// iterera över)

där obj är ansvarig för namnet på de uppräknade nycklarna,

objekt - för sina värderingar.

Och nu kommer här ett konkret exempel för dig.

1 2 3 4 5 6 7 8 var avto = (namn: "BMW 116i", färg: "svart", pris: 588 000); for (var obj i objekt) (varning (obj + ":" + objekt))

var avto = (namn: "BMW 116i", färg: "svart", pris: 588 000); for (var obj i objekt) (varning (obj + ":" + objekt))

Det är dags att bekanta sig med metoderna

Skriptspråket tillhandahåller skapandet av metoder. Detta är en absolut enkel mekanism genom vilken du när som helst kan lägga till en metod eller metoder till vilket objekt som helst som utökar kapaciteten för de skapade associativa arrayerna. De kallas även funktionsegenskaper.

Js i sig är väldigt dynamisk och fantastisk till viss del. Så här kan du skapa element av olika typer. När du lär dig detta språk behöver du inte memorera komplexa konstruktioner, eftersom många annonser är väldigt lika varandra.

Så för att skapa en metod måste du deklarera ett objekt och sedan börja skriva ett kommando som är precis som att skapa egenskaper. Men efter "=" är det inte längre värdet som skrivs, utan nyckelordsfunktionen (variabel). Och längre in lockiga hängslen uppräkningen av åtgärder pågår.

Här är implementeringen av denna mekanism:

var avto = () avto.name = “BMV” avto.year = 1999 avto.drive = funktion (k) (larm (”Fordon passerat” + n + “km.”)) avto.drive (300) avto.drive ( 450)

Som du kan se innehåller detta exempel egenskaper och metoder, vars anrop initialt är identiska.

Har JS också konstruktörer?

Ja sir! På det här språket, allt som använder sökordet " ny"Blir automatiskt en konstruktör. Så ovan såg du deklarationen av ett tomt objekt i formen: avto = nytt objekt () ;. Det här är konstruktören.

Överväg raderna nedan för tydlighetens skull.

var bob = nytt objekt ();

bob.name = "Bob Smith";

Detta är dock inte hela arsenalen av möjligheter. I js kan du skapa dina egna konstruktörer och sedan använda dem för att deklarera nya objekt.

Så jag vill "göra" en skräddarsydd konstruktör för redan inhemska bilar. Observera att namnet måste skrivas med stor bokstav... Detta är kännetecknet för funktioner. För att göra detta skriver jag följande mjukvaruimplementering:

funktion Avto (namn, pris) (

detta.namn = namn;

this.price = pris;

Nu, när du skapar ett obegränsat antal objekt och tillämpar denna konstruktor på dem, kommer de alla att tillhöra samma klass. Till exempel:

var car1 = new Avto ("BMW", 650000);

var car2 = new Avto ("Audi", 520000);

Dessutom kan metoder skapas inuti konstruktorn.

Funktioner för arv i JavaScript

Vanligtvis, på många språk, är arv baserat på klasser som kan ärva från varandra. Då kan man höra uttryck som "anfadersklass", "barnklass" osv.

Men i js är allt annorlunda. Objekt ärvs här.

Allt arv baseras på en intern referens mellan objekt, vilket är känt som "prototyp". Om du tilldelar ".prototype" till metoden genom en punkt och sedan skriver namnet på prototypen, kommer alla objekt i den valda metoden att ärva från denna prototyp.

Låt oss gå vidare till ett exempel.

function Transport (name) (this.name = name this.canDrive = true) var transport = new Transport ("avto") // skapade ett transportobjekt funktion Bike (name) (this.name = name) Bike.prototype = transport // vi anger att alla nya objekt i denna klass kommer att använda transportcykel1 = ny cykel ("för_sport") cykel2 = ny cykel ("för_barn") console.log (cykel1.namn) console.log (cykel2.namn) konsol . logg (bike1.canDrive)

Vid det här laget kommer jag förmodligen att sluta. Jag berättade om de grundläggande aspekterna skriptspråk... Detta är dock bara ytlig kunskap. Vidare kommer vi att gå djupare. Under tiden, glöm inte att gå med i mina prenumeranter och dela länken till artikeln med dina vänner. Lycka till!

Hejdå!

Med vänlig hälsning, Roman Chueshov

Läsa: 97 gånger

JavaScript är ett objektorienterat språk... Med undantag för grundläggande språkkonstruktioner som loopar och relationsoperationer, implementeras nästan alla JavaScript-funktioner på ett eller annat sätt med hjälp av objekt.

Objekt används ibland explicit för att utföra vissa uppgifter, som att bearbeta (X) HTML- och XML-baserade dokument. objektmodell dokumentera. I andra fall är objektens roll mindre uppenbar, till exempel String-objektets roll när man arbetar med primitiva strängdata.

Tidigare kapitel har redan gett exempel som tydligt visar användbarheten av inbyggda objekt, men i det här kapitlet kommer vi att börja utforska JavaScript-objekt direkt.

Objekt i JavaScript

Objekt i JavaScript kan delas in i fyra grupper.

  1. Anpassade objekt skapade av en programmerare och som har en struktur och enhet som motsvarar en specifik programmeringsuppgift. Vi kommer att diskutera möjligheterna att skapa och använda sådana objekt i detta kapitel.
  2. Inbyggda objekt erbjuds av JavaScript själv. Dessa inkluderar objekt associerade med datatyper (String, Number och Boolean), objekt som låter dig skapa anpassade objekt och sammansatta typer (Objekt och Array) och objekt som förenklar vanliga uppgifter (som Datum, Math och RegExp). Möjligheterna hos inbyggda objekt regleras av språkstandarden ECMA-262 och, i mindre utsträckning, av webbläsartillverkarnas specifikationer.
  3. Webbläsarobjekt som inte ingår i JavaScript-språk men stöds av de flesta webbläsare. Exempel på webbläsarobjekt är Window, ett objekt som styr webbläsarfönster och interagerar med användaren, och Navigator, ett objekt som tillhandahåller klientkonfigurationsinformation. Eftersom de flesta aspekter av webbläsarobjekt inte är standardiserade, kan deras egenskaper och beteende variera avsevärt från webbläsare till webbläsarversion. Objekt av denna typ kommer att diskuteras senare.
  4. Dokumentobjekt är en del av Document Object Model (DOM) som definieras av W3C. Sådana objekt ger programmeraren ett strukturerat gränssnitt för (X) HTML- och XML-dokument. Det är dessa objekt som gör det möjligt för JavaScript att manipulera kapslade formatmallar (CSS - Cascade Style Sheet) och förenkla implementeringen av dynamisk HTML (DHTML). Dokumentobjekt nås av webbläsaren via dokumentegenskapen för Window-objektet (window. Document). Vi kommer att prata mer om DOM senare.

Principer för att arbeta med objekt

Ett objektÄr en oordnad samling av data som inkluderar primitiva datatyper, funktioner och till och med andra objekt. Fördelen med objekt är att de samlar all data och logik som behövs för att utföra en specifik uppgift på ett ställe. String-objektet lagrar textdata och erbjuder många av de funktioner som behövs för att manipulera den. Även om objekt inte krävs i ett programmeringsspråk (det finns inga objekt i C, till exempel), gör de verkligen språket lättare att använda.

Objektskapande

Ett objekt skapas med hjälp av en konstruktor - en funktion av ett speciellt slag som förbereder ett nytt objekt för användning genom att initiera minnet som upptas av objektet. Vi såg i kapitel 4 att objekt kan skapas genom att tillämpa den nya operationen på deras konstruktörer. Denna operation får konstruktorn att skapa ett nytt objekt, vars natur bestäms av konstruktorn som anropas. Till exempel skapar String ()-konstruktorn String-objekt och Array ()-konstruktorn skapar Array-objekt. Så här definierar du objekttypsnamn i JavaScript: med namnet på konstruktorn som skapar objektet.
Här är ett enkelt exempel på att skapa ett objekt:

var stad = ny sträng ();

Denna sats skapar ett nytt String-objekt och placerar en referens till det i stadsvariabeln. Inga argument erbjuds till konstruktorn här, så stadsvariabeln får sitt standardvärde - in det här fallet det är en tom sträng. Du kan göra det här exemplet mer intressant genom att skicka ett initialvärdesargument till konstruktorn:

var city = new String ("San Diego");

I den här artikeln vill jag prata så fullständigt och konsekvent som möjligt om vad ett objekt är i JavaScript, vad dess kapacitet är, vilka relationer som kan byggas mellan objekt och vilka metoder för "native" arv som följer av detta, hur allt detta påverkar prestanda och vad gör allt :)

Artikeln kommer INTE att säga ett ord om: emulering av det traditionella klassobjektsparadigmet, syntaktisk socker, omslag och ramar.

Materialets komplexitet kommer att öka från början till slutet av artikeln, så för proffsen kan de första delarna verka tråkiga och triviala, men vidare kommer det att bli mycket mer intressant :)

Objekt i JavaScript

Många artiklar innehåller frasen "I JavaScript är allt ett objekt." Tekniskt sett är detta inte helt sant, men det gör rätt intryck på nybörjare :)

I själva verket är mycket i ett språk ett objekt, och även det som inte är ett objekt kan ha några av dess förmågor.

Det är viktigt att förstå att ordet "objekt" används här inte i betydelsen "ett objekt av en viss klass". Ett objekt i JavaScript är i första hand bara en samling egenskaper (om det är lättare för någon kan du kalla det en associativ array eller en lista), bestående av nyckel-värdepar. Dessutom kan nyckeln bara vara en sträng (även för arrayelement), men värdet kan vara vilken datatyp som helst som anges nedan.

Så det finns 6 i JavaScript grundläggande typer data är Odefinierad (betecknar inget värde), Null, Boolean (boolean), String (sträng), Number (nummer) och Objekt (objekt).
Dessutom är de första 5 primitiv datatyper, men Object är det inte. Dessutom kan vi villkorligt anta att objekttypen har "undertyper": en array (Array), en funktion (Function), vanligt uttryck(RegExp) och andra.
Detta är en något förenklad beskrivning, men i praktiken räcker det oftast.

Dessutom är de primitiva typerna String, Number och Boolean på något sätt associerade med de icke-primitiva "undertyperna" av Object: String, Number respektive Boolean.
Det betyder att strängen "Hello, world", till exempel, kan skapas som både ett primitivt värde och ett String-objekt.
Kort sagt, detta görs för att programmeraren ska kunna använda metoder och egenskaper när han arbetar med primitiva värden som om de vore objekt. Du kan läsa mer om detta i motsvarande avsnitt i denna artikel.

Arbeta med referens

En länk är ett sätt att komma åt ett objekt under olika namn... Arbete med alla föremål utförs uteslutande genom referens.
Låt oss visa detta med ett exempel:
testa = function () (varning ("Hej!")) // Skapa en funktion (varning ("Hej!")) (Och funktionen, som vi minns, är ett fullfjädrat objekt) och gör testvariabeln till en referens till den
test_länk = test; // test_link refererar nu även till vår funktion
test (); // Hej!
test_länk (); // Hej!


Som vi kan se ger både den första länken och den andra samma resultat.
Det är nödvändigt att inse att vi inte har någon funktion som heter test, och att testvariabeln inte är någon form av "huvud" eller "huvud" länk, och "test_link" är en mindre.

Vår funktion, precis som alla andra objekt, är bara ett område i minnet, och alla referenser till detta område är absolut likvärdiga. Dessutom kanske ett objekt inte har några referenser alls - i det här fallet kallas det anonymt och kan bara användas omedelbart efter skapandet (till exempel skickat till en funktion), annars kommer det att vara omöjligt att komma åt det och snart kommer att förstöras av garbage collector.(garbage collection), vilket är det som raderar objekt utan referenser.

Låt oss se varför det är så viktigt att förstå detta:

test = (prop: "någon text") // Skapa ett objekt med en prop-egenskap
test_länk = test; // Skapa ytterligare en länk till detta objekt

Alert (test.prop); // någon text

// Ändra egenskapen för objektet
test_link.prop = "nytext";

Alert (test.prop); // ny text
alert (testlänk.prop); // ny text
/ * Man kan säga att fastigheten har förändrats här och där - men det är det inte.
Objektet är ett. Så egenskapen har ändrats en gång i den, och länkarna fortsätter bara att peka dit de pekar. * /

// Lägg till en ny egenskap och ta bort den gamla
test.new_prop = "hej";
ta bort test.prop;

Alert (test_link.prop); // undefined - den här egenskapen finns inte längre
alert (testlänk.ny_prop);

// Ta bort länken
ta bort test;
alert (test.new_prop);
/ * Vid denna tidpunkt kommer skriptet att ge ett fel, eftersom testet inte längre existerar och test.new_prop inte existerar desto mer * /
alert (testlänk.ny_prop); // Hej
/ * men här är allt i sin ordning, eftersom vi har raderat inte själva objektet, utan bara en länk till det. Nu pekas vårt objekt på en enda länk test_link * /

// Skapa ett nytt objekt
test = test_länk; // Skapa först testlänken igen
test_link = (prop: "någon text") // Och här är det nya objektet

Alert (test_link.prop); // någon text
alert (test.prop); // odefinierat
/ * Att skapa ett nytt objekt bryter länken och nu pekar test och test_link till olika objekt.
I själva verket är detta detsamma som att ta bort test_länken och återskapa den, men redan peka på ett annat objekt * /
alert (test.new_prop); // hej - nu innehåller testet en länk till vårt allra första objekt


* Den här källkoden har markerats med Source Code Highlighter.

Detta beteende hos objekt väcker ofta många frågor för nybörjare, så jag hoppas att den här texten kommer att ge lite klarhet. Om vi ​​vill skapa en helt ny, oberoende kopia av objektet, och inte en länk, är det enda sättet att göra detta att skapa ett nytt objekt och kopiera de nödvändiga egenskaperna dit.

Det är också värt att notera att arbete med objekt genom referens, förutom de ovan nämnda roliga effekterna, också ger betydande minnesbesparingar, vilket är viktigt när ett objekt används flitigt på olika platser i programmet.

Primitiva värden

Som jag nämnde ovan kan datatyperna String och Number vara både objekt och primitiva värden.
obj = ny sträng ("hej"); // Skapa sträng som objekt
enkel = "hej"; // Skapa ett primitivt värde

Alert (obj); // Hej
alert (enkel); // hej - än så länge är allt förutsägbart

Alert (obj.längd); // 6 - ett objekt av typen String har en length-egenskap som lagrar längden på strängen
alert (enkel.längd); // 6
/ * Även om simple inte är ett objekt, kan vi komma åt samma uppsättning egenskaper som ett String-objekt. Det här är ganska praktiskt * /

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

Alert (obj.prop); // text - eftersom obj är ett vanligt objekt kan vi enkelt ge det en egenskap till
alert (enkel.prop); // undefined - men enkel är inte ett objekt, och detta nummer kommer inte att fungera för oss

* Den här källkoden har markerats med Source Code Highlighter.


Detsamma gäller för både Number- och Boolean-typerna (nåja, förutom det faktum att de inte har en length-egenskap, men det finns ett antal andra underbara egenskaper).
Att använda strängar och siffror som objekt är inte praktiskt användbart. primitiva värden är bekvämare att arbeta med, men behåller samtidigt all nödvändig funktionalitet. Men för fullständighetens skull är det nödvändigt att förstå denna mekanism.

Förväxla inte användningen av primitiva värden med användningen av bokstaver - till exempel, oavsett om vi skapar en array som "test = new Array ()" eller som "test =", kommer resultatet fortfarande att vara samma objekt . Vi kommer inte att få några primitiva värderingar.

Skapa och använda objekt

Så, till skillnad från språk där klass-objekt-paradigmet är implementerat, behöver vi inte skapa en klass först, för att skapa ett objekt av klassen senare. Vi kan omedelbart skapa ett objekt, vilket vi kommer att göra i följande exempel:
test = (
simple_property: "Hej",
objektegenskap: (
user_1: "Petya",
user_2: "Vasya"
},
function_property: function (användare) (
alert (denna .simple_property + "," + denna .object_property);
}
}

Test.function_property ("användare_1"); // Hej, Petya.

* Den här källkoden har markerats med Source Code Highlighter.


Före oss ligger testobjektet, som har 3 egenskaper, vars namn, hoppas jag, talar för sig själva. Det som intresserar oss mest med det är egenskapen function_property, som innehåller funktionen. En sådan funktion kan kallas en metod för ett objekt.

Vår funktion använder detta nyckelord två gånger, vilket är en pekare (dvs en referens) till objektet från vilket funktionen anropas. Således, this.simple_property = test.simple_property = "Hej", och this.object_property = test.object_property = "Peter".

Det bör tydligt förstås att detta alltid hänvisar till objektet från vilket funktionen anropas, och inte till objektet som den tillhör. Även om i detta exempel de är ett och samma objekt, så är det inte alltid.

test.function_property ("användare_1"); // Hej, Petya.

Test2 = nytt objekt (); // En annan form av att skapa ett nytt objekt, liknande test2 = ()

Test.function_property.call (test2, "användare_1"); //fel
/ * Anropsmetoden låter dig anropa en funktion på uppdrag av ett annat objekt. I det här fallet anropar vi funktion_egenskapsmetoden för testobjektet, och det här pekar inte på testobjektet, utan till objektet test2. Och sedan det finns ingen object_property-egenskap i den, då när du försöker få this.object_property kommer skriptet att ge ett fel * /

// försök att fixa situationen
test2.simple_property = "God dag";
test2.object_property = test.object_property; // I det här fallet kommer vi att använda indikationen av objektet genom referens för att inte duplicera koden

Test.function_property.call (test2, "användare_1"); // God dag, Petya.


* Den här källkoden har markerats med Source Code Highlighter.

Det bör också framgå av exemplet att det inte finns några tydliga steg för att skapa och använda ett objekt. Objektet kan modifieras på vilket sätt som helst när som helst - före, efter och även under användning. Det är det visst viktig skillnad från "traditionella" OOP.

Konstruktör

I exemplet ovan skapade vi 2 objekt som har vissa likheter. Både simple_property och object_property egenskaper fanns där. Uppenbarligen, när du skriver riktig kod, uppstår ofta uppgiften att skapa samma eller bara liknande objekt. Och naturligtvis behöver vi inte skapa alla sådana objekt manuellt.

En konstruktör kommer till vår hjälp. En konstruktor i JavaScript är inte en del av en klass (eftersom det inte finns några klasser), utan bara en funktion i sin egen rätt. Den vanligaste funktionen.

make_me = function (_name) (
alert ("Jag lanserades");
detta .namn = _namn;

}


/ * Låt oss se vad som händer här. Tolken ser den nya operatören och kontrollerar vad som finns till höger om den. Eftersom make_me är en funktion, och den kan användas som en konstruktor, sedan skapas ett nytt objekt i minnet och make_me-funktionen körs för exekvering, och detta pekar på detta nya objekt. Därefter läggs detta objekt till egenskapen name, som tilldelas värdet från argumentet _name, och metoden show_name. Dessutom (jag vet inte exakt i vilket ögonblick, men det spelar ingen roll) börjar den underordnade variabeln peka på vårt nya, nyfödda objekt * /

Varning (barn.namn); //Vasya
child.show_name (); //Vasya


child2.show_name (); //Peter

Child2.show_name = function () (varning ( "Jag säger inte mitt namn");} // Glöm inte att vi kan ändra våra objekt när som helst
child2.show_name (); // Jag kommer inte att säga mitt namn

Child.show_name (); // Vasya - barn påverkar inte varandra på något sätt


* Den här källkoden har markerats med Source Code Highlighter.

Du kan också jämföra konstruktören med en far - han föder ett barn och ger honom vissa egenskaper, men omedelbart efter skapandet blir barnet helt oberoende av föräldern och kan bli mycket annorlunda än sina bröder.
Om vi ​​minns beskrivningen av datatyper i början av artikeln, blir det tydligt att Object och dess undertyper (Function, Array och andra) faktiskt är konstruktörer som ger det skapade objektet kapaciteten hos en funktion, en array, etc.

Så det här är mycket bättre. Vi har nu möjlighet att skapa föremål enligt ett visst mönster. Men allt är inte bra. För det första tar varje objekt vi skapar och alla dess egenskaper och metoder en separat plats i minnet, även om de på många sätt upprepas. För det andra, tänk om vi vill behålla kopplingen mellan förälder och barn, och kunna ändra alla barnobjekt på en gång. En prototyp kommer att hjälpa oss.

Prototyp

Precis som varje barn har en far och mor (åtminstone i biologisk mening), så har alla objekt i JavaScript. Och om pappan, som vi bestämt, arbetar som designer, så är mamman bara en prototyp. Låt oss se hur detta händer:
make_me = function (_name) (
alert ("Jag lanserades");
detta .namn = _namn;
denna .show_name = funktion () (varning (detta .namn);)
}
/*
När tolken ser funktionsnyckelordet kontrollerar tolken koden till höger om det, och sedan allt ok - skapar ett nytt objekt i minnet, vilket också är vår funktion. Sedan skapas automatiskt (utan programmerarens deltagande) en prototypegenskap för denna funktion, som refererar till ett tomt objekt. Om vi ​​gjorde det manuellt skulle det se ut som make_me.prototype = new Object ();

Sedan läggs det givna objektet (som pekas på av prototypegenskapen) också till automatiskt med en konstruktoregenskap som pekar tillbaka till funktionen. Det visar sig en sådan cyklisk länk.

Nu är detta objekt, som kan beskrivas som (konstruktör: ... här är en referens till funktionen ...) - funktionsprototypen.
*/

// Objekt är verkligen ett objekt
alert (typeof make_me.prototype.constructor); // Funktion är vår funktion
alert (make_me.prototype.constructor === make_me); // Sann

// Lägg till en ny metod till prototypen för make_me-funktionen

Child = new make_me ("Vasya"); // de lanserade mig
/ * Nu, utöver allt som beskrivits i föregående exempel, skapas ytterligare en dold egenskap [] i det underordnade objektet, som pekar på samma objekt som make_me.prototype. Eftersom fastigheten är dold, vi kan varken se dess värde eller ändra den - den spelar dock en viktig roll i det fortsatta arbetet * /

Varning (barn.namn); //Vasya
child.show_name (); //Vasya

Child.set_name ("Kolya");
/ * Först letar tolken efter metoden set_name på det underordnade objektet. Eftersom den inte finns där fortsätter den att söka efter barnet [] Egendom, hittar den där och kör den. * /
child.show_name (); // Kolya - nu heter Vasya Kolya :)

Make_me.prototype.show_name2 = funktion () (varning ("Hej," + detta .namn;) //T.k. prototypen är ett vanligt föremål, vi kan också ändra det i farten

Child2 = new make_me ("Petya");
child2.show_name2 (); // Hej, Petya
child.show_name2 (); // Hej Kolya - förändringar i prototypen påverkar inte bara nyskapade objekt, utan även alla gamla

Child2.show_name2 = funktion () (varning ( "Jag säger inte mitt namn");} // Vi kan fortfarande ändra själva objektet, medan den nya metoden show_name2 i detta objekt (och bara i det) så att säga kommer att "skriva över" den gamla metoden från prototypen
child2.show_name2 (); // Jag kommer inte att säga mitt namn - för vi har nu vår egen show_name2-metod, då kallas den, och ingen sökning i prototypen sker

Child.show_name2 (); // Hej, Kolya - allt är fortfarande här

Make_me.prototype = (prop: "hej") // Låt oss försöka återskapa prototypen igen

Varning (barn.prop); // odefinierat
child.show_name2 (); //Hej Kolya
/ * Om du kommer ihåg vad att arbeta med referens är allt klart. Att återskapa prototypen bryter länken, och nu pekar egenskapen [] för objekten child och child2 till ett objekt (som tidigare var prototypen för make_me-funktionen), och make_me.prototype-egenskapen till ett annat objekt, vilket är ny prototyp av make_me-funktionen * /

Child3 = new make_me ("Oleg");
alert (barn3.prop); // hej - som förväntat


* Den här källkoden har markerats med Source Code Highlighter.

Som framgår av exemplet, medan pappan förblir mamman trogen (det vill säga medan prototypen av funktionen förblir densamma), är alla barn beroende av mamman och är känsliga för alla förändringar hos henne. Men så fort föräldrarna skiljer sig (designern ändrar prototypen till en annan), sprider barnen omedelbart vem var och det finns ingen längre koppling till dem.

Lite om terminologi
Tills den primära kopplingen mellan konstruktören och prototypen är bruten, kan vi observera följande bild:

make_me = function (_name) (
alert ("Jag lanserades");
detta .namn = _namn;
denna .show_name = funktion () (varning (detta .namn);)
}

Make_me.prototype.set_name = funktion (_namn) (detta .namn = _namn;)
barn = new make_me ("Vasya");

Alert (typeof make_me.prototype); // objekt - funktionen har en prototypegenskap
varning (typ av barn.prototyp); // odefinierad - y cos av detta föremål INGEN prototypegenskap
alert (child.constructor.prototype === make_me.prototype); // true - men objektet har en constructor-egenskap, som pekar på make_me-konstruktorfunktionen, som i sin tur har en prototyp-egenskap


* Den här källkoden har markerats med Source Code Highlighter.

Som jag märkte efter att ha läst många forum om detta ämne, de största problemen människor får när de blandar ihop prototypegenskapen för en funktion och den dolda [] egenskapen för ett objekt skapat med den funktionen.
Båda dessa egenskaper är referenser till samma objekt (så länge den primära länken mellan prototypen och konstruktören inte är bruten), men de är ändå olika egenskaper, med olika namn, en av dem är tillgänglig för programmeraren, och andra är inte.

Det är alltid nödvändigt att tydligt förstå att om det kommer om prototypen för konstruktorn - då är detta alltid prototypegenskapen, och om det handlar om prototypen för det skapade objektet - så är detta den dolda egenskapen [].

Arv

Vi vet nu att varje objekt har en dold prototypreferens, och varje prototyp är ett vanligt objekt.
De mest insiktsfulla läsarna har redan fått upp lukten av rekursion :)
Faktiskt sedan en prototyp är ett vanligt objekt, då har det i sin tur en länk till sin prototyp, och så vidare. Så här implementeras prototyphierarkin.
fågel = funktion () () // Det här är fågelns konstruktör
bird.prototype.cry = funktion () (alert ("Cree!");) // Fågeln kan skrika
bird.prototype.fly = funktion () (alert ("Jag flyger!");) // och flyga

Anka = funktion () ()
duck.prototype = ny fågel ();
duck.prototype.cry = funktion () (varning ("Quack quack!");) // Ankan skriker annorlunda
duck.prototype.constructor = anka; // Tvinga egenskapen prototype.constructor att ställas in på duck, eftersom annars kommer det att hänvisa till fågel

Billy = ny anka (); // Billy är vår anka
billy.fly (); //Jag flyger! – Billy kan flyga för att han är en fågel
billy.cry (); //Kvak kvack! – Billy skriker kvacksalvare för att han är en anka


* Den här källkoden har markerats med Source Code Highlighter.

På så sätt kan du implementera en hierarki av valfri kapslingsnivå.

Asterisk problem

Nu, eftersom vi vet så mycket om allt detta, låt oss försöka ta reda på hur mycket som händer på dessa tre rader.
make_me = funktion () ()
barn = new make_me ();
alert (child.toString ()); // utgångar

* Den här källkoden har markerats med Source Code Highlighter.

I första raden skapar vi ny funktion och en variabel make_me som pekar på denna funktion. Detta skapar en prototyp för funktionen make_me.prototype, som innehåller en konstruktoregenskap som pekar på make_me.
Men det är inte allt :)
Eftersom make_me-funktionen är också ett objekt, då har den i sin tur en pappa och en mamma, d.v.s. konstruktör och prototyp. Dess konstruktor är en inbyggd funktion av funktionsspråket () och dess prototyp är ett objekt som innehåller anrops-, applicerings-, etc.-metoder. – det är tack vare denna prototyp som vi kan använda dessa metoder i vilken funktion som helst. Detta ger make_me-funktionen en egenskap [] som pekar på Function.prototype.

I sin tur är prototypen för funktionskonstruktorn också ett objekt, vars konstruktor är (överraskning!) Objekt (dvs. Function.prototype. []. Konstruktor === Objekt), och prototypen är ett objekt som innehåller standardegenskaperna och metoder för objektet, såsom toString, hasOwnProperty och andra (med andra ord - Function.prototype. [] ["hasOwnProperty"] - detta är exakt samma metod som vi kan använda i alla härledda objekt - och detta är exakt egen metod för detta objekt, och inte ärvd ). På detta intressanta sätt finner vi att alla typer av objekt härrör från Object.

Kan vi fortsätta vidare? Det visar sig inte. Object.prototype innehåller de grundläggande egenskaperna för ett objekt just för att det inte har en egen prototyp. Object.prototype [] = Null; Vid denna tidpunkt stannar resan genom prototypkedjan för att hitta en egenskap eller metod.

En till intressant fakta- Konstruktören av Objekt är Funktion. De där. Objekt []. Konstruktör === Funktion.
Det finns en annan cirkulär referens - Objektkonstruktorn är Function och Function.prototypekonstruktorn är Object.

Låt oss gå tillbaka till vårt exempel. Vi förstod redan hur funktionen skapas, låt oss nu gå vidare till den andra raden. Där skapar vi ett barnobjekt vars konstruktor är make_me-funktionen och prototypen är make_me.prototype.

Jo, på tredje raden ser vi hur tolken går upp i kedjan, från barn till barn [] (Aka make_me.prototype), sedan till barn []. [] (Aka Object.prototype), och redan där finner toString-metoden, som lanseras för exekvering.

Föroreningar

Det kan tyckas som att arv via prototyper är det enda sättet JavaScript är möjligt. Det är inte sant.
Vi har att göra med ett väldigt flexibelt språk som inte ger så mycket regler som möjligheter.

Till exempel, om vi vill kan vi inte använda prototyper alls, utan programmera med konceptet mixins. För detta kommer våra gamla goda vänner - konstruktörer att komma väl till pass.

// Det här är en mänsklig konstruktör
man = funktion () (
denna .live = funktion () (varning ("Jag lever");) // En person vet hur man lever
denna .walk = funktion () (varning ("Jag går");) // En person kan gå
}

// Det här är poetens konstruktör
poet = funktion () (
denna .kill = funktion () (varning ( "Poeten dödade en man");} // En poet kan döda en person
denna .live = funktion () (larm ("Jag är död");) // Detta kommer att få personen att dö
}

Vladimir = ny man (); // Vladimir är en man
vladimir.live (); // Jag lever - han lever
vladimir.walk (); // Jag går - han går

Poet.call (vladimir); // Kör poetkonstruktören för vladimir-objektet
vladimir.kill (); // Poeten dödade mannen
vladimir.live (); //Jag är död

// Och nu fokus
man.call (vladimir);
vladimir.live (); //Jag bor


* Den här källkoden har markerats med Source Code Highlighter.

Vad ser vi i detta exempel? För det första är det möjligheten att ärva från flera objekt som inte är i samma hierarki. I exemplet finns det 2 av dem, men det kan vara hur många som helst.
För det andra är detta frånvaron av någon hierarki alls. Åsidosättande egenskaper och metoder bestäms enbart av i vilken ordning konstruktörer anropas.
För det tredje är detta förmågan att ändra objektet ännu mer dynamiskt, och det är det separat objekt, och inte alla ättlingar, som när man byter prototyp.

Uppdatering: Nedläggningar och privata fastigheter

För att inte blåsa upp den här redan ganska stora artikeln så ger jag en länk till inlägget Stängningar i JavaScript, där det står lite utförligt om det.

Vad ska man göra med allt detta nu

Som jag sa ovan, godtyckliga förändringar i enskilda objekt, och användningen av konstruktörer, och mixins, och flexibiliteten hos prototyper är bara verktyg, möjligheter som gör att en programmerare kan skapa kod som är både hemsk och vacker i alla avseenden. Det är bara viktigt att förstå vilka uppgifter vi löser, med vilka medel, vilka mål vi uppnår och vilket pris vi betalar för det.

Dessutom är frågan om priset ganska icke-trivial, särskilt om vi pratar om utveckling för webbläsaren. Internet Explorer 6 och 7 versioner.
1. Minne - allt är enkelt här. I alla webbläsare tar nedärvning av prototyper flera gånger mindre minne än när man skapar metoder genom konstruktörer. Dessutom, ju fler metoder och egenskaper vi har, desto större skillnad. Det är dock värt att komma ihåg att om vi inte har tusen identiska föremål, utan bara ett, så blir minnesförbrukningen i alla fall liten, eftersom det finns andra faktorer att ta hänsyn till här.
2. Processortid - här är de viktigaste finesserna förknippade med Microsofts webbläsare.
Å ena sidan kan objekt där metoder och egenskaper skapas genom en konstruktor skapas många gånger (i vissa fall tiotals eller hundratals gånger) långsammare än genom en prototyp. Ju fler metoder, desto långsammare. Så om din IE fryser i några sekunder under initieringen av skriptet - det finns en anledning att gräva i den här riktningen.

Å andra sidan kan ett objekts egna metoder (skapade via en konstruktor) exekvera något snabbare än prototypade. Om du desperat behöver påskynda exekveringen av en metod i den här webbläsaren, måste du ta hänsyn till detta. Tänk på att det är metodanropet (dvs sökningen efter det i objektet) som accelereras, och inte dess exekvering. Så om själva metoden körs en sekund, kommer du inte att märka någon speciell ökning av prestanda.

I andra webbläsare observeras liknande problem, där tiden för att skapa objekt och anropa deras metoder är ungefär densamma för båda tillvägagångssätten.

P.S. Vanligtvis, i artiklar av detta slag, erbjuder författaren någon form av omslag, antingen försöker implementera klassobjektsarv baserat på prototyp, eller bara syntaktisk socker för prototyparv. Jag gör inte detta med flit, eftersom Jag tror att en person som förstår innebörden av den här artikeln kan skriva vilken omslag som helst för sig själv och många fler intressanta saker :)

Taggar: Lägg till taggar




Objekt är ett av kärnbegreppen i JavaScript. När jag först började studera dem verkade de för mig ganska enkla: bara par av nycklar och värden, som beskrivs i teorin.

Det var först efter ett tag som jag började förstå att ämnet är mycket mer komplicerat än jag trodde. Och sedan började jag studera information från olika källor. Några av dem gav en bra uppfattning om ämnet, men jag kunde inte se hela bilden på en gång.

I det här inlägget har jag försökt täcka in alla aspekter av att arbeta med objekt i JS, utan att gå för djupt in på enskilda detaljer, men också utan att missa viktiga detaljer som hjälper dig att förstå ämnet och känna dig mer självsäker när du studerar det vidare.

Så låt oss börja med grunderna.

Ett objekt

Ett objekt i JavaScript är helt enkelt en samling egenskaper, som var och en är ett nyckel-värdepar. Du kan referera till nycklarna med hjälp av punkt ( obj.a) eller parentesnotation ( obj ["a"]).

Kom ihåg att parenteser ska användas om nyckeln är:

  • är inte en giltig JavaScript-identifierare (den innehåller ett mellanslag, bindestreck, börjar med ett nummer ...)
  • är en variabel.
En av egenskaperna som objekt i JS får när de skapas kallas Prototyp och detta är ett mycket viktigt koncept.

Prototyp

Varje objekt i JavaScript har en intern egenskap som kallas Prototyp... I de flesta webbläsare kan du referera till det med notationen __proto__.

Prototypär ett sätt att tillhandahålla egendomsarv i JavaScript. På så sätt kan du dela funktionalitet utan att duplicera kod i minnet. Metoden fungerar genom att skapa en länk mellan två objekt.

Enkelt uttryckt skapar Prototype en pekare från ett objekt till ett annat.

Prototypkedja

Varje gång JS letar efter en egenskap i ett objekt och inte hittar den direkt på själva objektet, kontrollerar den om egenskapen finns i prototypobjektet. Om det inte finns någon egenskap i den kommer JS att fortsätta söka i prototypen efter det relaterade objektet. Detta kommer att fortsätta tills JS hittar en lämplig fastighet eller når slutet av kedjan.

Låt oss ta ett exempel:

Var cons = function () (this.a = 1; this.b = 2;) var obj = new cons (); cons.prototype.b = 3; cons.prototype.c = 4;
nackdelarär en konstruktor (bara en funktion som kan anropas med operatorn ny).

På den femte raden skapar vi ett nytt objekt - en ny kopia nackdelar... Omedelbart efter skapandet obj får också prototypegenskapen.

Och nu lägger vi till egenskaper ( "före Kristus") objektprototyp nackdelar.
Överväga obj:

obj.a // 1- allting är likadant här, obj.aär fortfarande 1.
obj.c?- kl obj ingen egendom c! Men som tidigare nämnt kommer JS nu leta efter det i prototypen obj och returnerar värdet 4.

Låt oss nu tänka på innebörden obj.b och hur det kommer att bli när vi tar bort obj.b?

Obj.bär lika med 2. Vi tilldelade fastigheten b men vi gjorde det för prototypen nackdelar så när vi kollar obj.b, då får vi fortfarande 2. Dock direkt efter borttagning obj.b JS kan inte längre hitta b vid o bj, och kommer därför att fortsätta söka i prototypen och returnera värdet 3.

Objektskapande

Objekt bokstavlig: låt obj = (a: 1);
Vi har skapat ett objekt med följande prototypkedja: obj ---> Objekt.prototyp ---> null
Som du kan gissa, objekt.prototypär prototypen för objektet såväl som slutet av prototypkedjan.

Object.create ():var newObj = Object.create (obj);
Ha nyObj det kommer att finnas följande prototypkedja: newObj ---> obj ---> Object.prototype ---> null

Konstruktör. Som i exemplet ovan är en konstruktor bara en JS-funktion som låter oss dra fördel av operatören ny för att skapa nya instanser av det.

ES6 klasser:

Klassrektangel (konstruktör (höjd, bredd) (this.height = höjd; this.width = width;) getArea () (returnera this.height * this.width;)) låt kvadrat = ny rektangel (2, 2);
Fyrkant- konstruktörsinstans rektangel och så kan vi ringa square.getArea () // 4, kvadrat.bredd samt alla funktioner som ärvts från objekt.prototyp.

Vilket är det bästa sättet? Om du planerar att skapa flera instanser kan du använda ES6 eller konstruktorn. Om du planerar att skapa objektet en gång, är det bättre att ange en bokstavlig, eftersom detta är det enklaste sättet.

Och nu när vi har lärt oss om prototyp och bekantade oss med alla sätt att skapa nya objekt, kan vi gå vidare för att diskutera ett av de mest förvirrande ögonblicken i samband med objekt.

Jämföra och ändra objekt

I JavaScript är objekt av en referenstyp

När vi skapar ett objekt låt obj = (a: 1);, variabel obj får objektets minnesadress, men inte dess värde! Det är absolut nödvändigt att du förstår denna skillnad, annars kan fel uppstå. När vi skapar ett annat objekt låt nyObj = obj, skapar vi faktiskt pekare till ett visst minnesområde obj snarare än ett helt nytt föremål.

Detta innebär att genom att göra newObj.a = 2, vi ändrar oss faktiskt obj så att obj.a blir lika med 2!

Detta tillvägagångssätt leder lätt till buggar, vilket är anledningen till att många företag arbetar med oföränderliga objekt. Istället för att ändra ett redan skapat objekt måste du skapa ett nytt objekt igen (en kopia av originalet) och göra ändringar redan i det. Det är så viktiga bibliotek som Redux fungerar, och i allmänhet är det ett av kärnkoncepten för funktionell programmering. Du kan läsa mer om det.

Jämlikhet

Av ovanstående följer också att två objekt aldrig kan vara lika, även om de har samma egenskaper. Detta beror på det faktum att JS faktiskt jämför platsen för objekt i minnet, och två objekt är aldrig på samma minnesplats.

// Två distinkta objekt med samma egenskaper är inte lika var fruit = (namn: "äpple"); var fruitbear = (namn: "äpple"); frukt === fruktbär; // return false // här pekar frukt och fruktbjörn på samma objekt var fruit = (namn: "äpple"); var fruktbjörn = frukt; frukt === fruktbär; // returnera sant
Så du har förmodligen redan undrat hur du kan jämföra objekt eller hur man utför olika manipulationer med objekt, med tanke på kravet på deras oföränderlighet.

Låt oss överväga flera möjligheter.

Ändra ett objekt

Låt oss säga att det är klart att vi inte ska modifiera objekt på ett vänskapligt sätt, så vi vill skapa en kopia av motsvarande objekt och ändra dess egenskaper. Kommer till undsättning Object.assign ().

Var obj = (a: 1, b: 2); var newObj = Object.assign ((), obj, (a: 2)) // (a: 2, b: 2)
Om vi ​​vill ändra värdet på fastigheten a objekt obj, du kan använda objekt.tilldela för att skapa en kopia obj och dess förändringar.

I exemplet kan du se att vi först skapar ett tomt objekt, sedan kopierar värdena obj och göra våra ändringar och så småningom få ett nytt och färdigt objekt.

Observera att den här metoden inte fungerar för djupkopiering. När vi pratar om djupkopiering menar vi att du behöver kopiera ett objekt med en eller flera egenskaper.

Const obj = (a: 1, b: (a: 1)); // b egenskap är ett objekt
Object.assign () kopierar egenskaperna för ett objekt, så om egenskapsvärdet är en pekare till ett objekt, så kopieras bara pekaren.

En djup kopia kräver en rekursiv operation. Här kan du skriva en funktion eller bara använda metoden _.cloneDeep från Lodash-biblioteket.

Objektjämförelse

Ett coolt knep för att arbeta med objekt är strängkonvertering. I följande exempel konverterar vi båda objekten till strängar och jämför dem:

JSON.stringify (obj1) === JSON.stringify (obj2)
Detta tillvägagångssätt är motiverat, eftersom vi i slutändan jämför strängar som representerar en pekare till en värdetyp. Den dåliga nyheten är att det inte alltid fungerar, främst för att ordningen på objektets egenskaper inte är garanterad.

Övrig bra beslut- använd metoden _.är jämställd från Lodash som gör djupgående objektjämförelser.

Och innan vi stänger, låt oss gå igenom några vanliga frågor om föremål. Detta kommer att hjälpa till att dyka djupare in i ämnet och tillämpa kunskapen i praktiken.

Försök själv fundera över lösningen innan du läser svaret.

Hur vet jag längden på ett föremål?

För att få ett svar måste du iterera över objektets alla egenskaper en efter en och räkna dem. Det finns flera sätt att utföra denna iteration:
  • för in... Denna metod täcker alla räknebara egenskaper hos ett objekt och dess prototypkedjor. Vi lärde känna prototypen (och förhoppningsvis lärde oss materialet), så det borde stå klart att applikationen för in kommer inte alltid att vara korrekt för att få egenskaperna hos ett objekt.
  • Objekt.nycklar... Denna metod returnerar en array med alla nycklar egen(tillhör det angivna objektet) räkning egenskaper. Detta tillvägagångssätt är bättre, eftersom vi bara arbetar med objektets egenskaper, inte med hänvisning till egenskaperna. prototyp... Det finns dock situationer där du tilldelat ett attribut uppräknad viss egendom till falsk, och objekt.nycklar som ett resultat hoppar den över det och du får ett felaktigt resultat. Detta händer sällan, men i sådana fall kommer det väl till pass getOwnPropertyNames.
  • getOwnPropertyNames returnerar en array som innehåller alla egen objektnycklar (både räknebara och oräkneliga).
Också värt att nämna:
  • Objekt.värden itererar över sina egna räkningsbara egenskaper och returnerar en array med matchning värden.
  • Objekt.poster itererar över sina egna räknebara egenskaper och returnerar en array med nycklar och deras värden.
Jag tror att du har märkt att de flesta av ovanstående metoder returnerar en array. Detta är en möjlighet att dra nytta av alla fördelar JavaScript-metoder för att arbeta med arrayer.

En sådan metod är array.length... Till slut kan vi bara skriva

Låt objLength = Object.getOwnPropertyNames (obj) .length;

Hur kontrollerar man om ett objekt är tomt?

  1. JSON.stringify (myObj) === “()”?. Här använder vi återigen strängkonverteringsverktyget för att enkelt kontrollera om ett objekt är tomt (genom att jämföra strängar, inte objekt).
  2. ! Object.keys (myobj) .length // true?.? Som jag nämnde kan det vara till stor hjälp att konvertera ett objekts nycklar till en array. Här använder vi den bekväma fastigheten längdärvt från Array.prototype kontrollera längden på nycklarna i arrayen med den. I JS 0 blir till falskt, så att lägga till ! vi gör det sant. Alla andra siffror blir falska.

Till sist

Förhoppningsvis känner du dig nu mer säker på att skapa och arbeta med objekt. Låt oss sammanfatta:
  • Kom ihåg att objekt är av referenstyp, vilket innebär att det rekommenderas att arbeta med dem utan att ändra originalobjekten.
  • Bli vän med fastigheten prototyp och en prototypkedja.
  • Kolla in Object Assist Tools. Kom ihåg att du kan förvandla objekt till strängar, få en array med deras nycklar, eller helt enkelt iterera över deras egenskaper med hjälp av den uppsättning metoder vi har sett.
Lycka till med att lära dig JavaScript-objekt.

Senast uppdaterad: 2018-04-08

Objektorienterad programmering är ett av de dominerande paradigmen inom applikationsutveckling idag, och i JavaScript kan vi även dra full nytta av OOP. Samtidigt har objektorienterad programmering vissa egenheter i förhållande till JavaScript.

Objekt

I tidigare ämnen har vi arbetat med primitiva data – siffror, strängar, men data representerar inte alltid primitiva typer. Till exempel, om vi i vårt program behöver beskriva essensen av en person som har ett namn, ålder, kön och så vidare, så kommer vi naturligtvis inte att kunna representera essensen av en person i form av ett nummer eller ett snöre. Vi behöver några rader eller siffror för att korrekt beskriva personen. I detta avseende kommer en person att fungera som en komplex komplex struktur, som kommer att ha separata egenskaper - ålder, höjd, namn, efternamn, etc.

JavaScript använder objekt för att arbeta med sådana strukturer. Varje objekt kan lagra egenskaper som beskriver dess tillstånd och metoder som beskriver dess beteende.

Skapa ett nytt objekt

Det finns flera sätt att skapa ett nytt objekt.

Det första sättet är att använda objektkonstruktorn:

Var användare = nytt objekt ();

I det här fallet kallas objektet för användare. Den definieras precis som vilken vanlig variabel som helst med nyckelordet var.

Uttrycket nya Object () representerar ett anrop till en konstruktor, en funktion som skapar ett nytt objekt. Den nya operatören används för att anropa konstruktören. Att anropa en konstruktor är faktiskt som att anropa en vanlig funktion.

Det andra sättet att skapa ett objekt är att använda hängslen:

Var användare = ();

Idag är den andra metoden vanligare.

Objektegenskaper

Efter att ha skapat ett objekt kan vi definiera egenskaper i det. För att definiera en egenskap, efter namnet på objektet, ange namnet på egenskapen, separerad med en punkt, och tilldela den ett värde:

Var användare = (); user.name = "Tom"; användare.ålder = 26;

I detta fall deklareras två egenskaper, namn och ålder, och tilldelas motsvarande värden. Efter det kan vi använda dessa egenskaper, till exempel visa deras värden i konsolen:

Console.log (användarnamn); console.log (användare.ålder);

Du kan också definiera egenskaper när du definierar ett objekt:

Var användare = (namn: "Tom", ålder: 26);

I det här fallet används kolontecknet för att tilldela egenskapen ett värde och ett kommatecken (istället för semikolon) används efter egenskapsdefinitionen.

Dessutom finns ett förkortat sätt att definiera egenskaper:

Var name = "Tom"; var ålder = 34; var user = (namn, ålder); console.log (användarnamn); // Tom console.log (user.age); // 34

I det här fallet är namnen på variablerna också namnen på objektets egenskaper. Och på detta sätt kan du skapa mer komplexa strukturer:

Var name = "Tom"; var ålder = 34; var user = (namn, ålder); var lärare = (användare, kurs: "JavaScript"); console.log (lärare.användare); // (namn: "Tom", ålder: 34) console.log (teacher.course); // JavaScript

Objektmetoder

Ett objekts metoder definierar dess beteende eller de åtgärder det utför. Metoder är funktioner. Låt oss till exempel definiera en metod som visar namnet och åldern på en person:

Var användare = (); user.name = "Tom"; användare.ålder = 26; user.display = function () (console.log (user.name); console.log (user.age);); // anropa metoden user.display ();

Precis som med funktioner definieras metoder först och anropas sedan.

Metoder kan också definieras direkt när ett objekt definieras:

Var user = (namn: "Tom", ålder: 26, display: function () (console.log (this.name); console.log (this.age);));

Precis som med egenskaper tilldelas en metod en funktionsreferens med ett kolontecken.

För att referera till egenskaper eller metoder för ett objekt i det objektet, använd detta nyckelord. Det betyder en referens till det aktuella objektet.

Du kan också använda ett förkortat sätt att definiera metoder, när kolon och ordfunktionen utelämnas:

Var user = (namn: "Tom", ålder: 26, display () (console.log (this.name, this.age);), flytta (place) (console.log (this.name, "goes to" , plats);)); user.display (); // Tom 26 user.move ("butiken"); // Tom går till butiken

Array syntax

Det finns också alternativt sätt egenskaps- och metoddefinitioner med arraysyntax:

Var användare = (); användare ["name"] = "Tom"; användare ["ålder"] = 26; användare ["display"] = funktion () (console.log (användarnamn); console.log (användar.ålder); // anropa metoden användare ["display"] ();

Varje egenskap eller metodnamn omges av citattecken och inom hakparenteser och tilldelas sedan också ett värde. Till exempel, användare ["ålder"] = 26.

När du hänvisar till dessa egenskaper och metoder kan du använda antingen punktnotationen (användarnamn) eller så kan du hänvisa till detta: användare ["namn"]

Strängar som egenskaper och metoder

Det bör också noteras att namnen på egenskaper och metoder för ett objekt alltid är strängar. Det vill säga, vi skulle kunna skriva om den tidigare definitionen av ett objekt enligt följande:

Var user = ("name": "Tom", "age": 26, "display": function () (console.log (user.name); console.log (user.age);)); // anropa metoden user.display ();

Å ena sidan finns det ingen skillnad mellan de två definitionerna. Å andra sidan finns det fall där det kan hjälpa att fånga namnet i en sträng. Till exempel, om ett egenskapsnamn består av två ord separerade med ett mellanslag:

Var user = (namn: "Tom", ålder: 26, "fullständigt namn": "Tom Johns", "display info": function () (console.log (user.name); console.log (user.age) ;)); console.log (användare ["fullständigt namn"]); användare ["visa info"] ();

Endast i det här fallet, för att hänvisa till sådana egenskaper och metoder, måste vi använda syntaxen för arrayer.

Ta bort egenskaper

Ovan såg vi hur du dynamiskt kan lägga till nya egenskaper till ett objekt. Men vi kan också ta bort egenskaper och metoder med hjälp av delete-operatorn. Och precis som att lägga till kan vi ta bort egenskaper på två sätt. Det första sättet är att använda punktnotation:

Ta bort objekt.egenskap

Eller använd array-syntaxen:

Ta bort objekt ["egenskap"]

Låt oss till exempel ta bort egenskapen:

Var användare = (); user.name = "Tom"; användare.ålder = 26; user.display = function () (console.log (user.name); console.log (user.age);); console.log (användarnamn); // Tom radera användarnamn; // ta bort egendomen // Alternativt alternativ// ta bort användare ["namn"]; console.log (användarnamn); // odefinierat

Efter radering kommer egenskapen att vara odefinierad, så när du försöker komma åt den kommer programmet att returnera odefinierat.







2021 gtavrl.ru.