126

有没有办法(从某处)获取 Javascript 对象中的元素数量?(即恒定时间复杂度)。

我找不到检索该信息的属性或方法。到目前为止,我只能考虑对整个集合进行迭代,但那是线性时间。
奇怪的是没有直接访问对象的大小,你不觉得吗。

编辑:
我说的是Object对象(不是一般的对象):

var obj = new Object ;
4

6 回答 6

183

尽管 JS 实现可能会在内部跟踪这样的值,但没有标准的方法来获取它。

过去,Mozilla 的 Javascript 变体暴露了non-standard__count__,但在 1.8.5 版本中已将其删除。

对于跨浏览器脚本,您必须明确地迭代属性并检查hasOwnProperty()

function countProperties(obj) {
    var count = 0;

    for(var prop in obj) {
        if(obj.hasOwnProperty(prop))
            ++count;
    }

    return count;
}

在支持 ECMAScript 5 的实现的情况下,这也可以写成 (Kudos to Avi Flax )

function countProperties(obj) {
    return Object.keys(obj).length;
}

请记住,您还会错过不可枚举的属性(例如数组length)。

如果您使用 jQuery、Prototype、Mootools、$whatever-the-newest-hype 等框架,请检查它们是否带有自己的集合 API,这可能比使用原生 JS 对象更好地解决您的问题。

于 2009-06-05T16:35:04.387 回答
129

在任何 ES5 兼容的环境中执行此操作

Object.keys(obj).length

(来自此处的浏览器支持) (此处
有关 Object.keys 的文档,包括可以添加到非 ECMA5 浏览器的方法)

于 2013-03-15T09:03:09.257 回答
9

如果您已经在构建中使用 jQuery,请执行以下操作:

$(yourObject).length

它在对象上非常适合我,而且我已经将 jQuery 作为依赖项。

于 2014-12-02T14:12:55.230 回答
7
function count(){
    var c= 0;
    for(var p in this) if(this.hasOwnProperty(p))++c;
    return c;
}

var O={a: 1, b: 2, c: 3};

count.call(O);
于 2009-06-05T17:02:56.880 回答
1

AFAIK,没有办法可靠地做到这一点,除非你切换到一个数组。老实说,这似乎并不奇怪——对我来说,数组是可数的,而对象不是。

可能你会得到的最接近的是这样的

// Monkey patching on purpose to make a point
Object.prototype.length = function()
{
  var i = 0;
  for ( var p in this ) i++;
  return i;
}

alert( {foo:"bar", bar: "baz"}.length() ); // alerts 3

但这会产生问题,或者至少会产生问题。所有用户创建的属性都被计算在内,包括 _length 函数本身!虽然在这个简单的示例中,您可以通过使用普通函数来避免它,但这并不意味着您可以阻止其他脚本这样做。所以你会怎么做?忽略函数属性?

Object.prototype.length = function()
{
  var i = 0;
  for ( var p in this )
  {
      if ( 'function' == typeof this[p] ) continue;
      i++;
  }
  return i;
}

alert( {foo:"bar", bar: "baz"}.length() ); // alerts 2

最后,我认为您可能应该放弃使您的对象可数的想法,并找出另一种方法来做您正在做的任何事情。

于 2009-06-05T16:27:31.890 回答
0

数字/长度/维度的概念对于对象来说并没有真正意义,需要它表明你真的想要一个数组给我。

编辑:向我指出你想要一个 O(1) 。据我所知,恐怕不存在这样的方式。

于 2009-06-05T16:21:31.983 回答