檢測數組
對于一個網頁藏姐,或者一個全局作用域而言,使用 instanceof 操作符就能得到滿意的結果:
if (value instanceof Array){
//對數組執(zhí)行某些操作
}
instanceof 操作符的問題在于凉蜂,它假定只有一個全局執(zhí)行環(huán)境琼梆。如果網頁中包含多個框架,那實際上就存在兩個以上不同的全局執(zhí)行環(huán)境窿吩,從而存在兩個以上不同版本的 Array 構造函數叮叹。如果你從一個框架向另一個框架傳入一個數組,那么傳入的數組與在第二個框架中原生創(chuàng)建的數組分別具有各自不同的構造函數爆存。
為了解決這個問題,ECMAScript 5 新增了 **Array.isArray() **方法蝗砾。這個方法的目的是最終確定某個值到底是不是數組先较,而不管它是在哪個全局執(zhí)行環(huán)境中創(chuàng)建的。這個方法的用法如下悼粮。
if (Array.isArray(value)){
//對數組執(zhí)行某些操作
}
支持 Array.isArray() 方法的瀏覽器有 IE9+闲勺、Firefox 4+、Safari 5+扣猫、Opera 10.5+和 Chrome菜循。
轉換方法
所有對象都具有 toLocaleString() 、 toString() 和 valueOf() 方法申尤。其中癌幕,調用數組的 toString() 方法會返回由數組中每個值的字符串形式拼接而成的一個以逗號分隔的字符串衙耕。而調用 valueOf() 返回的還是數組。
var colors = ["red", "blue", "green"]; // 創(chuàng)建一個包含 3 個字符串的數組
alert(colors.toString()); // red,blue,green
alert(colors.valueOf()); // red,blue,green
alert(colors); // red,blue,green
由于 alert() 要接收字符串參數勺远,所以它會在后臺調用 toString() 方法橙喘,由此
會得到與直接調用 toString() 方法相同的結果。
var person1 = {
toLocaleString : function () {
return "a1";
},
toString : function() {
return "a2";
}
};
var person2 = {
toLocaleString : function () {
return "b1";
},
toString : function() {
return "b2";
}
};
alert(people); //Nicholas,Greg
alert(people.toString()); //a2,b2
alert(people.toLocaleString()); //a1,b1
數組繼承的 toLocaleString() 胶逢、 toString() 和 valueOf() 方法厅瞎,在默認情況下都會以逗號分隔的字符串的形式返回數組項。
join() 方法初坠,可以使用不同的分隔符來構建這個字符串和簸。
join() 方法只接收一個參數,即用作分隔符的字符串碟刺,然后返回包含所有數組項的字符串锁保。請看下面的例子:
var colors = ["red", "green", "blue"];
alert(colors.join(",")); //red,green,blue
alert(colors.join("||")); //red||green||blue
在這里,我們使用 join() 方法重現了 toString() 方法的輸出南誊。在傳遞逗號的情況下身诺,得到了以逗號分隔的數組值。
棧方法 push() + pop()
ECMAScript 數組也提供了一種讓數組的行為類似于其他數據結構的方法抄囚。具體說來霉赡,數組可以表現得就像棧一樣,后者是一種可以限制插入和刪除項的數據結構幔托。棧是一種 LIFO(Last-In-First-Out穴亏,后進先出)的數據結構,也就是最新添加的項最早被移除重挑。
而棧中項的插入(叫做推入)和移除(叫做彈出)嗓化,只發(fā)生在一個位置——棧的頂部。ECMAScript 為數組專門提供了 push() 和 pop() 方法谬哀,以便實現類似棧的行為刺覆。
push() 方法可以接收任意數量的參數,把它們逐個添加到數組末尾史煎,并返回修改后數組的長度谦屑。而pop() 方法則從數組末尾移除最后一項,減少數組的 length 值篇梭,然后返回移除的項氢橙。請看下面的例子:
var colors = new Array(); // 創(chuàng)建一個數組
var count = colors.push("red", "green"); // 推入兩項
alert(count); //2
count = colors.push("black"); // 推入另一項
alert(count); //3
var item = colors.pop(); // 取得最后一項
alert(item); //"black"
alert(colors.length); //2
隊列方法 push() + shift()
隊列數據結構的訪問規(guī)則是 FIFO(First-In-First-Out,先進先出)恬偷。隊列在列表的末端添加項悍手,從列表的前端移除項。由于 push() 是向數組末端添加項的方法,因此要模擬隊列只需一個從數組前端取得項的方法坦康。實現這一操作的數組方法就是 shift() 竣付,它能夠移除數組中的第一個項并返回該項,同時將數組長度減 1涝焙。結合使用 shift() 和 push() 方法卑笨,可以像使用隊列一樣使用數組。
var colors = new Array(); //創(chuàng)建一個數組
var count = colors.push("red", "green"); //推入兩項
alert(count); //2
count = colors.push("black"); //推入另一項
alert(count); //3
var item = colors.shift(); // 取得第一項
alert(item); //"red"
alert(colors.length); //2
ECMAScript 還為數組提供了一個 unshift() 方法仑撞。顧名思義赤兴, unshift() 與 shift() 的用途相反:它能在數組前端添加任意個項并返回新數組的長度。因此隧哮,同時使用 unshift() 和 pop() 方法桶良,可以從相反的方向來模擬隊列,即在數組的前端添加項沮翔,從數組末端移除項陨帆,如下面的例子所示。
var colors = new Array(); //創(chuàng)建一個數組
var count = colors.unshift("red", "green"); // 推入兩項
alert(count); //2
count = colors.unshift("black"); // 推入另一項
alert(count); //3
var item = colors.pop(); // 取得最后一項
alert(item); //"green"
alert(colors.length); //2
這個例子創(chuàng)建了一個數組并使用 unshift() 方法先后推入了 3 個值采蚀。首先是 "red" 和 "green" 疲牵,然后是 "black" ,數組中各項的順序為 "black" 榆鼠、 "red" 纲爸、 "green" 。在調用 pop() 方法時妆够,移除并返回的是最后一項识啦,即 "green" 。
IE7 及更早版本對 JavaScript 的實現中存在一個偏差神妹,其 unshift() 方法總是返回 undefined 而不是數組的新長度颓哮。IE8 在非兼容模式下會返回正確的長度值。
重排序方法
數組中已經存在兩個可以直接用來重排序的方法: reverse() 和 sort() 鸵荠。
reverse() 方法會反轉數組項的順序冕茅。
var values = [1, 2, 3, 4, 5];
values.reverse();
alert(values); //5,4,3,2,1
這個方法的作用相當直觀明了,但不夠靈活蛹找,因此才有了 sort() 方法姨伤。
在默認情況下, sort() 方法按升序排列數組項——即最小的值位于最前面熄赡,最大的值排在最后面。為了實現排序齿税, sort() 方法會調用每個數組項的 toString() 轉型方法彼硫,然后比較得到的字符串,以確定如何排序。即使數組中的每一項都是數值拧篮, sort() 方法比較的也是字符串词渤,如下所示。
var values = [0, 1, 5, 10, 15];
values.sort();
alert(values); //0,1,10,15,5
這種排序方式在很多情況下都不是最佳方案串绩。因此 sort() 方法可以接收一個比較函數作為參數缺虐,以便我們指定哪個值位于哪個值的前面。
比較函數接收兩個參數礁凡,如果第一個參數應該位于第二個之前則返回一個負數高氮,如果兩個參數相等則返回 0,如果第一個參數應該位于第二個之后則返回一個正數顷牌。以下就是一個簡單的比較函數:
function compare(value1, value2) {
if (value1 < value2) {
return -1;
} else if (value1 > value2) {
return 1;
} else {
return 0;
}
}
這個比較函數可以適用于大多數數據類型剪芍,只要將其作為參數傳遞給 sort() 方法即可,如下面這個例子所示窟蓝。
var values = [0, 1, 5, 10, 15];
values.sort(compare);
alert(values); //0,1,5,10,15
在將比較函數傳遞到 sort() 方法之后罪裹,數值仍然保持了正確的升序。當然运挫,也可以通過比較函數產生降序排序的結果状共,只要交換比較函數返回的值即可。
function compare(value1, value2) {
if (value1 < value2) {
return 1;
} else if (value1 > value2) {
return -1;
} else {
return 0;
}
}
var values = [0, 1, 5, 10, 15];
values.sort(compare);
alert(values); // 15,10,5,1,0
reverse() 和 sort() 方法的返回值是經過排序之后的數組谁帕。
對于數值類型或者其 valueOf() 方法會返回數值類型的對象類型峡继,可以使用一個更簡單的比較函數。這個函數只要用第二個值減第一個值即可雇卷。
function compare(value1, value2){
return value2 - value1;
}
由于比較函數通過返回一個小于零鬓椭、等于零或大于零的值來影響排序結果,因此減法操作就可以適當地處理所有這些情況关划。
操作方法
concat() 方法可以基于當前數組中的所有項創(chuàng)建一個新數組小染。具體來說,這個方法會先創(chuàng)建當前數組一個副本贮折,然后將接收到的參數添加到這個副本的末尾裤翩,最后返回新構建的數組。在沒有給 concat() 方法傳遞參數的情況下调榄,它只是復制當前數組并返回副本踊赠。如果傳遞給 concat() 方法的是一或多個數組,則該方法會將這些數組中的每一項都添加到結果數組中每庆。如果傳遞的值不是數組筐带,這些值就會被簡單地添加到結果數組的末尾。下面來看一個例子缤灵。
var colors = ["red", "green", "blue"];
var colors2 = colors.concat("yellow", ["black", "brown"]);
alert(colors); //red,green,blue
alert(colors2); //red,green,blue,yellow,black,brown
如果 slice() 方法的參數中有一個負數伦籍,則用數組長度加上該數來確定相應的位
置蓝晒。例如,在一個包含 5 項的數組上調用 slice(-2,-1) 與調用 slice(3,4) 得到的
結果相同帖鸦。如果結束位置小于起始位置芝薇,則返回空數組。
splice() 方法
-刪除:可以刪除任意數量的項作儿,只需指定 2 個參數:要刪除的第一項的位置和要刪除的項數洛二。例如, splice(0,2) 會刪除數組中的前兩項攻锰。
-插入:可以向指定位置插入任意數量的項晾嘶,只需提供 3 個參數:起始位置、0(要刪除的項數)和要插入的項口注。如果要插入多個項变擒,可以再傳入第四、第五寝志,以至任意多個項娇斑。例如,splice(2,0,"red","green") 會從當前數組的位置 2 開始插入字符串 "red" 和 "green" 材部。
-替換:可以向指定位置插入任意數量的項毫缆,且同時刪除任意數量的項,只需指定 3 個參數:起始位置乐导、要刪除的項數和要插入的任意數量的項苦丁。插入的項數不必與刪除的項數相等。例如物臂,splice (2,1,"red","green") 會刪除當前數組位置 2 的項旺拉,然后再從位置 2 開始插入字符串"red" 和 "green" 。
splice() 方法始終都會返回一個數組棵磷,該數組中包含從原始數組中刪除的項(如果沒有刪除任何項蛾狗,則返回一個空數組)。
-位置方法
ECMAScript 5 為數組實例添加了兩個位置方法: indexOf() 和 lastIndexOf() 仪媒。這兩個方法都接收兩個參數:要查找的項和(可選的)表示查找起點位置的索引沉桌。其中, indexOf() 方法從數組的開頭(位置 0)開始向后查找算吩, lastIndexOf() 方法則從數組的末尾開始向前查找留凭。
這兩個方法都返回要查找的項在數組中的位置,或者在沒找到的情況下返回?1偎巢。在比較第一個參數與數組中的每一項時蔼夜,會使用全等操作符;也就是說压昼,要求查找的項必須嚴格相等(就像使用===一樣)求冷。
var numbers = [1,2,3,4,5,4,3,2,1];
alert(numbers.indexOf(4)); //3
alert(numbers.lastIndexOf(4)); //5
alert(numbers.indexOf(4, 4)); //5
alert(numbers.lastIndexOf(4, 4)); //3
var person = { name: "Nicholas" };
var people = [{ name: "Nicholas" }];
var morePeople = [person];
alert(people.indexOf(person)); //-1
alert(morePeople.indexOf(person)); //0
使用 indexOf() 和 lastIndexOf() 方法查找特定項在數組中的位置非常簡單翠订,支持它們的瀏覽器包括 IE9+、Firefox 2+遵倦、Safari 3+、Opera 9.5+和 Chrome官撼。
迭代方法
ECMAScript 5 為數組定義了 5 個迭代方法梧躺。每個方法都接收兩個參數:要在每一項上運行的函數和(可選的)運行該函數的作用域對象——影響 this 的值。傳入這些方法中的函數會接收三個參數:數組項的值傲绣、該項在數組中的位置和數組對象本身掠哥。根據使用的方法不同,這個函數執(zhí)行后的返回值可能會也可能不會影響方法的返回值秃诵。以下是這 5 個迭代方法的作用续搀。
? every() :對數組中的每一項運行給定函數,如果該函數對每一項都返回 true 菠净,則返回 true 禁舷。
? filter() :對數組中的每一項運行給定函數,返回該函數會返回 true 的項組成的數組毅往。
? forEach() :對數組中的每一項運行給定函數牵咙。這個方法沒有返回值。
? map() :對數組中的每一項運行給定函數攀唯,返回每次函數調用的結果組成的數組洁桌。
? some() :對數組中的每一項運行給定函數,如果該函數對任一項返回 true 侯嘀,則返回 true 另凌。
在這些方法中,最相似的是 every() 和 some() 戒幔,它們都用于查詢數組中的項是否滿足某個條件吠谢。對 every() 來說,傳入的函數必須對每一項都返回 true 溪食,這個方法才返回 true 囊卜;否則,它就返回false 错沃。而 some() 方法則是只要傳入的函數對數組中的某一項返回 true 栅组,就會返回 true 。請看以下例子枢析。
var numbers = [1,2,3,4,5,4,3,2,1];
var everyResult = numbers.every(function(item, index, array){
return (item > 2);
});
alert(everyResult); //false
var someResult = numbers.some(function(item, index, array){
return (item > 2);
});
alert(someResult); //true
以上代碼調用了 every() 和 some() 玉掸,傳入的函數只要給定項大于2就會返回 true 。對于 every() 醒叁,它返回的是 false 司浪,因為只有部分數組項符合條件泊业。對于 some() ,結果就是 true 啊易,因為至少有一項是大于 2 的吁伺。
下面再看一看 filter() 函數,它利用指定的函數確定是否在返回的數組中包含某一項租谈。例如篮奄,要返回一個所有數值都大于 2 的數組,可以使用以下代碼割去。
var numbers = [1,2,3,4,5,4,3,2,1];
var filterResult = numbers.filter(function(item, index, array){
return (item > 2);
});
alert(filterResult); //[3,4,5,4,3]
這里窟却,通過調用 filter() 方法創(chuàng)建并返回了包含 3、4呻逆、5夸赫、4、3 的數組咖城,因為傳入的函數對它們每一項都返回 true 茬腿。這個方法對查詢符合某些條件的所有數組項非常有用。
map() 也返回一個數組宜雀,而這個數組的每一項都是在原始數組中的對應項上運行傳入函數的結果滓彰。例如,可以給數組中的每一項乘以 2州袒,然后返回這些乘積組成的數組揭绑,如下所示。
var numbers = [1,2,3,4,5,4,3,2,1];
var mapResult = numbers.map(function(item, index, array){
return item * 2;
});
alert(mapResult); //[2,4,6,8,10,8,6,4,2]
最后一個方法是 forEach() 郎哭,它只是對數組中的每一項運行傳入的函數他匪。這個方法沒有返回值,本質上與使用 for 循環(huán)迭代數組一樣夸研。來看一個例子邦蜜。
var numbers = [1,2,3,4,5,4,3,2,1];
numbers.forEach(function(item, index, array){
//執(zhí)行某些操作
});
這些數組方法通過執(zhí)行不同的操作,可以大大方便處理數組的任務亥至。支持這些迭代方法的瀏覽器有IE9+悼沈、Firefox 2+、Safari 3+姐扮、Opera 9.5+和 Chrome絮供。
歸并方法
ECMAScript 5 還新增了兩個歸并數組的方法: reduce() 和 reduceRight() 。這兩個方法都會迭代數組的所有項茶敏,然后構建一個最終返回的值壤靶。其中, reduce() 方法從數組的第一項開始惊搏,逐個遍歷到最后贮乳。而 reduceRight() 則從數組的最后一項開始忧换,向前遍歷到第一項。這兩個方法都接收兩個參數:一個在每一項上調用的函數和(可選的)作為歸并基礎的初始值向拆。傳給 reduce() 和 reduceRight() 的函數接收 4 個參數:前一個值亚茬、當前值、項的索引和數組對象浓恳。這個函數返回的任何值都會作為第一個參數自動傳給下一項才写。第一次迭代發(fā)生在數組的第二項上,因此第一個參數是數組的第一項奖蔓,第二個參數就是數組的第二項。
使用 reduce() 方法可以執(zhí)行求數組中所有值之和的操作讹堤,比如:
var values = [1,2,3,4,5];
var sum = values.reduce(function(prev, cur, index, array){
return prev + cur;
});
alert(sum); //15
reduceRight() 的作用類似吆鹤,只不過方向相反而已。來看下面這個例子洲守。
var values = [1,2,3,4,5];
var sum = values.reduceRight(function(prev, cur, index, array){
return prev + cur;
});
alert(sum); //15
在這個例子中疑务,第一次執(zhí)行回調函數, prev 是 5梗醇, cur 是 4知允。當然,最終結果相同叙谨,因為執(zhí)行的都是簡單相加的操作温鸽。
支持這兩個歸并函數的瀏覽器有 IE9+、Firefox 3+手负、Safari 4+涤垫、Opera 10.5 和 Chrome。