Arbeide med objekter og egenskaper

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.


Komplekse objekter

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.


Innkapsling av komplekse objekter på en programmisk fordelaktig måte

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.


Komme, sette inn og oppdatere et objekts egenskaper ved hjelp av punktnotasjon eller brakettnotasjon

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.


Slette objektegenskaper

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.


Hvordan henvisninger til objektegenskaper er løst

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.


Ved hjelp av hasOwnProperty å bekrefte at et objekteiendom ikke er fra prototypekjeden

Mens 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.


Kontrollere om et objekt inneholder en gitt egenskap ved hjelp av i Operatør

De 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.


Opptel (overgå) et objekts egenskaper ved hjelp av til i Loop

Ved 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.


Vertsobjekter og innfødte objekter

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).


Forbedre og forlenge objekter med Underscore.js

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

Konklusjon

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..