How to access the first property of an object in J

2019-01-01 14:26发布

问题:

Is there an elegant way to access the first property of an object...

  1. where you don\'t know the name of your properties
  2. without using a loop like for .. in or jQuery\'s $.each

For example, I need to access foo1 object without knowing the name of foo1:

var example = {
    foo1: { /* stuff1 */},
    foo2: { /* stuff2 */},
    foo3: { /* stuff3 */}
};

回答1:

var obj = { first: \'someVal\' };
obj[Object.keys(obj)[0]]; //returns \'someVal\'

Using this you can access also other properties by indexes. Be aware tho! Object.keys return order is not guaranteed as per ECMAScript however unofficially it is by all major browsers implementations, please read https://stackoverflow.com/a/23202095 for details on this.



回答2:

Try the for … in loop and break after the first iteration:

for (var prop in object) {
    // object[prop]
    break;
}


回答3:

Use Object.keys to get an array of the properties on an object. Example:

var example = {
    foo1: { /* stuff1 */},
    foo2: { /* stuff2 */},
    foo3: { /* stuff3 */}
};

var keys = Object.keys(example); // => [\"foo1\", \"foo2\", \"foo3\"] (Note: the order here is not reliable)

Documentation and cross-browser shim provided here. An example of its use can be found in another one of my answers here.

Edit: for clarity, I just want to echo what was correctly stated in other answers: the key order in javascript objects is undefined.



回答4:

You can also do Object.values(example)[0].



回答5:

A one-rule version:

var val = example[function() { for (var k in example) return k }()];


回答6:

There isn\'t a \"first\" property. Object keys are unordered.

If you loop over them with for (var foo in bar) you will get them in some order, but it may change in future (especially if you add or remove other keys).



回答7:

No. An object literal, as defined by MDC is:

a list of zero or more pairs of property names and associated values of an object, enclosed in curly braces ({}).

Therefore an object literal is not an array, and you can only access the properties using their explicit name or a for loop using the in keyword.



回答8:

Solution with lodash library:

_.find(example) // => {name: \"foo1\"}

but there is no guarantee of the object properties internal storage order because it depends on javascript VM implementation.



回答9:

I don\'t recommend you to use Object.keys since its not supported in old IE versions. But if you really need that, you could use the code above to guarantee the back compatibility:

if (!Object.keys) {
Object.keys = (function () {
var hasOwnProperty = Object.prototype.hasOwnProperty,
    hasDontEnumBug = !({toString: null}).propertyIsEnumerable(\'toString\'),
    dontEnums = [
      \'toString\',
      \'toLocaleString\',
      \'valueOf\',
      \'hasOwnProperty\',
      \'isPrototypeOf\',
      \'propertyIsEnumerable\',
      \'constructor\'
    ],
    dontEnumsLength = dontEnums.length;

return function (obj) {
  if (typeof obj !== \'object\' && typeof obj !== \'function\' || obj === null) throw new TypeError(\'Object.keys called on non-object\');

  var result = [];

  for (var prop in obj) {
    if (hasOwnProperty.call(obj, prop)) result.push(prop);
  }

  if (hasDontEnumBug) {
    for (var i=0; i < dontEnumsLength; i++) {
      if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
    }
  }
  return result;
}})()};

Feature Firefox (Gecko)4 (2.0) Chrome 5 Internet Explorer 9 Opera 12 Safari 5

More info: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys

But if you only need the first one, we could arrange a shorter solution like:

var data = {\"key1\":\"123\",\"key2\":\"456\"};
var first = {};
for(key in data){
    if(data.hasOwnProperty(key)){
        first.key = key;
        first.content =  data[key];
        break;
    }
}
console.log(first); // {key:\"key\",content:\"123\"}


回答10:

This has been covered here before.

The concept of first does not apply to object properties, and the order of a for...in loop is not guaranteed by the specs, however in practice it is reliably FIFO except critically for chrome (bug report). Make your decisions accordingly.



回答11:

If you need to access \"the first property of an object\", it might mean that there is something wrong with your logic. The order of an object\'s properties should not matter.



回答12:

Use an array instead of an object (square brackets).

var example = [ {/* stuff1 */}, { /* stuff2 */}, { /* stuff3 */}];
var fist = example[0];

Note that you lose the \'foo\' identifiers. But you could add a name property to the contained objects:

var example = [ 
  {name: \'foo1\', /* stuff1 */},
  {name: \'foo2\', /* stuff2 */},
  {name: \'foo3\', /* stuff3 */}
];
var whatWasFirst = example[0].name;


回答13:

Any reason not to do this?

> example.map(x => x.name);

(3) [\"foo1\", \"foo2\", \"foo3\"]