如何访问Javascript对象的第一个属性?


610

是否有一种优雅的方法来访问对象的第一个属性...

  1. 您不知道物业名称的地方
  2. 而不使用像for .. injQuery这样的循环$.each

例如,我需要在foo1不知道foo1名称的情况下访问对象:

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

1
它可能会更好先将其转换成一个阵列
cregox

Answers:


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

使用此方法,您还可以通过索引访问其他属性。请注意!Object.keys根据ECMAScript不能保证退货顺序,但是所有主要浏览器的实现都非正式地保证了退货顺序,有关详细信息,请阅读https://stackoverflow.com/a/23202095


25
您说这不是最快的方法。哪种方法会更快?
T Nguyen

3
这不是很有效,因为它会创建对象的所有键的整个数组。
安德鲁·毛

9
@T Nguyen如果我知道的话,我会发布它:)
Grzegorz Kaczan

5
@DavChana-您的基准设置错误。样板块将始终被执行,并且您的块2为空,这意味着第一个结果表示执行“ boilerplate + block1”,第二个结果仅表示样板这是正确的基准:http : //jsben.ch/#/R9aLQ,显示它们几乎相等(多次运行测试)。
myfunkyside

9
我希望first()或类似的东西可以解决这个问题。
Fr0zenFyr

113

尝试for … in循环并在第一次迭代后中断:

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

1
我认为这是唯一的选择。我不确定您是否保证会以可预测/有用的顺序迭代属性。即,您可能打算使用foo1但获得foo3。如果属性如示例中那样编号,则可以进行字符串比较以确定以“ 1”结尾的标识符。再说一次,如果顺序性是集合的主要关注点,则可能应该使用数组而不是对象。
steamer25 2009年

2
如果其他人担心订单,那么大多数浏览器的行为都可以预测:stackoverflow.com/questions/280713/…–
Flash

6
var prop; 对于(道具)中断;// object [prop]
netiul 2014年

12
老答案了。您可能要检查属性是否属于该对象。例如:for(..){if(!obj.hasOwnProperty(prop))继续;....休息; 假如万一对象实际上是空的,它就不会遍历原型或其他东西。
pgarciacamou 2014年


46

使用Object.keys获取属性的数组对象上。例:

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

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

这里提供文档和跨浏览器填充程序。其使用的例子可以在我的答案另一个可以找到这里

编辑:为清楚起见,我只想回应在其他答案中正确指出的内容:javascript对象中的键顺序未定义。


25

一个规则的版本:

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

2
有时,如果for in不检查就使用hasOwnProperty该对象,则可能会存在风险,因为该对象包含以编程方式附加到其上的其他不需要的值,因此您最终可能会从此代码段中得到不需要的结果。仅仅因为它短而整洁并不意味着它的安全性最佳。
哈维尔·科沃斯

24

没有“第一”属性。对象键是无序的。

如果使用来循环访问它们,(var foo in bar)则会以某种顺序获得它们,但是将来可能会更改(特别是如果添加或删除其他键)。


太棒了 我一直在使用一个对象来实现维护插入顺序的映射。一旦删除值,该操作就会中断,因为下一次插入将填补空白。:(
David Harkness

2
键/值顺序应该保存在JS的新版本
亚历山大·米尔斯

11

lodash库解决方案:

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

但不能保证对象属性的内部存储顺序,因为它取决于javascript VM的实现。


2
刚刚测试了一下,它不起作用。它仅返回值,而不返回键/值对。
克里斯·海恩斯

2
在这个问题中没有提到它应该返回键/值对,他只是请求对象,接受的答案与lodash函数一样多:它返回第一个属性的内容。它可能不适合您的特定需求,但是根据原始问题,此答案是正确的。
Carrm

是的,这项工作很有用,当您知道您的对象只有一个子对象时很有用var object = { childIndex: { .. } }; var childObject = _.find(Object);
Raja Khoury19年

9

否。由MDC定义的对象文字是:

零括号或更多对属性名称和一个对象的关联值的列表,用大括号({})括起来。

因此,对象文字不是数组,并且您只能使用其显式名称或for使用in关键字的循环来访问属性。


25
对于其他人,仅在此答案上看到绿色的勾号,该页面下方还有另一种解决方案,目前有350个支持。
redfox05

7

最高答案可以生成整个数组,然后从列表中捕获。这是另一个有效的捷径

var obj = { first: 'someVal' };
Object.entries(obj)[0][1] // someVal

3

这已经在这里讨论过了。

first的概念不适用于对象属性,规范不保证for ... in循环的顺序,但是实际上它是可靠的FIFO,对于chrome(错误报告)至关重要。做出相应的决定。


3

我不建议您使用Object.keys,因为旧IE版本不支持它。但是,如果确实需要,可以使用上面的代码来保证向后兼容性:

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

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

更多信息: https //developer.mozilla.org/zh-CN/docs/JavaScript/Reference/Global_Objects/Object/keys

但是,如果您只需要第一个,我们可以安排一个较短的解决方案,例如:

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"}

2

要获取对象中的第一个键名称,可以使用:

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

返回一个字符串,因此您无法访问嵌套对象,例如:

var obj = { first: { someVal : { id : 1} }; 在这种解决方案中,您无法访问ID。

如果要获取实际对象,最好的解决方案是使用lodash,例如:

obj[_.first(_.keys(obj))].id

要返回第一个键的值,(如果您不完全知道第一个键的名称):

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

如果您知道密钥名称,请使用:

obj.first

要么

obj['first']

0

如果您需要访问“对象的第一个属性”,则可能意味着您的逻辑有问题。对象属性的顺序无关紧要。


你是对的。本质上,我不需要第一个,而仅是foo属性之一,因此我可以使用它。我只需要一个,并且不确定是否有一种方法可以不使用...就抓住“第一个”。
atogle 2009年

0

使用数组而不是对象(方括号)。

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

请注意,您会丢失“ foo”标识符。但是您可以将name属性添加到所包含的对象中:

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

在某些情况下我们做不到。我们假设我们无法更改它们不在数组中的事实
1mike12 '16

1
我认为对可以控制其JSON模式的读者稍微推迟一下设计很有用。本质上,我通过一些示例扩展了Flavius Stef的答案。
steamer25 '16


0

您可以使用Object.prototype.keyswhich以相同顺序返回对象的所有键。因此,如果您想要第一个对象,只需获取该数组并将第一个元素用作所需键即可。

const o = { "key1": "value1", "key2": "value2"};
const idx = 0; // add the index for which you want value
var key = Object.keys(o)[idx];
value = o[key]
console.log(key,value); // key2 value2

1
当回答一个旧问题时,如果您包含一些上下文来解释您的答案如何帮助您的答案,则对其他StackOverflow用户将更加有用,尤其是对于已经接受了答案的问题。请参阅:如何写一个好的答案
大卫·巴克


0

这是获取第一把钥匙的一种更干净的方法:

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

var object2 = {
    needThis: 'This is a value of the property',
    foo2: { /* stuff2 */},
    foo3: { /* stuff3 */}
};

let [first] = Object.keys(example)
let [firstProp] = Object.keys(object2)

console.log(first)
//Prop : needThis, Value: This is a value of the property
console.log(`Prop : ${firstProp}, Value: ${object2[firstProp]}`)


但是为什么要围绕数组[first]。用户未请求数组作为答案。为什么要这样做first = Object.keys(example)[0]而无需将答案包装在数组中呢?为什么请您的清洁工?
Michael Durrant

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.