最近寫js時碰到了當數組key不為數字時,獲取數組的長度為0 的情況。
1、問題場景
arr[‘s1‘] = 1001;
console.log(arr.length);
通過chrome查看:

2、原因分析
js Array只支持數字索引,若指定的key為非數字索引,那么length為0.
另外,若key為數字索引,length的長度是根據key值得出的,比如一個數組a中key最大值為1000,value為1000,那么a的長度就是1001.只有a[1000] = 1000.從a[0]到a[999]的值為undefined
可以來驗證一下:
arr[1000] = 1001;
console.log(arr.length);

3、解決長度問題
出現問題的原因已經知道了,有的時候我們需要設置的key不是數字索引,而是非數字索引,那么如何獲取長度呢。我們可以把Array看成是特殊的Object類型。有兩種方式可以得到Object類型的長度:
第一種方法:通過 Object.keys(obj).length 獲取。
可以驗證下:
obj[1001] = 1001;
obj[1002] = 1002;
console.log(obj.length);
console.log(Object.keys(obj).length);

該方法獲取長度是會獲取到原型的屬性的,如果一個對象繼承了另一個對象,或者在原型中設置了屬性,要想獲取對象的本身的屬性時,這個方法是不靠譜的。
因此,第二個方法就是過濾到原型的屬性:
調用:var length = getPropertyCount(obj);
由於任何一個Object對象都有方法 hasOwnProperty,當屬性為原型定義的屬性,hasOwnProperty返回true。
function getPropertyCount(o){ var n, count = 0; for(n in o){ if(o.hasOwnProperty(n)){ count++; } } return count; }
問題到這里應該可以解決了,現在想要獲取一個數組的實際指定的長度,一般來說,我們不會為Array的原型添加額外的屬性,所以,我們可以通過采用上面的第一種方式解決。
可以驗證下:

題外話:
判斷一個屬性是否是共享屬性,可以通過hasOwnProperty 及in 聯合判斷。
hasOwnProperty:當對象存在屬性且屬性不是共享的,返回true
in:當對象中存在屬性,返回true.
因此,如判斷person中是否存在私有屬性屬性a,person.hasOwnPropety(a) && a in person 需返回true
