Javascript 如何获取具有值的对象的最后一个键

Javascript 如何获取具有值的对象的最后一个键,javascript,Javascript,我需要获取具有值的对象的最后一个键。所以如果这就是目标 const obj = { first: 'value', second: 'something', third: undefined, fourth: undefined } 。。。我需要获得秒 obj = { first: 'value', second: 'something', third: 'else', fourth: undefined } // result should be: 'third' obj = { any:

我需要获取具有值的对象的最后一个键。所以如果这就是目标

const obj = { first: 'value', second: 'something', third: undefined, fourth: undefined }
。。。我需要获得

obj = { first: 'value', second: 'something', third: 'else', fourth: undefined }
// result should be: 'third'
obj = { any: 'value', other: 'something', thing: undefined, bla: undefined }
// result should be: 'other'
对象属性确实具有与插入顺序不同的特定顺序,在本例中,插入顺序并没有真正的用处,如所述。堆栈溢出问题是一个很好的阅读主题,我建议阅读比第一个答案更深入的内容

因此,不要依赖于不能保证顺序1的对象,而要使用能够保证顺序的对象。您可以使用类似于a的东西,它类似于具有键/值对的对象,但对是有序的。例如:

const obj=新地图([
[“第一”,“foo”],
[“第二条”、“横条”],
[“第三”,未定义],
[“第四”,未定义]
]);
const result=Array.from(obj.keys()).reduce((lastKey,currKey)=>obj.get(currKey)!==未定义?currKey:lastKey);

控制台日志(结果)非常棘手,通过对象的迭代不一定保证顺序。按照创建顺序遍历symbol\string类型键的

假设具有值的最后一个键是在具有truthy值的对象中定义的最后一个条目:

function getLastKeyWithTruthyValue(obj) {
    Object.getOwnPropertyNames(obj).filter(key => !!obj[key]).slice(-1)[0]
}
  • 按创建顺序获取属性名称数组(大多数现代浏览器都支持Object.getOwnPropertyNames,)
  • 过滤掉falsy值(使用
    Filter(Boolean)
    是一种很酷的过滤方法。如果需要未定义的任何值,请使用
    val=>val!==undefined
    作为过滤器回调
  • 获取筛选数组中的最后一项(如果所有值都是falsy,则返回undefined)
  • 如果需要获取“具有值的最后一个属性”,则使用了错误的数据结构。对象不太合适。您希望使用数组或
    映射
    。我可能会使用
    映射
    ,因为它定义了有用的顺序和基于键的查找

    如果您坚持使用对象:从ES2015开始(也称为“ES6”)。该顺序仅由某些操作强制执行;对于in
    object.keys
    ,它不由
    强制执行。它由大多数其他操作强制执行,包括
    object.getOwnPropertyNames
    (ES2015),即将发布的ES2017规范中的
    Object.values
    ,以及(有趣的是)
    JSON.stringify

    但是顺序对您来说可能不是很有用。假设我们只讨论名称不是符号的“自有”属性,则顺序是:任何“整数索引”1的属性,按数字顺序,后跟任何其他属性,按它们添加到对象中的顺序

    您可以看到为什么对象的结构不正确:整数索引优先于其他属性,因此:

    const obj = { first: 'value', second: 'something', third: undefined, 42: 'value' };
    
    …使用对象的顺序,我们会说最后一个值是
    'something'
    ,而它应该是
    'value'
    。使用
    映射,您会得到正确的答案

    因此,我不建议为此使用对象,但如果您坚持这样做,下面介绍如何在完全兼容的ES2015+JavaScript引擎上执行此操作:

    功能测试(测试编号,obj){
    const last=Object.getOwnPropertyNames(obj).reduce((currentValue,key)=>{
    常量值=对象[键];
    返回值的类型===“未定义”?当前值:值;
    },未定义);
    log(`Test#${testNumber}:'${last}`);
    }
    //这表示“某物”(第二个值):
    测试(1,{第一:值,第二:某物,第三:未定义,第四:未定义});
    //上面写着'else'(第三个的值):
    测试(2,{第一:值,第二:某物,第三:其他,第四:未定义});
    //这表示“某物”(“其他”的值):
    测试(3,{any:'value',other:'something',thing:undefined,bla:undefined});
    //但是!这上面写的是‘某物’(第二个的值),而不是‘值’(42个的值)!
    测试(4,{first:'value',second:'something',third:undefined,42:'value'});
    。作为控制台包装器{
    最大高度:100%!重要;
    
    }
    如何定义“last”,这些是对象的字段。@user3142695您的问题是否仅针对此特定对象?“last”对对象属性没有意义。顺序不相关对象的属性没有内在顺序,因此您的问题实际上没有意义。没有“last”键。浏览器通常按字母顺序列出属性,例如在开发人员控制台中,但这只是为了方便开发人员。数组是具有内在顺序的结构。我投票将这个问题作为离题题来结束,因为没有进一步的信息,这是不可能解决的。
    它们只是一个无序的属性集合erties
    。实际上,我已经通过引入
    I
    计数变量对它们进行了排序。我希望像T.J.Crowder这样的人能对这种情况说点什么。@Kinduser:如果同时需要顺序和键查找,Andrew所示的
    Map
    就是正确的方法。使用对象进行排序是错误的,因为对象属性y顺序不是简单的插入顺序:名称为规范定义的整数索引的属性排在第一位。(当您进入继承时,它会变得更复杂。)@user3142695:Reuven的
    。filter(key=>!!obj[key])
    将过滤掉所有错误值(包括
    0
    ,等等),而不仅仅是
    未定义的
    ,因此如果这不是您想要的,您必须调整它。上面还创建了两个不必要的临时数组(但这不太重要)。有人提到他寻找一个有值的键。@user3142695没有提到他寻找的值不是未定义的,无论如何,我同意根据示例,这可能是用例。感谢您的评论,编辑了答案。