Как перечислять свойства объекта JavaScript?
Я действительно хочу перечислить все определенные переменные и их значения, но я узнал, что определение переменной на самом деле создает свойство объекта window.
Как перечислять свойства объекта JavaScript?
Я действительно хочу перечислить все определенные переменные и их значения, но я узнал, что определение переменной на самом деле создает свойство объекта window.
Достаточно просто:
for(var propertyName in myObject) {
// propertyName is what you want
// you can get the value like this: myObject[propertyName]
}
Теперь вы не получите частных переменных таким образом, потому что они недоступны.
EDIT: @bitwiseplatypus является правильным, если вы не используете метод hasOwnProperty()
, вы получите свойства, которые унаследованы, однако я не знаю, почему кто-то знакомый с объектно-ориентированным программированием, ожидал бы чего-то меньшего! Как правило, кто-то, кто приносит это, подвергался предупреждению Дугласа Крокфорда об этом, что меня немного путало. Опять же, наследование является нормальной частью языков OO и поэтому является частью JavaScript, несмотря на то, что оно является прототипом.
Теперь, что сказано, hasOwnProperty()
полезна для фильтрации, но нам не нужно вызывать предупреждение, как будто есть что-то опасное в получении унаследованных свойств.
EDIT 2: @bitwiseplatypus раскрывает ситуацию, которая произошла, если кто-то добавит свойства/методы к вашим объектам в определенный момент позже, чем когда вы изначально написали свои объекты (через его прототип) - хотя это правда, что это может вызвать неожиданное поведение, я лично не вижу в этом своей цели. Просто вопрос мнения. Кроме того, что, если я создаю вещи таким образом, что я использую прототипы во время построения моих объектов и все же имею код, который выполняет итерации по свойствам объекта, и я хочу все унаследованные свойства? Я бы не использовал hasOwnProperty()
. Затем, скажем, кто-то добавляет новые свойства позже. Это моя вина, если в этом случае ситуация плохо себя ведет? Я так не думаю. Я думаю, именно поэтому jQuery, как пример, указал способы расширения его работы (через jQuery.extend
и jQuery.fn.extend
).
Используйте цикл for..in
для перечисления свойств объекта, но будьте осторожны. Перечисление вернет свойства не только объекта, подлежащего перечислению, но и прототипов любых родительских объектов.
var myObject = {foo: 'bar'};
for (var name in myObject) {
alert(name);
}
// results in a single alert of 'foo'
Object.prototype.baz = 'quux';
for (var name in myObject) {
alert(name);
}
// results in two alerts, one for 'foo' and one for 'baz'
Чтобы избежать включения унаследованных свойств в перечисление, установите флажок hasOwnProperty()
:
for (var name in myObject) {
if (myObject.hasOwnProperty(name)) {
alert(name);
}
}
Изменить: Я не согласен с утверждением JasonBunting, что нам не нужно беспокоиться о перечислении унаследованных свойств. Существует опасность перечисления над унаследованными свойствами, которых вы не ожидаете, потому что это может изменить поведение вашего кода.
Не имеет значения, существует ли эта проблема на других языках; факт, что он существует, и JavaScript особенно уязвим, поскольку модификации прототипа объекта влияют на дочерние объекты, даже если модификация происходит после создания экземпляра.
Вот почему JavaScript предоставляет hasOwnProperty()
, и именно поэтому вы должны использовать его, чтобы гарантировать, что сторонний код (или любой другой код, который может изменить прототип) не нарушит ваш. Помимо добавления нескольких лишних байтов кода, нет недостатка в использовании hasOwnProperty()
.
Стандартный способ, который уже был предложен несколько раз:
for (var name in myObject) {
alert(name);
}
Однако Internet Explorer 6, 7 и 8 имеют ошибку в интерпретаторе JavaScript, что приводит к тому, что некоторые ключи не перечислены. Если вы запустите этот код:
var obj = { toString: 12};
for (var name in obj) {
alert(name);
}
Если появится предупреждение "12" во всех браузерах, кроме IE. IE просто игнорирует этот ключ. Ключевыми значениями являются:
isPrototypeOf
hasOwnProperty
toLocaleString
toString
valueOf
Чтобы быть действительно безопасным в IE, вам нужно использовать что-то вроде:
for (var key in myObject) {
alert(key);
}
var shadowedKeys = [
"isPrototypeOf",
"hasOwnProperty",
"toLocaleString",
"toString",
"valueOf"
];
for (var i=0, a=shadowedKeys, l=a.length; i<l; i++) {
if map.hasOwnProperty(a[i])) {
alert(a[i]);
}
}
Хорошей новостью является то, что EcmaScript 5 определяет функцию Object.keys(myObject)
, которая возвращает ключи объекта как массива, а некоторые браузеры (например, Safari 4) уже реализуют его.
В современных браузерах (ECMAScript 5) для получения всех перечислимых свойств вы можете:
Object.keys(obj) (Проверьте ссылку, чтобы получить фрагмент для обратной совместимости в старых браузерах)
Или получить также неперечислимые свойства:
Object.getOwnPropertyNames(obj)
Проверить таблицу совместимости ECMAScript 5
Дополнительная информация: Что такое перечислимый атрибут?
Я думаю, что пример случая, который застало меня врасплох, имеет значение:
var myObject = { name: "Cody", status: "Surprised" };
for (var propertyName in myObject) {
document.writeln( propertyName + " : " + myObject[propertyName] );
}
Но, к моему удивлению, вывод
name : Cody
status : Surprised
forEach : function (obj, callback) {
for (prop in obj) {
if (obj.hasOwnProperty(prop) && typeof obj[prop] !== "function") {
callback(prop);
}
}
}
Почему? Другой script на странице расширил прототип объекта:
Object.prototype.forEach = function (obj, callback) {
for ( prop in obj ) {
if ( obj.hasOwnProperty( prop ) && typeof obj[prop] !== "function" ) {
callback( prop );
}
}
};
for (prop in obj) {
alert(prop + ' = ' + obj[prop]);
}
Простой код JavaScript:
for(var propertyName in myObject) {
// propertyName is what you want.
// You can get the value like this: myObject[propertyName]
}
JQuery
jQuery.each(obj, function(key, value) {
// key is what you want.
// The value is in: value
});
Я нашел его... for (property in object) { // do stuff }
отобразит все свойства и, следовательно, все глобально объявленные переменные в объекте окна.
Если вы используете библиотеку Underscore.js, вы можете использовать функцию keys:
_.keys({one : 1, two : 2, three : 3});
=> ["one", "two", "three"]
Здесь перечислены свойства объекта:
var params = { name: 'myname', age: 'myage' }
for (var key in params) {
alert(key + "=" + params[key]);
}
У Python dict есть метод "keys", и это действительно полезно. Я думаю, что в JavaScript у нас может быть что-то такое:
function keys(){
var k = [];
for(var p in this) {
if(this.hasOwnProperty(p))
k.push(p);
}
return k;
}
Object.defineProperty(Object.prototype, "keys", { value : keys, enumerable:false });
EDIT: Но ответ @carlos-ruana работает очень хорошо. Я тестировал Object.keys (окно), и результат - то, что я ожидал.
EDIT через 5 лет: не рекомендуется расширять Object
, потому что он может конфликтовать с другими библиотеками, которые могут захотеть использовать keys
на своих объектах, и это приведет к непредсказуемому поведению в вашем проекте. @carlos-ruana ответ - правильный способ получить ключи от объекта.
Вы можете использовать for
циклы.
Если вы хотите использовать массив:
Object.keys(object1)
Ссылка Object.keys()
Если вы пытаетесь перечислить свойства, чтобы писать новый код с объектом, я бы рекомендовал использовать отладчик, например Firebug, для визуального просмотра.
Еще один удобный способ - использовать Prototype Object.toJSON() для сериализации объекта в JSON, который покажет вам имена и значения свойств.
var data = {name: 'Violet', occupation: 'character', age: 25, pets: ['frog', 'rabbit']};
Object.toJSON(data);
//-> '{"name": "Violet", "occupation": "character", "age": 25, "pets": ["frog","rabbit"]}'
Я все еще новичок в JavaScript, но я написал небольшую функцию для рекурсивного вывода всех свойств объекта и его дочерних элементов:
getDescription(object, tabs) {
var str = "{\n";
for (var x in object) {
str += Array(tabs + 2).join("\t") + x + ": ";
if (typeof object[x] === 'object' && object[x]) {
str += this.getDescription(object[x], tabs + 1);
} else {
str += object[x];
}
str += "\n";
}
str += Array(tabs + 1).join("\t") + "}";
return str;
}