Як отримати доступ до першої властивості об’єкта Javascript?


611

Чи є елегантний спосіб отримати доступ до першої властивості об'єкта ...

  1. де ви не знаєте назву своїх об'єктів
  2. без використання циклу типу for .. injQuery$.each

Наприклад, мені потрібно отримати доступ до foo1об'єкта, не знаючи імені foo1:

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

1
це, мабуть, краще перетворити спочатку на масив
Крегокс

Відповіді:


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

Використовуючи це, ви можете отримати доступ до інших властивостей за індексами. Будьте в курсі! Object.keysПорядок повернення не гарантується відповідно до ECMAScript, однак неофіційно це є всіма основними веб-переглядачами, будь ласка, прочитайте https://stackoverflow.com/a/23202095 для отримання детальної інформації про це.


25
Ви кажете, що це не найшвидший шлях. Який шлях був би швидшим?
T Nguyen

3
Це не дуже ефективно, оскільки створює цілий масив усіх клавіш об'єкта.
Ендрю Мао

9
@T Nguyen я б опублікував це, якби я знав це :)
Grzegorz Kaczan

5
@DavChana - у вас неправильний налаштування. Блок котла завжди буде виконуватися, і ваш блок 2 буде порожнім, тобто перший результат являє собою виконання котлоагрегату + блок1 , а другий результат являє собою лише котельну . Ось правильний орієнтир: http://jsben.ch/#/R9aLQ , показуючи, що вони майже однакові (запустіть тест кілька разів).
myfunkyside

9
Я б хотів, first()або щось подібне могло б впоратися з цим.
Fr0zenFyr

113

Спробуйте for … inцикл і перервіть після першої ітерації:

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

1
Я думаю, що це єдиний варіант. Я не впевнений, що ви гарантуєте, що властивості будуть повторені в передбачуваному / корисному порядку. Тобто ви можете мати намір foo1, але отримаєте foo3. Якщо властивості пронумеровані, як у прикладі, ви можете зробити порівняння рядків для встановлення ідентифікатора, що закінчується на "1". Знову ж таки, якщо звичайність є основною проблемою колекції, ви, ймовірно, повинні використовувати масив замість об'єкта.
пароплав25

2
Якщо хтось ще стурбований замовленням, більшість браузерів ведуть себе передбачувано: stackoverflow.com/questions/280713/…
Flash

6
вар проп; для (опора в об’єкті) перерва; // об’єкт [опора]
netiul

12
Стара відповідь, але. Ви можете перевірити, чи властивість належить об'єкту. як: for (..) {if (! obj.hasOwnProperty (prop)) продовжувати; .... перерва; } на всякий випадок, якщо об’єкт справді порожній, він не проходить прототип або щось подібне.
pgarciacamou

65

Ви також можете зробити Object.values(example)[0].


Це не у всіх браузерах, посилання stackoverflow.com/a/38748490/719689
AlxVallejo

1
Мені це подобається краще Object.keys, тому що ви гарантовано отримаєте перший предмет.
ThetherSide

Оновлення з 2019 року, я вважаю, що це працює в більшості браузерів, крім IE developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
ppak10

46

Використовуйте Object.keysдля отримання масиву властивостей об’єкта. Приклад:

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

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

Документація і крос-браузерна прокладка при умови тут . Приклад його використання можна знайти в іншій моїй відповіді тут .

Редагувати : для наочності я просто хочу повторити те, що було правильно сказано в інших відповідях: порядок клавіш в об’єктах JavaScript не визначений.


25

Версія з одним правилом:

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

2
Іноді це може бути ризиковано for inбез перевірки, hasOwnPropertyоскільки об’єкт містить інші небажані значення, додані до нього програмно, так що ви можете отримати в результаті цього фрагмента небажаний результат. Тільки тому, що його короткий і охайний не означає його безпечного оптимальності.
Хав'єр Кобос

24

Немає "першого" властивості. Клавіші об'єкта не упорядковані.

Якщо ви перекинете їх на, (var foo in bar)ви отримаєте їх у певному порядку, але це може змінитися в майбутньому (особливо, якщо ви додасте або видалите інші ключі).


Дивовижно. Я використовував об'єкт для реалізації карти, яка підтримує порядок вставки. Після цього я вимикаю значення, оскільки наступне вставлення заповнює проміжок. :(
Девід Харкнес

2
Замовлення ключ / значення має зберігатися в новіших версіях JS
Alexander Mills

11

Рішення з бібліотекою lodash :

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

але немає гарантії внутрішнього порядку зберігання властивостей об'єкта, оскільки це залежить від реалізації VM JavaScript.


2
Просто перевірено це, і воно не працює. Він повертає лише значення, а не пара ключ / значення.
Кріс Хейнс

2
У питанні немає жодної згадки про те, що він повинен повернути пару ключ / значення, він просто запитує об’єкт, і прийнята відповідь виконує так само, як і ця функція lodash: вона повертає вміст першої властивості. Це може не відповідати вашим конкретним потребам, але ця відповідь є правильною на основі оригінального запитання.
Каррм

Так, ця робота корисна, коли ви знаєте, що ваш об’єкт матиме лише один дочірній об’єктvar object = { childIndex: { .. } }; var childObject = _.find(Object);
Раджа

9

Ні. Літеральним об'єктом, визначеним MDC, є:

список нульових або більше пар імен властивостей та пов'язаних з ними значень об’єкта, укладених у фігурні дужки ({}).

Тому літерал об'єкта не є масивом, і ви можете отримати доступ до властивостей лише за допомогою їх явного імені або forциклу, використовуючи inключове слово.


25
Для інших, що бачать лише зелену галочку в цій відповіді, є ще одне рішення, яке надалі переходить на сторінку з наразі 350 оновленими повідомленнями.
redfox05

7

Верхня відповідь може генерувати весь масив, а потім захоплювати зі списку. Ось ще один ефективний ярлик

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

3

Це було висвітлено тут раніше.

Поняття спочатку не застосовується до властивостей об'єкта, і порядок циклу для ... у циклі не гарантується специфікаціями, однак на практиці це надійно FIFO, за винятком критичного для хромування ( звіт про помилку ). Приймайте свої рішення відповідно.


3

Я не рекомендую вам використовувати Object.keys, оскільки він не підтримується у старих версіях IE. Але якщо вам це справді потрібно, ви можете скористатись наведеним вище кодом, щоб гарантувати сумісність із спинкою:

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

Функція Firefox (Gecko) 4 (2.0) Chrome 5 Internet Explorer 9 Opera 12 Safari 5

Більше інформації: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys

Але якщо вам потрібен лише перший, ми можемо організувати коротше рішення на зразок:

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

Для отримання першого імені ключа в об’єкті ви можете використовувати:

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

Повертає рядок, тому ви не можете отримати доступ до вкладених об'єктів, якщо таких було, наприклад:

var obj = { first: { someVal : { id : 1} }; Тут з цим рішенням ви не можете отримати доступ до ідентифікатора.

Найкращим рішенням, якщо ви хочете отримати власне об'єкт, є використання lodash типу:

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

Щоб повернути значення першого ключа (якщо ви точно не знаєте ім'я першого ключа):

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

якщо ви знаєте ім'я ключа, просто використовуйте:

obj.first

або

obj['first']

0

Якщо вам потрібно отримати доступ до "першої властивості об'єкта", це може означати, що у вашій логіці щось не так. Порядок властивостей об'єкта не повинен мати значення.


Ти правий. Перший, як такий, мені не потрібен, а лише одна з властивостей foo, щоб я міг працювати з ним. Мені потрібен лише один і не був впевнений, чи знайдеться спосіб просто схопити "першого", не використовуючи для ... дюйма
atogle

0

Використовуйте масив замість об'єкта (квадратні дужки).

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

Зауважте, що ви втрачаєте ідентифікатори "foo". Але ви можете додати властивість імені до об'єктів, що містяться:

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

є ситуації, в яких ми не можемо. Ми припускаємо, що не можемо змінити той факт, що вони не в масиві
1mike12

1
Я думаю, що корисно трохи відштовхуватись від дизайну для читачів, які можуть керувати їх схемою JSON. По суті, я поширюю відповідь Флавія Стефа на деяких прикладах.
пароплав25


0

Ви можете використовувати, Object.prototype.keysякий повертає всі ключі об'єкта в одному порядку. Отже, якщо ви хочете перший об'єкт, просто отримайте цей масив і використовуйте перший елемент як потрібний ключ.

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
Відповідаючи на старе запитання, ваша відповідь була б набагато кориснішою для інших користувачів StackOverflow, якщо ви включили якийсь контекст, щоб пояснити, як допомагає ваша відповідь, особливо на питання, на яке вже є прийнята відповідь. Див.: Як написати гарну відповідь .
Девід Бак

0

ми також можемо зробити цей підхід.

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

0

Ось більш чіткий спосіб отримання першого ключа:

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


Але чому масив навколо [first]. Користувач не запитував масив як відповідь. Чому це робити, над first = Object.keys(example)[0]яким буде робити те саме, не потрібно загортати відповідь у масив. Чому ваш прибиральник, будь ласка?
Майкл Дюрант

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.