How to get all properties values of a JavaScript Object (without knowing the keys)?ECMAScript 3+ECMAScript 5+ECMAScript 2015+ (A.K.A. ES6)ECMAScript 2017+ Object.values shimFinally...

2022-08-29 23:03:38

If there is a JavaScript object:

var objects={...};

Suppose, it has more than 50 properties, without knowing the property names (that's without knowing the 'keys') how to get each property value in a loop?


答案 1

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 , which is not available in IE < 9. See the compatibility table.Object.keys

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 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 useif

Object.prototype.hasOwnProperty.call(obj, key) // ok

rather than

obj.hasOwnProperty(key) // bad

because ECMAScript 5+ allows you to create prototypeless objects with , and these objects will not have the method. Naughty code might also produce objects which override the method.Object.create(null)hasOwnPropertyhasOwnProperty

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 is your object:obj

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 is your friend:Array.prototype.forEach

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 safe against (as is), then you can do .Object.keysnullfor-inObject.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 in place of .Object.getOwnPropertyNamesObject.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 , instances of which may be used as property names. To get the symbols of an object to enumerate over, use (this function is why can't be used to make private properties). The new API from ECMAScript 2015 provides , which returns a list of property names (including non-enumerable ones) and symbols.SymbolObject.getOwnPropertySymbolsSymbolReflectReflect.ownKeys

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 and . Both return arrays (which will be surprising to some given the analogy with ). can be used as is or with a loop.Object.valuesObject.entriesArray.entriesObject.valuesfor-of

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 is for you. It produces an array filled with pairs. You can use this as is, or (note also the ECMAScript 2015 destructuring assignment) in a loop:Object.entries[key, value]for-of

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 (which is much less dangerous). Using fat-arrow functions, this can be done in one line too:Object

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 exists, then you can do:Object.values

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.


答案 2

By using a simple loop:for..in

for(var key in objects) {
    var value = objects[key];
}