數(shù)組的基本理解及規(guī)則
本質(zhì)上少梁,數(shù)組屬于一種特殊的對象。typeof運(yùn)算符會返回數(shù)組的類型是object悬赏。
typeof [1, 2, 3] // "object"
數(shù)組的特殊性體現(xiàn)在丐吓,它的鍵名是按次序排列的一組整數(shù)(0,1柿汛,2…)冗酿。
var arr = ['a', 'b', 'c'];
Object.keys(arr)
// ["0", "1", "2"]
JavaScript語言規(guī)定,對象的鍵名一律為字符串络断,所以裁替,數(shù)組的鍵名其實(shí)也是字符串。之所以可以用數(shù)值讀取貌笨,是因?yàn)榉亲址逆I名會被轉(zhuǎn)為字符串弱判。
var arr = ['a', 'b', 'c'];
arr['0'] // 'a'
arr[0] // 'a'
需要注意的是,這一條在賦值時也成立锥惋。如果一個值可以被轉(zhuǎn)換為整數(shù)昌腰,則以該值為鍵名,等于以對應(yīng)的整數(shù)為鍵名净刮。
var a = [];
a['1000'] = 'abc';
a[1000] // 'abc'
a[1.00] = 6;
a[1] // 6
之前說過對象有兩種讀取成員的方法:“點(diǎn)”結(jié)構(gòu)(object.key)和方括號結(jié)構(gòu)(object[key])剥哑。但是,對于數(shù)值的鍵名淹父,不能使用點(diǎn)結(jié)構(gòu)株婴。
var arr = [1, 2, 3];
arr.0 // SyntaxError
上面代碼中,arr.0的寫法不合法暑认,因?yàn)閱为?dú)的數(shù)值不能作為標(biāo)識符(identifier)困介。所以,數(shù)組成員只能用方括號arr[0]表示(方括號是運(yùn)算符蘸际,可以接受數(shù)值)座哩。
length屬性
數(shù)組的length屬性,返回數(shù)組的成員數(shù)量粮彤。
['a', 'b', 'c'].length // 3
length屬性是可寫的根穷。如果人為設(shè)置一個小于當(dāng)前成員個數(shù)的值姜骡,該數(shù)組的成員會自動減少到length設(shè)置的值。
var arr = [ 'a', 'b', 'c' ];
arr.length // 3
arr.length = 2;
arr // ["a", "b"]
上面代碼表示屿良,當(dāng)數(shù)組的length屬性設(shè)為2(即最大的整數(shù)鍵只能是1)那么整數(shù)鍵2(值為c)就已經(jīng)不在數(shù)組中了圈澈,被自動刪除了。
將數(shù)組清空的一個有效方法尘惧,就是將length屬性設(shè)為0康栈。
如果人為設(shè)置length大于當(dāng)前元素個數(shù),則數(shù)組的成員數(shù)量會增加到這個值喷橙,新增的位置都是空位啥么。
值得注意的是,由于數(shù)組本質(zhì)上是對象的一種贰逾,所以我們可以為數(shù)組添加屬性悬荣,但是這不影響length屬性的值。
var a = [];
a['p'] = 'abc';
a.length // 0
a[2.1] = 'abc';
a.length // 0
數(shù)組的遍歷
for...in循環(huán)不僅可以遍歷對象似踱,也可以遍歷數(shù)組隅熙,畢竟數(shù)組只是一種特殊對象。
但是核芽,for...in不僅會遍歷數(shù)組所有的數(shù)字鍵囚戚,還會遍歷非數(shù)字鍵。
var a = [1, 2, 3];
a.foo = true;
for (var key in a) {
console.log(key);
}
// 0
// 1
// 2
// foo
上面代碼在遍歷數(shù)組時轧简,也遍歷到了非整數(shù)鍵foo驰坊。所以,不推薦使用for...in遍歷數(shù)組哮独。
數(shù)組的遍歷可以考慮使用for循環(huán)或while循環(huán)拳芙。
var a = [1, 2, 3];
// for循環(huán)
for(var i = 0; i < a.length; i++) {
console.log(a[i]);
}
// while循環(huán)
var i = 0;
while (i < a.length) {
console.log(a[i]);
i++;
}
var l = a.length;
while (l--) {
console.log(a[l]);
}
上面代碼是三種遍歷數(shù)組的寫法。最后一種寫法是逆向遍歷皮璧,即從最后一個元素向第一個元素遍歷舟扎。
數(shù)組常用方法
- 元素添加/刪除
// 直接使用索引
var a=new Array(1,2,3);
a[3]=4;
console.log(a);//[1, 2, 3, 4]
// 棧方法(length屬性自動變化)
var a = new Array(1,2,3);
a.push(4);
console.log(a);//[1, 2, 3, 4]
console.log(a.length);//4
console.log(a.pop());//4
console.log(a); //[1, 2, 3]
console.log(a.length);//3
// 隊(duì)列方法(length屬性自動變化)
var a=new Array(1,2,3);
a.unshift(4);
console.log(a);//[4, 1, 2, 3]
console.log(a.length);//4
console.log(a.shift());//4
console.log(a); //[1, 2, 3]
console.log(a.length);//3
除此之外我們還有一位全能選手-splice
方法,方法有三個參數(shù):
1.開始索引
2.刪除元素的位移
3.插入的新元素悴务,當(dāng)然也可以寫多個
splice方法返回一個由刪除元素組成的新數(shù)組睹限,沒有刪除則返回空數(shù)組
// 刪除
var a = new Array(1,2,3,4,5);
console.log(a.splice(1,3));//[2, 3, 4]
console.log(a.length);//2
console.log(a);//[1,5]
//插入與替換
var a = [1,2,3,4,5];
a.splice(1,0,9,99,999);
console.log(a.length); //8
console.log(a);//[1, 9, 99, 999, 2, 3, 4, 5]
a.splice(1,3,8,88,888);
console.log(a.length);//8
console.log(a);//[1, 8, 88, 888, 2, 3, 4, 5]
- 常用操作
join(char)
這個方法在C#等語言中也有,作用是把數(shù)組元素(對象調(diào)用其toString()方法)使用參數(shù)作為連接符連接成一字符串讯檐,不會修改原數(shù)組內(nèi)容
var a = [1,2,3,4,5];
console.log(a.join(',')); //1,2,3,4,5
console.log(a.join(' ')); //1 2 3 4 5
slice(start,end)
slice方法用于返回數(shù)組中一個片段或子數(shù)組羡疗,如果只寫一個參數(shù)返回參數(shù)到數(shù)組結(jié)束部分,如果參數(shù)出現(xiàn)負(fù)數(shù)别洪,則從數(shù)組尾部計數(shù)(-3意思是數(shù)組倒第三個)叨恨,如果start大于end返回空數(shù)組。
slice不會改變原數(shù)組挖垛,而是返回一個新的數(shù)組痒钝。
var a = [1,2,3,4,5];
console.log(a); //[1, 2, 3, 4, 5]
console.log(a.slice(1,2));//2
console.log(a.slice(1,-1));//[2, 3, 4]
console.log(a.slice(3,2));//[]
console.log(a); //[1, 2, 3, 4, 5]
concat(array)
concat方法用于拼接數(shù)組秉颗,a.concat(b)返回一個a和b共同組成的新數(shù)組,同樣不會修改任何一個原始數(shù)組午乓,也不會遞歸連接數(shù)組內(nèi)部數(shù)組
var a = [1,2,3,4,5];
var b = [6,7,8,9];
console.log(a.concat(b));//[1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(a); //[1, 2, 3, 4, 5]
console.log(b); //[6, 7, 8, 9]
reverse()
方法用于將數(shù)組逆序站宗,與之前不同的是它會修改原數(shù)組
var a = [1,2,3,4,5];
a.reverse();
console.log(a); //[5, 4, 3, 2, 1]
sort
sort方法用于對數(shù)組進(jìn)行排序闸准,當(dāng)沒有參數(shù)的時候會按字母表升序排序益愈,如果含有undefined會被排到最后面,對象元素則會調(diào)用其toString方法夷家,如果想按照自己定義方式排序蒸其,可以傳一個排序方法進(jìn)去,很典型的策略模式库快,同樣sort會改變原數(shù)組摸袁。
var a=[5,4,3,2,1];
a.sort();
console.log(a);//[1, 2, 3, 4, 5]
但如果出現(xiàn)10、11等以1開頭的多位數(shù)會排序出錯义屏,所以我們可以傳入自定義排序函數(shù)
var a = [7,8,9,10,11];
a.sort(function(v1,v2){
return v1-v2;
});
console.log(a);//[7, 8, 9, 10, 11]
sort內(nèi)部使用快速排序靠汁,每次比較兩個元素大小的時候如果沒有參數(shù),則直接判斷字母表闽铐,如果有參數(shù)蝶怔,則把正在比較的兩個參數(shù)傳入自定義方法并調(diào)用(正在比較的兩個數(shù)會傳給自定義方法的v1、v2)兄墅,如果返回值大于0表示v1 > v2踢星,如果等于0,表示v1 = v2隙咸,如果小于0沐悦,表示v1 < v2,其實(shí)我們傳入的方法就是告訴sort怎么比較兩個元素誰大誰小