Как вывести список свойств объекта JavaScript?

Скажем, я создаю объект таким образом:

var myObject =
        {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

Как лучше всего получить список имен свойств? то есть я хотел бы получить некоторые переменные 'ключи', такие как:

keys == ["ircEvent", "method", "regex"]

Немного не по теме, но если вы используете underscore.js: _.keys(myJSONObject)

Endy Tjahjono 28.09.2013 12:44
TL; DR: If you want enumerable properties only: Object.keys(obj) Sometimes you want non-enumerable properties as well. Make sure to remember this if you do! To get them, use Object.getOwnPropertyNames(obj)stackoverflow.com/a/32413145/1599699
Andrew 17.06.2020 04:12
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
881
2
799 262
17
Перейти к ответу Данный вопрос помечен как решенный

Ответы 17

Ответ принят как подходящий

В современных браузерах (IE9 +, FF4 +, Chrome5 +, Opera12 +, Safari5 +) вы можете использовать встроенный метод Object.keys:

var keys = Object.keys(myObject);

В приведенном выше примере есть полный полифилл, но упрощенная версия:

var getKeys = function(obj){
   var keys = [];
   for(var key in obj){
      keys.push(key);
   }
   return keys;
}

В качестве альтернативы замените var getKeys на Object.prototype.keys, чтобы вы могли вызывать .keys() для любого объекта. Расширение прототипа имеет некоторые побочные эффекты, и я бы не рекомендовал это делать.

Я бы снова обновился, сказав, что «у вас может возникнуть соблазн сделать это с прототипом объекта ... но не делайте этого!»

AnthonyWJones 16.10.2008 16:44

кто-нибудь захочет пролить свет, почему не рекомендуется добавлять функции в прототип объекта?

Vishwanath 23.01.2012 14:47

Это совсем другой вопрос сам по себе, быстрый поиск здесь в stackoverflow или в google даст вам много, чтобы прочитать

ximi 01.03.2012 23:48

Я пробовал это в Google Chrome 27: вы можете просто использовать keys(myJsonObject), не ссылаясь на Object.

wecsam 14.06.2013 23:50

Метод for (var key in myObject) {...} полезен для среды выполнения javascript вне браузеров и V8. Например, при передаче запросов javascript map-reduce в Riak объект Object не существует, поэтому метод Object.keys недоступен.

ekillaby 20.06.2013 23:46

полифил намного быстрее. jsperf.com/listing-javascript-properties

rdllopes 13.03.2014 17:35

Object.keys() в ECMA 5.1. В ближайшее время он будет доступен где угодно!

gavenkoa 05.07.2014 22:29

@slashnick Ваша «упрощенная версия» возвращает все свойства в цепочке прототипов объекта (поскольку она использует «for ... in»), тогда как метод (ECMAScript 5.1) Object.keys возвращает только собственные свойства объекта. Я считаю это важным отличием.

Martin Carel 17.10.2014 01:57

Я согласен с @MartinCarel. На мой взгляд, ответ следует отредактировать, чтобы отфильтровать свойства с помощью hasOwnProperty (поскольку это упрощенная версия, вероятно, не нужно включать обходной путь ошибки перечисления). Это в основном то, что задает исходный вопрос (контекстуально), и что делает фактическая функция Object.keys.

user3100783 19.10.2014 23:10

Как указывает слэшник, вы можете использовать конструкцию «for in» для итерации по объекту для его имен атрибутов. Однако вы будете перебирать все имена атрибутов в цепочке прототипов объекта. Если вы хотите выполнить итерацию Только по собственным атрибутам объекта, вы можете использовать метод Объект # hasOwnProperty (). Таким образом имея следующее.

for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
        /* useful code here */
    }
}

Мне жаль, что я не прочитал это до ответа Слэшника выше. Мне просто пришлось потратить 15 минут, удерживая клавишу esc, потому что у объекта было около миллиона свойств, большинство из которых не использовались, и у меня было предупреждение.

Mark Henderson 16.08.2010 10:10

Вот отличная статья на эту тему самого Закаса: nczonline.net/blog/2010/07/27/…

Pablo Cabrera 19.08.2010 15:17

LOL @MarkHenderson - но в следующий раз просто закройте процесс браузера и перезапустите его вместо того, чтобы тратить 15 минут :)

JD Smith 06.09.2012 09:53

Связанная функция - obj.getOwnPropertyNames () - developer.mozilla.org/en-US/docs/JavaScript/Reference/…

Steve Goodman 04.12.2012 01:28

@MarkHenderson Почему вы не используете console.info?

LasagnaAndroid 31.03.2014 23:03

Красиво, надо было обновить выбранный ответ этим вместо того, чтобы добавлять новый.

LasagnaAndroid 31.03.2014 23:21

IE не поддерживает (i in obj) для собственных свойств. Вот список всего реквизита, который я смог найти.

Кажется, stackoverflow выполняет глупую фильтрацию.

Список доступен внизу этого сообщения группы Google: - https://groups.google.com/group/hackvertor/browse_thread/thread/a9ba81ca642a63e0

Я большой поклонник функции дампа.

http://ajaxian.com/archives/javascript-variable-dump-in-coldfusionalt text

+1 потому что я попал сюда с намерением построить нечто подобное (хотя и не такое хорошее).

Camilo Martin 21.02.2011 09:12
netgrow.com.au/assets/files/dump/dump.zip не найденКак мне скачать дамп javascript?
Kiquenet 26.07.2017 14:14

@Kiquenet каждый раз, когда я хотел создать что-то подобное, я соглашался на обычный инспектор объектов, если вы хотите, чтобы это отображалось в HTML, есть такие вещи, как модули npm. Честно говоря, я застрял в том, что я хотел чего-то лучшего, чем то, что изображено на этом изображении, но так и не смог концептуализировать это. Дерьмово просматривать объекты в инспекторе, но эвристика, пытающаяся вывести значение из произвольных объектов (например, сортировка массивов объектов по таблицам со столбцами), не всегда работает на практике.

Camilo Martin 30.07.2017 18:37

Что насчет Довольно печатный Javascripthttps://j11y.io/demos/prettyprint/?

Kiquenet 04.09.2017 12:16

Обратите внимание, что Object.keys и другие методы ECMAScript 5 поддерживаются Firefox 4, Chrome 6, Safari 5, IE 9 и выше.

Например:

var o = {"foo": 1, "bar": 2}; 
alert(Object.keys(o));

Таблица совместимости ECMAScript 5: http://kangax.github.com/es5-compat-table/

Описание новых методов: http://markcaudill.com/index.php/2009/04/javascript-new-features-ecma5/

Также проверьте ключи () в консоли для Chrome Dev Tools, Firebug и т. д.

Sam Dutton 17.09.2011 13:59
markcaudill.com/index.php/2009/04/javascript-new-features-ec‌ ma5 не найден
Kiquenet 04.09.2017 12:18

Как ответил Сэм Даттон, в ECMAScript 5th Edition появился новый метод именно для этой цели. Object.keys() будет делать то, что вы хотите, и поддерживается в Firefox 4, Chrome 6, Safari 5 и IE 9.

Вы также можете очень легко реализовать метод в браузерах, которые его не поддерживают. Однако некоторые реализации не полностью совместимы с Internet Explorer. Вот более совместимое решение:

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 (o) {
        if (typeof o != "object" && typeof o != "function" || o === null)
            throw new TypeError("Object.keys called on a non-object");
    
        var result = [];
        for (var name in o) {
            if (hasOwnProperty.call(o, name))
                result.push(name);
        }
    
        if (hasDontEnumBug) {
            for (var i = 0; i < DontEnumsLength; i++) {
                if (hasOwnProperty.call(o, DontEnums[i]))
                    result.push(DontEnums[i]);
            }   
        }
    
        return result;
    };
})();

Обратите внимание, что принятый в настоящее время ответ не включает проверку hasOwnProperty () и возвращает свойства, которые наследуются через цепочку прототипов. Он также не учитывает известную ошибку DontEnum в Internet Explorer, когда неперечислимые свойства в цепочке прототипов заставляют локально объявленные свойства с тем же именем наследовать свой атрибут DontEnum.

Реализация Object.keys () даст вам более надежное решение.

Обновлено: после недавнего обсуждения с Кангакс, хорошо известным участником Prototype, я реализовал обходной путь для ошибки DontEnum на основе кода для его функции Object.forIn(), найденной здесь.

Отличный ответ, я думаю, что принятый ответ остается наиболее эффективным точным решением, если предположить, что это всегда JSON dict. Это, безусловно, тот, который можно использовать в другом месте.

David Snabel-Caunt 26.10.2010 18:00

@David Caunt: Спасибо :-) К сожалению, принятый ответ все равно не соответствует ошибке DontEnum, и вы никогда не знаете, какой объект JSON может иметь строку типа «valueOf» или «constructor» в качестве одного из ключей. Он также будет повторять расширения Object.prototype. Однако часто бывает, что более короткий код выглядит значительно более привлекательным, чем более крупный и надежный код, но суть этого ответа заключается в использовании ECMAScript 5th Object.keys(), который может быть реализован в браузерах, которые не поддерживают его с помощью этого кода. Родная версия была бы даже более производительной, чем эта.

Andy E 26.10.2010 18:15

Хороший момент - вы правы насчет ошибки. Я надеюсь, что любой хороший разработчик протестирует нативные методы перед использованием своих собственных реализаций.

David Snabel-Caunt 27.10.2010 02:12

Очень мило, Энди :) Я просто хотел бы напомнить - никто, кажется, не упоминает в этой теме - что ES5 Object.keys возвращает только массив строк, соответствующих свойствам перечислимый объекта. Это может не иметь решающего значения при работе с собственными (определяемыми пользователем) объектами, но должно быть очень хорошо видно для узловых объектов (хотя поведение неопределенных узловых объектов - это отдельная - болезненная - история). Для перечисления по ВСЕМ (включая неперечислимые) свойства ES5 предоставляет Object.getOwnPropertyNames (см. Его поддержку в моей таблице совместимости - kangax.github.com/es5-compat-table)

kangax 27.10.2010 06:43

Я интегрировал это решение в es5-shim github.com/kriskowal/es5-shim/blob/master/es5-shim.js#L390

Kris Kowal 27.10.2010 07:25

@Kris: это здорово, спасибо за указание :-) @kangax: да, это определенно стоит упомянуть и просто напомнило мне о фрагменте кода, который мне нужно обновить, спасибо :-)

Andy E 27.10.2010 13:11

Конечно, это все еще работает только для Object. Если бы вы сделали что-то глупое, например, поместили свойство затенения getFullYear в экземпляр Date, это все равно не сделало бы это перечислимым. Чтобы обойти это, вам нужно иметь гораздо более длинный список всех собственных свойств IE <9 и проверять каждое с помощью hasOwnProperty и propertyIsEnumerable. Не очень весело.

bobince 28.10.2010 18:36

@bobince: правда, не так уж и весело! Надеюсь, это поможет нам, пока IE <9 не станет далеким воспоминанием :-)

Andy E 28.10.2010 19:00

Может кто-нибудь объяснить, почему это реализовано как Object.keys(stuff), а не stuff.keys()?

Blazemonger 16.09.2011 20:29

@ mblase75: вместо того, чтобы объяснять это здесь, вы можете прочитать обсуждение этого в списке рассылки es-Disc, начиная с здесь.

Andy E 16.09.2011 21:51

@Kiquenet: да, к сожалению, блог потерялся для эфира, когда я оставил предыдущую работу, которая включала хостинг ... извините за это!

Andy E 27.07.2017 13:56
ww1.whattheheadsaid.com/2010/10/… not found, maybe found in archive.org ?
Kiquenet 04.09.2017 12:20

если вы пытаетесь получить только элементы, но не функции, этот код может вам помочь

this.getKeys = function() {

    var keys = new Array();
    for(var key in this) {

        if ( typeof this[key] !== 'function') {

            keys.push(key);
        }
    }
    return keys;
}

это часть моей реализации HashMap, и мне нужны только ключи, "this" - это объект hashmap, который содержит ключи

Это будет работать в большинстве браузеров, даже в IE8, и никаких библиотек не требуется. var i - ваш ключ.

var myJSONObject =  {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}; 
var keys=[];
for (var i in myJSONObject ) { keys.push(i); }
alert(keys);

Ваш ответ похож на уже опубликованный, что еще добавить?

VKen 10.10.2012 22:31

В браузерах, поддерживающих js 1.8:

[i for(i in obj)]

Можно было сделать это с помощью jQuery следующим образом:

var objectKeys = $.map(object, function(value, key) {
  return key;
});

В Mozilla есть полная информация о реализации о том, как это сделать в браузере, где он не поддерживается, если это помогает:

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

Вы можете включить его, как хотите, но, возможно, в какой-то файл extensions.js наверху вашего стека скриптов.

Реализация MDN основана на Andy E's, которое уже было дано в качестве ответа.

outis 24.07.2016 00:24

Основываясь на принятом ответе.

Если у объекта есть свойства, которые вы хотите вызвать, скажем .properties () попробуйте!

var keys = Object.keys(myJSONObject);

for (var j=0; j < keys.length; j++) {
  Object[keys[j]].properties();
}

Поскольку я использую underscore.js почти в каждом проекте, я бы использовал функцию keys:

var obj = {name: 'gach', hello: 'world'};
console.info(_.keys(obj));

Результатом этого будет:

['name', 'hello']

Это библиотека набора инструментов для часто используемых функций javascript: underscorejs.org

schmijos 04.09.2017 16:18

Object.getOwnPropertyNames(obj)

Эта функция также показывает неперечислимые свойства в дополнение к свойствам, показанным Object.keys(obj).

В JS каждое свойство имеет несколько свойств, включая логическое значение enumerable.

В общем, неперечислимые свойства являются более «внутренними» и используются реже, но иногда полезно изучить их, чтобы увидеть, что происходит на самом деле.

Пример:

var o = Object.create({base:0})
Object.defineProperty(o, 'yes', {enumerable: true})
Object.defineProperty(o, 'not', {enumerable: false})

console.info(Object.getOwnPropertyNames(o))
// [ 'yes', 'not' ]

console.info(Object.keys(o))
// [ 'yes' ]

for (var x in o)
    console.info(x)
// yes, base

Также обратите внимание, как:

  • Object.getOwnPropertyNames и Object.keysне идут вверх по цепочке прототипов, чтобы найти base.
  • for in делает

Подробнее о цепочке прототипов здесь: https://stackoverflow.com/a/23877420/895245

Решение работает на моих кейсах и кроссбраузерно:

var getKeys = function(obj) {
    var type = typeof  obj;
    var isObjectType = type === 'function' || type === 'object' || !!obj;

    // 1
    if (isObjectType) {
        return Object.keys(obj);
    }

    // 2
    var keys = [];
    for(var i in obj) {
        if (obj.hasOwnProperty(i)) {
            keys.push(i)
        }
    }
    if (keys.length) {
        return keys;
    }

    // 3 - bug for ie9 <
    var hasEnumbug = !{toString: null}.propertyIsEnumerable('toString');
    if (hasEnumbug) {
        var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
            'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];

        var nonEnumIdx = nonEnumerableProps.length;

        while (nonEnumIdx--) {
            var prop = nonEnumerableProps[nonEnumIdx];
            if (Object.prototype.hasOwnProperty.call(obj, prop)) {
                keys.push(prop);
            }
        }

    }

    return keys;
};

Используйте Reflect.ownKeys()

var obj = {a: 1, b: 2, c: 3};
Reflect.ownKeys(obj) // ["a", "b", "c"]

Object.keys и Object.getOwnPropertyNames не могут получить свойства не перечислимый. Работает даже для свойств не перечислимый.

var obj = {a: 1, b: 2, c: 3};
obj[Symbol()] = 4;
Reflect.ownKeys(obj) // ["a", "b", "c", Symbol()]

В ES6 и более поздних версиях (ECMAScript 2015) вы можете получить все свойства, подобные этому:

let keys = Object.keys(myObject);

И если вы хотите перечислить все значения:

let values = Object.keys(myObject).map(key => myObject[key]);

Другие вопросы по теме