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


178

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

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

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

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

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

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

  0

I Я просто вскакиваю в javascript, но этот пост может вам помочь. http://dean.edwards.name/weblog/2006/07/enum/ 20 авг. 082008-08-20 21:47:42

  0

Возможный дубликат [Получить массив ключей объекта] (http://stackoverflow.com/questions/8763125/get-array-of-objects- ключи) 02 фев. 162016-02-02 13:48:01

+1

Как получить значения из ключей? Кроме того, количество ключей в хеше. 10 май. 162016-05-10 19:52:29

  0

Ответ 2017: Object.keys (h) Object.values ​​(h) 24 май. 172017-05-24 13:29:55

249

Существует функция в современной JavaScript (ECMAScript 5) называется Object.keys выполнения этой операции:

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

детали совместимости можно найти here.

На Mozilla site есть также отрезала для обратной совместимости:

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

разве это не было бы более естественным? 'if (! Object.prototype.keys) Object.prototype.keys = function() { if (this! == Object (this)) throw new TypeError ('Object.keys, вызываемые не-объектом'); var ret = [], p; для (p в этом), если (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()); ' 22 дек. 112011-12-22 00:44:09

+2

Как я понимаю,' 'Object.prototype.keys' сделает' keys' доступными для всех подклассов Object, поэтому для всех объектов. Что, вероятно, вы хотите, если вы пытаетесь использовать ООП. В любом случае это действительно зависит от ваших требований. 22 дек. 112011-12-22 21:12:31

+1

Если вы используете mootools, Object.keys() должен быть доступен во всех браузерах. 10 сен. 122012-09-10 16:43:47

  0

Есть ли что-нибудь, что можно использовать в угловых шаблонах? Он не работает там внутри частичных. 06 дек. 132013-12-06 14:52:42

  0

Я думаю, вы должны задать это как отдельный вопрос с образцом кода. 07 дек. 132013-12-07 01:05:41


13

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

var keys = []; 
for (var k in h)keys.push(k); 
+2

Это также не работает, когда Object.prototype запутан. 26 июл. 112011-07-26 08:40:14

+4

Было бы лучше использовать это, а не «возиться с» Object.prototype. Кажется, что все ломается, если мы добавляем вещи в Object.prototype: это чрезвычайно распространенная идиома, которая перебирает ключи массива/объекта. 07 май. 122012-05-07 07:59:30


6

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

function getKeys(h) { 
    Array keys = new Array(); 
    for (var key in h) 
    keys.push(key); 
    return keys; 
} 
  0

Это не работает, см. Ответ Аннан 26 июл. 112011-07-26 08:39:16


79

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

По состоянию на ECMAScript 5 - Object.defineProperty

По ECMA5 вы можете использовать Object.defineProperty() определить несчетное свойство. current compatibility по-прежнему требует многого, но в конечном итоге это должно стать удобным во всех браузерах. (В частности, обратите внимание на текущую несовместимость с 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 не было настолько грязным.

+9

«hasOwnProperty» исключает свойства прототипов этого объекта, что полезно знать. 13 ноя. 092009-11-13 11:09:58

+2

Ответ принят, потому что именно так я и начал реализовывать его, но я считаю, что это должна быть встроенная функция языка. 29 мар. 112011-03-29 22:16:48

+5

Обратите внимание, что вы должны использовать «for (var i in this) ...», чтобы избежать создания глобальной переменной. 13 май. 112011-05-13 12:31:03

+5

Я бы не стал модифицировать Object.prototype - как еще один комментарий, отмеченный ниже, это может легко сломать скрипты, которые не заботятся о проверке hasOwnProperty(). Вместо этого используйте менее удобный для OO способ: определите функцию «ключей», если она еще не существует. (Firefox и Chrome реализуют функцию native keys(), которая делает именно то, что хочет OP - IE не делает) 31 май. 112011-05-31 22:08:04

  0

В ECMAScript 5. В ECMAScript 5 нет объектов Object.prototype.key. https://gist.github.com/1034464 11 авг. 112011-08-11 18:35:49

+1

Кажется плохой идеей добавить что-либо в Object.prototype, поскольку он разбивает каждый нормальный цикл как: for (var k in array) {} или for (var k in object), и эта идиома - хотя это может быть ошибочным - чрезвычайно распространен. Например, в соответствии с ответом Мэтью Дарвина ниже, он разбивает Карты Google. 07 май. 122012-05-07 08:01:00

  0

Это не способ пойти по ряду причин; 1) Вы действительно не должны добавлять вещи в Object.prototype вообще, и, конечно, не так. 2) Вы должны использовать 'Object.keys', как упоминалось в ответе Ивана Невостуева. 03 сен. 122012-09-03 14:32:07

  0

@OliverNightingale Я не уверен, как чтобы принять ваш комментарий. Я уже говорю то же самое в части * Edit * моего ответа. 10 сен. 122012-09-10 12:15:17


4

Я хотел использовать популярнейших ответ выше

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

Однако при использовании в сочетании с API v3 Google Maps, Google Maps не функционирует.

for (var key in h) ... 

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


34

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

_.keys({one : 1, two : 2, three : 3}); 
// => ["one", "two", "three"] 
  0

Ну, это не совсем то, что было задано, потому что @Pat ищет встроенную функцию, но тем не менее это интересная библиотека, и она не изменяет 'Object.prototype' 11 авг. 112011-08-11 22:11:34

+2

. В эти дни я думаю, что это гораздо полезнее чтобы использовать эти изящные библиотеки, а не писать собственные реализации ... В любом случае, в большинстве проектов реального мира мы всегда используем Underscore или эквивалентные библиотеки. Лично мне лучше пойти с Подчеркиванием. 22 авг. 122012-08-22 20:40:48

  0

'_.keys (obj) .length', чтобы увидеть, есть ли какие-либо ключи. 24 сен. 122012-09-24 21:04:50


9

с помощью 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

+3

Если вы хотите пройти этот маршрут, вы также можете использовать 'JQuery.map': ' $ .map (h, function (v, k) {return k;}); ' 16 май. 122012-05-16 14:20:10


1

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

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


38

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

Object.keys(h) 
+3

Добавлено в ECMAScript 5, но должно работать в большинстве основных браузеров 30 авг. 132013-08-30 10:15:00