Comment accéder à la première propriété d'un objet Javascript?

611

Existe-t-il un moyen élégant d'accéder à la première propriété d'un objet ...

  1. où vous ne connaissez pas le nom de vos propriétés
  2. sans utiliser une boucle comme for .. inou jQuery$.each

Par exemple, j'ai besoin d'accéder à un foo1objet sans connaître le nom de foo1:

var example = {
    foo1: { /* stuff1 */},
    foo2: { /* stuff2 */},
    foo3: { /* stuff3 */}
};
Google
la source
1
il est probablement préférable de le transformer d'abord en tableau
cregox

Réponses:

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

En utilisant cela, vous pouvez également accéder à d'autres propriétés par des index. Soyez conscient tho! Object.keysl'ordre de retour n'est pas garanti selon ECMAScript, mais officieusement c'est par toutes les implémentations principales des navigateurs, veuillez lire https://stackoverflow.com/a/23202095 pour plus de détails à ce sujet.

Grzegorz Kaczan
la source
25
Vous dites que ce n'est pas le moyen le plus rapide. Quel chemin serait plus rapide?
T Nguyen
3
Ce n'est pas très efficace car il crée un tableau complet de toutes les clés de l'objet.
Andrew Mao
9
@T Nguyen Je le
posterais
5
@DavChana - Votre référence a été mal configurée. Le bloc passe-partout sera toujours exécuté et votre bloc 2 était vide, ce qui signifie que le premier résultat représente l'exécution passe- partout + bloc1 , et le deuxième résultat ne représente que le passe- partout . Voici le benchmark correct: http://jsben.ch/#/R9aLQ , montrant qu'ils sont à peu près égaux (exécutez le test plusieurs fois).
myfunkyside
9
Je souhaite first()ou quelque chose de similaire pourrait gérer cela.
Fr0zenFyr
113

Essayez la for … inboucle et coupez après la première itération:

for (var prop in object) {
    // object[prop]
    break;
}
Gombo
la source
1
Je pense que c'est à peu près la seule option. Je ne suis pas sûr que vous soyez assuré que les propriétés seront itérées dans un ordre prévisible / utile. C'est-à-dire que vous pouvez vouloir foo1 mais obtenir foo3. Si les propriétés sont numérotées comme dans l'exemple, vous pouvez comparer une chaîne pour vérifier l'identifiant se terminant par «1». Là encore, si l'ordinalité est la principale préoccupation de la collection, vous devez probablement utiliser un tableau au lieu d'un objet.
steamer25
2
Si quelqu'un d'autre est préoccupé par la commande, la plupart des navigateurs se comportent de façon prévisible: stackoverflow.com/questions/280713/…
Flash
6
var prop; pour (appui dans l'objet) pause; // object [prop]
netiul
12
Ancienne réponse mais. Vous voudrez peut-être vérifier si la propriété appartient à l'objet. comme: pour (..) {if (! obj.hasOwnProperty (prop)) continue; .... Pause; } juste au cas où l'objet est réellement vide, il ne traverse pas le prototype ou quelque chose.
pgarciacamou
47

Utilisez Object.keyspour obtenir un tableau des propriétés d'un objet. Exemple:

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

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

Documentation et module d'interface multi-navigateur fournis ici . Un exemple de son utilisation peut être trouvé dans une autre de mes réponses ici .

Edit : pour plus de clarté, je veux juste faire écho à ce qui a été correctement déclaré dans d'autres réponses: l'ordre des touches dans les objets javascript n'est pas défini.

benekastah
la source
25

Une version à une règle:

var val = example[function() { for (var k in example) return k }()];
netiul
la source
2
Parfois, il peut être risqué d'utiliser for insans vérifier hasOwnPropertycar l'objet contient d'autres valeurs indésirables qui lui sont ajoutées par programme afin que vous puissiez finir par obtenir un résultat indésirable à partir de cet extrait. Ce n'est pas parce qu'il est court et soigné qu'il est optimal et sûr.
Javier Cobos
24

Il n'y a pas de "première" propriété. Les clés d'objet ne sont pas ordonnées.

Si vous les parcourez avec pour (var foo in bar)vous les obtiendrez dans un certain ordre, mais cela peut changer à l'avenir (surtout si vous ajoutez ou supprimez d'autres clés).

Quentin
la source
Impressionnant. J'ai utilisé un objet pour implémenter une carte qui maintient l'ordre d'insertion. Cela se brise une fois que j'ai supprimé une valeur car l'insertion suivante remplit l'espace. :(
David Harkness
2
l'ordre des clés / valeurs devrait être conservé dans les nouvelles versions de JS
Alexander Mills
11

Solution avec la bibliothèque lodash :

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

mais il n'y a aucune garantie de l'ordre de stockage interne des propriétés de l'objet car cela dépend de l'implémentation de la machine virtuelle javascript.

pocheptsov
la source
2
Je viens de tester cela, et cela ne fonctionne pas. Il renvoie uniquement la valeur, pas la paire clé / valeur.
Chris Haines
2
Il n'y a aucune mention dans la question qu'il devrait retourner la paire clé / valeur, il demande juste l'objet et la réponse acceptée fait tout autant que cette fonction lodash: elle retourne le contenu de la première propriété. Cela pourrait ne pas convenir à vos besoins spécifiques, mais cette réponse EST correcte en fonction de la question d'origine.
Carrm
Oui fait le travail, utile lorsque vous savez que votre objet n'aura qu'un seul objet enfantvar object = { childIndex: { .. } }; var childObject = _.find(Object);
Raja Khoury
9

Non. Un littéral objet, tel que défini par MDC, est:

une liste de zéro ou plusieurs paires de noms de propriété et des valeurs associées d'un objet, entre accolades ({}).

Par conséquent, un littéral d'objet n'est pas un tableau et vous ne pouvez accéder aux propriétés qu'en utilisant leur nom explicite ou une forboucle en utilisant le inmot clé.

Alex Rozanski
la source
25
Pour d'autres qui ne voient que la coche verte sur cette réponse, il existe une autre solution plus bas sur la page avec actuellement 350 votes positifs.
redfox05
7

La première réponse pourrait générer l'ensemble du tableau, puis capturer à partir de la liste. Voici un autre raccourci efficace

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

Cela a déjà été abordé ici.

Le concept de premier ne s'applique pas aux propriétés des objets, et l'ordre d'une boucle for ... in n'est pas garanti par les spécifications, mais dans la pratique, il est fiable FIFO sauf de manière critique pour chrome ( rapport de bogue ). Prenez vos décisions en conséquence.

annakata
la source
3

Je ne vous recommande pas d'utiliser Object.keys car il n'est pas pris en charge dans les anciennes versions d'IE. Mais si vous en avez vraiment besoin, vous pouvez utiliser le code ci-dessus pour garantir la compatibilité arrière:

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;
}})()};

Fonctionnalité Firefox (Gecko) 4 (2.0) Chrome 5 Internet Explorer 9 Opera 12 Safari 5

Plus d'informations: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys

Mais si vous n'avez besoin que du premier, nous pourrions organiser une solution plus courte comme:

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"}
Javier Cobos
la source
2

Pour obtenir le premier nom de clé dans l'objet, vous pouvez utiliser:

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

Renvoie une chaîne, vous ne pouvez donc pas accéder aux objets imbriqués s'il y en avait, comme:

var obj = { first: { someVal : { id : 1} }; Ici, avec cette solution, vous ne pouvez pas accéder à id.

La meilleure solution si vous souhaitez obtenir l'objet réel est d'utiliser lodash comme:

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

Pour renvoyer la valeur de la première clé (si vous ne connaissez pas exactement le premier nom de clé):

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

si vous connaissez le nom de la clé, utilisez simplement:

obj.first

ou

obj['first']
Diego Unanue
la source
0

Si vous devez accéder à "la première propriété d'un objet", cela peut signifier qu'il y a un problème avec votre logique. L'ordre des propriétés d'un objet ne devrait pas avoir d'importance.

Flavius ​​Stef
la source
Tu as raison. Je n'ai pas besoin de la première, en soi, mais simplement d'une des propriétés foo pour que je puisse travailler avec. Je n'en ai besoin que d'un et je ne savais pas s'il y avait un moyen de saisir le "premier" sans utiliser pour ... dans.
Google
0

Utilisez un tableau au lieu d'un objet (crochets).

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

Notez que vous perdez les identifiants «foo». Mais vous pouvez ajouter une propriété de nom aux objets contenus:

var example = [ 
  {name: 'foo1', /* stuff1 */},
  {name: 'foo2', /* stuff2 */},
  {name: 'foo3', /* stuff3 */}
];
var whatWasFirst = example[0].name;
steamer25
la source
il y a des situations où nous ne pouvons pas. Nous supposons que nous ne pouvons pas changer le fait qu'ils ne sont pas dans un tableau
1mike12
1
Je pense qu'il est utile de repousser un peu la conception pour les lecteurs qui peuvent contrôler leur schéma JSON. Essentiellement, j'étends la réponse de Flavius ​​Stef avec quelques exemples.
steamer25
0

Une raison de ne pas faire ça?

> example.map(x => x.name);

(3) ["foo1", "foo2", "foo3"]
jtr13
la source
8
Parce qu'il .map()n'existe que pour les itérables
intégrés
0

Vous pouvez utiliser Object.prototype.keysqui renvoie toutes les clés d'un objet dans le même ordre. Donc, si vous voulez le premier objet, obtenez simplement ce tableau et utilisez le premier élément comme clé souhaitée.

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
akash kumar
la source
1
Lorsque vous répondez à une ancienne question, votre réponse serait beaucoup plus utile aux autres utilisateurs de StackOverflow si vous incluez un contexte pour expliquer en quoi votre réponse est utile, en particulier pour une question qui a déjà une réponse acceptée. Voir: Comment écrire une bonne réponse .
David Buck
0

on peut aussi faire avec cette approche.

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

Voici une façon plus propre d'obtenir la première clé:

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]}`)

Ntiyiso Rikhotso
la source
Mais pourquoi le tableau autour [first]. L'utilisateur n'a pas demandé de tableau comme réponse. Pourquoi faire cela sur first = Object.keys(example)[0]qui fera la même chose sans avoir à envelopper la réponse dans un tableau. Pourquoi le vôtre est-il plus propre s'il vous plaît?
Michael Durrant
C'est une tâche destructrice developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Ntiyiso Rikhotso