Et komplekst objekt kan inneholde noen tillatt JavaScript-verdi. I følgende kode lager jeg en Gjenstand()
objekt som heter myObject
og legg deretter til egenskaper som representerer de fleste verdiene som er tilgjengelige i JavaScript.
Eksempel: sample29.html
Det enkle konseptet å lære her er at komplekse objekter kan containere refererer til alt du kan uttrykke uttrykkelig i JavaScript. Du bør ikke bli overrasket når du ser dette gjort, da alle de innfødte objektene kan bli mutert. Dette gjelder også for Streng ()
, Nummer()
, og Boolean ()
verdier i deres objektform, dvs. når de er opprettet med ny
operatør.
De Gjenstand()
, Array ()
, og Funksjon()
Objekter kan inneholde andre komplekse gjenstander. I den følgende prøven demonstrerer jeg dette ved å sette opp et objekttre med Gjenstand()
objekter.
Eksempel: sample30.html
Det samme kan gjøres med en Array ()
objekt (aka flerdimensjonal array), eller med a Funksjon()
gjenstand.
Eksempel: sample31.html
Hovedbegrepet å ta bort her er at noen av de komplekse gjenstandene er utformet for å inkapslere andre gjenstander på en programmisk fordelaktig måte.
Vi kan få, sette eller oppdatere objektets egenskaper ved å bruke enten punktnotering eller brakettnotasjon.
I følgende eksempel demonstrerer jeg punktnotering, som oppnås ved å bruke objektnavnet etterfulgt av en periode, og deretter etterfulgt av egenskapen for å få, angi eller oppdatere (f.eks.., objectName.property
).
Eksempel: sample32.html
Dot notation er den vanligste notasjonen for å få, sette inn eller oppdatere objektets egenskaper.
Brakettnotasjon, med mindre det er nødvendig, er ikke så vanlig. I følgende eksempel erstatter jeg punktnotasjonen som ble brukt i den forrige prøven med brakettnotasjon. Objektnavnet er etterfulgt av en åpningsbrakett, eiendomsnavnet (i anførselstegn), og deretter en sluttbrakett:
Eksempel: sample33.html
Brakettnotasjon kan være svært nyttig når du trenger tilgang til en egenskapstast og hva du må jobbe med er en variabel som inneholder en strengverdi som representerer eiendomsnavnet. I den neste prøven demonstrerer jeg fordelen av brakettnotasjon over punktnotering ved å bruke den for å få tilgang til eiendommen foobar
. Jeg gjør dette ved å bruke to variabler som, når de blir med, produserer strengversjonen av egenskapsnøkkelen som finnes i foobarObject
.
Eksempel: sample34.html
I tillegg kan brakett notering komme til nytte for å komme til eiendomsnavn som er ugyldige JavaScript-identifikatorer. I følgende kode bruker jeg et nummer og et reservert søkeord som et eiendomsnavn (gyldig som en streng) som bare brakettnotasjon kan få tilgang til.
Eksempel: sample35.html
Fordi objekter kan inneholde andre objekter, cody.object.object.object.object
eller Cody [ 'objekt'] [ 'objekt'] [ 'objekt'] [ 'objekt']
kan ses til tider. Dette kalles objektkjetting. Innkapslingen av objekter kan gå på ubestemt tid.
Objekter er mutable i JavaScript, noe som betyr at det å få, sette inn eller oppdatere dem, kan utføres på de fleste objekter når som helst. Ved å bruke brakettnotasjonen (f.eks., cody [ 'alder']
), kan du etterligne associative arrays funnet på andre språk.
Hvis en egenskap inne i et objekt er en metode, er alt du trenger å gjøre, å bruke ()
operatører (f.eks., cody.getGender ()
) for å påkalle eiendomsmetoden.
De slette
operatør kan brukes til å helt fjerne egenskaper fra en gjenstand. I følgende kodestykke sletter vi Bar
eiendom fra foo
gjenstand.
Eksempel: sample36.html
slette
Vil ikke slette egenskaper som finnes på prototypekjeden.
Sletting er den eneste måten å faktisk fjerne en eiendom fra et objekt. Setter en eiendom til udefinert
eller null
endrer bare verdien av eiendommen. Det fjerner ikke eiendommen fra objektet.
Hvis du forsøker å få tilgang til en egenskap som ikke finnes i et objekt, vil JavaScript forsøke å finne egenskapen eller metoden ved hjelp av prototypekjeden. I følgende eksempel lager jeg en matrise og forsøker å få tilgang til en eiendom som kalles foo
som ennå ikke er definert. Du tror kanskje det fordi myArray.foo
er ikke en eiendom av myArray
objekt, vil JavaScript umiddelbart returnere udefinert
. Men JavaScript vil se på to steder (Array.prototype
og så Object.prototype
) for verdien av foo
før den kommer tilbake udefinert
.
Eksempel: sample37.html
eiendommen. Hvis den har eiendommen, vil den returnere verdien av eiendommen, og det er ingen arv som oppstår fordi prototypekjeden ikke er leveransert. Hvis forekomsten ikke har egenskapen, vil JavaScript se etter det på objektets konstruktørfunksjon prototype
gjenstand.
Alle objektet forekomster har en eiendom som er en hemmelig lenke (aka __proto__
) til konstruktørfunksjonen som skapte forekomsten. Denne hemmelige lenken kan brukes til å ta tak i konstruktørfunksjonen, spesielt prototypegenskapen til instanskonstruktorfunksjonen.
Dette er en av de mest forvirrende aspekter av objekter i JavaScript. Men la oss begrunne dette. Husk at en funksjon er også et objekt med egenskaper. Det er fornuftig å tillate gjenstander å arve egenskaper fra andre gjenstander. Akkurat som å si: "Hei objekt B, jeg vil at du skal dele alle egenskapene som objekt A har." JavaScript slår dette hele opp for innfødte objekter som standard via prototype
gjenstand. Når du lager dine egne konstruktørfunksjoner, kan du også utnytte prototype-kjetting.
Hvordan nettopp JavaScript oppnår dette er forvirrende til du ser det for hva det er: bare et sett med regler. La oss lage en matrise for å undersøke prototype
eiendom nærmere.
Eksempel: sample38.html
Våre Array ()
eksempel er et objekt med egenskaper og metoder. Når vi åpner en av matematiske metoder, for eksempel bli med()
, la oss spørre oss selv: Oppretter myArray-forekomsten fra Array ()
Konstruktøren har sin egen bli med()
metode? La oss sjekke.
Eksempel: sample39.html
Nei det gjør det ikke. Likevel har myArray tilgang til bli med()
Metode som om det var egen eiendom. Hva skjedde her? Vel, du har bare observert prototypekjeden i aksjon. Vi har tilgang til en egenskap som, selv om den ikke finnes i myArray-objektet, kan bli funnet av JavaScript et annet sted. At et annet sted er veldig spesifikt. Når Array ()
konstruktør ble opprettet av JavaScript, the bli med()
Metoden ble lagt til (blant annet) som en eiendom av prototype
tilhører Array ()
.
For å gjenta, hvis du prøver å få tilgang til en eiendom på et objekt som ikke inneholder det, vil JavaScript søke i prototype
kjede for denne verdien. Først vil det se på konstruktørfunksjonen som skapte objektet (f.eks., Array
), og inspiser prototypen (f.eks., Array.prototype
) for å se om eiendommen kan bli funnet der. Hvis det første prototypobjektet ikke har egenskapen, fortsetter JavaScript å søke opp kjeden på konstruktøren bak den opprinnelige konstruktøren. Det kan gjøre dette hele veien opp til enden av kjeden.
Hvor slutter kjeden? La oss undersøke eksemplet på nytt, påkalle toLocaleString ()
metode på myArray
.
Eksempel: sample40.html
De toLocaleString ()
Metoden er ikke definert i myArray
gjenstand. Så, prototype chaining regel er påkalt og JavaScript ser etter eiendommen i Array
konstruktørens prototypeegenskaper (f.eks., Array.prototype
). Det er heller ikke der, så kjedestyrelsen påberopes igjen, og vi ser etter eiendommen i Gjenstand()
prototype eiendom (Object.prototype
). Og ja, det er funnet der. Hadde det ikke blitt funnet der, ville JavaScript ha produsert en feil som angav at eiendommen var udefinert
.
Siden alle prototypegenskaper er objekter, er den endelige koblingen i kjeden Object.prototype
. Det er ingen andre konstruktørprototypegenskaper som kan undersøkes.
Det er et helt kapittel som bryter ned prototypekjeden i mindre deler, så hvis dette var helt tapt på deg, les det kapitlet og kom tilbake til denne forklaringen for å styrke din forståelse. Fra denne korte lese om saken, håper jeg at du forstår det når en eiendom ikke er funnet (og anses udefinert
), Vil JavaScript ha sett på flere prototypeobjekter for å fastslå at en eiendom er udefinert
. Et oppslag skjer alltid, og denne oppslagsprosessen er hvordan JavaScript håndterer arv, så vel som enkle eiendomsoppslag.
hasOwnProperty
å bekrefte at et objekteiendom ikke er fra prototypekjedenMens i
operatøren kan sjekke egenskapene til et objekt, inkludert egenskaper fra prototypekjeden, hasOwnProperty
Metoden kan sjekke et objekt for en egenskap som ikke er fra prototypekjeden.
I den følgende prøven vil vi vite om myObject
inneholder eiendommen foo
, og at den ikke arver eiendommen fra prototypekjeden. For å gjøre dette spør vi om myObject
har sin egen eiendom kalt foo
.
Eksempel: sample41.html
De hasOwnProperty
Metoden bør utnyttes når du må avgjøre om en eiendom er lokal til en gjenstand eller arvet fra prototypekjeden.
i
OperatørDe i
operatør brukes til å verifisere (true eller false) hvis et objekt inneholder en gitt egenskap. I denne prøven sjekker vi for å se om foo
er en eiendom i myObject
.
Eksempel: sample42.html
Du bør være oppmerksom på at i
Operatøren kontrollerer ikke bare egenskaper som finnes i objektet som refereres, men også for egenskaper som objektet arver via prototype
kjede. Således gjelder de samme egenskapene for oppsøkingsregler og eiendommen, om ikke i det nåværende objektet, vil bli søkt på prototype
kjede.
Dette betyr at myObject i den forrige prøven faktisk inneholder en toString
eiendomsmetode via prototype
kjede (Object.prototype.toString
), selv om vi ikke angav en (f.eks., myObject.toString = 'foo'
).
Eksempel: sample43.html
I det siste kodeeksemplet er egenskapen toString ikke bokstavelig talt inne i myObject-objektet. Det er imidlertid arvet fra Object.prototype
, og så i
operatøren konkluderer med det myObject
har faktisk en arvet toString ()
eiendomsmetode.
til
i
LoopVed bruk av for i
, vi kan gå over hver eiendom i et objekt. I følgende eksempel bruker vi for i
loop for å hente eiendomsnavnet fra cody-objektet.
Eksempel: sample44.html
De for i
loop har en ulempe. Det vil ikke bare få tilgang til egenskapene til det bestemte objektet som er sløyfet over. Det vil også inkludere i løpet av løkken noen egenskaper som ervervet (via prototypekjeden) av objektet. Således, hvis dette ikke er det ønskede resultatet, og det meste av tiden ikke er, må vi bruke en enkel hvis
uttalelse innsiden av sløyfen for å sikre at vi bare får tilgang til egenskapene som finnes i den spesifikke gjenstanden vi slår over. Dette kan gjøres ved å bruke hasOwnProperty ()
metode arvet av alle objekter.
Ordren der egenskapene er tilgjengelige i løkken, er ikke alltid den rekkefølgen de er definert i løkken. I tillegg er rekkefølgen du definerte egenskaper ikke nødvendigvis den rekkefølgen de er tilgjengelige for.
Bare egenskaper som er tallrike (dvs. tilgjengelig når looping over objektegenskaper) dukker opp med for i
sløyfe. For eksempel vil ikke konstruktøregenskapen dukke opp. Det er mulig å sjekke hvilke egenskaper som er tallrike med propertyIsEnumerable ()
metode.
Du bør være oppmerksom på at miljøet (for eksempel en nettleser) der JavaScript utføres, inneholder vanligvis det som er kjent som vertsobjekter. Vertsobjekter er ikke en del av ECMAScript-implementeringen, men er tilgjengelige som objekter under utførelse. Selvfølgelig er tilgjengeligheten og oppførselen til et vertsobjekt helt avhengig av hva vertsmiljøet gir.
For eksempel, i nettlesermiljøet betraktes vinduet / hodetobjektet og alle dets inneholdende objekter (unntatt det som JavaScript oppgir) vertsobjekter.
I det følgende eksemplet undersøker jeg egenskapene til vindu
gjenstand.
Eksempel: sample45.html
Du har kanskje lagt merke til at innfødte JavaScript-objekter ikke er oppført blant vertsobjektene. Det er ganske vanlig at en nettleser skiller mellom vertsobjekter og innfødte objekter.
Som det gjelder nettlesere, er det mest kjente av alle verteobjekter grensesnittet for å arbeide med HTML-dokumenter, også kjent som DOM. Følgende eksempel er en metode for å liste alle objekter som er inneholdt i window.document
objekt levert av nettlesermiljøet.
Eksempel: sample46.html
Det jeg vil at du skal lære her er at JavaScript-spesifikasjonen ikke gjelder seg med vertsobjekter og omvendt. Det er en skillelinje mellom det JavaScript gir (f.eks. JavaScript 1.5, ECMA-262, Edition 3 versus Mozillas JavaScript 1.6, 1.7, 1.8, 1.8.1, 1.8.5) og hva vertsmiljøet gir, og disse to skal ikke være forvirret.
Vertsmiljøet (for eksempel en nettleser) som kjører JavaScript-kode, gir vanligvis hovedobjektet (for eksempel vinduobjekt i en nettleser) der de opprinnelige delene av språket lagres sammen med vertsobjekter (f.eks.., window.location
i en nettleser) og brukerdefinerte objekter (for eksempel koden du skriver for å kjøre i nettleseren).
Noen ganger vil en nettleserprodusent, som vert for JavaScript-tolk, skyve fram en versjon av JavaScript eller legge til fremtidige spesifikasjoner til JavaScript før de er godkjent (f.eks. Mozilla's Firefox JavaScript 1.6, 1.7, 1.8, 1.8.1, 1.8. 5).
JavaScript 1.5 mangler når det kommer tid til å manipulere og håndtere saker på alvor. Hvis du kjører JavaScript i en nettleser, vil jeg gjerne være fet her og foreslå bruken av Underscore.js når du trenger mer funksjonalitet enn det som er gitt av JavaScript 1.5. Underscore.js gir følgende funksjonalitet når det handler om objekter.
Disse funksjonene fungerer på alle objekter og arrays:
Hver()
kart()
redusere()
reduceRight ()
detektere ()
å velge()
avvise ()
alle()
noen()
inkludere()
påkalle ()
plukke()
max ()
min ()
Sorter etter()
sortIndex ()
toArray ()
størrelse()
Disse funksjonene fungerer på alle objekter:
nøkler ()
verdier ()
funksjoner ()
forlenge()
klone ()
trykk ()
er lik()
er tom()
isElement ()
isArray ()
isArguments
isFunction ()
isString ()
ISNUMBER
isBoolean
isDate
isRegExp
isNaN
isNull
isUndefined
Jeg liker dette biblioteket fordi det utnytter de nye innfødte tilleggene til JavaScript der nettlesere støtter dem, men gir også samme funksjonalitet til nettlesere som ikke gjør det, uten å endre den innfødte implementeringen av JavaScript, med mindre det må.
Før du begynner å bruke Underscore.js, må du kontrollere at funksjonaliteten du trenger ikke allerede er gitt av et JavaScript-bibliotek eller et rammeverk som allerede er i bruk i koden din..