探索JavaScript陣列奧祕
一 概述
JavaScript陣列同後端語言一樣,具有它自己的資料結構,歸根結底,這種資料結構,本質就是一種集合。
在後端語言中(如java,.net等),陣列是這樣定義的:陣列是用來儲存相同資料型別的集合。這個定義,“相同資料型別”6個字限制了資料只能儲存相同的資料型別,如int[]陣列只能儲存數字,而不能儲存字串,如下定義方式,是錯誤的,因為string不屬於整型
int[] arr = { 10, 20,"string" };
然而,在JavaScript中,陣列的定義卻是非常寬鬆的,這也決定了其能儲存一切資料的特點。JavaScript陣列具有如下特點
特點1:儲存相同基本資料型別的資料;
特點2:儲存不同基本資料型別的資料;
特點3:儲存物件
這三個特點,我們可歸結為一句話:JavaScript儲存一切物件,而不像後端語言那樣,只能儲存相同資料型別。除此之外,JavaScript陣列還提供了很多豐富的操作方法。如下為常用的操作方法。
本篇文章將主要結合程式碼來論述JavaScript陣列。
二 對陣列的基本操作
(一)建立陣列
第一種方式:建構函式方式
//第一種建立陣列的方式:建構函式方式 var colors = new Array();//未知陣列長度 //var colors = new Array(4);//已知陣列長度 //var colors = new Array('green', 'yellow', 'white', 'red');//建立陣列同時,給陣列賦值 //var colors = Array();//在建立時,可以省略new關鍵字
第二種方式:字面量方式
//第二種建立陣列方式:使用陣列字面量
var colors = ['green', 'yellow', 'white', 'red'];
var name = [];//建立空陣列
(二)訪問陣列
訪問陣列,通過陣列的下標來訪問
//建立陣列 var colors = ['green', 'yellow', 'white', 'red']; //輸出索引值 for (var i = 0; i < colors.length; i++) { alert(colors[i]);//green,yellow,white,red }
提示:for...in...訪問陣列屬性(索引),而不是陣列屬性值
//建立陣列
var colors = ['green', 'yellow', 'white', 'red'];
//輸出陣列索引
for (var propAttr in colors) {
alert(propAttr);//0,1,2,3
}
(三)為陣列新增元素
第一種方式:棧方式(後進先出,從陣列尾部加入資料)
//建立陣列
var colors = ['green', 'yellow', 'white', 'red'];
//第一種方式:棧方式
colors.push("orange");
for (var i = 0; i < colors.length; i++) {
alert(colors[i]);//green,yellow,white,red,orange
}
第二種方式:佇列方式(先進先出,從陣列頭部加入資料)
var colors = ['green', 'yellow', 'white', 'red'];
colors.unshift('orange');
for (var i = 0; i < colors.length; i++) {
alert(colors[i]);//orange,green,yellow,white,red
}
(四)移除陣列元素
第一種方式:棧方式(後進先出,從陣列尾部移除資料)
//建立陣列
var colors = ['green', 'yellow', 'white', 'red'];
//從尾部彈出資料
colors.pop();
for (var i = 0; i < colors.length; i++) {
alert(colors[i]);//green,yellow,white
}
第二種方式:佇列方式(先進先出,從資料頭部移除資料)
//建立陣列
var colors = ['green', 'yellow', 'white', 'red'];
//從頭部移除資料
colors.shift();
for (var i = 0; i < colors.length; i++) {
alert(colors[i]);//yellow,white,red
}
第三種方式:length方式(藉助length屬性可訪問性來操作)
//建立陣列
var colors = ['green', 'yellow', 'white', 'red'];
//從尾部移除資料,與pop()一樣
colors.length = 3;
for (var i = 0; i < colors.length; i++) {
alert(colors[i]);//green,yellow,white
}
三 陣列方法
(一)檢測方法
陣列檢測方式,可通過typeof,instranceof和Array.isArray()來檢測。
(二)轉換方法
所有物件都具有toLocaleString(),toString()和valueOf()三個方法,陣列也如此。
1.toString()
toString()將資料的每個屬性值轉化為對應的字串,然後再輸出轉換後的字串值。
var colors = ['red','green','yellow'];
alert(colors.toString());//red,green,yellow
而下列程式碼與如上程式碼是一樣的,因為alert()接收的是字串,所以會在後臺呼叫toString()方法
var colors = ['red','green','yellow'];
alert(colors);//red,green,yellow
2.valueOf()
valueOf()方法同toString()方法一樣,也是返回陣列的字串
var colors = ['red', 'green', 'yellow'];
alert(colors.valueOf());//red,green,yellow
3.toLocaleString()
toLocaleString()返回陣列的字串形式。
var colors = ['red', 'green', 'yellow'];
alert(colors.toLocaleString());//red,green,yellow
4 三者之間關係
關係1:當不顯示指出呼叫哪個方法時(toString(),toLocaleString()和valueOf()),預設呼叫每個屬性的toString();
關係2:當顯示地指出呼叫哪個方法時,就呼叫每個屬性的該方法;
關係3:關於valueOf問題,暫留
var person1 = {
toString: function () {
return "Alan";
},
toLocaleString: function () {
return "Alan_beijing";
},
valueOf: function () {
return "valueOf1";
}
};
var person2 = {
toString: function () {
return "Alan1";
},
toLocaleString: function () {
return "Alan_beijing1";
}
}
var people = [person1, person2];
alert(people.toString());//Alan,Alan1
alert(people.toLocaleString());//Alan_beijing,Alan_beijing1
alert(people.valueOf());//Alan,Alan1
alert(people);//Alan,Alan1
(三)棧方法
棧是一種資料結構,其演算法為:LIFO(Last input First out)後進先出,其兩個核心方法為push()和pop();
1.push()
push()表示將資料壓入棧中,且放在棧的最後位置,即從棧的尾部壓入資料。對於陣列,則在陣列的尾部加入資料,操作的順序為:先把陣列length+1,再壓入資料。
var arr = [10, 20, 30];
arr.push('新加入的資料');
alert(arr.toString());//10,20,30,新加入的資料
2.pop()
push()表示將資料從棧中彈出,且從棧的最後位置彈出。對於陣列,則在陣列的尾部彈出資料,操作的順序為:先彈出資料,再陣列length-1
var arr = [10, 20, 30];
arr.pop();
alert(arr.toString());//10,20
(四)佇列
佇列是一種資料結構,其演算法為:FIFO(First input First out)後進先出,其兩個核心方法為unshift()()和shift();
1.unshift()
unshift()表示從佇列頭部加入資料。對於陣列,則從陣列索引最小位置加入資料,操作順序為:先將數length+1,再將當前陣列屬性值往後移動1個位置,最後將新資料新增到索引0處。
var arr = [10, 20, 30];
arr.unshift(40);
alert(arr.toString());//40,10,20,30
2.shift()
shift()表示從佇列頭部移除資料。對於陣列,則從陣列索引最小位置移除資料。
var arr = [20, 30];
arr.shift();
alert(arr.toString());//30
(五)排序方法
在js陣列中,兩個重要的重排序方法:reverse()和sort()
1.reverse()
reverse(),顧名思義,逆序方法。
var arr = [1,2,3,4,5];
alert(arr.reverse());//5,4,3,2,1
2.sort()
sort()是比較靈活的排序方法了,支援自定義排序規則,預設排序為升序
預設為升序
var arr = [3, 1, 2, 5, 4];
alert(arr.sort());//1,2,3,4,5
自定義排序規則
var arr = [3, 1, 2, 5, 4];
alert(arr.sort(Compare));//1,2,3,4,5
//自定義排序規則:正序
function Compare(value1, value2) {
if (value1 > value2) {
return 1;
} else if (value1 < value2) {
return -1;
} else {
return 0;
}
}
(六)位置方法
js陣列提供了兩個位置方法:indexof()和lastIndexOf()
indexOf()表示首次滿足條件的位置;而lastIndexOf()則表示最後滿足條件的位置
var arr = [20, 30,20,40,10];
alert(arr.indexOf(20)); //0
alert(arr.lastIndexOf(20));//2
(七)迭代方法
ECMAScript5提供了5個迭代方法:every(),filter(),forEach(),map()和some()
這個五個方法,均接收2個引數。
1.every()
對陣列中的每項執行給定函式,如果該函式對每一項都返回ture,則返回true,否則返回false.
//every
var num = [1, 2, 3, 4, 5, 4, 3, 2, 1];
var everyResult = num.every(function (item, index,array) {
return item>2
});
alert(everyResult);//fasle
2.some
對陣列中的每項執行給定函式,如果該函式對任意一項返回ture,則返回true,否則返回false
//some
var num = [1, 2, 3, 4, 5, 4, 3, 2, 1];
var someResult = num.some(function (item, index, array) {
return item > 2;
});
alert(someResult);//true
3.filter
對陣列中的每項執行給定函式,返回該函式會返回true的項組成的陣列
//filter
var num = [1, 2, 3, 4, 5, 4, 3, 2, 1];
var filterResult = num.filter(function (item, index, array) {
return item > 2;
});
alert(filterResult);//3,4,5,4,3
4.map
對陣列中的每項執行給定函式,返回每次函式呼叫的結果組成的陣列
//map
var num = [1, 2, 3, 4, 5, 4, 3, 2, 1];
var mapResult = num.map(function (item, index, array) {
return item * 2;
});
alert(mapResult);//2,4,6,8,10,8,6,4,2
5.forEach
對陣列中的每項執行給定函式。注意,該方法沒返回值
//forEach
num.forEach(function (item, index, array) {
//執行想要執行的操作
});
(八)求和方法
ECMAScript提供了2個縮減方法:reduce()和reduceRight()
reduce和reduceRight,相當於.net的斐波拉列數列,計算演算法為:f(n)=f(n-1)+f(n-2);
1.reduce
reduce計算陣列時,按照從左到右的順序
var values = [1, 2, 3, 4, 5];
var sum = values.reduce(function (prev, cur, index, array) {
return prev + cur;
});
alert(sum);//15
2.reduceRight
reduceTight計算陣列時,從右到左順序
var values = [1, 2, 3, 4, 5];
var sum1 = values.reduceRight(function (prev, cur, index, array) {
return prev + cur;
});
alert(sum1);//15
(九)其他方法
ECMAScript為陣列操作提供了很多方法,如concat()和slice()
1.concat()
concat()方法是將兩個物件合併,從而生成新物件,合併同時,不會改變原來物件的值,只是做簡單的拷貝
var color1 = ['red', 'green', 'yellow'];
var color2 = ['white', 'blue'];
//新增陣列
var concatColor = color1.concat(color2);
alert(concatColor);//red,green,yellow,white,blue
//新增單個值
var concatSingelColor = color1.concat('orange');
alert(concatSingelColor);//red,green,yellow,orange
//不新增值,只是簡單copy
var concatColor1 = color1.concat();
alert(concatColor1);//red,green,yellow
2.slice
slice()方法用於從目標資料中擷取新資料,不會改變被擷取物件的值。
var color1 = ['red', 'green', 'yellow'];
//不傳遞引數:表示擷取整個陣列
var color2 = color1.slice();
alert(color2);//red,green,yellow
//傳遞一個引數:表示從該位置處開始擷取資料,直到陣列最後一個數
var color3 = color1.slice(1);
alert(color3);//green,yellow
//傳遞2個引數:第一個引數表示從該位置開始擷取,第二個引數減1表示所截資料的最後位置
var color4 = color1.slice(1, color1.length);
alert(color4);//green,yellow
四 參考文獻
【01】JavaScript 高階程式設計(第三版) (美)Nicholas C.Zakas 著 李鬆峰 曹力 譯
【02】JavaScript 權威指南 (第6版) David Flanagan 著