题 JavaScript对象的长度


如果我有一个JavaScript对象,比如说

var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;

是否有内置或接受的最佳实践方法来获取此对象的长度?


1827
2017-08-07 19:42


起源


javascript中的对象文字默认为关联数组,例如object.propertyName.propertyValue与object [propertyName] [propertyValue]相同 - neitony
在Underscore.js中添加了一行内容: stackoverflow.com/a/11346637/11236 - ripper234
一旦回答是使用Object.keys(myArray).length为@aeosynth说。 - Ranadheer Reddy
好的,怎么样 Object.keys(obj).length - Muhammad Umer
为什么object.length无效?它为我返回正确的结果。 - Adrian M


答案:


最强大的答案(即捕获您尝试做的意图同时导致最少的错误)将是:

Object.size = function(obj) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

// Get the size of an object
var size = Object.size(myArray);

你有一种JavaScript惯例 不要向Object.prototype添加内容,因为它可以破坏各种库中的枚举。但是,向Object添加方法通常是安全的。


这是2016年和2016年的更新 ES5的广泛部署 超越。  对于IE9 +和所有其他现代ES5 +浏览器,您可以使用 Object.keys() 所以上面的代码变成:

var size = Object.keys(myObj).length;

这不需要修改任何现有的原型 Object.keys() 现在是内置的。

编辑:对象可以具有无法通过Object.key方法返回的符号属性。所以答案是不完整的而不提及它们。

符号类型已添加到语言中,以便为对象属性创建唯一标识符。 Symbol类型的主要好处是防止覆盖。

Object.keys 要么 Object.getOwnPropertyNames 不适用于符号属性。要返回它们,您需要使用 Object.getOwnPropertySymbols

var person = {
  [Symbol('name')]: 'John Doe',
  [Symbol('age')]: 33,
  "occupation": "Programmer"
};

const propOwn = Object.getOwnPropertyNames(person);
console.log(propOwn.length); // 1

let propSymb = Object.getOwnPropertySymbols(person);
console.log(propSymb.length); // 2

2022
2017-08-09 08:31



@Tres - 你的代码可能会被破坏,如果有人来到并且覆盖'size'属性而不知道你已经在代码中的某个地方宣布它,所以总是值得检查它是否已经定义 - vsync
@vsync你是对的。一个人应该总是实施必要的健全性检查:) - Tres
为什么每个人都忽略了这一点: Object.keys(obj).length - Muhammad Umer
@MuhammadUmer可能是因为这个方法在写这个答案时根本不存在。即使在今天,使用它可能需要旧浏览器的polyfill。 - Chris Hayes
@stonyau IE8,IE9,IE10是死的浏览器,没有得到微软的支持。 IE8,IE9,IE10用户收到来自Microsoft的通知,他们使用旧的,不受支持的浏览器,并且应该期望这些内容对他们不起作用。 support.microsoft.com/en-us/kb/3123303 - Lukas


如果你知道你不必担心 hasOwnProperty 检查,你可以非常简单地做到这一点:

Object.keys(myArray).length

1413
2018-04-03 01:44



为什么不?据我所知,这是一个标准: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/... - vsync
这不是普遍的 实施 方法,但您可以检查哪个浏览器支持它 这张桌子。 - aeosynth
没有IE8支持=没有去。 - ripper234
时间切换到firefox =不幸的是,你切换并不意味着你的网站的用户会...... - mdup
@ ripper234没有IE支持=时间到polyfill - John Dvorak


更新:如果你正在使用 Underscore.js (推荐,它很轻巧!),那么你就可以做到

_.size({one : 1, two : 2, three : 3});
=> 3

如果不,无论出于何种原因你都不想乱用Object属性,并且已经在使用jQuery,插件同样可以访问:

$.assocArraySize = function(obj) {
    // http://stackoverflow.com/a/6700/11236
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

252
2017-07-05 14:39



_.size() 是我的完美解决方案 流星 项目,有下划线支持。 - tokyovariable
我使用下划线,这篇文章只是提醒我,我在这个项目中没有使用它。如果处理对象,则应该有underscore.js可用。 - jbolanos
下划线>(全部 - ['lo-dash']) - Rayjax
也得到了 lodash.js  lodash - hipkiss
@Babydead来区分对象和继承对象的真实属性。 developer.mozilla.org/en/docs/Web/JavaScript/Reference/... - ripper234


使用简单的东西:

Object.keys(obj).length

它并不困难,绝对不需要另外的功能来完成。


153
2017-10-27 03:46



这与aeosynth的答案有什么不同? - DanMan
你看过这个问题的答案数量了吗?当我写它时,我没有看到(几个)重复。 James Coglan在aeosynth之前3年以这种方式回答,所以你没有阅读所有答案......或者你已经看过了。 - Michael
@迈克尔不,他没有。这是另一位用户在02-28-2016的编辑。 评论 - old_mountain


这是最跨浏览器的解决方案。

这比接受的答案更好,因为它使用本机Object.keys(如果存在)。 因此,它是所有现代浏览器中最快的。

if (!Object.keys) {
    Object.keys = function (obj) {
        var arr = [],
            key;
        for (key in obj) {
            if (obj.hasOwnProperty(key)) {
                arr.push(key);
            }
        }
        return arr;
    };
}

Object.keys(obj).length;

43
2017-09-01 16:12



Object.keys() 返回一个数组,其中只包含可枚举的属性的名称。如果你想要一个包含ALL属性的数组,你应该使用 Object.getOwnPropertyNames() 代替。看到 developer.mozilla.org/en/docs/Web/JavaScript/Reference/... - John Slegers


我不是JavaScript专家,但看起来你必须遍历元素并计算它们,因为Object没有length方法:

var element_count = 0;
for (e in myArray) {  if (myArray.hasOwnProperty(e)) element_count++; }

@palmsey:为了公平对待OP,JavaScript文档实际上明确地将这种类型的Object类型的变量称为“关联数组”。


27
2017-08-07 19:52



不起作用,因为它也会计算方法,通过原型添加。 - Lajos Meszaros


此方法在数组中获取所有对象的属性名称,因此您可以获得该数组的长度,该长度等于对象的键的长度。

Object.getOwnPropertyNames({"hi":"Hi","msg":"Message"}).length; // => 2

25
2017-07-01 12:40



我更喜欢这种方法,因为它在内部调用“hasOwnProperty”,因此它不会推送从原型链继承的属性名称,而且它只是一个单行 Object.keys(...).length 但是我刚才说的原因要安全得多。 - Patrick Roberts
@PatrickRoberts keys方法不返回原型链中的属性。那么为什么需要在这里使用hasOwnProperty。此外,getOwnProperty将返回隐藏属性,因为长度在数组中等。 - Muhammad Umer
@MuhammadUmer“如果我有一个JavaScript关联数组......”这是一个对象,而不是一个数组。 length 是Array实例的属性,因此应该在键的长度中考虑它。是的,你对原型链是正确的,我撤销了这个陈述。我的意思是,如果你有一个非类似数组的对象,通常你甚至想要不可枚举的属性,因为一个数组已经有了 length 物业开始。 - Patrick Roberts
这在IE-8中有效吗? - marcusshep


为了不弄乱原型或其他代码,您可以构建和扩展自己的对象:

function Hash(){
    var length=0;
    this.add = function(key, val){
         if(this[key] == undefined)
         {
           length++;
         }
         this[key]=val;
    }; 
    this.length = function(){
        return length;
    };
}

myArray = new Hash();
myArray.add("lastname", "Simpson");
myArray.add("age", 21);
alert(myArray.length()); // will alert 2

如果始终使用add方法,则length属性将是正确的。如果您担心您或其他人忘记使用它,您也可以添加其他人发布的属性计数器到长度方法。

当然,您总是可以覆盖这些方法。但即使你这样做,你的代码可能会明显失败,使其易于调试。 ;)


19
2018-06-11 15:44



我认为这是最好的解决方案,因为它不需要使用'for'进行循环,如果数组很大,这可能会很昂贵 - Digitlimit