Come accedere alla prima proprietà di un oggetto Javascript?


611

Esiste un modo elegante per accedere alla prima proprietà di un oggetto ...

  1. dove non conosci il nome delle tue proprietà
  2. senza usare un ciclo come for .. ino jQuery$.each

Ad esempio, devo accedere foo1all'oggetto senza conoscere il nome di foo1:

var example = {
    foo1: { /* stuff1 */},
    foo2: { /* stuff2 */},
    foo3: { /* stuff3 */}
};

1
è probabilmente meglio prima trasformarlo in un array
cregox il

Risposte:


1393
var obj = { first: 'someVal' };
obj[Object.keys(obj)[0]]; //returns 'someVal'

Usando questo puoi accedere anche ad altre proprietà tramite indici. Attenzione però! Object.keysl'ordine di reso non è garantito come da ECMAScript, ma ufficiosamente è implementato da tutte le principali implementazioni dei browser, per favore leggi https://stackoverflow.com/a/23202095 per dettagli su questo.


25
Dici che non è il modo più veloce. In che modo sarebbe più veloce?
T Nguyen,

3
Questo non è molto efficiente in quanto crea un intero array di tutte le chiavi dell'oggetto.
Andrew Mao,

9
@T Nguyen lo pubblicherei se lo sapessi :)
Grzegorz Kaczan

5
@DavChana - Il tuo benchmark è stato impostato in modo errato. Il blocco boilerplate verrà sempre eseguito e il blocco 2 era vuoto, il che significa che il primo risultato rappresenta l'esecuzione boilerplate + block1 , e il secondo risultato rappresenta solo il boilerplate . Ecco il benchmark corretto: http://jsben.ch/#/R9aLQ , che mostra che sono praticamente uguali (esegui il test più volte).
myfunkyside,

9
Vorrei che first()qualcosa di simile potesse gestirlo.
Fr0zenFir

113

Prova il for … inciclo e interrompi dopo la prima iterazione:

for (var prop in object) {
    // object[prop]
    break;
}

1
Penso che si tratti dell'unica opzione. Non sono sicuro che tu abbia la garanzia che le proprietà saranno ripetute in un ordine prevedibile / utile. Cioè, potresti intendere foo1 ma ottenere foo3. Se le proprietà sono numerate come nell'esempio, è possibile eseguire un confronto di stringhe per accertare l'identificatore che termina con '1'. Inoltre, se l'ordinalità è la principale preoccupazione della raccolta, è consigliabile utilizzare una matrice anziché un oggetto.
steamer25,

2
Se qualcun altro è preoccupato per l'ordine, la maggior parte dei browser si comporta in modo prevedibile: stackoverflow.com/questions/280713/…
Flash

6
var prop; per interruzione (prop in oggetto); // object [prop]
netiul

12
Vecchia risposta ma. Si consiglia di verificare se la proprietà appartiene all'oggetto. come: for (..) {if (! obj.hasOwnProperty (prop)) continua; .... rompere; } nel caso in cui l'oggetto sia effettivamente vuoto, non attraversa il prototipo o qualcosa del genere.
pgarciacamou,


46

Utilizzare Object.keysper ottenere una matrice delle proprietà su un oggetto. Esempio:

var example = {
    foo1: { /* stuff1 */},
    foo2: { /* stuff2 */},
    foo3: { /* stuff3 */}
};

var keys = Object.keys(example); // => ["foo1", "foo2", "foo3"] (Note: the order here is not reliable)

Documentazione e shim cross-browser forniti qui . Un esempio del suo utilizzo può essere trovato in un'altra delle mie risposte qui .

Modifica : per chiarezza, voglio solo fare eco a ciò che è stato correttamente affermato in altre risposte: l'ordine delle chiavi negli oggetti javascript non è definito.


25

Una versione a una regola:

var val = example[function() { for (var k in example) return k }()];

2
A volte può essere rischioso da usare for insenza controllare hasOwnPropertypoiché l'oggetto contiene altri valori indesiderati aggiunti a livello di codice in modo da poter ottenere un risultato indesiderato da questo frammento. Solo perché è corto e pulito non significa che sia sicuro ottimale.
Javier Cobos,

24

Non esiste una "prima" proprietà. I tasti oggetto non sono ordinati.

Se li attraversi con un ciclo, li (var foo in bar)otterrai in un certo ordine, ma potrebbe cambiare in futuro (soprattutto se aggiungi o rimuovi altre chiavi).


Eccezionale. Sto usando un oggetto per implementare una mappa che mantiene l'ordine di inserimento. Ciò si interrompe quando rimuovo un valore perché l'inserimento successivo colma il gap. :(
David Harkness,

2
l'ordine di chiave / valore dovrebbe essere conservato nelle versioni più recenti di JS
Alexander Mills,

11

Soluzione con la libreria lodash :

_.find(example) // => {name: "foo1"}

ma non esiste alcuna garanzia dell'ordine di archiviazione interno delle proprietà dell'oggetto poiché dipende dall'implementazione della VM javascript.


2
Ho appena provato questo e non funziona. Restituisce solo il valore, non la coppia chiave / valore.
Chris Haines,

2
Nella domanda non viene menzionato che dovrebbe restituire la coppia chiave / valore, egli chiede solo l'oggetto e la risposta accettata fa esattamente come questa funzione lodash: restituisce il contenuto della prima proprietà. Potrebbe non soddisfare le tue esigenze specifiche, ma questa risposta È corretta in base alla domanda originale.
Carrm,

Sì, fa il lavoro, utile quando sai che il tuo oggetto avrà un solo oggetto figliovar object = { childIndex: { .. } }; var childObject = _.find(Object);
Raja Khoury,

9

No. Un oggetto letterale, come definito da MDC è:

un elenco di zero o più coppie di nomi di proprietà e valori associati di un oggetto, racchiuso tra parentesi graffe ({}).

Pertanto un oggetto letterale non è un array e puoi accedere alle proprietà solo usando il loro nome esplicito o un forciclo usando la inparola chiave.


25
Per gli altri che vedono solo il segno di spunta verde su questa risposta, c'è un'altra soluzione più in basso nella pagina con attualmente 350 voti.
Redfox05

7

La risposta migliore potrebbe generare l'intero array e quindi catturare dall'elenco. Ecco un'altra scorciatoia efficace

var obj = { first: 'someVal' };
Object.entries(obj)[0][1] // someVal

3

Questo è stato trattato qui prima.

Il concetto di first non si applica alle proprietà degli oggetti, e l'ordine di un ciclo for ... in non è garantito dalle specifiche, tuttavia in pratica è affidabile FIFO tranne che criticamente per chrome ( bug report ). Prendi le tue decisioni di conseguenza.


3

Non ti consiglio di usare Object.keys poiché non è supportato nelle vecchie versioni di IE. Ma se ne hai davvero bisogno, potresti usare il codice sopra per garantire la retrocompatibilità:

if (!Object.keys) {
Object.keys = (function () {
var hasOwnProperty = Object.prototype.hasOwnProperty,
    hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
    dontEnums = [
      'toString',
      'toLocaleString',
      'valueOf',
      'hasOwnProperty',
      'isPrototypeOf',
      'propertyIsEnumerable',
      'constructor'
    ],
    dontEnumsLength = dontEnums.length;

return function (obj) {
  if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');

  var result = [];

  for (var prop in obj) {
    if (hasOwnProperty.call(obj, prop)) result.push(prop);
  }

  if (hasDontEnumBug) {
    for (var i=0; i < dontEnumsLength; i++) {
      if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
    }
  }
  return result;
}})()};

Funzionalità Firefox (Gecko) 4 (2.0) Chrome 5 Internet Explorer 9 Opera 12 Safari 5

Ulteriori informazioni: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys

Ma se hai solo bisogno del primo, potremmo organizzare una soluzione più breve come:

var data = {"key1":"123","key2":"456"};
var first = {};
for(key in data){
    if(data.hasOwnProperty(key)){
        first.key = key;
        first.content =  data[key];
        break;
    }
}
console.log(first); // {key:"key",content:"123"}

2

Per ottenere il primo nome chiave nell'oggetto è possibile utilizzare:

var obj = { first: 'someVal' };
Object.keys(obj)[0]; //returns 'first'

Restituisce una stringa, quindi non è possibile accedere agli oggetti nidificati se presenti, come:

var obj = { first: { someVal : { id : 1} }; Qui con quella soluzione non è possibile accedere all'ID.

La soluzione migliore se vuoi ottenere l'oggetto reale è usare lodash come:

obj[_.first(_.keys(obj))].id

Per restituire il valore della prima chiave, (se non si conosce esattamente il nome della prima chiave):

var obj = { first: 'someVal' };
obj[Object.keys(obj)[0]]; //returns 'someVal'

se conosci il nome della chiave basta usare:

obj.first

o

obj['first']

0

Se devi accedere alla "prima proprietà di un oggetto", potrebbe significare che c'è qualcosa di sbagliato nella tua logica. L'ordine delle proprietà di un oggetto non dovrebbe avere importanza.


Hai ragione. Non ho bisogno del primo, di per sé, ma solo di una delle proprietà foo in modo da poter lavorare con esso. Ne ho solo bisogno e non ero sicuro che ci fosse un modo solo per afferrare il "primo" senza usare per ... in.
atogle l'

0

Utilizzare un array anziché un oggetto (parentesi quadre).

var example = [ {/* stuff1 */}, { /* stuff2 */}, { /* stuff3 */}];
var fist = example[0];

Nota che perdi gli identificatori "pieni". Ma potresti aggiungere una proprietà name agli oggetti contenuti:

var example = [ 
  {name: 'foo1', /* stuff1 */},
  {name: 'foo2', /* stuff2 */},
  {name: 'foo3', /* stuff3 */}
];
var whatWasFirst = example[0].name;

ci sono situazioni in cui non possiamo. Partiamo dal presupposto che non possiamo cambiare il fatto che non sono in un array
1mike12

1
Penso che sia utile spingere un po 'indietro il design per i lettori che possono controllare il loro schema JSON. In sostanza, sto estendendo la risposta di Flavius ​​Stef con alcuni esempi.
piroscafo25


0

È possibile utilizzare Object.prototype.keysquale restituisce tutte le chiavi di un oggetto nello stesso ordine. Quindi, se vuoi il primo oggetto, prendi quell'array e usa il primo elemento come chiave desiderata.

const o = { "key1": "value1", "key2": "value2"};
const idx = 0; // add the index for which you want value
var key = Object.keys(o)[idx];
value = o[key]
console.log(key,value); // key2 value2

1
Quando rispondi a una vecchia domanda, la tua risposta sarebbe molto più utile per gli altri utenti StackOverflow se includessi un contesto per spiegare come la tua risposta aiuta, in particolare per una domanda che ha già una risposta accettata. Vedi: Come scrivo una buona risposta .
David Buck,

0

possiamo anche fare con questo approch.

var example = {
  foo1: { /* stuff1 */},
  foo2: { /* stuff2 */},
  foo3: { /* stuff3 */}
}; 
Object.entries(example)[0][1];

0

Ecco un modo più pulito di ottenere la prima chiave:

var example = {
    foo1: { /* stuff1 */},
    foo2: { /* stuff2 */},
    foo3: { /* stuff3 */}
};

var object2 = {
    needThis: 'This is a value of the property',
    foo2: { /* stuff2 */},
    foo3: { /* stuff3 */}
};

let [first] = Object.keys(example)
let [firstProp] = Object.keys(object2)

console.log(first)
//Prop : needThis, Value: This is a value of the property
console.log(`Prop : ${firstProp}, Value: ${object2[firstProp]}`)


Ma perché l'array in giro [first]. L'utente non ha richiesto un array come risposta. Perché farlo oltre il first = Object.keys(example)[0]quale farà lo stesso senza dover avvolgere la risposta in un array. Perché il tuo pulitore è per favore?
Michael Durrant,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.