Object.values()的替代版本

我正在寻找一个替代版本的 Object.values()函数。
由于 这里描述的的 Internet Explorer,该函数不受支持。

执行下列示例代码时:

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

Firefox 和 Chrome 都可以使用,但在 IE11中会出现以下错误:

对象不支持属性或方法“值”

在这里你可以测试它: 小提琴

那么,快速解决办法是什么?

85656 次浏览

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])

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 }));

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.

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>

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);

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]);

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

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

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

   import 'core-js/es7/object';

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.

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]]);

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]