Как найти ключи хеша?

Я знаю, в javascript объекты удваиваются как хеши, но я не смог найти встроенную функцию для получения ключей

var h = {a:'b',c:'d'};

Я хочу что-то вроде

var k = h.keys() ; // k = ['a','c'];

Легко написать саму функцию для перебора элементов и добавления ключей в массив, который я возвращаю, но есть ли стандартный более чистый способ сделать это?

Я продолжаю чувствовать, что это должна быть простая встроенная функция, которую я пропустил, но я не могу ее найти!

20.08.2008 21:35:59
Я просто прыгаю в JavaScript, но этот пост может вам помочь. dean.edwards.name/weblog/2006/07/enum
jason saldo 20.08.2008 21:47:42
Возможный дубликат массива ключей объекта
blo0p3r 2.02.2016 13:48:01
Как насчет получения значений из ключей? Также получаем количество ключей в хеше.
zero_cool 10.05.2016 19:52:29
Ответ на 2017 год: Object.keys (h) Object.values ​​(h)
losty 24.05.2017 13:29:55
9 ОТВЕТОВ
РЕШЕНИЕ

В современном JavaScript (ECMAScript 5) есть функция, которая Object.keysвыполняет эту операцию:

var obj = { "a" : 1, "b" : 2, "c" : 3};
alert(Object.keys(obj)); // will output ["a", "b", "c"]

Подробности о совместимости можно найти здесь .

На сайте Mozilla также есть фрагмент обратной совместимости:

if(!Object.keys) Object.keys = function(o){
   if (o !== Object(o))
      throw new TypeError('Object.keys called on non-object');
   var ret=[],p;
   for(p in o) if(Object.prototype.hasOwnProperty.call(o,p)) ret.push(p);
   return ret;
}
274
6.03.2019 15:05:47
разве это не было бы более естественным? if(!Object.prototype.keys) Object.prototype.keys = function() { if (this !== Object(this)) throw new TypeError('Object.keys called on non-object'); var ret = [], p; for (p in this) if (Object.prototype.hasOwnProperty.call(this, p)) ret.push(p); return ret; } var x = { a: { A: 1, B: 2, C: 3 }, b: { A: 10, B: 20 } }; alert(x.a.keys());
ekkis 22.12.2011 00:44:09
Как я понимаю, это Object.prototype.keysсделает keysдоступным для всех подклассов объекта, следовательно, для всех объектов. Что, вероятно, вы хотите, если вы пытаетесь использовать ООП. В любом случае это действительно зависит от ваших требований.
Ivan Nevostruev 22.12.2011 21:12:31
Если вы используете mootools, Object.keys () должен быть доступен во всех браузерах.
thepeer 10.09.2012 16:43:47
Есть ли что-нибудь, чтобы использовать это в угловых шаблонах? Это не работает там внутри частичных.
Jay Shukla 6.12.2013 14:52:42
Я думаю, что вы должны задать это как отдельный вопрос с примером кода.
Ivan Nevostruev 7.12.2013 01:05:41

Это лучшее, что вы можете сделать, насколько я знаю ...

var keys = [];
for (var k in h)keys.push(k);
13
20.08.2008 21:49:23
Это также не работает, когда Object.prototype был испорчен.
Phil 26.07.2011 08:40:14
Было бы лучше использовать это, а не "связываться с" Object.prototype. Кажется, что все ломается, если мы добавляем вещи в Object.prototype: это очень распространенная идиома для циклического перебора ключей массива / объекта.
Sam Watkins 7.05.2012 07:59:30

Я полагаю, что вы можете просмотреть свойства объекта, используя for / in, так что вы можете сделать что-то вроде этого:

function getKeys(h) {
  Array keys = new Array();
  for (var key in h)
    keys.push(key);
  return keys;
}
6
20.08.2008 21:51:08

Для производственного кода, требующего большой совместимости с клиентскими браузерами, я все же предлагаю ответ Ивана Невоструева, приведенный выше, с шимом, чтобы убедиться Object.keysв старых браузерах. Тем не менее, можно получить точную функциональность, запрошенную с помощью новой definePropertyфункции ECMA .

Начиная с ECMAScript 5 - Object.defineProperty

Начиная с ECMA5 вы можете использовать Object.defineProperty()для определения не перечисляемых свойств. Тока совместимость до сих пор желать лучшего, но это должно в конечном итоге стать полезной во всех браузерах. (Обратите особое внимание на текущую несовместимость с IE8!)

Object.defineProperty(Object.prototype, 'keys', {
  value: function keys() {
    var keys = [];
    for(var i in this) if (this.hasOwnProperty(i)) {
      keys.push(i);
    }
    return keys;
  },
  enumerable: false
});

var o = {
    'a': 1,
    'b': 2
}

for (var k in o) {
    console.log(k, o[k])
}

console.log(o.keys())

# OUTPUT
# > a 1
# > b 2
# > ["a", "b"]

Однако, так как ECMA5 уже добавлен, Object.keysвы также можете использовать:

Object.defineProperty(Object.prototype, 'keys', {
  value: function keys() {
    return Object.keys(this);
  },
  enumerable: false
});

Оригинальный ответ

Object.prototype.keys = function ()
{
  var keys = [];
  for(var i in this) if (this.hasOwnProperty(i))
  {
    keys.push(i);
  }
  return keys;
}

Изменить: так как этот ответ был вокруг некоторое время, я оставлю вышеизложенное нетронутым. Любой, кто читает это, должен также прочитать ответ Ивана Невоструева ниже.

Не существует способа сделать функции-прототипы не перечисляемыми, что приводит к их постоянному включению в циклы for-in, которые не используются hasOwnProperty. Я все еще думаю, что этот ответ был бы идеальным, если бы расширение прототипа Object не было таким грязным.

80
5.01.2018 12:52:59
«hasOwnProperty» исключает свойства прототипов этого объекта, которые полезно знать.
ijw 13.11.2009 11:09:58
Ответ принят, потому что так я его реализовал, но я чувствую, что это должно было быть встроенной функцией языка.
Pat 29.03.2011 22:16:48
Обратите внимание, что вы должны использовать «for (var i in this) ...», чтобы избежать создания глобальной переменной.
Brad G. 13.05.2011 12:31:03
Я бы не стал изменять Object.prototype - как заметил другой комментатор ниже, это может легко сломать скрипты, которые не заботятся о проверке hasOwnProperty (). Вместо этого используйте менее дружественный к OO способ: определите функцию «keys», если она еще не существует. (Firefox и Chrome оба реализуют встроенную функцию keys (), которая делает именно то, что хочет OP, а IE нет)
digitalbath 31.05.2011 22:08:04
Кажется плохой идеей добавлять что-либо в Object.prototype, так как он прерывает каждый нормальный цикл, например: for (var k в массиве) {} или for (var k в объекте), и эта идиома - хотя это может быть ошибочно - чрезвычайно распространено. Например, согласно ответу Мэтью Дарвина ниже, это нарушает Google Maps.
Sam Watkins 7.05.2012 08:01:00

Я хотел использовать ответ с самым высоким рейтингом выше

Object.prototype.keys = function () ...

Однако при использовании вместе с API карт Google v3 карты Google не работают.

for (var key in h) ...

работает хорошо.

4
24.07.2010 15:02:00

Вы можете использовать Underscore.js , который является утилитарной библиотекой Javascript.

_.keys({one : 1, two : 2, three : 3}); 
// => ["one", "two", "three"]
33
11.08.2011 22:10:20
Ну, это не совсем то, о чем спрашивали, потому что @Pat ищет встроенную функцию, но тем не менее это интересная библиотека, и она не модифицируетсяObject.prototype
fresskoma 11.08.2011 22:11:34
Сегодня я думаю, что гораздо полезнее использовать эти изящные маленькие библиотеки, чем продолжать писать свои собственные реализации ... В любом случае, в большинстве реальных проектов мы в любом случае используем Underscore или эквивалентные библиотеки. Лично я предпочел бы пойти с Underscore.
kumarharsh 22.08.2012 20:40:48
_.keys(obj).lengthчтобы увидеть, есть ли какие-либо ключи.
chovy 24.09.2012 21:04:50

используя jQuery, вы можете получить ключи следующим образом:

var bobject =  {primary:"red",bg:"maroon",hilite:"green"};
var keys = [];
$.each(bobject, function(key,val){ keys.push(key); });
console.log(keys); // ["primary", "bg", "hilite"]

Или:

var bobject =  {primary:"red",bg:"maroon",hilite:"green"};
$.map(bobject, function(v,k){return k;});

благодаря @pimlottc

8
7.04.2018 10:02:48
Если вы хотите пойти по этому пути, вы также можете использовать JQuery.map: $.map(h, function(v,k) { return k; });
pimlottc 16.05.2012 14:20:10

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

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

1
5.01.2018 12:54:16

вы можете использовать Object.keys

Object.keys(h)
42
5.01.2018 12:53:30
Добавлен в ECMAScript 5, но к настоящему времени должен работать в большинстве основных браузеров
Pat 30.08.2013 10:15:00