Как перечислить свойства объекта JavaScript?

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

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

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

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

Ответ 1

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

var keys = Object.keys(myObject);

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

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

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

Ответ 2

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

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

Ответ 3

Как ответил Сэм Даттон, в 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() даст вам более надежное решение.

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

Ответ 5

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.log(Object.getOwnPropertyNames(o))
// [ 'yes', 'not' ]

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

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

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

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

Подробнее о цепочке прототипов здесь: fooobar.com/questions/539/...

Ответ 7

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

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

Ответ 8

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

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, содержащий ключи

Ответ 9

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

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

Ответ 10

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

[i for(i in obj)]

Ответ 11

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 в верхней части стека script.

Ответ 12

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

Кажется, stackoverflow делает какую-то глупую фильтрацию.

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

Ответ 13

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

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

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

['name', 'hello']

Ответ 14

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

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

var keys = Object.keys(myJSONObject);

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

Ответ 15

Вы можете использовать object-values ​​ повторно используемый компонент для получения всех значений объекта.

Пример:

values({ a: 1, b: 2, c: 3 }) // => [1, 2, 3]

Как это работает:

function values(object: {[any]: any}): any[] {
  const objValues = [];
  forEach(object, val => objValues.push(val)); 
  return objValues;
};

Ответ 16

Решение работает над моими делами и кросс-браузером:

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