在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ HTML/ 數(shù)組
面向?qū)ο蟮?Javascript
客戶端的 JavaScript
概述
核心概念深入
函數(shù)式的 Javascript
對象與 JSON
前端 JavaScript 框架
基本概念
數(shù)組
閉包
正則表達(dá)式
函數(shù)

數(shù)組

JavaScript 的數(shù)組也是一個比較有意思的主題,雖然名為數(shù)組(Array),但是根據(jù)數(shù)組對象上的方法來看,更像是將很多東西混在在一起的結(jié)果。而傳統(tǒng)的程序設(shè)計語言如 C/Java 中,數(shù)組內(nèi)的元素需要具有相同的數(shù)據(jù)類型,而作為弱類型的 JavaScript,則沒有這個限制,事實上,JavaScript 的同一個數(shù)組中,可以有各種完全不同類型的元素。

方法 描述
concat() 連接兩個或更多的數(shù)組,并返回結(jié)果。
join() 把數(shù)組的所有元素放入一個字符串。元素通過指定的分隔符進(jìn)行分隔。
pop() 刪除并返回數(shù)組的最后一個元素。
push() 向數(shù)組的末尾添加一個或更多元素,并返回新的長度。
reverse() 顛倒數(shù)組中元素的順序。
shift() 刪除并返回數(shù)組的第一個元素。
slice() 從某個已有的數(shù)組返回選定的元素。
sort() 對數(shù)組的元素進(jìn)行排序。
splice() 刪除元素,并向數(shù)組添加新元素。
unshift() 向數(shù)組的開頭添加一個或更多元素,并返回新的長度。
valueOf() 返回數(shù)組對象的原始值。

可以看出,JavaScript 的數(shù)組對象比較復(fù)雜,包含有 pop,push 等類似與棧的操作,又有 slice, reverse,sort 這樣類似與列表的操作?;蛟S正因為如此,JavaScript 中的數(shù)組的功能非常強(qiáng)大。

數(shù)組的特性

數(shù)組包括一些屬性和方法,其最常用的屬性則為 length,length 表示數(shù)組的當(dāng)前長度,與其他語言不同的是,這個變量并非只讀屬性,比如:

var array = new Array(1, 2, 3, 4, 5);  
print(array.length);  
array.length = 3;  
print(array.length);<span style="font-size: small;"><span style="font-size: 13px;">  
</span></span> 

運(yùn)行結(jié)果為:

5
3
1,2,3

注意到最后的 print 語句的結(jié)果是”1,2,3”,原因是對 length 屬性的修改會使得數(shù)組后邊的元素變得不可用(如果修改后的 length 比數(shù)組實際的長度小的話),所以可以通過設(shè)置 length 屬性來將數(shù)組元素裁減。

另一個與其他語言的數(shù)組不同的是,字符串也可以作為數(shù)組的下標(biāo)(事實上,在 JavaScript 的數(shù)組中,數(shù)字下標(biāo)最終會被解釋器轉(zhuǎn)化為字符串,也就是說,所謂的數(shù)字下標(biāo)只不過是看著像數(shù)字而實際上是字符的屬性名),比如:

var stack = new Array();  

stack['first'] = 3.1415926;  
stack['second'] = "okay then.";  
stack['third'] = new Date();  

for(var item in stack){  
    print(typeof stack[item]);  
}  

運(yùn)行結(jié)果為:

number
string
object

在這個例子里,還可以看到不同類型的數(shù)據(jù)是如何存儲在同一個數(shù)組中的,這么做有一定的好處,但是在某些場合則可能形成不便,比如我們在函數(shù)一章中討論過的 sum 函數(shù),sum 接受非顯式的參數(shù)列表,使用這個函數(shù),需要調(diào)用者必須為 sum 提供數(shù)字型的列表(當(dāng)然,字符串無法做 sum 操作)。如果是強(qiáng)類型語言,則對 sum 傳入字符串?dāng)?shù)組會被編譯程序認(rèn)為是非法的,而在 JavaScript 中,程序需要在運(yùn)行時才能偵測到這一錯誤。

使用數(shù)組

數(shù)組的基本方法使用

數(shù)組有這樣幾種方式來創(chuàng)建:

var array = new Array();  
var array = new Array(10);//長度  
var array = new Array("apple", "borland", "cisco");

不過,運(yùn)用最多的為字面量方式來創(chuàng)建,如果第三章中的 JSON 那樣,我們完全可以這樣創(chuàng)建數(shù)組:

var array = [];  
var array = ["one", "two", "three", "four"]; 

下面我們通過一些實際的小例子來說明數(shù)組的使用(主要方法的使用):

向數(shù)組中添加元素:

var array = [];  

array.push(1);  
array.push(2);  
array.push(3);  

array.push("four");  
array.push("five");  

array.push(3.1415926);  

前面提到過,JavaScript 的數(shù)組有列表的性質(zhì),因此可以向其中 push 不同類型的元素,接上例:

var len = array.length;  
for(var i = 0; i < len; i++){  
    print(typeof array[i]);  
} 

結(jié)果為:

number
number
number
string
string
number

彈出數(shù)組中的元素:

for(var i = 0; i < len; i++){  
    print(array.pop());  
}  
print(array.length);

運(yùn)行結(jié)果如下,注意最后一個 0 是指 array 的長度為 0,因為這時數(shù)組的內(nèi)容已經(jīng)全部彈出:

3.1415926
five
four
3
2
1
0

join,連接數(shù)組元素為一個字符串:

array = ["one", "two", "three", "four", "five"];  

var str1 = array.join(",");  
var str2 = array.join("|");  

print(str1);  
print(str2);  

運(yùn)行結(jié)果如下:

one,two,three,four,five
one|two|three|four|five

連接多個數(shù)組為一個數(shù)組:

var another = ["this", "is", "another", "array"];  
var another2 = ["yet", "another", "array"];  

var bigArray = array.concat(another, another2);

結(jié)果為:

one,two,three,four,five,this,is,another,array,yet,another,array

從數(shù)組中取出一定數(shù)量的元素,不影響數(shù)組本身:

print(bigArray.slice(5,9));  

結(jié)果為:

this,is,another,array

slice 方法的第一個參數(shù)為起始位置,第二個參數(shù)為終止位置,操作不影響數(shù)組本身。下面我們來看splice方法,雖然這兩個方法的拼寫非常相似,但是功用則完全不同,事實上,splice是一個相當(dāng)難用的方法:

bigArray.splice(5, 2);  

bigArray.splice(5, 0, "very", "new", "item", "here");  

第一行代碼表示,從 bigArray 數(shù)組中,從第 5 個元素起,刪除 2 個元素;而第二行代碼表示,從第 5 個元素起,刪除0個元素,并把隨后的所有參數(shù)插入到從第 5 個開始的位置,則操作結(jié)果為:

one,two,three,four,five,very,new,item,here,another,array,yet,another,array

我們再來討論下數(shù)組的排序,JavaScript 的數(shù)組的排序函數(shù) sort 將數(shù)組按字母順序排序,排序過程會影響源數(shù)組,比如:

var array = ["Cisio", "Borland", "Apple", "Dell"];  
print(array);  
array.sort();  
print(array); 

執(zhí)行結(jié)果為:

Cisio,Borland,Apple,Dell
Apple,Borland,Cisio,Dell

這種字母序的排序方式會造成一些非你所預(yù)期的小 bug,比如:

var array = [10, 23, 44, 58, 106, 235];  
array.sort();  
print(array); 

得到的結(jié)果為:

10,106,23,235,44,58

可以看到,sort 不關(guān)注數(shù)組中的內(nèi)容是數(shù)字還是字母,它僅僅是按照字母的字典序來進(jìn)行排序,對于這種情況,JavaScript 提供了另一種途徑,通過給 sort 函數(shù)傳遞一個函數(shù)對象,按照這個函數(shù)提供的規(guī)則對數(shù)組進(jìn)行排序。

function sorter(a, b){  
    return a - b;  
}  

var array = [10, 23, 44, 58, 106, 235];  
array.sort(sorter);  
print(array); 

函數(shù) sorter 接受兩個參數(shù),返回一個數(shù)值,如果這個值大于 0,則說明第一個參數(shù)大于第二個參數(shù),如果返回值為0,說明兩個參數(shù)相等,返回值小于 0,則第一個參數(shù)小于第二個參數(shù),sort 根據(jù)這個返回值來進(jìn)行最終的排序:

10,23,44,58,106,235

當(dāng)然,也可以簡寫成這樣:

array.sort(function(a, b){return a - b;});//正序  
array.sort(function(a, b){return b - a;});//逆序  

刪除數(shù)組元素

雖然令人費(fèi)解,但是 JavaScript 的數(shù)組對象上確實沒有一個叫做 delete 或者 remove 的方法,這就使得我們需要自己擴(kuò)展其數(shù)組對象。一般來說,我們可以擴(kuò)展 JavaScript 解釋器環(huán)境中內(nèi)置的對象,這種方式的好處在于,擴(kuò)展之后的對象可以適用于其后的任意場景,而不用每次都顯式的聲明。而這種做法的壞處在于,修改了內(nèi)置對象,則可能產(chǎn)生一些難以預(yù)料的錯誤,比如遍歷數(shù)組實例的時候,可能會產(chǎn)生令人費(fèi)解的異常。

數(shù)組中的每個元素都是一個對象,那么,我們可以使用 delete 來刪除元素嗎?來看看下邊這個小例子:

var array = ["one", "two","three","four"];  
//數(shù)組中現(xiàn)在的內(nèi)容為:  
//one,two,three,four  
//array.length == 4  
delete array[2]; 

然后,我們再來看看這個數(shù)組的內(nèi)容:

one, two, undefined, four
//array.length == 4

可以看到,delete 只是將數(shù)組 array 的第三個位置上的元素刪掉了,可是數(shù)組的長度沒有改變,顯然這個不是我們想要的結(jié)果,不過我們可以借助數(shù)組對象自身的 slice 方法來做到。一個比較好的實現(xiàn),是來自于 jQuery 的設(shè)計者 John Resig:

//Array Remove - By John Resig (MIT Licensed)  
Array.prototype.remove = function(from, to) {  
    var rest = this.slice((to || from) + 1 || this.length);  
    this.length = from < 0 ? this.length + from : from;  
    return this.push.apply(this, rest);  
};  

這個函數(shù)擴(kuò)展了 JavaScript 的內(nèi)置對象 Array,這樣,我們以后的所有聲明的數(shù)組都會自動的擁有 remove 能力,我們來看看這個方法的用法:

var array = ["one", "two", "three", "four", "five", "six"];  
print(array);  
array.remove(0);//刪除第一個元素  
print(array);  
array.remove(-1);//刪除倒數(shù)第一個元素  
print(array);  
array.remove(0,2);//刪除數(shù)組中下標(biāo)為0-2的元素(3個)  
print(array);

會得到這樣的結(jié)果:

one,two,three,four,five,six
two,three,four,five,six
two,three,four,five
five

也就是說,remove 接受兩個參數(shù),第一個參數(shù)為起始下標(biāo),第二個參數(shù)為結(jié)束下標(biāo),其中第二個參數(shù)可以忽略,這種情況下會刪除指定下標(biāo)的元素。當(dāng)然,不是每個人都希望影響整個原型鏈(原因在下一個小節(jié)里討論),因此可以考慮另一種方式:

//Array Remove - By John Resig (MIT Licensed)  
Array.remove = function(array, from, to) {  
    var rest = array.slice((to || from) + 1 || array.length);  
    array.length = from < 0 ? array.length + from : from;  
    return array.push.apply(array, rest);  
};  

其操作方式與前者并無二致,但是不影響全局對象,代價是你需要顯式的傳遞需要操作的數(shù)組作為第一個參數(shù):

var array = ["one", "two", "three", "four", "five", "six"];  
Array.remove(array, 0, 2);//刪除0, 1, 2三個元素  
print(array); 

這種方式,相當(dāng)于給JavaScript內(nèi)置的Array添加了一個靜態(tài)方法。

遍歷數(shù)組

在對象與 JSON 這一章中,我們討論了 for…in 這種遍歷對象的方式,這種方式同樣適用于數(shù)組,比如:

var array = [1, 2, 3, 4];  
for(var item in array){  
    print(array[item]);  
}

將會打?。?/p>

1
2
3
4

但是這種方式并不總是有效,比如我們擴(kuò)展了內(nèi)置對象 Array,如下:

Array.prototype.useless = function(){}  

然后重復(fù)執(zhí)行上邊的代碼,會得到這樣的輸出:

1
2
3
4
function(){}

設(shè)想這樣一種情況,如果你對數(shù)組的遍歷做sum操作,那么會得到一個莫名其妙的錯誤,畢竟函數(shù)對象不能做求和操作。幸運(yùn)的是,我們可以用另一種遍歷方式來取得正確的結(jié)果:

for(var i = 0, len = array.length; i < len;i++){  
    print(array[i]);  
}  

這種 for 循環(huán)如其他很多語言中的寫法一致,重要的是,它不會訪問哪些下標(biāo)不是數(shù)字的元素,如上例中的 function,這個 function 的下標(biāo)為 useless,是一個字符串。從這個例子我們可以看出,除非必要,盡量不要對全局對象進(jìn)行擴(kuò)展,因為對全局對象的擴(kuò)展會造成所有繼承鏈上都帶上“烙印”,而有時候這些烙印會成為滋生 bug 的溫床。