js引用類型2:Array類型

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胰伍。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末齿诞,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子骂租,更是在濱河造成了極大的恐慌祷杈,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件渗饮,死亡現(xiàn)場離奇詭異但汞,居然都是意外死亡,警方通過查閱死者的電腦和手機互站,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門私蕾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人胡桃,你說我怎么就攤上這事踩叭。” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵容贝,是天一觀的道長自脯。 經(jīng)常有香客問我,道長斤富,這世上最難降的妖魔是什么膏潮? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮满力,結(jié)果婚禮上焕参,老公的妹妹穿的比我還像新娘。我一直安慰自己油额,他們只是感情好叠纷,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著悔耘,像睡著了一般讲岁。 火紅的嫁衣襯著肌膚如雪我擂。 梳的紋絲不亂的頭發(fā)上衬以,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音校摩,去河邊找鬼看峻。 笑死,一個胖子當(dāng)著我的面吹牛衙吩,可吹牛的內(nèi)容都是我干的互妓。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼坤塞,長吁一口氣:“原來是場噩夢啊……” “哼冯勉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起摹芙,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤灼狰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后浮禾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體交胚,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年盈电,在試婚紗的時候發(fā)現(xiàn)自己被綠了蝴簇。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡匆帚,死狀恐怖熬词,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤互拾,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布均践,位于F島的核電站,受9級特大地震影響摩幔,放射性物質(zhì)發(fā)生泄漏彤委。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一或衡、第九天 我趴在偏房一處隱蔽的房頂上張望焦影。 院中可真熱鬧,春花似錦封断、人聲如沸斯辰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽彬呻。三九已至,卻和暖如春柄瑰,著一層夾襖步出監(jiān)牢的瞬間闸氮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工教沾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蒲跨,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓授翻,卻偏偏與公主長得像或悲,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子堪唐,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344