2 Array類型
2.0.1 創(chuàng)建方式
- 第一種是使用
Array 構(gòu)造函數(shù)
let colors = new Array(); //創(chuàng)建一個空數(shù)組
let colors = new Array(20); //創(chuàng)建length值為20的空數(shù)組
let colors = new Array("red"); //創(chuàng)建length值為1的非空數(shù)組
let colors = Array(3); //可以省略new操作符击孩,然后情況跟new Array()使用方式相同
- 第二種基本方式是使用
數(shù)組字面量表示法
let colors = ["red", "blue", "green"]; // 創(chuàng)建一個包含3 個字符串的數(shù)組
let names = []; // 創(chuàng)建一個空數(shù)組
let values = [1,2,]; // 不要這樣!這樣會創(chuàng)建一個包含2 或3 項的數(shù)組
let options = [,,,,,]; // 不要這樣湿硝!這樣會創(chuàng)建一個包含5 或6 項的數(shù)組
具體原因說一下:因為IE8 及之前版本中的ECMAScript 實現(xiàn)在數(shù)組字面量方面存在bug速缨。IE8及更早的版本萝勤,可能會創(chuàng)建6項荤傲;在IE9+、Firefox烘绽、Opera淋昭、Safari 和Chrome 中可能會創(chuàng)建5項。在像這種省略值的情況下安接,每一項都將獲得undefined 值翔忽;這個結(jié)果與調(diào)用Array 構(gòu)造函數(shù)時傳遞項數(shù)在邏輯上是相同的。但是由于IE 的實現(xiàn)與其他瀏覽器不一致盏檐,因此我們強烈建議不要使用這種語法歇式。
2.1檢測數(shù)組
- instanceof(適用于只有一個全局作用域)
if (value instanceof Array){
//對數(shù)組執(zhí)行某些操作
};
instanceof 操作符的問題在于胡野,它假定只有一個全局執(zhí)行環(huán)境贬丛。如果網(wǎng)頁中包含多個框架,那實際上就存在兩個以上不同的全局執(zhí)行環(huán)境给涕,從而存在兩個以上不同版本的Array 構(gòu)造函數(shù)豺憔,從而產(chǎn)生錯誤檢測結(jié)果。
- Array.isArray()
if (Array.isArray(value)){
//對數(shù)組執(zhí)行某些操作
};
支持Array.isArray()方法的瀏覽器有IE9+够庙、Firefox 4+恭应、Safari 5+、Opera 10.5+和Chrome耘眨。
然后:
由于兩種方法都有各自的局限性昼榛,要在尚未實現(xiàn)這個方法中的瀏覽器中準確檢測數(shù)組,不妨采用下面提供的方法
- 使用Object.prototype上的原生toString()方法判斷數(shù)據(jù)類型
大家知道剔难,在任何值上調(diào)用Object 原生的
toString()
方法胆屿,都會返回一個
[object NativeConstructorName]
格式的字符串。每個類在內(nèi)部都有一個[[Class]]
屬性偶宫,這個屬性中就指定了上述字符串中的構(gòu)造函數(shù)名非迹。舉個例子吧。
alert(Object.prototype.toString.call(value)); //"[object Array]"
由于原生數(shù)組的構(gòu)造函數(shù)名與全局作用域無關(guān)纯趋,因此使用
toString()
就能保證返回一致的值憎兽。利用這一點冷离,可以創(chuàng)建如下函數(shù):
function isArray(value){
return Object.prototype.toString.call(value) == "[object Array]";
}
同樣,也可以基于這一思路來測試某個值是不是原生函數(shù)或正則表達式(擴展一下):
function isFunction(value){
return Object.prototype.toString.call(value) == "[object Function]";
}
function isRegExp(value){
return Object.prototype.toString.call(value) == "[object RegExp]";
}
不過要注意纯命,對于在IE 中以COM 對象形式實現(xiàn)的任何函數(shù)西剥,isFunction()都將返回false(因為它們并非原生的JavaScript 函數(shù))
這一技巧也廣泛應(yīng)用于檢測原生JSON 對象。Object 的toString()
方法不能檢測非原生構(gòu)造函數(shù)的構(gòu)造函數(shù)名亿汞。因此瞭空,開發(fā)人員定義的任何構(gòu)造函數(shù)都將返回[object Object]
。有些JavaScript 庫會包含與下面類似的代碼疗我。
let isNativeJSON = window.JSON && Object.prototype.toString.call(JSON) == "[object JSON]";
在Web 開發(fā)中能夠區(qū)分原生與非原生JavaScript 對象非常重要匙铡。只有這樣才能確切知道某個對象到底有哪些功能。這個技巧可以對任何對象給出正確的結(jié)論碍粥。
請注意鳖眼,Object.prototpye.toString()
本身也可能會被修改。本節(jié)討論的
技巧假設(shè)Object.prototpye.toString()
是未被修改過的原生版本嚼摩。
2.2轉(zhuǎn)換方法
如前所述钦讳,所有對象都具有toLocaleString()、toString()和valueOf()方法枕面。
let colors = ["red", "blue", "green"]; // 創(chuàng)建一個包含3 個字符串的數(shù)組
alert(colors.toString()); // "red,blue,green"
alert(colors.valueOf()); // [red,blue,green]
alert(colors.toLocalString()); // "red,blue,green"
alert(colors.join("||")); //"red||green||blue"
先拋出這么多愿卒,join方法還是挺有用的。
2.3棧方法 (LIFO:Last-In-First-Out潮秘,后進先出)
push方法是像數(shù)組末端添加項琼开,返回的是數(shù)組長度;pop方法返回的是取出的最后一項枕荞;
let colors = new Array(); // 創(chuàng)建一個數(shù)組
let count = colors.push("red", "green"); // 推入兩項
alert(count); //2
count = colors.push("black"); // 推入另一項
alert(count); //3
let item = colors.pop(); // 取得最后一項
alert(item); //"black"
alert(colors.length); //2
colors[colors.length] = "yellow"; // 賦值最后一項柜候,功能類似push();
alert(colors); //["red", "green", "yellow"]
2.4隊列方法 (FIFO:First-In-First-Out,先進先出)
實現(xiàn)這一操作的數(shù)組方法就是shift()躏精,它能夠移除數(shù)組中的第一個項并返回該項渣刷,同時將數(shù)組長度減1。結(jié)合使用shift()和push()方法矗烛,可以像使用隊列一樣使用數(shù)組辅柴。
let colors = new Array(); //創(chuàng)建一個數(shù)組
let count = colors.push("red", "green"); //推入兩項
alert(count); //2
count = colors.push("black"); //推入另一項
alert(count); //3
let item = colors.shift(); //取得第一項
alert(item); //"red"
alert(colors.length); //2
同時使用unshift()和pop()方法,可以從相反的方向來模擬隊列瞭吃,即在數(shù)組的前端添加項碌嘀,從數(shù)組末端移除項。
let colors = new Array(); //創(chuàng)建一個數(shù)組
let count = colors.unshift("red", "green"); //推入兩項
alert(count); //2
count = colors.unshift("black"); //推入另一項
alert(count); //3
elt item = colors.pop(); //取得最后一項
alert(item); //"green"
alert(colors.length); //2
tips:IE7 及更早版本對JavaScript 的實現(xiàn)中存在一個偏差歪架,其unshift()方法總是返回undefined 而不是數(shù)組的新長度股冗。IE8 在非兼容模式下會返回正確的長度值。
2.5 重排序方法
數(shù)組中已經(jīng)存在兩個可以直接用來重排序的方法:reverse()和sort()牡拇。
let values = [1, 2, 3, 4, 5];
values.reverse();
alert(values); //5,4,3,2,1
let values = [0, 1, 5, 10, 15];
values.sort();
alert(values); //0,1,10,15,5
對于數(shù)值類型或者其valueOf()方法會返回數(shù)值類型的對象類型魁瞪,可以使用一個更簡單的比較函數(shù)穆律。這個函數(shù)只要用第二個值減第一個值即可惠呼。
let arr = [1,5,6,8,3,6,9];
function compare(value1, value2){
return value2 - value1;
};
alert(arr.sort(compare)); //[9, 8, 6, 6, 5, 3, 1]
想要實現(xiàn)從小到大排列就用value1-value2
2.6 操作方法
concat()方法可以基于當(dāng)前數(shù)組中的所有項創(chuàng)建一個新數(shù)組导俘。具體來說,這個方法會先創(chuàng)建當(dāng)前數(shù)組一個副本剔蹋,然后將接收到的參數(shù)添加到這個副本的末尾旅薄,最后返回新構(gòu)建的數(shù)組。在沒有給concat()方法傳遞參數(shù)的情況下泣崩,它只是復(fù)制當(dāng)前數(shù)組并返回副本少梁。如果傳遞給concat()方法的是一或多個數(shù)組,則該方法會將這些數(shù)組中的每一項都添加到結(jié)果數(shù)組中矫付。如果傳遞的值不是數(shù)組凯沪,這些值就會被簡單地添加到結(jié)果數(shù)組的末尾。注意:concat()方法不會影響原始數(shù)組
let colors = ["red", "green", "blue"];
let colors2 = colors.concat("blue", ["red", "brown"]);
alert(colors); //red,green,blue
alert(colors2); //red,green,blue,blue,red,brown
下一個方法是slice()买优,它能夠基于當(dāng)前數(shù)組中的一或多個項創(chuàng)建一個新數(shù)組妨马。slice()方法可以接受一或兩個參數(shù),即要返回項的起始和結(jié)束位置杀赢。在只有一個參數(shù)的情況下烘跺,slice()方法返回從該參數(shù)指定位置開始到當(dāng)前數(shù)組末尾的所有項。如果有兩個參數(shù)脂崔,該方法返回起始和結(jié)束位置之間的項——但不包括結(jié)束位置的項滤淳。注意,slice()方法不會影響原始數(shù)組砌左。
let colors = ["red", "green", "blue", "yellow", "purple"];
let colors2 = colors.slice(1);
let colors3 = colors.slice(1,4);
alert(colors2); //green,blue,yellow,purple
alert(colors3); //green,blue,yellow
splice()方法脖咐,這個方法恐怕要算是最強大的數(shù)組方法了,它有很多種用法汇歹。
splice()的主要用途是向數(shù)組的中部插入項文搂,但使用這種方法的方式則有如下3 種。
- 刪除:可以刪除任意數(shù)量的項秤朗,只需指定2 個參數(shù):要刪除的第一項的位置和要刪除的項數(shù)煤蹭。
例如,splice(0,2)會刪除數(shù)組中的前兩項取视。
- 插入:可以向指定位置插入任意數(shù)量的項硝皂,只需提供3 個參數(shù):起始位置、0(要刪除的項數(shù))和要插入的項作谭。如果要插入多個項稽物,可以再傳入第四、第五折欠,以至任意多個項贝或。
例如吼过,splice(2,0,"red","green")會從當(dāng)前數(shù)組的位置2 開始插入字符串"red"和"green"。
- 替換:可以向指定位置插入任意數(shù)量的項咪奖,且同時刪除任意數(shù)量的項盗忱,只需指定3 個參數(shù):起始位置、要刪除的項數(shù)和要插入的任意數(shù)量的項羊赵。插入的項數(shù)不必與刪除的項數(shù)相等趟佃。
例如,splice (2,1,"red","green")會刪除當(dāng)前數(shù)組位置2 的項昧捷,然后再從位置2 開始插入字符串"red"和"green"闲昭。
splice()方法始終都會返回一個數(shù)組,該數(shù)組中包含從原始數(shù)組中刪除的項(如果沒有刪除任何項靡挥,則返回一個空數(shù)組)而且修改的其實就是原數(shù)組序矩,所以會影響原數(shù)組。
let colors = ["red", "green", "blue"];
let removed = colors.splice(0,1); // 刪除第一項
alert(colors); // green,blue
alert(removed); // red跋破,返回的數(shù)組中只包含一項
removed = colors.splice(1, 0, "yellow", "orange"); // 從位置1 開始插入兩項
alert(colors); // green,yellow,orange,blue
alert(removed); // 返回的是一個空數(shù)組
removed = colors.splice(1, 1, "red", "purple"); // 插入兩項簸淀,刪除一項
alert(colors); // green,red,purple,orange,blue
alert(removed); // yellow,返回的數(shù)組中只包含一項
2.7 位置方法
indexOf()和lastIndexOf()幔烛。這兩個方法都接收兩個參數(shù):要查找的項和(可選的)表示查找起點位置的索引啃擦。其中,indexOf()方法從數(shù)組的開頭(位置0)開始向后查找饿悬,lastIndexOf()方法則從數(shù)組的末尾開始向前查找令蛉。
這兩個方法都返回要查找的項在數(shù)組中的位置,或者在沒找到的情況下返回-1狡恬。在比較第一個參數(shù)與數(shù)組中的每一項時珠叔,會使用全等操作符;也就是說弟劲,要求查找的項必須嚴格相等(就像使用===一樣)祷安。
let 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()方法查找特定項在數(shù)組中的位置非常簡單,支持它們的瀏覽器包括IE9+兔乞、Firefox 2+汇鞭、Safari 3+、Opera 9.5+和Chrome庸追。
2.8 迭代方法
數(shù)組定義了5 個迭代方法霍骄。每個方法都接收兩個參數(shù):要在每一項上運行的函數(shù)和(可選的)運行該函數(shù)的作用域?qū)ο蟆绊憈his 的值。傳入這些方法中的函數(shù)會接收三個參數(shù):數(shù)組項的值淡溯、該項在數(shù)組中的位置和數(shù)組對象本身读整。根據(jù)使用的方法不同,這個函數(shù)執(zhí)行后的返回值可能會也可能不會影響方法的返回值咱娶。
- every():對數(shù)組中的每一項運行給定函數(shù)米间,如果該函數(shù)對每一項都返回true强品,則返回true。
- filter():對數(shù)組中的每一項運行給定函數(shù)屈糊,返回該函數(shù)會返回true 的項組成的數(shù)組的榛。
- forEach():對數(shù)組中的每一項運行給定函數(shù)。這個方法沒有返回值另玖。
- map():對數(shù)組中的每一項運行給定函數(shù)困曙,返回每次函數(shù)調(diào)用的結(jié)果組成的數(shù)組表伦。
- some():對數(shù)組中的每一項運行給定函數(shù)谦去,如果該函數(shù)對任一項返回true,則返回true蹦哼。
以上方法都不會修改數(shù)組中的包含的值鳄哭。
在這些方法中,最相似的是every()和some()纲熏,它們都用于查詢數(shù)組中的項是否滿足某個條件妆丘。對every()來說,傳入的函數(shù)必須對每一項都返回true局劲,這個方法才返回true勺拣;否則,它就返回false鱼填。而some()方法則是只要傳入的函數(shù)對數(shù)組中的某一項返回true药有,就會返回true。
- 最后一個方法是forEach()苹丸,它只是對數(shù)組中的每一項運行傳入的函數(shù)愤惰。這個方法沒有返回值,本質(zhì)上與使用for 循環(huán)迭代數(shù)組一樣赘理。
let numbers = [1,2,3,4,5,4,3,2,1];
numbers.forEach(function(item, index, array){
//執(zhí)行某些操作
});
這些數(shù)組方法通過執(zhí)行不同的操作宦言,可以大大方便處理數(shù)組的任務(wù)。支持這些迭代方法的瀏覽器有IE9+商模、Firefox 2+奠旺、Safari 3+、Opera 9.5+和Chrome施流。
2.9 歸并方法
ECMAScript 5 還新增了兩個歸并數(shù)組的方法:reduce()和reduceRight()响疚。這兩個方法都會迭代數(shù)組的所有項,然后構(gòu)建一個最終返回的值嫂沉。其中稽寒,reduce()方法從數(shù)組的第一項開始,逐個遍歷到最后趟章。而reduceRight()則從數(shù)組的最后一項開始杏糙,向前遍歷到第一項慎王。
這兩個方法都接收兩個參數(shù):一個在每一項上調(diào)用的函數(shù)和(可選的)作為歸并基礎(chǔ)的初始值。傳給reduce()和reduceRight()的函數(shù)接收4 個參數(shù):前一個值宏侍、當(dāng)前值赖淤、項的索引和數(shù)組對象。這個函數(shù)返回的任何值都會作為第一個參數(shù)自動傳給下一項谅河。第一次迭代發(fā)生在數(shù)組的第二項上咱旱,因此第一個參數(shù)是數(shù)組的第一項,第二個參數(shù)就是數(shù)組的第二項
绷耍。
使用reduce()方法可以執(zhí)行求數(shù)組中所有值之和的操作吐限,比如:
let values = [1,2,3,4,5];
let sum = values.reduce(function(prev, cur, index, array){
return prev + cur;
});
alert(sum); //15
第一次執(zhí)行回調(diào)函數(shù),prev 是1褂始,cur 是2诸典。第二次,prev 是3(1 加2 的結(jié)果)崎苗,cur 是3(數(shù)組的第三項)狐粱。這個過程會持續(xù)到把數(shù)組中的每一項都訪問一遍,最后返回結(jié)果胆数。reduceRight()的作用類似肌蜻,只不過方向相反而已。
支持這兩個歸并函數(shù)的瀏覽器有IE9+必尼、Firefox 3+蒋搜、Safari 4+、Opera 10.5 和Chrome胰伍。