Alternative version for Object.values()
Asked Answered
A

11

89

I'm looking for an alternative version for the Object.values() function.
As described here the function is not supported in Internet Explorer.

When executing the following example code:

var obj = { foo: 'bar', baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]

It works in both, Firefox and Chrome, but throws the following error in IE11:

Object doesn't support property or method "values"

Here you can test it: Fiddle.

So, what would be a quick fix?

Aguste answered 16/3, 2017 at 9:39 Comment(0)
L
189

You can get array of keys with Object.keys() and then use map() to get values.

var obj = { foo: 'bar', baz: 42 };
var values = Object.keys(obj).map(function(e) {
  return obj[e]
})

console.log(values)

With ES6 you can write this in one line using arrow-functions.

var values = Object.keys(obj).map(e => obj[e])
Lid answered 16/3, 2017 at 9:41 Comment(3)
thanks! For my angular 5 code, I changed objectValues = Object.values; to objectValues = ((obj) => { return Object.keys(obj).map(e => obj[e]); });Iverson
@Iverson why don't you look at angular polyfills?Braunschweig
angular8 polyfill.ts: import 'core-js/es/object/values';Vaudevillian
P
26

Object.values() is part of the ES8(June 2017) specification. Using Cordova, I realized Android 5.0 Webview doesn't support it. So, I did the following, creating the polyfill function only if the feature is not supported:

if (!Object.values) Object.values = o=>Object.keys(o).map(k=>o[k]);
Pydna answered 10/6, 2018 at 5:38 Comment(1)
You need to change your answer to use long hand functions. IE doesn't support arrow functions as much as it doesn't support Object.values. The question mentions the need for IE and many companies still use it (sadly). I still have to support it. ☹Mungo
O
19

Since Object is a (not so) recent implementation, if you want to support all browsers (AKA IE11 and below), then you need to create your own function:

function objectValues(obj) {
    var res = [];
    for (var i in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, i)) {
            res.push(obj[i]);
        }
    }
    return res;
}

You can also modify this for Object.keys() and Object.entries() easily.

PS: Just noticed the ecmascript-6 tag. Btw I keep this answer here, just in case someone needs it.

Overunder answered 16/3, 2017 at 9:45 Comment(2)
Not even IE11 supports Object.valuesMungo
@Mungo oh that's trueKa
E
10

If you are already using core-js (e.g. by using Angular) you can just import the according polyfill:

   import 'core-js/es7/object';
Endive answered 8/4, 2019 at 9:46 Comment(1)
Depending on which version of Angular you're using, you may need to change your import: import 'core-js/es/object';Blinking
F
6

You can use a polyfill:

const valuesPolyfill = function values (object) {
  return Object.keys(object).map(key => object[key]);
};

const values = Object.values || valuesPolyfill;

console.log(values({ a: 1, b: 2, c: 3 }));
Fatso answered 16/3, 2017 at 9:43 Comment(0)
T
4

For people using UnderscoreJS, you can get object values by using _.values :

var obj = { foo: 'bar', baz: 42 };
console.log(_.values(obj)); // ['bar', 42]
Thorough answered 13/11, 2018 at 9:4 Comment(0)
A
3

var x = {Name: 'John', Age: 30, City: 'Bangalore'};
 
Object.prototype.values = function(obj) {
                                var res = [];
    for (var i in obj) {
        if (obj.hasOwnProperty(i)) {
            res.push(obj[i]);
        }
    }
    return res;
};
 
document.getElementById("tag").innerHTML = Object.values(x)
<p id="tag"></p>
Aundrea answered 16/3, 2018 at 10:9 Comment(1)
It's not a prototype method.Scrawly
G
1

As I didn't found an answer for my needs:

var obj = { foo: 'bar', baz: 42 };


console.log(obj[Object.keys(obj)[0]]) // bar

console.log(obj[Object.keys(obj)[1]])  // 42

Using the possibility of objects to adress them per literal.

Grayback answered 22/11, 2019 at 20:22 Comment(3)
Not an answer my friendDarill
@fluidguid: thanks for the comment, its my first answer, I have to learn. Why? I thought the problem is to get the values of an object in IE. So, with i.e. a simple "for" I have them. what is wrong?Grayback
@Darill it is an answer. The principle of using object.keys works. You could offer something constructive if you don't think it's good enough eg using a loop.Mungo
U
0

I know it is a old topic. I was playing arround and just want to add another implementation. It is simply the map version with the map itself implemented with a reduce :

let obj = { foo: 'bar', baz: 42 };

const valueArray = Object.keys(obj).reduce((acc, key) => {
  acc.push(obj[key]);
  return acc;
}, []);

console.log(valueArray);

It does the job but it has something that bother me. The reducer function uses obj and the obj was not injected in it. We should avoid global variable inside functions and make our functions more testable. So I do prefer this version with a reducer function helper that takes the obj as parameter an return the actual reducer function . It becomes:

let obj = { foo: 'bar', baz: 42 };

// reducer function helper take obj and return the actual reducer function
let reducerFuncHelper= obj => (acc, key) => {
  acc.push(obj[key]);
  return acc;
}
//much better
const valueArray = Object.keys(obj).reduce(reducerFuncHelper(obj), []);
console.log(valueArray);
Unitarianism answered 21/4, 2018 at 22:15 Comment(0)
A
0

You can get array of keys using Object.keys(). This will work in IE also. Object.values() is not required at all to get values since we can use the keys obtained from Object.keys() to get values as below:

var obj = { foo: 'bar', baz: 42 };
var keyArray = Object.keys(obj);
for(var i = 0; i < keyArray.length; i++)
    console.log(obj[keyArray[i]]); 
Amaris answered 3/2, 2020 at 14:40 Comment(2)
You really believe this is a good solution to Object.values????Atheistic
@Atheistic what's wrong with it? Object.keys is supported in IE. Object.values is not. The question indicates a requirement for IE compatibility. This works perfectly.Mungo
H
0

Best way is to replace it with the values method of ramda:

import * as R from 'ramda';

const obj = { foo: 'bar', test: 10 };

console.log(R.values(obj)) // ['bar', 10]
Harappa answered 22/5, 2020 at 1:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.