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.
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.
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.
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.
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.
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.
hasOwnProperty
för att verifiera att en objektegenskap inte kommer från prototypkedjanMedan 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.
i
OperatörDe 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.
för
i
SlingaGenom 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.
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).
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
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.