Arbeta med objekt och egenskaper

Ett komplext objekt kan innehålla något tillåtet JavaScript-värde. I följande kod skapar jag en Objekt() objekt som heter myObject och lägg sedan till egenskaper som representerar de flesta värden som finns tillgängliga i JavaScript.


Komplexa objekt

Prov: sample29.html

 

Det enkla konceptet att lära sig här är att komplexa objekt kan innehålla hänvisar till allt du kan uttrycka uttryckligen i JavaScript. Du bör inte bli förvånad när du ser detta gjort, eftersom alla föremålen kan muteras. Detta gäller även för Sträng(), Siffra(), och Boolean () värden i deras objektform, dvs när de skapas med ny operatör.


Inkapslar komplexa objekt på ett programmässigt fördelaktigt sätt

De Objekt(), Array (), och Fungera() Objekt kan innehålla andra komplexa objekt. I följande exempel demonstrerar jag detta genom att skapa ett objektträ med Objekt() objekt.

Prov: sample30.html

 

Samma sak kan göras med en Array () objekt (aka multidimensionell array), eller med a Fungera() objekt.

Prov: sample31.html

 

Huvudbegreppet att ta bort här är att några av de komplexa föremålen är utformade för att inkapsla andra objekt på ett programmässigt fördelaktigt sätt.


Hämta, ställa in och uppdatera ett objekts egenskaper med hjälp av punktnotation eller fästnotation

Vi kan få, ställa in eller uppdatera ett objekts egenskaper med antingen pricknotation eller konsolnotation.

I följande exempel demonstrerar jag punktnotering, som uppnås genom att använda objektnamnet följt av en period och sedan följt av egenskapen att få, ställa in eller uppdatera (t.ex.., objectName.property).

Prov: sample32.html

 

Dot notation är den vanligaste notationen för att få, ställa in eller uppdatera objektets egenskaper.

Fäste notering, om inte krävs, är inte lika vanligt. I följande prov ersätter jag punktnotationen som användes i föregående prov med fästnotation. Objektnamnet följs av en öppningsfäste, egenskapsnamnet (i citat) och sedan en stängningsfäste:

Prov: sample33.html

 

Fäste notering kan vara mycket användbar när du behöver komma åt en fastighetsnyckel och vad du måste arbeta med är en variabel som innehåller ett strängvärde som representerar egenskapsnamnet. I nästa prov demonstrerar jag fördelen med konsolnotation över punktnotering genom att använda den för att komma åt fastigheten Foo bar. Jag gör det med två variabler som, när de går ihop, producerar strängversionen av egenskapsnyckeln som finns i foobarObject.

Prov: sample34.html

 

Dessutom kan fäste notering vara till nytta för att komma till egenskapsnamn som är ogiltiga JavaScript-identifierare. I följande kod använder jag ett nummer och ett reserverat nyckelord som ett fastighetsnamn (giltigt som en sträng) som endast fästnamn kan komma åt.

Prov: sample35.html

 

Eftersom objekt kan innehålla andra objekt, cody.object.object.object.object eller cody [ 'objekt'] [ 'objekt'] [ 'objekt'] [ 'objekt'] kan ses ibland. Detta kallas objektkedja. Inkapslingen av objekt kan gå på obestämd tid.

Objekt är mutable i JavaScript, vilket innebär att det går att få, ställa in eller uppdatera dem på alla objekt när som helst. Genom att använda konsolnotationen (t.ex.., cody [ 'okänd']), kan du efterlikna associativa arrayer som finns på andra språk.

Om en egenskap inom ett objekt är en metod, är allt du behöver göra med att använda () operatörer (t.ex.., cody.getGender ()) för att anropa fastighetsmetoden.


Radera objektegenskaper

De radera Operatören kan användas för att helt ta bort egenskaper från ett objekt. I följande kodsedel tar vi bort bar egendom från foo objekt.

Prov: sample36.html

 

radera kommer inte ta bort egenskaper som finns i prototypkedjan.

Att radera är det enda sättet att faktiskt ta bort en egenskap från ett objekt. Ställa in en egenskap till odefinierad eller null Ändrar bara egenskapens värde. Det tar inte bort egenskapen från objektet.


Hur referenser till objektegenskaper löses

Om du försöker komma åt en egenskap som inte finns i ett objekt försöker JavaScript att hitta egenskapen eller metoden med prototypkedjan. I följande prov skapar jag en array och försöker få åtkomst till en egenskap som heter foo som ännu inte har definierats. Du kanske tror det för myArray.foo är inte en egenskap hos myArray objekt, kommer JavaScript omedelbart tillbaka odefinierad. Men JavaScript kommer att se på två ställen (Array.prototype och då Object.prototype) för värdet av foo innan den återvänder odefinierad.

Prov: sample37.html

 

egendomen. Om den har fastigheten, kommer den att returnera värdet på fastigheten, och det finns inget arv som uppstår eftersom prototypkedjan inte är levererad. Om förekomsten inte har egenskapen söker JavaScript efter det på objektets konstruktörsfunktion prototyp objekt.

Alla objekt instanser har en egenskap som är en hemlig länk (aka __proto__) till konstruktörfunktionen som skapade förekomsten. Denna hemliga länk kan utnyttjas för att ta tag i konstruktörfunktionen, speciellt prototypegenskapen hos instanskonstruktörfunktionen.

Detta är en av de mest förvirrande aspekterna av objekt i JavaScript. Men låt oss förklara det här. Kom ihåg att en funktion också är ett objekt med egenskaper. Det är vettigt att låta föremål att ärva egenskaper från andra objekt. Precis som att säga: "Hej objekt B, jag skulle vilja att du delar alla egenskaper som objektet A har." JavaScript slår det här hela för inbyggda objekt som standard via prototyp objekt. När du skapar dina egna konstruktörsfunktioner kan du också utnyttja prototypkedjan.

Hur exakt JavaScript uppnår detta är förvirrande tills du ser det för vad det är: bara en uppsättning regler. Låt oss skapa en matris för att undersöka prototyp fastighet närmare.

Prov: sample38.html

 

Vår Array () Exempel är ett objekt med egenskaper och metoder. När vi öppnar en av matrismetoderna, till exempel Ansluta sig(), låt oss fråga oss: Gör myArray-förekomsten från Array () konstruktören har sin egen Ansluta sig() metod? Låt oss kolla.

Prov: sample39.html

 

Nej det gör det inte. Yet myArray har tillgång till Ansluta sig() metod som om det var egen egendom. Vad hände här? Tja, du har bara observerat prototypkedjan i aktion. Vi åtkomst till en egenskap som, även om den inte finns i myArray-objektet, kunde hittas av JavaScript någon annanstans. Att någon annanstans är mycket specifik. När Array () konstruktör skapades av JavaScript, the Ansluta sig() Metoden tillsattes (bland annat) som en egenskap av prototyp egendom av Array ().

För att upprepa, om du försöker komma åt en egenskap på ett objekt som inte innehåller det, söker JavaScript i prototyp kedja för detta värde. Först kommer det att se på konstruktörfunktionen som skapade objektet (t.ex.., Array) och inspektera dess prototyp (t.ex.., Array.prototype) för att se om egendomen kan hittas där. Om det första prototypobjektet inte har egenskapen, fortsätter JavaScript att söka upp kedjan på konstruktorn bakom den ursprungliga konstruktorn. Det kan göra det hela vägen fram till slutet av kedjan.

Var slutar kedjan? Låt oss undersöka exemplet igen, påpeka toLocaleString () metod på myArray.

Prov: sample40.html

 

De toLocaleString () Metoden är inte definierad inom myArray objekt. Så kallas prototypkedjestyrningen och JavaScript letar efter egendomen i Array konstruktörens prototypegenskaper (t.ex.., Array.prototype). Det finns inte heller heller, så kedjeregeln påkallas igen och vi letar efter egendomen i Objekt() prototypegenskap (Object.prototype). Och ja det finns där. Hade det inte hittats där, skulle JavaScript ha orsakat ett fel som anger att fastigheten var odefinierad.

Eftersom alla prototypegenskaper är objekt, är den sista länken i kedjan Object.prototype. Det finns ingen annan konstruktörs prototypegenskap som kan undersökas.

Det finns ett helt kapitel framöver som bryter ner prototypkedjan i mindre delar, så om detta var helt förlorat på dig, läs det kapitlet och kom tillbaka till denna förklaring för att stärka din förståelse. Från denna korta läs om frågan hoppas jag att du förstår det när en egendom inte hittas (och anses vara odefinierad), Har JavaScript tittat på flera prototypobjekt för att bestämma att en egenskap är odefinierad. En uppslagning sker alltid, och denna uppslagsprocess är hur JavaScript hanterar arv såväl som enkla egenskapsuppslag.


Använder sig av hasOwnProperty för att verifiera att en objektegenskap inte kommer från prototypkedjan

Medan i Operatören kan kontrollera egenskaper för ett objekt, inklusive egenskaper från prototypkedjan, hasOwnProperty Metoden kan kontrollera ett objekt för en egenskap som inte är från prototypkedjan.

I följande prov vill vi veta om myObject innehåller fastigheten foo, och att det inte ärva arvet från prototypkedjan. För att göra detta frågar vi om myObject har sin egen egendom kallad foo.

Prov: sample41.html

 

De hasOwnProperty Metoden bör utnyttjas när du behöver bestämma om en egenskap är lokal för ett objekt eller ärvt från prototypkedjan.


Kontrollera om ett objekt innehåller en given egenskap med hjälp av i Operatör

De i operatör används för att verifiera (true eller false) om ett objekt innehåller en given egenskap. I det här provet kontrollerar vi för att se om foo är en egendom i myObject.

Prov: sample42.html

 

Du borde vara medveten om att i Operatören kontrollerar inte bara egenskaper som finns i objektet som refereras, utan också för alla egenskaper som objektet ärverger via prototyp kedja. Således gäller samma egenskapsuppslagningsregler och egenskapen, om inte i det aktuella objektet, kommer att sökas på prototyp kedja.

Detta innebär att myObject i föregående exempel faktiskt innehåller a att stränga fastighetsmetod via prototyp kedja (Object.prototype.toString), även om vi inte angav en (t.ex.., myObject.toString = 'foo').

Prov: sample43.html

 

I det sista kodexemplet är egenskapen toString inte bokstavligen inne i myObject-objektet. Men det är ärvt från Object.prototype, och så i operatören slutsatsen att myObject har faktiskt en ärvt att stränga() fastighetsmetod.


Räkna upp (Loop Over) ett objekts egenskaper med hjälp av för i Slinga

Genom att använda för in, vi kan slinga över varje egendom i ett objekt. I följande prov använder vi för in loop för att hämta egenskapsnamnen från cody-objektet.

Prov: sample44.html

 

De för in loop har en nackdel. Det kommer inte bara att få åtkomst till egenskaperna hos det specifika objektet som slingas över. Det kommer också att inkludera alla egenskaper som ärvs (via prototypkedjan) av objektet i slingan. Om detta inte är det önskade resultatet, och det mesta är det inte, måste vi använda en enkel om uttalande inuti slingan för att se till att vi bara får tillgång till egenskaperna som ingår i det specifika objektet vi slingrar över. Detta kan göras genom att använda hasOwnProperty () metod som ärftas av alla objekt.

Ordningen i vilken egenskaperna är åtkomliga i slingan är inte alltid den ordning i vilken de definieras i slingan. Dessutom är ordningen där du definierade egenskaper inte nödvändigtvis den ordning de är åtkomna.

Endast egenskaper som är uppräknade (dvs tillgängliga vid slingning över objektegenskaper) dyker upp med för in slinga. Konfigurationsegenskapen kommer till exempel inte att dyka upp. Det är möjligt att kolla vilka egenskaper som kan räknas med propertyIsEnumerable () metod.


Värdarobjekt och infödda objekt

Du bör vara medveten om att miljön (t.ex. en webbläsare) där JavaScript körs innehåller vanligtvis vad som kallas värdobjekt. Värdobjekt ingår ej i ECMAScript-implementeringen, men är tillgängliga som objekt under körning. Naturligtvis beror tillgängligheten och beteendet hos ett värdobjekt fullständigt på vad värdmiljön ger.

Till exempel, i webbläsarmiljön anses fönstret / huvudobjektet och alla dess innehållande objekt (med undantag för vad JavaScript tillhandahåller) som värdobjekt.

I följande exempel undersöker jag egenskaperna hos fönster objekt.

Prov: sample45.html

 

Du kanske har märkt att inbyggda JavaScript-objekt inte är listade bland värdobjekten. Det är ganska vanligt att en webbläsare skiljer mellan värdobjekt och inhemska objekt.

Som det gäller webbläsare är det mest kända av alla värdobjekt gränssnittet för att arbeta med HTML-dokument, även känt som DOM. Följande prov är en metod för att lista alla föremål som finns i window.document objekt som tillhandahålls av webbläsarmiljön.

Prov: sample46.html

 

Vad jag vill att du ska lära dig här är att JavaScript-specifikationen inte berör sig av värdobjekt och vice versa. Det finns en delningslinje mellan vad JavaScript tillhandahåller (t.ex. JavaScript 1.5, ECMA-262, Edition 3 versus Mozillas JavaScript 1.6, 1.7, 1.8, 1.8.1, 1.8.5) och vad värdmiljön ger, och dessa två borde inte vara förvirrad.

Värdmiljön (t.ex. en webbläsare) som kör JavaScript-kod tillhandahåller vanligtvis huvudobjektet (t ex fönsterobjekt i en webbläsare) där de inhemska delarna av språket lagras tillsammans med värdobjekt (t.ex.., window.location i en webbläsare) och användardefinierade objekt (t ex koden du skriver för att köra i webbläsaren).

Ibland kommer en webbläsarproducent, som värd för JavaScript-tolken, att driva fram en version av JavaScript eller lägga till framtida specifikationer för JavaScript innan de har godkänts (t.ex. Mozilla Firefox JavaScript 1.6, 1.7, 1.8, 1.8.1, 1.8. 5).


Förbättra och förlänga objekt med Underscore.js

JavaScript 1.5 saknas när det är dags att seriöst manipulera och hantera objekt. Om du kör JavaScript i en webbläsare vill jag vara fet här och föreslå användningen av Underscore.js när du behöver mer funktionalitet än vad som tillhandahålls av JavaScript 1.5. Underscore.js ger följande funktion när man hanterar objekt.

Dessa funktioner fungerar på alla objekt och arrays:

  • varje()
  • Karta()
  • minska()
  • reduceRight ()
  • upptäcka, detektera()
  • Välj()
  • avvisa()
  • Allt()
  • några()
  • inkludera()
  • åberopa()
  • plocka()
  • max ()
  • min ()
  • sortera efter()
  • sortIndex ()
  • toArray ()
  • storlek()

Dessa funktioner fungerar på alla objekt:

  • nycklar ()
  • värden ()
  • funktioner ()
  • förlänga()
  • klona()
  • kran()
  • är jämställd()
  • är tom()
  • isElement ()
  • IsArray ()
  • isArguments
  • isfunction ()
  • isString ()
  • ISNUMBER
  • IsBoolean
  • IsDate
  • isRegExp
  • isNaN
  • är inget
  • isUndefined

Slutsats

Jag gillar det här biblioteket eftersom det utnyttjar de nya infödda tilläggen till JavaScript där webbläsare stöder dem, men ger också samma funktion till webbläsare som inte alls utan att ändra den inhemska implementeringen av JavaScript om det inte är nödvändigt att.

Innan du börjar använda Underscore.js, se till att funktionaliteten du behöver inte redan tillhandahålls av ett JavaScript-bibliotek eller en ram som redan kan användas i din kod.