Lavorare con oggetti e proprietà

Un oggetto complesso può contenere qualsiasi valore JavaScript consentito. Nel seguente codice, creo un Oggetto() oggetto chiamato myObject e quindi aggiungere proprietà che rappresentano la maggior parte dei valori disponibili in JavaScript.


Oggetti complessi

Esempio: sample29.html

 

Il concetto semplice da apprendere qui è che gli oggetti complessi possono contenere o riferirsi a qualsiasi cosa tu possa esprimere nominalmente in JavaScript. Non dovresti essere sorpreso quando vedi questo fatto, poiché tutti gli oggetti nativi possono essere mutati. Questo vale anche per Stringa(), Numero(), e Booleana () valori nella loro forma oggetto, cioè quando vengono creati con il nuovo operatore.


Incapsulamento di oggetti complessi in modo programmaticamente vantaggioso

Il Oggetto(), Array (), e Funzione() gli oggetti possono contenere altri oggetti complessi. Nell'esempio seguente, lo dimostrerò configurando un albero degli oggetti usando Oggetto() oggetti.

Esempio: sample30.html

 

La stessa cosa può essere fatta con un Array () oggetto (aka array multidimensionale), o con a Funzione() oggetto.

Esempio: sample31.html

 

Il concetto principale da portare via è che alcuni degli oggetti complessi sono progettati per incapsulare altri oggetti in modo programmaticamente vantaggioso.


Recupero, impostazione e aggiornamento delle proprietà di un oggetto mediante notazione a punti o notazione di parentesi

Possiamo ottenere, impostare o aggiornare le proprietà di un oggetto utilizzando la notazione a punti o la notazione di parentesi.

Nell'esempio seguente, mostro la notazione dei punti, che viene eseguita utilizzando il nome dell'oggetto seguito da un punto e quindi seguito dalla proprietà per ottenere, impostare o aggiornare (ad es.., objectName.property).

Esempio: sample32.html

 

La notazione a punti è la notazione più comune per ottenere, impostare o aggiornare le proprietà di un oggetto.

La notazione del bracketing, se non richiesto, non è così comunemente usata. Nel seguente esempio, sostituisco la notazione punto utilizzata nel campione precedente con notazione della parentesi. Il nome dell'oggetto è seguito da una parentesi aperta, dal nome della proprietà (tra virgolette) e da una parentesi chiusa:

Esempio: sample33.html

 

La notazione di parentesi può essere molto utile quando è necessario accedere a una chiave di proprietà e ciò con cui si deve lavorare è una variabile che contiene un valore di stringa che rappresenta il nome della proprietà. Nell'esempio successivo, mostro il vantaggio della notazione delle parentesi sulla notazione dei punti usandola per accedere alla proprietà foobar. Lo faccio utilizzando due variabili che, una volta uniti, producono la versione di stringa della chiave di proprietà contenuta in foobarObject.

Esempio: sample34.html

 

Inoltre, la notazione delle parentesi può essere utile per ottenere nomi di proprietà che non sono identificativi JavaScript validi. Nel codice seguente, utilizzo un numero e una parola chiave riservata come nome di una proprietà (valido come stringa) a cui può accedere solo la notazione della parentesi.

Esempio: sample35.html

 

Perché gli oggetti possono contenere altri oggetti, cody.object.object.object.object o Cody [ 'oggetto'] [ 'oggetto'] [ 'oggetto'] [ 'oggetto'] può essere visto a volte. Questo è chiamato concatenamento di oggetti. L'incapsulamento degli oggetti può continuare all'infinito.

Gli oggetti sono mutabili in JavaScript, il che significa che è possibile ottenerli, impostarli o aggiornarli sulla maggior parte degli oggetti in qualsiasi momento. Usando la notazione della parentesi (ad es., Cody [ 'età']), puoi imitare gli array associativi trovati in altre lingue.

Se una proprietà all'interno di un oggetto è un metodo, tutto ciò che devi fare è usare il () operatori (ad es., cody.getGender ()) per richiamare il metodo della proprietà.


Eliminazione delle proprietà dell'oggetto

Il Elimina l'operatore può essere utilizzato per rimuovere completamente le proprietà da un oggetto. Nel seguente frammento di codice, eliminiamo il bar proprietà dal foo oggetto.

Esempio: sample36.html

 

Elimina non cancellerà le proprietà che si trovano sulla catena del prototipo.

L'eliminazione è l'unico modo per rimuovere effettivamente una proprietà da un oggetto. Impostazione di una proprietà a non definito o nullo cambia solo il valore della proprietà. Non rimuove la proprietà dall'oggetto.


Come vengono risolti i riferimenti alle proprietà dell'oggetto

Se si tenta di accedere a una proprietà che non è contenuta in un oggetto, JavaScript tenterà di trovare la proprietà o il metodo utilizzando la catena del prototipo. Nel seguente esempio, creo una matrice e tento di accedere a una proprietà chiamata foo che non è stato ancora definito. Potresti pensarlo perché myArray.foo non è una proprietà del myArray oggetto, JavaScript restituirà immediatamente non definito. Ma JavaScript guarderà in altri due posti (Array.prototype e poi Object.prototype) per il valore di foo prima che ritorni non definito.

Esempio: sample37.html

 

la proprietà. Se ha la proprietà, restituirà il valore della proprietà e non vi è alcuna eredità che si verifica perché la catena del prototipo non viene sfruttata. Se l'istanza non ha la proprietà, JavaScript la cercherà sulla funzione di costruzione dell'oggetto prototipo oggetto.

Tutte le istanze di oggetti hanno una proprietà che è un collegamento segreto (aka __proto__) alla funzione di costruzione che ha creato l'istanza. Questo collegamento segreto può essere sfruttato per afferrare la funzione di costruzione, in particolare la proprietà prototipo della funzione di costruzione delle istanze.

Questo è uno degli aspetti più confusi degli oggetti in JavaScript. Ma ragioniamo su questo. Ricorda che una funzione è anche un oggetto con proprietà. Ha senso consentire agli oggetti di ereditare proprietà da altri oggetti. Proprio come dire: "Ehi oggetto B, vorrei che tu condividessi tutte le proprietà dell'oggetto A". JavaScript collega questo tutto per gli oggetti nativi per impostazione predefinita tramite prototipo oggetto. Quando crei le tue funzioni di costruzione, puoi sfruttare anche il concatenamento dei prototipi.

Quanto esattamente JavaScript riesca a realizzare questo è fonte di confusione finché non lo si vede per quello che è: solo un insieme di regole. Creiamo un array per esaminare il prototipo proprietà più vicina.

Esempio: sample38.html

 

Nostro Array () istanza è un oggetto con proprietà e metodi. Come accediamo a uno dei metodi dell'array, come ad esempio aderire(), chiediamoci: l'istanza myArray creata da Array () costruttore ha il suo aderire() metodo? Controlliamo.

Esempio: sample39.html

 

No non lo fa. Tuttavia myArray ha accesso a aderire() metodo come se fosse di sua proprietà. Cos'è successo qua? Bene, hai appena osservato la catena del prototipo in azione. Abbiamo accesso a una proprietà che, sebbene non contenuta nell'oggetto myArray, potrebbe essere trovata da JavaScript da qualche altra parte. Che da qualche altra parte è molto specifico. Quando il Array () costruttore è stato creato da JavaScript, il aderire() il metodo è stato aggiunto (tra gli altri) come proprietà di prototipo proprietà di Array ().

Per reiterare, se provi ad accedere a una proprietà su un oggetto che non lo contiene, JavaScript cercherà il prototipo catena per questo valore. Innanzitutto esaminerà la funzione di costruzione che ha creato l'oggetto (ad es., schieramento), e ispezionare il suo prototipo (ad es., Array.prototype) per vedere se la proprietà può essere trovata lì. Se il primo oggetto prototipo non ha la proprietà, allora JavaScript continua a cercare la catena nel costruttore dietro il costruttore iniziale. Può farlo fino alla fine della catena.

Dove finisce la catena? Esaminiamo di nuovo l'esempio, invocando il toLocaleString () metodo attivo myArray.

Esempio: sample40.html

 

Il toLocaleString () il metodo non è definito all'interno del myArray oggetto. Quindi, viene invocata la regola del concatenamento del prototipo e JavaScript cerca la proprietà nel schieramento proprietà prototipo di costruttori (ad es., Array.prototype). Non è neanche lì, quindi la regola della catena viene invocata di nuovo e cerchiamo la proprietà nel Oggetto() proprietà prototipo (Object.prototype). E sì, si trova lì. Se non fosse stato trovato lì, JavaScript avrebbe prodotto un errore affermando che la proprietà era non definito.

Poiché tutte le proprietà del prototipo sono oggetti, il collegamento finale della catena è Object.prototype. Non esiste altra proprietà prototipo del costruttore che possa essere esaminata.

C'è un intero capitolo avanti che suddivide la catena del prototipo in parti più piccole, quindi se questo è stato completamente perso su di te, leggi quel capitolo e poi torna a questa spiegazione per consolidare la tua comprensione. Da questa breve lettura sull'argomento, spero che tu capisca che quando una proprietà non viene trovata (e considerata non definito), JavaScript avrà esaminato diversi oggetti prototipo per determinare che una proprietà è non definito. Si verifica sempre una ricerca e questo processo di ricerca è il modo in cui JavaScript gestisce l'ereditarietà e le ricerche di proprietà semplici.


utilizzando hasOwnProperty per verificare che una proprietà dell'oggetto non provenga dalla catena del prototipo

Mentre il nel l'operatore può controllare le proprietà di un oggetto, incluse le proprietà della catena del prototipo, il hasOwnProperty il metodo può controllare un oggetto per una proprietà che non proviene dalla catena del prototipo.

Nel seguente esempio, vogliamo sapere se myObject contiene la proprietà foo, e che non eredita la proprietà dalla catena del prototipo. Per fare questo, chiediamo se myObject ha una sua proprietà chiamata foo.

Esempio: sample41.html

 

Il hasOwnProperty il metodo deve essere sfruttato quando è necessario determinare se una proprietà è locale a un oggetto o ereditata dalla catena del prototipo.


Verifica se un oggetto contiene una proprietà data utilizzando il nel Operatore

Il nel l'operatore viene utilizzato per verificare (vero o falso) se un oggetto contiene una determinata proprietà. In questo esempio, stiamo controllando per vedere se foo è una proprietà in myObject.

Esempio: sample42.html

 

Dovresti essere consapevole che il nel l'operatore controlla non solo le proprietà contenute nell'oggetto referenziato, ma anche le proprietà che l'oggetto eredita tramite prototipo catena. Pertanto, si applicano le stesse regole di ricerca proprietà e la proprietà, se non nell'oggetto corrente, verrà cercata sul prototipo catena.

Ciò significa che myObject nel campione precedente contiene effettivamente a accordare metodo di proprietà tramite il prototipo catena (Object.prototype.toString), anche se non ne abbiamo specificato uno (ad es., myObject.toString = 'foo').

Esempio: sample43.html

 

Nell'ultimo esempio di codice, la proprietà toString non si trova letteralmente all'interno dell'oggetto myObject. Tuttavia, è ereditato da Object.prototype, e così il nel l'operatore lo conclude myObject ha infatti ereditato accordare() metodo di proprietà.


Enumerare (Loop Over) le proprietà di un oggetto usando il per nel Ciclo continuo

Usando per dentro, possiamo scorrere su ogni proprietà in un oggetto. Nel seguente esempio, stiamo usando il per dentro loop per recuperare i nomi delle proprietà dall'oggetto cody.

Esempio: sample44.html

 

Il per dentro il ciclo ha un inconveniente. Non solo accederà alle proprietà dell'oggetto specifico in fase di looping. Includerà inoltre nel ciclo tutte le proprietà ereditate (tramite la catena del prototipo) dall'oggetto. Quindi, se questo non è il risultato desiderato, e il più delle volte non lo è, dobbiamo usare un semplice Se istruzione all'interno del ciclo per essere sicuri di accedere solo alle proprietà contenute all'interno dell'oggetto specifico su cui stiamo eseguendo il ciclo. Questo può essere fatto usando il hasOwnProperty () metodo ereditato da tutti gli oggetti.

L'ordine in cui le proprietà sono accessibili nel ciclo non è sempre l'ordine in cui sono definite all'interno del ciclo. Inoltre, l'ordine in cui sono state definite le proprietà non è necessariamente l'ordine a cui si accede.

Solo le proprietà enumerabili (ovvero disponibili quando si esegue il looping su una proprietà di un oggetto) vengono visualizzate con per dentro ciclo continuo. Ad esempio, la proprietà del costruttore non verrà visualizzata. È possibile controllare quali proprietà sono enumerabili con propertyIsEnumerable () metodo.


Oggetti host e oggetti nativi

È necessario essere consapevoli del fatto che l'ambiente (ad es. Un browser Web) in cui viene eseguito JavaScript in genere contiene i cosiddetti oggetti host. Gli oggetti host non fanno parte dell'implementazione di ECMAScript, ma sono disponibili come oggetti durante l'esecuzione. Naturalmente, la disponibilità e il comportamento di un oggetto host dipendono completamente da ciò che fornisce l'ambiente host.

Ad esempio, nell'ambiente del browser Web l'oggetto window / head e tutti i relativi oggetti contenenti (esclusi i dati forniti da JavaScript) sono considerati oggetti host.

Nell'esempio seguente, esamino le proprietà di finestra oggetto.

Esempio: sample45.html

 

Potresti aver notato che gli oggetti JavaScript nativi non sono elencati tra gli oggetti host. È abbastanza comune che un browser distingua tra oggetti host e oggetti nativi.

Per quanto riguarda i browser web, il più famoso di tutti gli oggetti ospitati è l'interfaccia per lavorare con documenti HTML, noto anche come DOM. Il seguente esempio è un metodo per elencare tutti gli oggetti contenuti all'interno di window.document oggetto fornito dall'ambiente del browser.

Esempio: sample46.html

 

Quello che voglio che tu apprenda qui è che la specifica JavaScript non riguarda se stessa con gli oggetti host e viceversa. Esiste una linea divisoria tra ciò che JavaScript fornisce (ad esempio, JavaScript 1.5, ECMA-262, Edizione 3 rispetto a JavaScript di Mozilla 1.6, 1.7, 1.8, 1.8.1, 1.8.5) e ciò che l'ambiente host fornisce, e questi due non dovrebbero essere confuso.

L'ambiente host (ad esempio, un browser Web) che esegue il codice JavaScript fornisce in genere l'oggetto principale (ad esempio, l'oggetto finestra in un browser Web) in cui le porzioni native della lingua vengono archiviate insieme agli oggetti host (ad es.., window.location in un browser Web) e oggetti definiti dall'utente (ad esempio, il codice che scrivi per essere eseguito nel browser Web).

A volte un produttore di browser web, come l'host dell'interprete JavaScript, spinge in avanti una versione di JavaScript o aggiunge specifiche future a JavaScript prima che siano state approvate (ad esempio Firefox JavaScript 1.6, 1.7, 1.8, 1.8.1, 1.8 di Mozilla. 5).


Miglioramento ed estensione di oggetti con Underscore.js

JavaScript 1.5 manca quando arriva il momento di manipolare e gestire seriamente gli oggetti. Se stai usando JavaScript in un browser web, vorrei essere grassetto qui e suggerire l'uso di Underscore.js quando hai bisogno di più funzionalità di quelle fornite da JavaScript 1.5. Underscore.js fornisce le seguenti funzionalità quando si tratta di oggetti.

Queste funzioni funzionano su tutti gli oggetti e gli array:

  • ogni()
  • carta geografica()
  • ridurre()
  • reduceRight ()
  • rilevare ()
  • selezionare()
  • rifiutare()
  • tutti()
  • qualunque()
  • includere()
  • invocare()
  • cogliere ()
  • max ()
  • min ()
  • ordina per()
  • sortIndex ()
  • toArray ()
  • taglia()

Queste funzioni funzionano su tutti gli oggetti:

  • (tasti)
  • valori()
  • funzioni ()
  • estendere()
  • clone()
  • rubinetto()
  • è uguale()
  • è vuoto()
  • isElement ()
  • IsArray ()
  • isArguments
  • isfunction ()
  • IsString ()
  • ISNUMBER
  • IsBoolean
  • IsDate
  • isRegExp
  • isNaN
  • è zero
  • isUndefined

Conclusione

Mi piace questa libreria perché sfrutta le nuove aggiunte native a JavaScript in cui i browser li supportano, ma fornisce anche le stesse funzionalità ai browser che non lo fanno, il tutto senza modificare l'implementazione nativa di JavaScript a meno che non debba.

Prima di iniziare a utilizzare Underscore.js, assicurati che la funzionalità di cui hai bisogno non sia già fornita da una libreria JavaScript o da un framework che potrebbe essere già in uso nel tuo codice.