【问题标题】:How to access the first property of a Javascript object?如何访问 Javascript 对象的第一个属性?
【发布时间】:2010-11-02 06:24:30
【问题描述】:

有没有一种优雅的方式来访问对象的第一个属性...

  1. 您不知道您的属性名称的地方
  2. 不使用像 for .. in 或 jQuery 的 $.each 这样的循环

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

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

【问题讨论】:

  • 最好先把它转成数组

标签: javascript object


【解决方案1】:
var obj = { first: 'someVal' };
obj[Object.keys(obj)[0]]; //returns 'someVal'

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

【讨论】:

  • 你说这不是最快的方法。什么方法会更快?
  • 这不是很有效,因为它会创建一个包含所有对象键的整个数组。
  • @T Nguyen 如果我知道的话我会发布它:)
  • @DavChana - 你的基准设置错误。 boilerplate block 总是会被执行,而你的 block 2 是空的,这意味着第一个结果代表执行 boilerplate+block1,第二个结果代表只有样板这是正确的基准:http://jsben.ch/#/R9aLQ,表明它们几乎相等(多次运行测试)。
  • 我希望 first() 或类似的东西可以处理这个问题。
【解决方案2】:

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

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

【讨论】:

  • 我认为这是唯一的选择。我不确定您是否能保证这些属性将以可预测/有用的顺序进行迭代。即,您可能想要 foo1 但得到 foo3。如果属性按照示例编号,您可以进行字符串比较以确定以“1”结尾的标识符。再说一次,如果序数是集合的主要关注点,您可能应该使用数组而不是对象。
  • 如果其他人关心订单,大多数浏览器的行为都是可以预见的:stackoverflow.com/questions/280713/…
  • var 属性; for (prop in object) break; //对象[道具]
  • 旧答案但是。您可能想要检查该属性是否属于该对象。比如:for(..){ if(!obj.hasOwnProperty(prop)) 继续; .... 休息;以防万一对象实际上是空的,它不会遍历原型或其他东西。
【解决方案3】:

你也可以Object.values(example)[0]

【讨论】:

  • 这不是在所有浏览器中都可用,参考stackoverflow.com/a/38748490/719689
  • 我比Object.keys更喜欢这个,因为保证你会拿到第一个。
  • 从 2019 年开始更新,我认为这适用于大多数浏览器,除了 IE developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • @theUtherSide ordering 对于所有Object.keysObject.valuesfor...in 都是相同的,唯一的显着区别是@987654328 @ 循环也在原型链上,因此您必须手动检查 hasOwnProperty() 那里。
【解决方案4】:

使用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)

文档和跨浏览器 shim 提供 here。它的使用示例可以在我的另一个答案here 中找到。

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

【讨论】:

    【解决方案5】:

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

    如果你用 for (var foo in bar) 循环它们,你会以一些的顺序得到它们,但它将来可能会改变(特别是如果你添加或删除其他键)。

    【讨论】:

    • 太棒了。我一直在使用一个对象来实现一个维护插入顺序的地图。一旦我删除一个值,它就会中断,因为下一次插入会填补空白。 :(
    • 键/值顺序应保留在较新版本的 JS 中
    【解决方案6】:

    单规则版本:

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

    【讨论】:

    • 有时使用for in 而不检查hasOwnProperty 可能会有风险,因为对象包含以编程方式附加到它的其他不需要的值,因此您最终可能会从这个sn-p 中得到不需要的结果。仅仅因为它的短而整洁并不意味着它的安全性是最佳的。
    【解决方案7】:

    您可以使用 Object.values() 来访问对象的值:

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

    【讨论】:

    • 最简单的方法
    【解决方案8】:

    lodash 库的解决方案:

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

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

    【讨论】:

    • 刚刚测试过,还是不行。它只返回值,而不是键/值对。
    • 问题中没有提到它应该返回键/值对,他只是询问对象,并且接受的答案与这个 lodash 函数一样多:它返回第一个财产。它可能不适合您的特定需求,但根据原始问题,此答案是正确的。
    • 是的,当你知道你的对象只有一个子对象时很有用var object = { childIndex: { .. } }; var childObject = _.find(Object);
    【解决方案9】:

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

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

    【讨论】:

      【解决方案10】:

      没有。 MDC 定义的对象字面量是:

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

      因此,对象字面量不是数组,您只能使用它们的显式名称或使用 in 关键字的 for 循环访问属性。

      【讨论】:

      • 对于其他人只看到这个答案上的绿色勾号,页面下方还有另一个解决方案,目前有 350 个赞。
      【解决方案11】:

      这是获取第一个密钥的更简洁的方法:

      var object = {
          foo1: 'value of the first property "foo1"',
          foo2: { /* stuff2 */},
          foo3: { /* stuff3 */}
      };
      
      let [firstKey] = Object.keys(object)
      
      console.log(firstKey)
      console.log(object[firstKey])

      【讨论】:

      【解决方案12】:

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

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

      【讨论】:

        【解决方案13】:

        如果有人更喜欢数组解构

        const [firstKey] = Object.keys(object);
        

        【讨论】:

          【解决方案14】:

          这里之前已经介绍过了。

          first 的概念不适用于对象属性,规范不保证 for...in 循环的顺序,但实际上它是可靠的 FIFO except 对于 chrome (bug report)。做出相应的决定。

          【讨论】:

            【解决方案15】:

            我不建议您使用 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/en-US/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"}
            

            【讨论】:

              【解决方案16】:

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

              【讨论】:

              • 你是对的。我本身不需要第一个,只需要一个 foo 属性,以便我可以使用它。我只需要一个,但不确定是否有办法在不使用 for ... in 的情况下抓住“第一个”。
              【解决方案17】:

              我们也可以使用这种方法。

              var example = {
                foo1: { /* stuff1 */},
                foo2: { /* stuff2 */},
                foo3: { /* stuff3 */}
              }; 
              Object.entries(example)[0][1];
              

              【讨论】:

                【解决方案18】:

                有什么理由不这样做?

                > example.map(x => x.name);
                
                (3) ["foo1", "foo2", "foo3"]
                

                【讨论】:

                【解决方案19】:

                正如其他人所指出的,如果属性的顺序很重要,那么将它们存储在对象中并不是一个好主意。相反,您应该通过方括号使用数组。例如,

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

                请注意,您会丢失“foo”标识符。但是你可以为包含的对象添加一个 name 属性:

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

                对于那些寻求类似问题的答案的人,即:“我如何找到一个或多个与特定模式匹配的属性?”,我建议使用Object.keys()。扩展benekastah的答案:

                for (const propName of Object.keys(example)) {
                  if (propName.startsWith('foo')) {
                    console.log(`Found propName ${propName} with value ${example[propName]}`);
                    break;
                  }
                }
                

                【讨论】:

                • 有些情况是我们做不到的。我们假设我们无法改变它们不在数组中的事实
                • 我认为对于可以控制其 JSON 模式的读者来说,稍微推迟一下设计很有用。本质上,我用一些例子扩展了 Flavius Stef 的答案。
                猜你喜欢
                • 1970-01-01
                • 2015-07-01
                • 2019-09-25
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多