javascript中的數組擴展(一)javascript
隨着學習的深刻,發現須要學習的關於數組的內容也愈來愈多,後面將會慢慢概括,有的是對前面的強化,有些則是關於前面的補充。java
1、數組的本質
數組是按照次序排列的一組值,本質上,數組是一種特殊的對象
console.log(typeof[1,2,3]);//object
數組是對象可是對象不是數組
var arr = ['a','b','c','d','e'];
console.log(Array.isArray(arr));//true
console.log(Array.isArray([]));//true
console.log(Array.isArray({}));//false,空的對象不是數組
數組的特性體如今,它的鍵名是按次序排列的一組整數。因爲數組成員的鍵名是固定的,所以數組不用爲每一個元素指定鍵名,而對象的每一個成員都要指定鍵名。
var aa = ['a','b','c'];
console.log(Object.keys(aa));//0,1,2
var obj = {
name1:'a',
name2:'b',
name3:'c'
};
數組是對象的特殊形式。在javascript中規定對象的鍵名一概爲字符串,因此數組的鍵名也爲字符串。
var o = {
1:'one',
2:'two',
}
console.log(o[1]);//one
在數組中:(非字符串的鍵名會被轉爲字符串,然戶將其做爲屬性名來使用)
var a = ['a','b','c'];
console.log(a['0']);//a
console.log(a[1]);//a
可是在數組中要區分數組的索引和對象的屬性名:全部的索引都是屬性名,但只有在(0~2的32次方-2)之間的整數屬性名纔是索引
當屬組的屬性不是(0~2的32次方-2)之間的整數時,只是數組的屬性名,其明顯特徵是不改變數組數組長度
注意:單獨的數值不能做爲標識符,數組的成員只能用方括號法表示
var a = [1,2,3] ;
console.log(a[0]);//0
console.log(a.0);//Uncaught SyntaxError: Unexpected number
下面經過例子來區別索引和屬性名
var a = [1,2,3] ;
a[-1.23]=true;//屬性名
console.log(a.length);//3
a[10] = 11;//索引
console.log(a.length);//11
a['abc'] = 'foodoir';//屬性名
console.log(a.length);//11數組
2、在談到數組的本質的時候,咱們不得不提數組檢測的幾種方法:
【typeof】
var arr = [1,2,3];
console.log(typeof arr);//object,這個方法能很好的證實數組是對象
【instanceof】
var arr = [1,2,3];
console.log(arr instanceof Array);//true
var str = 'abc';
console.log(str instanceof Array);//false
//擴充
var str = 'abc';
str[0] = 1;
str[1] = 2;
str[2] = 3;
console.log(str[1]);//b
console.log(str.length);//3
console.log(str instanceof Array);//false
var str = [];
str[0] = 1;
str[1] = 2;
str[2] = 3;
console.log(str[1]);//2
console.log(str.length);//3
console.log(str instanceof Array);//true
【toString】
var arr = [1,2,3];
console.log(Object.prototype.toString.call(arr) === '[object Array]');//true
【valueof()】函數
方法返回數組自己
var a = [1,2,3];
console.log(a.valueOf());//1,2,3
console.log(a.valueOf() instanceof Array);//true學習
後來ECMAScript5新增了【Array.isArray()】方法。這個方法的目的最終是肯定某個值究竟是不是數組,而無論他是在哪一個全局執行環境中建立的。這個方法的使用以下:spa
if(Array.isArray(value)){
//對數組執行某些操做
}prototype
3、關於數組的長度
通用公式:數組長度 = 最大索引 + 1,再次強調:delete操做並不應變數組的長度
關於數組長度的深度剖析
一、當索引大於現有數組長度時,length屬性的值將設置爲索引值+1
var a = [1,2,3];
console.log(a.length);//3
a[10] = 11;
console.log(a.length);//11
二、當length屬性的設置小於當前長度時,將當前索引值大於設置的數組長度的元素從數組中刪除
var a = [1,2,3,4,5];
a.length = 3;
console.log(a);//1,2,3
a.length = 0;
console.log(a);//''
a.length = 10;
console.log(a);//,,,,,,,,,,
console.log(a[3]);//undefined
三、將數組的長度設爲大於當前的長度,實際上並無想數組中添加新元素,只是在數組的尾部建立了一個空的區域(見上)
四、將數組的length值設爲不合法的值,咱們來看結果
[].length = -1;//Uncaught RangeError: Invalid array length
[].length = Math.pow(2,32);//Uncaught RangeError: Invalid array length
[].length = 'abc';//Uncaught RangeError: Invalid array length
五、那麼問題來了,咱們如何設置數組的長度不可修改呢?
咱們能夠經過前面學習對象時的相關知識來解決
var arr = [1,2,3];
Object.defineProperty(arr,'length',{
writable:false,
});
console.log(arr.length);//3
arr[4] = 4;
console.log(arr.length);//3
console.log(arr)//1,2,3 說明設置不可修改length屬性成功了對象
4、前面介紹了遍歷數組的三種方法:for、for/in、forEach,接下來咱們針對這三種方法進行一下擴展
for()循環
當索引連續時,能夠用for循環遍歷
var arr = ['a','b','c',123];
for(var i = 0 ; i<arr.length;i++){
console.log(arr[i]);//a,b,c,123
}
補充:當索引連續時,也能夠用while循環遍歷數組
var a = [1,2,3,4];
var i = 0;
while(i<a.length){
console.log(a[i]);//1,2,3
i++;
}
var j = a.length;
while(j--){
console.log(a[j]);//3,2,1
}
可是如數組爲稀疏數組時,仍要使用for循環怎麼辦?
此時應該給for循環增長一些條件
var a = [1,,,,5,6];
for(var i=0;i<a.length;i++){
if(!(i in a)){
//console.log(typeof i);//number,注意:此時的返回值爲number!!!
console.log(a[i]);//undefined
}
}
前面是我本身踏進去的個坑,下面纔是正確的解法,比較這兩者的區別
var a = [1,,,,5,6];
for(var i=0;i<a.length;i++){
if(!(i in a)) continue;
//console.log(typeof i);//number,注意:此時的返回值爲number!!!
console.log(a[i]);//1,5,6
}
for/in循環
從前面能夠看出,在面對稀疏數組時,咱們用for/in循環的話會方便不少
var a = [1,,,,5,6];
for(var i in a){
console.log(a[i]);//1,5,6
}
因爲for/in循環可以枚舉繼承的屬性名,如添加到Array.prototype中的方法。因爲這個緣由,在數組上不該該使用for/in循環,除非使用額外的檢測方法來過濾掉不想要的屬性
var a = [1,,,4];
a.b = 'b';
a.c = -5;
a.d = 7.8
for(var i in a){
console.log(a[i]);//1,4,b,-5,7.8
}
咱們能夠經過加斷定條件來跳過不是非負整數的i
var a = [1,,,4];
a.b = 'b';
a.c = -5;
a.d = 7.8
for(var i in a){
//console.log(typeof i);//String,注意:在前面用for循環中的for/in循環中typeof的返回值爲number
if(String(Math.floor(Math.abs(Number(i))))!==i) continue;
console.log(a[i]);//1,4
}
下面咱們經過前面對象的方法中的hasOwnProperty()函數來獲取不是繼承下來的屬性
var arr1 = [];
arr1[1] = 'x';
arr1[22] = 'y';
arr1[333] = 'z';
for(var i in arr1){
console.log(arr1[i]);//x,y,z
}//這種方法遍歷的是繼承下來的屬性,若不想遍歷繼承下來的屬性能夠用hasOwnProperty()函數
for(var i in arr1){
if(arr1.hasOwnProperty(i)){
console.log(arr1[i]);//x,y,z
}
}//這種方法遍歷的不是繼承下來的屬性
咱們還能夠經過forEach()方法來遍歷數組
語法:Array.forEach(function(value[,index[,array]]){函數體})
var arr2 = [1,2,3,4,5,6];
方法一:
arr2.forEach(function(x){
console.log(x);
});1,2,3,4,5,6
方法二:
function Test(element,index,array){
console.log('要處理的數組爲:'+array);
console.log('索引:'+index+'--值爲:'+element);
}
arr2.forEach(Test);繼承
5、類數組:擁有length屬性和對應非負整數屬性的對象叫類數組
var obj = {};
obj[0] = 'a';
obj[1] = 'b';
console.log(obj);//Object {0: "a", 1: "b"}
console.log(obj.length);//undefined
可是將{}換成[],這樣是否是就很熟悉了
var arr = [];
arr[0] = 'a';
arr[1] = 'b';
console.log(arr);//["a", "b"]
console.log(arr.length);//2
前面那個帶有{}的就是類數組,咱們能夠經過下面的例子來進一步瞭解它
var a = {};
var i = 0;
while(i<10){
a[i]=i*i;
i++;
}
a.length = i;
var total = 0;
for(var j=0;j<a.length;j++){
total += a[j];
}
console.log(total);//285
有三個常見的類數組對象:arguments對象,DOM方法,字符串
arguments對象
function args(){
return arguments;
}
var arrayLike = args('a','b');
console.log(arrayLike[0]);//a
console.log(arrayLike.length);//2
console.log(arrayLike instanceof Array);//false
DOM方法
var elts = document.getElementsByTagName('div');
for(var i=0;i<elts.length;i++){
return true;
}
console.log(elts.length);//?
console.log(elts instanceof Array);//false
字符串
console.log('abc'[1]);//b
console.log('abc'.length);//3
console.log('abc' instanceof Array);//false
注意:字符串是不可變值,故把它們看成數組來看時,它們是隻讀的。push()、sort()、reverse()、splice()等方法會修改數組,它們在字符串上是無效的,且會報錯。
索引