2008-09-17 2 views
553

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

На самом деле я хочу перечислить все определенные переменные и их значения, но я узнал, что определение переменной фактически создает свойство объекта window. достаточно

+1

Дата не имеет значения при выборе дубликатов. Лучший вопрос остается открытым, другой закрыт как дубликат. – meagar

ответ

714

Простой:

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).

+7

Я думаю, @bitwiseplatypus просто говорит «будьте осторожны». Я считаю, что JavaScript для/in должен преподаваться только с упоминанием hasOwnProperty() и других менее очевидных краевых случаев прототипального наследования. – pcorcoran

+0

Интересно, что это не работает для свойств геттера, определенных с Object.defineProperty, но работает для прямых геттеров. См. Мой [jsfiddle] (http://jsfiddle.net/Sgf8N/4/). – Ciantic

+25

Я думаю, что * большинство * людей удивляются, что 'for (x in {})' перечисляет что-либо вообще, поскольку он похож на простую итерацию ключевого словаря. Это очень неожиданно и, безусловно, заслуживает специального предупреждения. –

9

Я нашел его ... for (property in object) { // do stuff } будут перечислены все свойства, и, следовательно, все глобально объявленные переменные на объект окна ..

203

Используйте 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); 
    } 
} 

Edit: Я не согласен с утверждением JasonBunting, что нам не нужно беспокоиться о перечислении наследуемых свойств. Там is опасность в перечислении над унаследованными свойствами, которых вы не ожидаете, потому что это может изменить поведение вашего кода.

Не имеет значения, существует ли эта проблема на других языках; факт, что он существует, и JavaScript особенно уязвим, поскольку модификации прототипа объекта влияют на дочерние объекты, даже если модификация происходит после создания экземпляра.

Именно поэтому JavaScript предоставляет hasOwnProperty(), и именно поэтому вы должны использовать его, чтобы гарантировать, что сторонний код (или любой другой код, который может изменить прототип) не сломает ваш. Помимо добавления нескольких дополнительных байтов кода, нет недостатка в использовании hasOwnProperty().

+4

Преданные hasOwnProperty обычно являются теми, кто: a) страдал от агрессивных общих библиотек [например .: Prototype.js около 2003], или б) построил основы для гетерогенных систем (думаю, веб-порталы). Все остальные должны просто обернуть hasOwnProperty в шаблон итератора и выйти за пивом. – pcorcoran

+4

Я поддержал это, потому что использование hasOwnProperty является полезным дополнением к циклу for, хотя в то время мне это не нужно. – davenpcj

+25

Этот шаблон необходим и используется, потому что javascript объединяет «Объекты Актера» с «Хэш-таблицами». когда объект является * описанием поведения и признаков *, тогда применяются обычные правила, вы хотите знать о свойствах объекта, не заботясь о том, как они туда попали. Если, с другой стороны, вы используете объект в качестве хранилища ключей, тогда вам, скорее всего, только интересуются фактические ключи, которые фактически хранятся на объекте. Другие свойства являются совпадающими и не представляют фактическое состояние объекта. Другие языки решают это различие с различными типами. – SingleNegationElimination

0

Если вы пытаетесь перечислить свойства, чтобы написать новый код для объекта, я бы рекомендовал использовать отладчик, например Firebug, для визуального просмотра.

Еще один удобный способ - использовать Object объекта 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"]}' 

http://www.prototypejs.org/api/object/tojson

13
for (prop in obj) { 
    alert(prop + ' = ' + obj[prop]); 
} 
+0

Самый простой ответ, который объясняет все необходимое для основного использования. – TetraDev

22

Я думаю, что пример случая, который поймал меня врасплох, актуальна:

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

Почему? Другой скрипт на странице продлила прототип объекта:

Object.prototype.forEach = function (obj, callback) { 
    for (prop in obj) { 
    if (obj.hasOwnProperty(prop) && typeof obj[prop] !== "function") { 
     callback(prop); 
    } 
    } 
}; 
+0

Интересно, я полагаю, это означает, что невозможно вызвать обратный вызов при переопределении функции forEach, что может сделать перерасчет свойств. – davenpcj

+0

Да, я хочу сказать, что другой скрипт мог добавить что-либо к прототипу объекта. Такие изменения могут быть там, они не могут, и добавленные методы могут что-то сделать. Я не утверждаю, что этот пример forEach хорош - только что-то, что может сделать скрипт, который изменит результаты для .. для других скриптов. – cyberhobo

+0

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

48

Стандартный способ, который уже был предложен в несколько раз:

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) уже реализует его.

+1

Спасибо Фабиан. Это очень полный ответ. –

9

Простой код 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 
}); 
7

Если вы используете Underscore.js библиотеку, вы можете использовать функцию keys:

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

Вот как перечислить Свойства объекта:

var params = { name: 'myname', age: 'myage' } 

for (var key in params) { 
    alert(key + "=" + params[key]); 
} 
39

В современных браузерах (ECMAScript 5), чтобы получить все перечисляемые свойства, которые вы можете сделать:

Object.keys(obj) (Проверьте ссылку, чтобы получить фрагмент кода для обратной совместимости на старых браузерах)

Или получить Кроме того, не перечислимое свойство:

Object.getOwnPropertyNames(obj)

Check ECMAScript 5 compatibility table

Дополнительная информация: What is a enumerable attribute?

+0

'Object.getOwnPropertyNames (obj)' - это то, что вы хотите, если вы имеете дело с каким-то объектом Error (например, TypeError), потому что свойства неперечислимы. – vossad01

5

ДИКТ Python имеет метод 'ключи', и это действительно полезно. Я думаю, что в 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: Но ответ @ Карлос-ruana работает очень хорошо. Я тестировал Object.keys (окно), и результат - то, что я ожидал.

0

Вы можете использовать цикл for.

Если вы хотите использовать массив Object.keys (Object1)

0

Я еще новичок в 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; 
} 
Смежные вопросы