计算具有'仅非数字索引'的数组的长度,而不是in循环

时间:2012-01-05 18:10:46

标签: javascript

如果索引是非数字的,则Array定义length = 0.

我遇到了这种获取长度的实现,但我仍然担心在数组循环中使用。循环的大多数地方被指示为“不良做法”。 see here

可以像这样实施吗?

有人可以提供替代解决方案(不进行循环播放)吗?

for for loop的任何示例?

我使用hasOwnProperty(..)方法来避免Array.prototype的属性。

Array.prototype.global = 1;

var arr = [];
arr['first'] = 1;
arr['second'] = 2;

console.log(arr.length);  //0

var length = 0;
for(index in arr){
   if(arr.hasOwnProperty(index)) {length++;}
}

console.log(length); //3

1 个答案:

答案 0 :(得分:5)

您的示例中不再使用数组作为数组。 JS中的数组(严格来说)只是这样的一堆东西:

['a', 'b', 'c']

你所做的是开始使用空数组作为对象.. [] simple通过字符串/变量访问属性...所以

var obj = {test: 'blah'}
obj['test'] //is 'blah'
obj.test //is also blah

通常,当您要通过变量访问属性或方法或者属性或方法不是“安全”时,使用[]表示法。例如'int'。

因此,将您拥有的内容更改为对象,然后使用“for in”循环逐步执行键。是的,你仍然需要检查每一个是否有onOwnProperty(或者使用jquery / underscore'each'),但至少你会使用正确的工具来完成工作:)或者你只是想要键的数量,underscore.js有一个很好的小_.keys方法..所以_.keys(obj).length会给你键的数量。很确定它只是本地键,而不是原型键。

编辑:作为一个重新阅读,希望更好的答案,JS中没有属性,我知道你可以简单地计算密钥的位置。如果它只是你正在使用的特定事物而不是'所有对象',你可以做类似的事情。

var specialObject = function () {this.keys = 0;};
specialObject.prototype.set = function (key, val)  {
    if(!this[key]) {
       this.keys++;
    }
    this[key] = val;
};
var so = new specialObject();
so.set('test', 'blah');
so.keys //would be 1
so.test //would be 'blah'

然后只使用'set'。你想要制作一个'unset',也可能是'get'方法。

希望这一切都有意义......这有点像是一种强烈的。