Я знаю, что объекты javascript дублируются как хэши, но мне не удалось найти встроенную функцию для получения ключей.
var h = {a:'b',c:'d'};
Я хочу что-то вроде
var k = h.keys() ; // k = ['a','c'];
Самостоятельно написать функцию для перебора элементов и добавления ключей в массив, который я возвращаю, просто, но есть ли стандартный более чистый способ сделать это?
Я все время чувствую, что это должна быть простая встроенная функция, которую я пропустил, но я не могу ее найти!
Возможный дубликат Получить массив ключей объекта
А как насчет получения значений из ключей? Также получение количества ключей в хеше.
Ответ 2017 года: Object.keys (h) Object.values (h)



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Насколько я знаю, это лучшее, что вы можете сделать ...
var keys = [];
for (var k in h)keys.push(k);
Это также не работает, когда был испорчен Object.prototype.
Лучше бы этим воспользоваться, а не «возиться с» Object.prototype. Кажется, что все ломается, если мы добавляем что-то в Object.prototype: это чрезвычайно распространенная идиома, чтобы перебирать ключи массива / объекта.
Я считаю, что вы можете прокручивать свойства объекта, используя for / in, поэтому вы можете сделать что-то вроде этого:
function getKeys(h) {
Array keys = new Array();
for (var key in h)
keys.push(key);
return keys;
}
Для производственного кода, требующего большой совместимости с клиентскими браузерами, я все же предлагаю ответ Ивана Невоструева выше с прокладкой, чтобы обеспечить Object.keys в старых браузерах. Тем не менее, можно получить точную функциональность, запрошенную с помощью новой функции ECMA defineProperty.
Начиная с 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.info(k, o[k])
}
console.info(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 не было таким запутанным.
'hasOwnProperty' исключает свойства прототипов этого объекта, о чем полезно знать.
Ответ принят, потому что именно так я и реализовал его, но я считаю, что это должна быть встроенная функция языка.
Обратите внимание, что вы должны использовать «for (var i in this) ...», чтобы избежать создания глобальной переменной.
Я бы избегал изменения Object.prototype - как заметил ниже другой комментатор, это может легко сломать скрипты, которые не заботятся о проверке hasOwnProperty (). Вместо этого используйте менее ориентированный на объектно-ориентированный способ: определите функцию «ключей», если она еще не существует. (Firefox и Chrome реализуют собственную функцию keys (), которая делает именно то, что хочет OP, а IE - нет)
В ECMAScript 5 нет Object.prototype.keys. gist.github.com/1034464
Кажется плохой идеей добавлять что-либо в Object.prototype, поскольку он прерывает каждый нормальный цикл, например: for (var k in array) {} или for (var k in object), и эта идиома - хотя это может быть ошибочным - крайне часто. Например, согласно ответу Мэтью Дарвина ниже, он нарушает работу Google Maps.
Это не лучший способ по ряду причин; 1) Вам действительно не следует добавлять что-либо в Object.prototype вообще, и, конечно, не таким образом 2) Вы должны использовать Object.keys, как указано в ответе Ивана Невостуева
@OliverNightingale Я не знаю, как отреагировать на ваш комментарий. Я уже говорю то же самое в части своего ответа Редактировать.
Я хотел использовать ответ с наивысшей оценкой выше
Object.prototype.keys = function () ...
Однако при использовании вместе с API карт Google v3 карты Google не работают.
for (var key in h) ...
работает хорошо.
В современном 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;
}
не было бы это естественнее? 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());
Насколько я понимаю, этот Object.prototype.keys сделает keys доступным для всех подклассов Object, следовательно, для всех объектов. Что, вероятно, вы захотите, если пытаетесь использовать ООП. В любом случае это действительно зависит от ваших требований.
Если вы используете mootools, Object.keys () должен быть доступен во всех браузерах.
Есть ли что-нибудь, что можно использовать в шаблонах angular? Он не работает внутри частичных.
Я думаю, вам следует задать этот вопрос как отдельный вопрос с образцом кода.
Вы можете использовать Underscore.js, служебную библиотеку Javascript.
_.keys({one : 1, two : 2, three : 3});
// => ["one", "two", "three"]
Ну, на самом деле это не то, о чем спрашивали, потому что @Pat ищет встроенную функцию, но, тем не менее, это интересная библиотека, и она не изменяет Object.prototype.
В наши дни я думаю, что гораздо полезнее использовать эти изящные маленькие библиотеки-let, чем писать свои собственные реализации ... В любом случае, в большинстве реальных проектов мы все равно используем Underscore или эквивалентные библиотеки. Лично я предпочитаю Underscore.
_.keys(obj).length, чтобы увидеть, есть ли какие-нибудь ключи.
используя jQuery, вы можете получить такие ключи:
var bobject = {primary:"red",bg:"maroon",hilite:"green"};
var keys = [];
$.each(bobject, function(key,val){ keys.push(key); });
console.info(keys); // ["primary", "bg", "hilite"]
Или же:
var bobject = {primary:"red",bg:"maroon",hilite:"green"};
$.map(bobject, function(v,k){return k;});
благодаря @pimlottc
Если вы хотите пойти по этому пути, вы можете использовать JQuery.map: $.map(h, function(v,k) { return k; });.
если вы пытаетесь получить только элементы, но не функции, этот код может вам помочь
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, содержащий ключи
вы можете использовать Object.keys
Object.keys(h)
Добавлен в ECMAScript 5, но на данный момент должен работать в большинстве основных браузеров
Я просто перехожу на javascript, но этот пост может вам помочь. dean.edwards.name/weblog/2006/07/enum