2009-03-23 6 views
109

Скажет, у вас объекты JavaScript, как это:Как мне получить доступ к свойствам объекта javascript, если я не знаю имен?

var data = { foo: 'bar', baz: 'quux' }; 

Вы можете получить доступ к свойствам под именем свойства:

var foo = data.foo; 
var baz = data["baz"]; 

Но есть возможность получить эти значения, если вы не знаете, имя свойства? Разве неупорядоченный характер этих свойств делает невозможным рассказать их обособленно?

В моем случае я думаю конкретно о ситуации, когда функция должна принимать серию пар имя-значение, но имена свойств могут измениться.

Мои мысли о том, как это сделать до сих пор, - передать имена свойств функции вместе с данными, но это похоже на взлома. Я бы предпочел сделать это с помощью интроспекции, если это возможно.

ответ

46

Старые версии JavaScript (< ES5) требуют применения for..in цикла:

for (var key in data) { 
    if (data.hasOwnProperty(key)) { 
    // do something with key 
    } 
} 

ES5 вводит Object.keys и Array#forEach, что делает это немного легче:

var data = { foo: 'bar', baz: 'quux' }; 

Object.keys(data); // ['foo', 'baz'] 
Object.keys(data).map(function(key){ return data[key] }) // ['bar', 'quux'] 
Object.keys(data).forEach(function (key) { 
    // do something with data[key] 
}); 

ES2017 вводит Object.values и Object.entries.

Object.values(data) // ['bar', 'quux'] 
Object.entries(data) // [['foo', 'bar'], ['baz', 'quux']] 
+1

Теперь это на самом деле отвечает на вопрос, хорошо сделано @Adam Lassek, очень красиво сделано. –

+0

Неверно использовать как «имя», так и «значение» в качестве объектных ключей. Эта функция возвращает только ключи в списке, а не значения. {name1: 'value1', name2: 'value2'} позволит избежать путаницы для новичков. Object.keys (данные); // ['name1', 'name2'] –

+2

@JamesNicholson Я согласен, отредактирован, чтобы быть менее запутанным. –

127

Вы можете перебрать ключи, как это:

for (var key in data) { 
    console.log(key); 
} 

Это журналы "Name" и "Value".

Если у вас более сложный тип объекта (а не просто простой хэш-объект, как в исходном вопросе), вам нужно будет только прокручивать ключи, принадлежащие самому объекту, в отличие от клавиш на объект prototype:

for (var key in data) { 
    if (data.hasOwnProperty(key)) { 
    console.log(key); 
    } 
} 

Как вы заметили, ключи не гарантируется в любом порядке. Обратите внимание, как это отличается от следующего:

for each (var value in data) { 
    console.log(value); 
} 

Этот пример перебирает значений, так что журнал будет Property Name и 0. N.B .: Синтаксис for each в основном поддерживается только в Firefox, но не в других браузерах.

Если ваши целевые браузеры поддерживают ES5, или ваш сайт включает в себя es5-shim.js (рекомендуется), вы можете также использовать Object.keys:

var data = { Name: 'Property Name', Value: '0' }; 
console.log(Object.keys(data)); // => ["Name", "Value"] 

и петля с Array.prototype.forEach:

Object.keys(data).forEach(function (key) { 
    console.log(data[key]); 
}); 
// => Logs "Property Name", 0 
+0

Вы только что сделали это последнее и действительно ушли с ним? Хорошо сделано ... =) –

+0

Это существует в Firefox ([docs] (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/for_each...in)), но справедливая точка что он не универсален. Я уточню ответ, чтобы упомянуть об этом. –

+25

btw alert - это плохой способ отладки вещей, попробуйте console.log – StackOverflowed

4

Вы часто будете хотеть изучите свойства объекта экземпляра, без использования всех методов и свойств прототипа общего доступа:

Obj.prototype.toString= function(){ 
     var A= []; 
     for(var p in this){ 
      if(this.hasOwnProperty(p)){ 
       A[A.length]= p+'='+this[p]; 
      } 
     } 

    return A.join(', '); 
} 
0
var fs = require("fs"); 

fs.stat(process.argv[1], function(err, stats){ 
if (err) { 
    console.log(err.message); 
    return;  
} else { 
console.log(JSON.stringify(stats)); 

/* this is the answer here */ 

    for (var key in Object.keys(stats)){ 
    var t = Object.keys(stats)[key]; 
    console.log(t + " value =: " + stats[t] ); 
    } 

/* to here, run in node */ 
    } 
}); 
+0

Не могли бы вы добавить больше объяснений? –

+0

'Object.keys (stats) [key]' не имеет смысла, всегда будет 'undefined'. –

-2
var attr, object_information=''; 

for(attr in object){ 

     //Get names and values of propertys with style (name : value) 
     object_information += attr + ' : ' + object[attr] + '\n'; 

    } 


alert(object_information); //Show all Object 
+0

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

2
function getDetailedObject(inputObject) { 
    var detailedObject = {}, properties; 

    do { 
     properties = Object.getOwnPropertyNames(inputObject); 
     for (var o in properties) { 
      detailedObject[properties[o]] = inputObject[properties[o]]; 
     } 
    } while (inputObject = Object.getPrototypeOf(inputObject)); 

    return detailedObject; 
} 

Это позволит получить все свойства и их значения (по наследству или самостоятельно, перечислимы или нет) в новом объекте. оригинальный объект не тронут. Теперь новый объект может быть пройден с использованием

var obj = { 'b': '4' }; //example object 
var detailedObject = getDetailedObject(obj); 
for(var o in detailedObject) { 
    console.log('key: ' + o + ' value: ' + detailedObject[o]); 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^