Home > OS >  Object.values vs Array.from, what's the difference?
Object.values vs Array.from, what's the difference?

Time:03-03

I recently faced issues where I couldn't use .map on iterable objects and had to convert them to arrays with either Object.values or Array.from

I seem to get same result in both cases, so I'm wondering what the difference is. In which case do you use one over the other?

CodePudding user response:

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.from creates an array from any iterable or array-like object (an object with a length and index properties like 0 and 1).

  • Object.values creates an array of the values of an object's own enumerable properties. The object doesn't have to be iterable (Object.values doesn't even look to see if it is.)

  • Array.from accepts 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 length property
  • Properties named with strings that are numbers in the normal decimal form for the values 0 through length - 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.

CodePudding user response:

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
  • Related