iterating an object properties - javascript

is there a way to iterate an object properties and methods. i need to write a utility function like so:
function iterate(obj)
{
//print all obj properties
//print all obj methods
}
so running this function:
iterate(String);
will print:
property: lenght
function: charAt
function: concat...
any ideas?

Should be as simple as this:
function iterate(obj) {
for (p in obj) {
console.log(typeof(obj[p]), p);
}
}
Note: The console.log function is assuming you are using firebug. At this point, the following:
obj = {
p1: 1,
p2: "two",
m1: function() {}
};
iterate(obj);
would return:
number p1
string p2
function m1

See my answer in this other question, but you can't read built-in properties like that.

This only works in modern browsers (Chrome, Firefox 4+, IE9+), but in ECMAScript 5, you can get all the properties of an object with Object.getOwnPropertyNames. It just takes a little extra code to get the inherited properties from the prototype.
// Put all the properties of an object (including inherited properties) into
// an object so they can be iterated over
function getProperties(obj, properties) {
properties = properties || {};
// Get the prototype's properties
var prototype = Object.getPrototypeOf(obj);
if (prototype !== null) {
getProperties(prototype, properties);
}
// Get obj's own properties
var names = Object.getOwnPropertyNames(obj);
for (var i = 0; i < names.length; i++) {
var name = names[i];
properties[name] = obj[name];
}
return properties;
}
function iterate(obj) {
obj = Object(obj);
var properties = getProperties(obj);
for (var name in properties) {
if (typeof properties[name] !== "function") {
console.log("property: " + name);
}
}
for (var name in properties) {
if (typeof properties[name] === "function") {
console.log("function: " + name);
}
}
}

You can use the for loop to iterate an object's properties.
Here is a simple example
var o ={'test':'test', 'blah':'blah'};
for(var p in o)
alert(p);

Related

How to slice() return values from JSON API [duplicate]

var obj = {
name: "Simon",
age: "20",
clothing: {
style: "simple",
hipster: false
}
}
for(var propt in obj){
console.log(propt + ': ' + obj[propt]);
}
How does the variable propt represent the properties of the object? It's not a built-in method or property. Why does it come up with every property in the object?
Iterating over properties requires this additional hasOwnProperty check:
for (var prop in obj) {
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
// do stuff
}
}
It's necessary because an object's prototype contains additional properties for the object which are technically part of the object. These additional properties are inherited from the base object class, but are still properties of obj.
hasOwnProperty simply checks to see if this is a property specific to this class, and not one inherited from the base class.
It's also possible to call hasOwnProperty through the object itself:
if (obj.hasOwnProperty(prop)) {
// do stuff
}
But this will fail if the object has an unrelated field with the same name:
var obj = { foo: 42, hasOwnProperty: 'lol' };
obj.hasOwnProperty('foo'); // TypeError: hasOwnProperty is not a function
That's why it's safer to call it through Object.prototype instead:
var obj = { foo: 42, hasOwnProperty: 'lol' };
Object.prototype.hasOwnProperty.call(obj, 'foo'); // true
As of JavaScript 1.8.5 you can use Object.keys(obj) to get an Array of properties defined on the object itself (the ones that return true for obj.hasOwnProperty(key)).
Object.keys(obj).forEach(function(key,index) {
// key: the name of the object key
// index: the ordinal position of the key within the object
});
This is better (and more readable) than using a for-in loop.
Its supported on these browsers:
Firefox (Gecko): 4 (2.0)
Chrome: 5
Internet Explorer: 9
See the Mozilla Developer Network Object.keys()'s reference for futher information.
Girls and guys we are in 2019 and we do not have that much time for typing... So lets do this cool new fancy ECMAScript 2016:
Object.keys(obj).forEach(e => console.log(`key=${e} value=${obj[e]}`));
In up-to-date implementations of ES, you can use Object.entries:
for (const [key, value] of Object.entries(obj)) { }
or
Object.entries(obj).forEach(([key, value]) => ...)
If you just want to iterate over the values, then use Object.values:
for (const value of Object.values(obj)) { }
or
Object.values(obj).forEach(value => ...)
It's the for...in statement (MDN, ECMAScript spec).
You can read it as "FOR every property IN the obj object, assign each property to the PROPT variable in turn".
It's just a for...in loop. Check out the documentation at Mozilla.
if (typeof obj === 'object' && obj !== null) {
Object.keys(obj).forEach(key => {
console.log("\n" + key + ": " + obj[key]);
});
}
// *** Explanation line by line ***
// Explaining the bellow line
// It checks if obj is neither null nor undefined, which means it's safe to get its keys.
// Otherwise it will give you a "TypeError: Cannot convert undefined or null to object" if obj is null or undefined.
// NOTE 1: You can use Object.hasOwnProperty() instead of Object.keys(obj).length
// NOTE 2: No need to check if obj is an array because it will work just fine.
// NOTE 3: No need to check if obj is a string because it will not pass the 'if typeof obj is Object' statement.
// NOTE 4: No need to check if Obj is undefined because it will not pass the 'if type obj is Object' statement either.
if (typeof obj === 'object' && obj !== null) {
// Explaining the bellow line
// Just like in the previous line, this returns an array with
// all keys in obj (because if code execution got here, it means
// obj has keys.)
// Then just invoke built-in javascript forEach() to loop
// over each key in returned array and calls a call back function
// on each array element (key), using ES6 arrow function (=>)
// Or you can just use a normal function ((key) { blah blah }).
Object.keys(obj).forEach(key => {
// The bellow line prints out all keys with their
// respective value in obj.
// key comes from the returned array in Object.keys(obj)
// obj[key] returns the value of key in obj
console.log("\n" + key + ": " + obj[key]);
});
}
If your environment supports ES2017 then I would recommend Object.entries:
Object.entries(obj).forEach(([key, value]) => {
console.log(`${key} ${value}`);
});
As shown in Mozillas Object.entries() documentation:
The Object.entries() method returns an array of a given object's own
enumerable property [key, value] pairs, in the same order as that
provided by a for...in loop (the difference being that a for-in loop
enumerates properties in the prototype chain as well).
Basically with Object.entries we can forgo the following extra step that is required with the older for...in loop:
// This step is not necessary with Object.entries
if (object.hasOwnProperty(property)) {
// do stuff
}
Dominik's answer is perfect, I just prefer to do it that way, as it's cleaner to read:
for (var property in obj) {
if (!obj.hasOwnProperty(property)) continue;
// Do stuff...
}
jquery allows you to do this now:
$.each( obj, function( key, value ) {
alert( key + ": " + value );
});
The for...in loop represents each property in an object because it is just like a for loop. You defined propt in the for...in loop by doing:
for(var propt in obj){
alert(propt + ': ' + obj[propt]);
}
A for...in loop iterates through the enumerable properties of an object. Whichever variable you define, or put in the for...in loop, changes each time it goes to the next property it iterates. The variable in the for...in loop iterates through the keys, but the value of it is the key's value. For example:
for(var propt in obj) {
console.log(propt);//logs name
console.log(obj[propt]);//logs "Simon"
}
You can see how the variable differs from the variable's value. In contrast, a for...of loop does the opposite.
I hope this helps.
To add ES2015's usage of Reflect.ownKeys(obj) and also iterating over the properties via an iterator.
For example:
let obj = { a: 'Carrot', b: 'Potato', Car: { doors: 4 } };
can be iterated over by
// logs each key
Reflect.ownKeys(obj).forEach(key => console.log(key));
If you would like to iterate directly over the values of the keys of an object, you can define an iterator, just like JavaScipts's default iterators for strings, arrays, typed arrays, Map and Set.
JS will attempt to iterate via the default iterator property, which must be defined as Symbol.iterator.
If you want to be able to iterate over all objects you can add it as a prototype of Object:
Object.prototype[Symbol.iterator] = function*() {
for(p of Reflect.ownKeys(this)){ yield this[p]; }
}
This would enable you to iterate over the values of an object with a for...of loop, for example:
for(val of obj) { console.log('Value is:' + val ) }
Caution: As of writing this answer (June 2018) all other browsers, but IE, support generators and for...of iteration via Symbol.iterator
The above answers are a bit annoying because they don't explain what you do inside the for loop after you ensure it's an object: YOU DON'T ACCESS IT DIRECTLY! You are actually only delivered the KEY that you need to apply to the OBJ:
var obj = {
a: "foo",
b: "bar",
c: "foobar"
};
// We need to iterate the string keys (not the objects)
for(var someKey in obj)
{
// We check if this key exists in the obj
if (obj.hasOwnProperty(someKey))
{
// someKey is only the KEY (string)! Use it to get the obj:
var myActualPropFromObj = obj[someKey]; // Since dynamic, use [] since the key isn't literally named "someKey"
// NOW you can treat it like an obj
var shouldBeBar = myActualPropFromObj.b;
}
}
This is all ECMA5 safe. Even works in the lame JS versions like Rhino ;)
let obj = {"a": 3, "b": 2, "6": "a"}
Object.keys(obj).forEach((item) => {console.log("item", obj[item])})
// a
// 3
// 2
You can access the nested properties of the object using the for...in and forEach loop.
for...in:
for (const key in info) {
console.log(info[key]);
}
forEach:
Object.keys(info).forEach(function(prop) {
console.log(info[prop]);
// cities: Array[3], continent: "North America", images: Array[3], name: "Canada"
// "prop" is the property name
// "data[prop]" is the property value
});
You can use Lodash. The documentation
var obj = {a: 1, b: 2, c: 3};
_.keys(obj).forEach(function (key) {
...
});
Object.keys(obj).forEach(key =>
console.log(`key=${key} value=${obj[key]}`)
);
Nowadays you can convert a standard JS object into an iterable object just by adding a Symbol.iterator method. Then you can use a for of loop and acceess its values directly or even can use a spread operator on the object too. Cool. Let's see how we can make it:
var o = {a:1,b:2,c:3},
a = [];
o[Symbol.iterator] = function*(){
var ok = Object.keys(this);
i = 0;
while (i < ok.length) yield this[ok[i++]];
};
for (var value of o) console.log(value);
// or you can even do like
a = [...o];
console.log(a);
Your for loop is iterating over all of the properties of the object obj. propt is defined in the first line of your for loop. It is a string that is a name of a property of the obj object. In the first iteration of the loop, propt would be "name".
Objects in JavaScript are collections of properties and can therefore be looped in a for each statement.
You should think of obj as an key value collection.
If running Node I'd recommend:
Object.keys(obj).forEach((key, index) => {
console.log(key);
});
While the top-rated answer is correct, here is an alternate use case i.e if you are iterating over an object and want to create an array in the end. Use .map instead of forEach
const newObj = Object.keys(obj).map(el => {
//ell will hold keys
// Getting the value of the keys should be as simple as obj[el]
})
I want to add to the answers above, because you might have different intentions from Javascript. A JSON object and a Javascript object are different things, and you might want to iterate through the properties of a JSON object using the solutions proposed above, and then be surprised.
Suppose that you have a JSON object like:
var example = {
"prop1": "value1",
"prop2": [ "value2_0", "value2_1"],
"prop3": {
"prop3_1": "value3_1"
}
}
The wrong way to iterate through its 'properties':
function recursivelyIterateProperties(jsonObject) {
for (var prop in Object.keys(example)) {
console.log(prop);
recursivelyIterateProperties(jsonObject[prop]);
}
}
You might be surprised of seeing the console logging 0, 1, etc. when iterating through the properties of prop1 and prop2 and of prop3_1. Those objects are sequences, and the indexes of a sequence are properties of that object in Javascript.
A better way to recursively iterate through a JSON object properties would be to first check if that object is a sequence or not:
function recursivelyIterateProperties(jsonObject) {
for (var prop in Object.keys(example)) {
console.log(prop);
if (!(typeof(jsonObject[prop]) === 'string')
&& !(jsonObject[prop] instanceof Array)) {
recursivelyIterateProperties(jsonObject[prop]);
}
}
}
What for..in loop does is that it creates a new variable (var someVariable) and then stores each property of the given object in this new variable(someVariable) one by one. Therefore if you use block {}, you can iterate. Consider the following example.
var obj = {
name:'raman',
hobby:'coding',
planet:'earth'
};
for(var someVariable in obj) {
//do nothing..
}
console.log(someVariable); // outputs planet
Here I am iterating each node and creating meaningful node names. If you notice, instanceOf Array and instanceOf Object pretty much does the same thing (in my application, i am giving different logic though)
function iterate(obj,parent_node) {
parent_node = parent_node || '';
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
var node = parent_node + "/" + property;
if(obj[property] instanceof Array) {
//console.log('array: ' + node + ":" + obj[property]);
iterate(obj[property],node)
} else if(obj[property] instanceof Object){
//console.log('Object: ' + node + ":" + obj[property]);
iterate(obj[property],node)
}
else {
console.log(node + ":" + obj[property]);
}
}
}
}
note - I am inspired by Ondrej Svejdar's answer. But this solution has better performance and less ambiguous
Also adding the recursive way:
function iterate(obj) {
// watch for objects we've already iterated so we won't end in endless cycle
// for cases like var foo = {}; foo.bar = foo; iterate(foo);
var walked = [];
var stack = [{obj: obj, stack: ''}];
while(stack.length > 0)
{
var item = stack.pop();
var obj = item.obj;
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (typeof obj[property] == "object") {
// check if we haven't iterated through the reference yet
var alreadyFound = false;
for(var i = 0; i < walked.length; i++)
{
if (walked[i] === obj[property])
{
alreadyFound = true;
break;
}
}
// new object reference
if (!alreadyFound)
{
walked.push(obj[property]);
stack.push({obj: obj[property], stack: item.stack + '.' + property});
}
}
else
{
console.log(item.stack + '.' + property + "=" + obj[property]);
}
}
}
}
}
Usage:
iterate({ foo: "foo", bar: { foo: "foo"} });
You basically want to loop through each property in the object.
JSFiddle
var Dictionary = {
If: {
you: {
can: '',
make: ''
},
sense: ''
},
of: {
the: {
sentence: {
it: '',
worked: ''
}
}
}
};
function Iterate(obj) {
for (prop in obj) {
if (obj.hasOwnProperty(prop) && isNaN(prop)) {
console.log(prop + ': ' + obj[prop]);
Iterate(obj[prop]);
}
}
}
Iterate(Dictionary);
To further refine the accepted answer it's worth noting that if you instantiate the object with a var object = Object.create(null) then object.hasOwnProperty(property) will trigger a TypeError. So to be on the safe side, you'd need to call it from the prototype like this:
for (var property in object) {
if (Object.prototype.hasOwnProperty.call(object, property)) {
// do stuff
}
}
Check type
You can check how propt represent object propertis by
typeof propt
to discover that it's just a string (name of property). It come up with every property in the object due the way of how for-in js "build-in" loop works.
var obj = {
name: "Simon",
age: "20",
clothing: {
style: "simple",
hipster: false
}
}
for(var propt in obj){
console.log(typeof propt, propt + ': ' + obj[propt]);
}
If you just want to iterate to map property values then lodash has _.mapValues
const obj = {
a: 2,
b: 3
}
const res = _.mapValues(obj, v => v * 2)
console.log(res)
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.21/lodash.min.js"></script>

How to log/debug object properties, ignoreing method/function clutter

I'd like to use Chrome's dev console to track an object's properties, but on objects with a lot of methods, it's a pain to wade through all the function references. Is there a pretty way to debug objects without displaying their associated methods/functions? I've been toying with the following code, to replicate the object and strip function references, but I can't get it working... Thanks!
<script src='https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.js' type='text/javascript'></script>
<script>
function plog(obj){
var key;
var clone = jQuery.extend(true, {}, obj);
for (key in obj){
if(typeof(obj.key) == "function") {
delete clone[key];
}
}
console.log(clone);
}
</script>
Click Here
To get a value of property you should use index access like obj[key] inside for-in loop beecause key is a String with the name of property.
var getProperties = function(obj) {
var propsCopy,
i;
propsCopy = {};
for(i in obj) {
if(typeof(obj[i]) !== 'function') {
propsCopy[i] = obj[i];
}
}
return propsCopy;
};
var obj = {
x: 1,
y: 2,
fn: function(x) {
return x * x;
}
};
console.log(obj);
console.log(getProperties(obj));
DEMO
Also it could be good to read this documentation page.

Why does this JavaScript prototype function break jQuery?

Question:
As soon as I add the below code to my html page, I get:
Line: 4
Error: Object doesn't support the property or method "exec".
This is the prototype that causes the bug:
Object.prototype.allKeys = function () {
var keys = [];
for (var key in this)
{
// Very important to check for dictionary.hasOwnProperty(key)
// otherwise you may end up with methods from the prototype chain..
if (this.hasOwnProperty(key))
{
keys.push(key);
//alert(key);
} // End if (dict.hasOwnProperty(key))
} // Next key
keys.sort();
return keys;
}; // End Extension Function allKeys
And this is the minimum code required to reproduce the error (Browser in question: IE9):
<!DOCTYPE html>
<html>
<head>
<title>TestPage</title>
<script type="text/javascript" src="jquery-1.9.1.min.js"></script>
<script type="text/javascript">
/*
Object.prototype.getName111 = function () {
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec((this).constructor.toString());
return (results && results.length > 1) ? results[1] : "";
}; // End Function getName
*/
Object.prototype.allKeys = function () {
var keys = [];
for (var key in this)
{
// Very important to check for dictionary.hasOwnProperty(key)
// otherwise you may end up with methods from the prototype chain..
if (this.hasOwnProperty(key))
{
keys.push(key);
//alert(key);
} // End if (dict.hasOwnProperty(key))
} // Next key
keys.sort();
return keys;
}; // End Extension Function allKeys
</script>
</head>
<body>
<select id="selLayers" name="myddl">
<option value="1">One</option>
<option value="2">Twooo</option>
<option value="3">Three</option>
<option value="4">Text1</option>
<option value="5">Text2</option>
</select>
<script type="text/javascript">
//var dict = { "de": { "Text1": "Ersetzung 1", "Text2": "Ersetzung 2" }, "fr": { "Text1": "Replacement 1", "Text2": "Réplacement 2" }, "it": { "Text1": "Replacemente 1", "Text2": "Replacemente 2" }, "en": { "Text1": "Replacement 1", "Text2": "Replacement 2"} };
/*
var languages = dict.allKeys();
for (var j = 0; j < languages.length; ++j)
{
var strCurrentLanguage = languages[j];
var dictReplacements = dict[strCurrentLanguage]
var keys = dictReplacements.allKeys();
//alert(JSON.stringify(dictReplacements));
//alert(JSON.stringify(keys));
for (var i = 0; i < keys.length; ++i) {
var strKey = keys[i];
var strReplacement = dictReplacements[strKey];
alert(strKey + " ==> " + strReplacement);
//alert('#selLayers option:contains("' + strKey + '")');
//$('#selLayers option:contains("' + strKey + '")').html(strReplacement);
//$('#selLayers option:contains("Text1")').html("foobar");
}
}
*/
$('#selLayers option:contains("Twooo")').text('Fish');
//alert(dict.allKeys());
//alert(dict["de"]["abc"]);
/*
$('#selLayers option[value=2]').text('Fish');
$('#selLayers option:contains("Twooo")').text('Fish');
$('#selLayers option:contains("Twooo")').html('Étage');
// http://stackoverflow.com/questions/7344220/jquery-selector-contains-to-equals
$("#list option[value=2]").text();
$("#list option:selected").each(function () {
alert($(this).text());
});
$("#list").change(function() {
alert($(this).find("option:selected").text()+' clicked!');
});
*/
</script>
</body>
</html>
I tried renaming the prototype function, just in case it conflicts with any jquery prototype, but that doesn't help at all.
Because this is going to add an enumerable item to every single object. Sizzle (which jQuery uses) uses object literals to configure their selector parsing. When it loops these config objects to get all tokens, it doesn't expect your function. In this case, it's probably trying to use your function as a RegExp.
Imagine this scenario:
var obj = { a: 1, b: 2, c: 3 };
var result = 0;
for (var prop in obj) {
// On one of these iterations, `prop` will be "allKeys".
// In this case, `obj[prop]` will be a function instead of a number.
result += obj[prop] * 2;
}
console.log(result);
If you have added anything to Object's prototype that can't be used as a number, you will get NaN for your result.
A good solution to this problem is to add the allKeys function to Object instead of Object.prototype. This mimics Object.keys:
Object.allKeys = function (obj) {
var keys = [];
for (var key in obj)
{
// Very important to check for dictionary.hasOwnProperty(key)
// otherwise you may end up with methods from the prototype chain..
if (obj.hasOwnProperty(key))
{
keys.push(key);
//alert(key);
} // End if (dict.hasOwnProperty(key))
} // Next key
keys.sort();
return keys;
}; // End Extension Function allKeys
You may be able to overcome this side-effect by using defineProperty which allows for setting descriptors.
Object.defineProperty(Object.prototype, 'propName', {value: 'your value', enumerable: false});
Because jQuery doesn't bog down its code with checks for .hasOwnProperty() when enumerating objects.
To do so, is to place guards against bad coding practices. Rather than weigh down their code to accommodate such practices, they require that their users adhere to good practices, like never putting enumerable properties on Object.prototype.
In other words... Don't add enumerable properties to Object.prototype unless you want all your code to run guards against those properties, and you never want to enumerate inherited properties.
FWIW, if you really want to call methods on plain objects, just make a constructor so that you have an intermediate prototype object that can be safely extended.
function O(o) {
if (!(this instanceof O))
return new O(o)
for (var p in o)
this[p] = o[p]
}
O.prototype.allKeys = function() {
// ...
};
Now you create your objects like this:
var foo = O({
foo: "foo",
bar: "bar",
baz: "baz"
});
...and the Object.prototype remains untouched, so plain objects are still safe. You'll just need to use the .hasOwnProperty() guard when enumerating your O objects.
for (var p in foo) {
if (foo.hasOwnProperty(p)) {
// do stuff
}
}
And with respect to JSON data being parsed, you can use a reviver function to swap out the plain objects with your O object.
var parsed = JSON.parse(jsondata, function(k, v) {
if (v && typeof v === "object" && !(v instanceof Array)) {
return O(v)
}
return v
});

Iterating over javascript object and valueOf toString methods

var x = {
article: "bla bla bla ",
journal: "le monde ",
magazine: "playboy"
};
for (var i in x) {
alert(i + " "+ x[i]);
}
Every JS object has a valueOf and a toString method. Why can't I see them when I iterate over the properties of the x object?
They are not enumerable properties. Try Object.getOwnPropertyNames. Only works in some browsers:
This DOESNT check proto though, so you need to do something very complicated:
var x, y, z, getAllKeys;
getAllKeys = function (obj,ar) {
ar = ar || [new Array];
ar[0] = ar[0].concat(Object.getOwnPropertyNames(obj));
if (obj !== Function.prototype && Object.getPrototypeOf(obj)) {
getAllKeys(Object.getPrototypeOf(obj),ar);
}
return ar[0];
}
console.log (getAllKeys(new Array));
for (x in y = getAllKeys(z = new Array)) {
var key = y[x];
var value = z[y[x]];
}
Blame JavaScript for being ridiculous and looking like assembly, maybe jASM would be a better name? (joke)
The engine specifically hides these methods from enumeration.
The purpose of this is to allow to iterate over Object properties without being annoyed by the object's prototypal properties. This way you can iterate over Array indices, use Objects as hash tables and iterate over its properties.
This can however be easily broken. For example if you use a custom method in Object.property, it will suddenly appear during the enumeration of all objects' properties:
var obj = { foo: 0 };
Object.prototype.bar = 1;
// prints 'foo' and 'bar'
for (var k in obj) {
console.log(k);
}
This is makes it dangerous to extend Object.prototype.
You can test if a property comes from the object itself or it's prototype by using the Object.hasOwnProperty method:
// prints 'foo'
for (var k in obj) {
if (!obj.hasOwnProperty(a)) continue;
console.log(k);
}
Alternatively, you could use Object.defineProperty do define non-enumerable properties, if you don't care of old browsers:
Object.defineProperty(Object.prototype, 'bar', {value: 1, enumerable: false});
// prints 'foo'
for (var k in obj) {
console.log(k);
}

How to list the properties of a JavaScript object?

Say I create an object thus:
var myObject =
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
What is the best way to retrieve a list of the property names? i.e. I would like to end up with some variable 'keys' such that:
keys == ["ircEvent", "method", "regex"]
In modern browsers (IE9+, FF4+, Chrome5+, Opera12+, Safari5+) you can use the built in Object.keys method:
var keys = Object.keys(myObject);
The above has a full polyfill but a simplified version is:
var getKeys = function(obj){
var keys = [];
for(var key in obj){
keys.push(key);
}
return keys;
}
Alternatively replace var getKeys with Object.prototype.keys to allow you to call .keys() on any object. Extending the prototype has some side effects and I wouldn't recommend doing it.
As slashnick pointed out, you can use the "for in" construct to iterate over an object for its attribute names. However you'll be iterating over all attribute names in the object's prototype chain. If you want to iterate only over the object's own attributes, you can make use of the Object#hasOwnProperty() method. Thus having the following.
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
/* useful code here */
}
}
As Sam Dutton answered, a new method for this very purpose has been introduced in ECMAScript 5th Edition. Object.keys() will do what you want and is supported in Firefox 4, Chrome 6, Safari 5 and IE 9.
You can also very easily implement the method in browsers that don't support it. However, some of the implementations out there aren't fully compatible with Internet Explorer. Here's a more compatible solution:
Object.keys = Object.keys || (function () {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !{toString:null}.propertyIsEnumerable("toString"),
DontEnums = [
'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty',
'isPrototypeOf', 'propertyIsEnumerable', 'constructor'
],
DontEnumsLength = DontEnums.length;
return function (o) {
if (typeof o != "object" && typeof o != "function" || o === null)
throw new TypeError("Object.keys called on a non-object");
var result = [];
for (var name in o) {
if (hasOwnProperty.call(o, name))
result.push(name);
}
if (hasDontEnumBug) {
for (var i = 0; i < DontEnumsLength; i++) {
if (hasOwnProperty.call(o, DontEnums[i]))
result.push(DontEnums[i]);
}
}
return result;
};
})();
Note that the currently accepted answer doesn't include a check for hasOwnProperty() and will return properties that are inherited through the prototype chain. It also doesn't account for the famous DontEnum bug in Internet Explorer where non-enumerable properties on the prototype chain cause locally declared properties with the same name to inherit their DontEnum attribute.
Implementing Object.keys() will give you a more robust solution.
EDIT: following a recent discussion with kangax, a well-known contributor to Prototype, I implemented the workaround for the DontEnum bug based on code for his Object.forIn() function found here.
Note that Object.keys and other ECMAScript 5 methods are supported by Firefox 4, Chrome 6, Safari 5, IE 9 and above.
For example:
var o = {"foo": 1, "bar": 2};
alert(Object.keys(o));
ECMAScript 5 compatibility table
Description of new methods
Object.getOwnPropertyNames(obj)
This function also shows non-enumerable properties in addition to those shown by Object.keys(obj).
In JS, every property has a few properties, including a boolean enumerable.
In general, non-enumerable properties are more "internalish" and less often used, but it is insightful to look into them sometimes to see what is really going on.
Example:
var o = Object.create({base:0})
Object.defineProperty(o, 'yes', {enumerable: true})
Object.defineProperty(o, 'not', {enumerable: false})
console.log(Object.getOwnPropertyNames(o))
// [ 'yes', 'not' ]
console.log(Object.keys(o))
// [ 'yes' ]
for (var x in o)
console.log(x)
// yes, base
Also note how:
Object.getOwnPropertyNames and Object.keys don't go up the prototype chain to find base
for in does
More about the prototype chain here: https://stackoverflow.com/a/23877420/895245
I'm a huge fan of the dump function.
Ajaxian » JavaScript Variable Dump in Coldfusion
Download the dump function
Could do it with jQuery as follows:
var objectKeys = $.map(object, function(value, key) {
return key;
});
if you are trying to get the elements only but not the functions then this code can help you
this.getKeys = function() {
var keys = new Array();
for(var key in this) {
if( typeof this[key] !== 'function') {
keys.push(key);
}
}
return keys;
}
this is part of my implementation of the HashMap and I only want the keys, "this" is the hashmap object that contains the keys
This will work in most browsers, even in IE8 , and no libraries of any sort are required. var i is your key.
var myJSONObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
var keys=[];
for (var i in myJSONObject ) { keys.push(i); }
alert(keys);
Use Reflect.ownKeys()
var obj = {a: 1, b: 2, c: 3};
Reflect.ownKeys(obj) // ["a", "b", "c"]
Object.keys and Object.getOwnPropertyNames cannot get non-enumerable properties. It's working even for non-enumerable properties.
var obj = {a: 1, b: 2, c: 3};
obj[Symbol()] = 4;
Reflect.ownKeys(obj) // ["a", "b", "c", Symbol()]
Under browsers supporting js 1.8:
[i for(i in obj)]
Mozilla has full implementation details on how to do it in a browser where it isn't supported, if that helps:
if (!Object.keys) {
Object.keys = (function () {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function (obj) {
if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');
var result = [];
for (var prop in obj) {
if (hasOwnProperty.call(obj, prop)) result.push(prop);
}
if (hasDontEnumBug) {
for (var i=0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
}
}
return result;
};
})();
}
You could include it however you'd like, but possibly in some kind of extensions.js file at the top of your script stack.
With ES6 and later (ECMAScript 2015), you can get all properties like this:
let keys = Object.keys(myObject);
And if you wanna list out all values:
let values = Object.keys(myObject).map(key => myObject[key]);
Building on the accepted answer.
If the Object has properties you want to call say .properties() try!
var keys = Object.keys(myJSONObject);
for (var j=0; j < keys.length; j++) {
Object[keys[j]].properties();
}
Since I use underscore.js in almost every project, I would use the keys function:
var obj = {name: 'gach', hello: 'world'};
console.log(_.keys(obj));
The output of that will be:
['name', 'hello']
IE does not support for(i in obj) for native properties. Here is a list of all the props I could find.
It seems stackoverflow does some stupid filtering.
The list is available at the bottom of this google group post:-
https://groups.google.com/group/hackvertor/browse_thread/thread/a9ba81ca642a63e0
A lot of answers here... This is my 2 cents.
I needed something to print out all the JSON attributes, even the ones with sub-objects or arrays (parent name included).
So - For this JSON:
mylittleJson = {
"one": "blah",
"two": {
"twoone": "",
"twotwo": "",
"twothree": ['blah', 'blah']
},
"three": ""
}
It'd print this:
.one
.two.twoone
.two.twotwo
.two.twothree
.three
Here is function
function listatts(parent, currentJson){
var attList = []
if (typeof currentJson !== 'object' || currentJson == undefined || currentJson.length > 0) {
return
}
for(var attributename in currentJson){
if (Object.prototype.hasOwnProperty.call(currentJson, attributename)) {
childAtts = listatts(parent + "." + attributename, currentJson[attributename])
if (childAtts != undefined && childAtts.length > 0)
attList = [...attList, ...childAtts]
else
attList.push(parent + "." + attributename)
}
}
return attList
}
mylittleJson = {
"one": "blah",
"two": {
"twoone": "",
"twotwo": "",
"twothree": ['blah', 'blah']
},
"three": ""
}
console.log(listatts("", mylittleJson));
Hope it helps too.
The solution work on my cases and cross-browser:
var getKeys = function(obj) {
var type = typeof obj;
var isObjectType = type === 'function' || type === 'object' || !!obj;
// 1
if(isObjectType) {
return Object.keys(obj);
}
// 2
var keys = [];
for(var i in obj) {
if(obj.hasOwnProperty(i)) {
keys.push(i)
}
}
if(keys.length) {
return keys;
}
// 3 - bug for ie9 <
var hasEnumbug = !{toString: null}.propertyIsEnumerable('toString');
if(hasEnumbug) {
var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
var nonEnumIdx = nonEnumerableProps.length;
while (nonEnumIdx--) {
var prop = nonEnumerableProps[nonEnumIdx];
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
keys.push(prop);
}
}
}
return keys;
};

Categories