It's not true in the general case that you'll get the same result from Array.from(x) and Object.values(x) when x is an iterable object. In fact, it's fairly rare (just arrays and array-likes¹ that hide their length property by making it non-enumerable or inheriting it and don't have any other own, enumerable properties). Array.from will loop through the iterable object using iteration; Object.values will loop through the object looking for own, enumerable properties. For an array that doesn't have any non-array properties, that ends up being the same thing, but it's not true in the general case.
In the general case, Array.from and Object.values do very different things and have different results:
Array.fromcreates an array from any iterable or array-like object (an object with alengthand index properties like 0 and 1).Object.valuescreates an array of the values of an object's own enumerable properties. The object doesn't have to be iterable (Object.valuesdoesn't even look to see if it is.)Array.fromaccepts a second argument, a function that can be used to map the values from the iterable/array-like into new values for the array.
Here's an example where Object.values gets [] (because the Set has no own enumerable properties) but Array.from gets [1, 2, 3] (because the Set's iterator provides those three values):
const x = new Set([1, 2, 3]);
// Shows an empty array
console.dir(Object.values(x));
// Shows [1, 2, 3]
console.dir(Array.from(x));
Conversely, here's one where Object.values returns [1, 2, 3] because the object has those as own enumerable properties, but Array.from returns [] because the object is neither iterable nor array-like:
const x = {a: 1, b: 2, c: 3};
// Shows [1, 2, 3];
console.dir(Object.values(x));
// Shows []
console.dir(Array.from(x));
¹ An array-like object is an object with:
- A
lengthproperty - Properties named with strings that are numbers in the normal decimal form for the values
0throughlength - 1(but there can be gaps).
For instance, this is an array-like object:
const obj = {0: "zero", 1: "one", length: 2};
(I've used number literals for the property names, but they'll be converted to string.)
Note that that object will give you different results for Array.from and Object.values because length is an own, inherited property.
javascript - Object.values vs Array.from, what's the difference? - Stack Overflow
function - Get values from an object in JavaScript - Stack Overflow
How to get all properties values of a JavaScript Object (without knowing the keys)? - Stack Overflow
How to Access Object value with Javascript?
It's not true in the general case that you'll get the same result from Array.from(x) and Object.values(x) when x is an iterable object. In fact, it's fairly rare (just arrays and array-likes¹ that hide their length property by making it non-enumerable or inheriting it and don't have any other own, enumerable properties). Array.from will loop through the iterable object using iteration; Object.values will loop through the object looking for own, enumerable properties. For an array that doesn't have any non-array properties, that ends up being the same thing, but it's not true in the general case.
In the general case, Array.from and Object.values do very different things and have different results:
Array.fromcreates an array from any iterable or array-like object (an object with alengthand index properties like 0 and 1).Object.valuescreates an array of the values of an object's own enumerable properties. The object doesn't have to be iterable (Object.valuesdoesn't even look to see if it is.)Array.fromaccepts a second argument, a function that can be used to map the values from the iterable/array-like into new values for the array.
Here's an example where Object.values gets [] (because the Set has no own enumerable properties) but Array.from gets [1, 2, 3] (because the Set's iterator provides those three values):
const x = new Set([1, 2, 3]);
// Shows an empty array
console.dir(Object.values(x));
// Shows [1, 2, 3]
console.dir(Array.from(x));
Conversely, here's one where Object.values returns [1, 2, 3] because the object has those as own enumerable properties, but Array.from returns [] because the object is neither iterable nor array-like:
const x = {a: 1, b: 2, c: 3};
// Shows [1, 2, 3];
console.dir(Object.values(x));
// Shows []
console.dir(Array.from(x));
¹ An array-like object is an object with:
- A
lengthproperty - Properties named with strings that are numbers in the normal decimal form for the values
0throughlength - 1(but there can be gaps).
For instance, this is an array-like object:
const obj = {0: "zero", 1: "one", length: 2};
(I've used number literals for the property names, but they'll be converted to string.)
Note that that object will give you different results for Array.from and Object.values because length is an own, inherited property.
Array.from creates a new array, usually from another array, but can also be used on Set. It also has a second arguments, that allows to map each element to another value.
Object.values on the other hand creates a new array with the values from the supplied object.
I'm not exactly sure why you say they do the same thing, as they don't. Except maybe the fac that you end up with an array as the results. Take this example for instance:
Object.values({a: 2, b:3}) // will return [2, 3]
on the other hand
Array.from({a: 2, b:3}) // will return [], as an object is not an array-like object
To access the properties of an object without knowing the names of those properties you can use a for ... in loop:
for(key in data) {
if(data.hasOwnProperty(key)) {
var value = data[key];
//do something with value;
}
}
In ES2017 you can use Object.values():
Object.values(data)
At the time of writing support is limited (FireFox and Chrome).All major browsers except IE support this now.
In ES2015 you can use this:
Object.keys(data).map(k => data[k])
Depending on which browsers you have to support, this can be done in a number of ways. The overwhelming majority of browsers in the wild support ECMAScript 5 (ES5), but be warned that many of the examples below use Object.keys, which is not available in IE < 9. See the compatibility table.
ECMAScript 3+
If you have to support older versions of IE, then this is the option for you:
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
var val = obj[key];
// use val
}
}
The nested if makes sure that you don't enumerate over properties in the prototype chain of the object (which is the behaviour you almost certainly want). You must use
Object.prototype.hasOwnProperty.call(obj, key) // ok
rather than
obj.hasOwnProperty(key) // bad
because ECMAScript 5+ allows you to create prototypeless objects with Object.create(null), and these objects will not have the hasOwnProperty method. Naughty code might also produce objects which override the hasOwnProperty method.
ECMAScript 5+
You can use these methods in any browser that supports ECMAScript 5 and above. These get values from an object and avoid enumerating over the prototype chain. Where obj is your object:
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
var val = obj[keys[i]];
// use val
}
If you want something a little more compact or you want to be careful with functions in loops, then Array.prototype.forEach is your friend:
Object.keys(obj).forEach(function (key) {
var val = obj[key];
// use val
});
The next method builds an array containing the values of an object. This is convenient for looping over.
var vals = Object.keys(obj).map(function (key) {
return obj[key];
});
// use vals array
If you want to make those using Object.keys safe against null (as for-in is), then you can do Object.keys(obj || {})....
Object.keys returns enumerable properties. For iterating over simple objects, this is usually sufficient. If you have something with non-enumerable properties that you need to work with, you may use Object.getOwnPropertyNames in place of Object.keys.
ECMAScript 2015+ (A.K.A. ES6)
Arrays are easier to iterate with ECMAScript 2015. You can use this to your advantage when working with values one-by–one in a loop:
for (const key of Object.keys(obj)) {
const val = obj[key];
// use val
}
Using ECMAScript 2015 fat-arrow functions, mapping the object to an array of values becomes a one-liner:
const vals = Object.keys(obj).map(key => obj[key]);
// use vals array
ECMAScript 2015 introduces Symbol, instances of which may be used as property names. To get the symbols of an object to enumerate over, use Object.getOwnPropertySymbols (this function is why Symbol can't be used to make private properties). The new Reflect API from ECMAScript 2015 provides Reflect.ownKeys, which returns a list of property names (including non-enumerable ones) and symbols.
Array comprehensions (do not attempt to use)
Array comprehensions were removed from ECMAScript 6 before publication. Prior to their removal, a solution would have looked like:
const vals = [for (key of Object.keys(obj)) obj[key]];
// use vals array
ECMAScript 2017+
ECMAScript 2016 adds features which do not impact this subject. The ECMAScript 2017 specification adds Object.values and Object.entries. Both return arrays (which will be surprising to some given the analogy with Array.entries). Object.values can be used as is or with a for-of loop.
const values = Object.values(obj);
// use values array or:
for (const val of Object.values(obj)) {
// use val
}
If you want to use both the key and the value, then Object.entries is for you. It produces an array filled with [key, value] pairs. You can use this as is, or (note also the ECMAScript 2015 destructuring assignment) in a for-of loop:
for (const [key, val] of Object.entries(obj)) {
// use key and val
}
Object.values shim
Finally, as noted in the comments and by teh_senaus in another answer, it may be worth using one of these as a shim. Don't worry, the following does not change the prototype, it just adds a method to Object (which is much less dangerous). Using fat-arrow functions, this can be done in one line too:
Object.values = obj => Object.keys(obj).map(key => obj[key]);
which you can now use like
// ['one', 'two', 'three']
var values = Object.values({ a: 'one', b: 'two', c: 'three' });
If you want to avoid shimming when a native Object.values exists, then you can do:
Object.values = Object.values || (obj => Object.keys(obj).map(key => obj[key]));
Finally...
Be aware of the browsers/versions you need to support. The above are correct where the methods or language features are implemented. For example, support for ECMAScript 2015 was switched off by default in V8 until recently, which powered browsers such as Chrome. Features from ECMAScript 2015 should be be avoided until the browsers you intend to support implement the features that you need. If you use babel to compile your code to ECMAScript 5, then you have access to all the features in this answer.
By using a simple for..in loop:
for(var key in objects) {
var value = objects[key];
}