typora-copy-images-to: media 數組 一、概念 對象中可以通過鍵值對存儲多個數據,且數據的類型是沒有限制的,所以通常會存儲一個商品的信息或一個人的信息: var obj = { goodsname:"手機", price:"5000", introduce:"手機很時尚,很 ...
typora-copy-images-to: media
數組
一、概念
對象中可以通過鍵值對存儲多個數據,且數據的類型是沒有限制的,所以通常會存儲一個商品的信息或一個人的信息:
var obj = {
goodsname:"手機",
price:"5000",
introduce:"手機很時尚,很漂亮!"
}
var person = {
name:"張三",
age:12,
sex:"男"
}
但對象在存儲同類型數據的時候比較困難,例如,存儲一個班級所以人的姓名:
var obj = {
name1:"張三",
name2:"李四",
name3:"王五",
...
}
這種存儲方式我們沒有辦法通過一個人的姓名獲取到這個人的編號,也沒有辦法通過一個編號獲取到某個人的姓名。
js提供了另外一種對象類型的數據,可以通過編號來存儲數據:數組。也是對象3種表現形式中的另外一種,[]
定義的對象。
二、數組定義
var arr = []
這是一個空數組,定義帶數據的數組:
var arr = ['張三','李四','王五','趙六']
輸出結果:
數組中的數據類型沒有限制,在實際項目中,數組中通常會存儲同一類型的數據。
var arr = ['a',2,false,undefined,{name:"張三"}];
數組這種數據,相當於在一個大空間中,有很多小空間,每個值前面的數字,表示這個小空間的編號,專業術語叫下標。第一個下標永遠是0,依次向後遞增,最後一個下標是值的個數-1
也就是說,數組這種數據中每個值是有順序的。
js還提供了一個構造函數,用來創建數組:
var arr = new Array("張三","李四","王五")
這兩種方式定義的數據是一樣的。
有一種情況,這兩種定義方式是不一樣的:
var arr = [5]
var brr = new Array(5)
console.log(arr,brr)
[]
形式定義的是一個數組中有一個小空間,其中的值是5;構造函數方式定義的,表示有5個空的小空間。
數組的規律:
第一個值的下標永遠是0;
最後一個值的下標永遠是值的個數-1。
三、數組基本操作
數組中值的個數:數組.length
var arr = ['張三',"李四","王五","趙六"];
var arr1 = [1,2,3,4,5,6];
console.log(arr.length); // 4
console.log(arr1.length); // 6
訪問數組中的元素:數組[下標]
例:
var arr = ["張三","李四","王五"];
console.log(arr[1]); // 李四
第一個值永遠是:數組[0]
;最後一個值永遠是:數組[數組.length-1]
添加元素:數組[下標] = 值
例:
var arr = ["張三","李四"];
arr[2] = "王五";
console.log(arr); // (3) ["張三", "李四", "王五"]
arr[10] = "趙六";
console.log(arr); // (11) ["張三", "李四", "王五", empty × 7, "趙六"] 中間還有7個空元素
修改元素:數組[下標] = 值
例:
var arr = ["張三","李四"];
arr[0] = "王五";
console.log(arr); // (2) ["王五", "李四"]
使用說明:如果下標是已經存在的,那賦值操作就是修改數組元素的值,如果下標是不存在,那賦值操作就給數組添加元素。
刪除元素:delete 數組[下標]
var arr = [1,2,3];
delete arr[0];
console.log(arr)
這種刪除方式,只能刪除值,並不能刪除小空間。
數組長度的賦值:
var arr = [1,2,3];
arr.length = 0;
console.log(arr) // []
var arr = [1,2,3];
arr.length = 10;
console.log(arr)
var arr = [1,2,3];
arr.length = 1;
console.log(arr) // [1]
遍曆數組:
如果要將數組中的所有元素都輸出,操作如下:
var arr = ["張三","李四","王五","趙六"];
console.log(arr[0]); // 張三
console.log(arr[1]); // 李四
console.log(arr[2]); // 王五
console.log(arr[3]); // 趙六
從上面輸出的代碼中可以看出,多次輸出是在進行重覆動作,並且多次重覆之間是有規律可循的,所以可以使用迴圈進行這個重覆動作:
var arr = ["張三","李四","王五","趙六"];
var length = arr.length;
for(var i=0;i<length;i++){
console.log(arr[i]);
}
結果:
迴圈輸出數組中的每個值 |
---|
這種使用迴圈將數組中每個元素輸出的操作叫做數組的遍歷 - 每個元素都經歷一次
遍歷對象的for in
語法也可以遍曆數組:
var arr = ["張三","李四","王五","趙六"];
for(var i in arr){
console.log(arr[i]);
}
兩種遍歷方式有區別:
var arr = ['a','b','c'];
arr[5] = 'd'
console.log(arr);
for(var i=0;i<arr.length;i++){
console.log(arr[i]);
}
空的空間會遍歷出undefined
var arr = ['a','b','c'];
arr[5] = 'd'
console.log(arr);
for(var i in arr){
console.log(arr[i]);
}
空的空間不會被遍歷。
var arr = ['a','b','c'];
for(var i=0;i<arr.length;i++){
console.log(i);
}
下標是數字。
var arr = ['a','b','c'];
for(var i in arr){
console.log(i);
}
下標是字元串。所以for in
的語法更適合遍歷對象,為了避免不必要的錯誤,儘量不要用這種語法來遍曆數組。
四、數組練習
-
利用for迴圈求數字數組中所有元素的和
var arr = [10,20,30,40,50]; var sum = 0; for(var i = 0;i < arr.length; i++){ sum += arr[i]; } console.log(sum);
-
有一個數組,具體內容如下:
var arr = [ "越南被曝咖啡造假:咖啡粉里摻加電池芯", "抗日神劇被當教材:機密文件居然有女優名字", "王俊凱任聯合國大使:系最年輕的聯合國大使", "行人闖紅燈遭水噴 目前還在測試階段", "68條魚估價超600萬 什麼魚要這麼貴?" ]
利用迴圈使用js做出如下圖效果:
var arr = [ "越南被曝咖啡造假:咖啡粉里摻加電池芯", "抗日神劇被當教材:機密文件居然有女優名字", "王俊凱任聯合國大使:系最年輕的聯合國大使", "行人闖紅燈遭水噴 目前還在測試階段", "68條魚估價超600萬 什麼魚要這麼貴?" ]; document.write("<ul>"); for(var i=0;i<arr.length;i++){ document.write("<li>"+arr[i]+"</li>"); } document.write("</ul>")
-
求數組中的最大值
var arr = [1,9,3,6,8,5,4,7,2,12]; // 求出最大值 var length = arr.length; var max = arr[0]; for(var i=1;i<length;i++){ if(max<arr[i]){ max = arr[i]; } } console.log(max);
-
把1~100這個100個數字存到數組中
var arr = []; for(var i=1;i<=100;i++){ arr[arr.length] = i }
-
整理數組數據,模擬京東的商品列表
<script> var arr = [ { goodsImg:'https://img30.360buyimg.com/seckillcms/s140x140_jfs/t1/186995/37/12433/183771/60e7ffb3E1b78db87/c5696abfd650ef64.jpg.webp', goodsname:'榮耀暢玩20 手機 老人機 學生智能機 【咨詢加贈華為原裝Type-C線】 幻夜黑 全網通(6G+128G)', goodsoldprice:'1399', goodsnowproce:'1029' }, { goodsImg:'https://img20.360buyimg.com/seckillcms/s140x140_jfs/t1/116335/26/233/214256/5e8998c4E3b5fc871/ec122a9622175d7e.jpg.webp', goodsname:'【純銀999十二生肖七彩建盞】【配銀飾鑒定證+禮盒+禮盒袋+收藏證書】天目釉原礦鐵胎茶盞主人杯茶具茶 純手工七彩盞-蓮花純銀999', goodsoldprice:'659', goodsnowproce:'199' }, { goodsImg:'https://img12.360buyimg.com/seckillcms/s140x140_jfs/t1/182318/5/13135/123400/60e55430E14b60a71/070af11351a8de90.jpg.webp', goodsname:'風味坐標 手撕牛肉乾 400g(經典原味) 內蒙古錫林浩特特產 高蛋白休閑零食', goodsoldprice:'229', goodsnowproce:'69' }, { goodsImg:'https://img11.360buyimg.com/seckillcms/s140x140_jfs/t1/185818/10/12878/72765/60e41060Ed9ebc1a3/5fa7730180a53328.jpg.webp', goodsname:'蔬果園藍風鈴香水洗衣液除菌液母嬰可用持久留香酵素英式香氛香味洗衣液潔凈家庭組合套裝 藍風鈴2kg*3+500g*5袋+留香珠18g*2', goodsoldprice:'159', goodsnowproce:'119' }, ]; // 遍曆數組,輸出標簽 for(var i=0;i<arr.length;i++){ document.write('<li>'); document.write('<img src="' + arr[i].goodsImg + '">'); document.write('<h4>'+arr[i].goodsname+'</h4>'); document.write('<b>'+arr[i].goodsnowproce+'</b>'); document.write('<span>'+arr[i].goodsoldprice+'</span>'); document.write('</li>'); } </script> <style> li{ list-style-type: none; padding: 0; margin: 0; width: 140px; height: 190px; border:1px solid #000; float:left; margin:0 10px; } li h4{ width: 140px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 0; margin: 0; } </style>
五、基礎類型和引用類型
js中允許出現的數據:number、string、boolean、null、undefined、{}、[]、function
根據不同類型的數據存儲方式以及賦值方式的不同,我們將數據分為兩類:基本類型和引用類型。
基礎數據類型:number、string、boolean、undefined、null
引用數據類型:[]、function, {}
基礎類型和引用類型的區別:
-
存儲方式不同
基礎類型將值存在棧記憶體中;引用類型將值存在堆記憶體中,將堆記憶體的記憶體地址存在棧中。
var a = 1; var obj = {name:"張三",age:12}
-
賦值過程不同
基礎類型賦值時,將值複製給另一個變數;引用類型賦值時,將棧中的地址複製給別的變數。
var a = 1 var b = a; a = 2; console.log(b) // 2
複製值以後,修改其中一個,另一個不會受到影響。
var arr = ['a','b','c']; var brr = arr; arr[0] = 'd' console.log(brr) // ['d','b','c'];
當改變其中一個變數中的值,另一個變數中的值也會發生改變。
-
全等的比較規則不同
基礎類型全等比較的時候,比較類型和值;
var a = 1; var b = 1; console.log(a === b)
引用類型全等比較的時候比較棧中存的記憶體地址是否相同。
var arr = [1,2,3]; var brr = [1,2,3] console.log(arr === brr)
註意:直接給變數賦值,一定會將變數棧空間中內容清空,然後重新放入新數據。
六、數組方法
如何給數組的開頭添加一個元素?
var arr = ['a','b','c']
for(var i=arr.length-1;i>=0;i++){
arr[i+1] = arr[i]
}
arr[0] = 'd'
console.log(arr)
這樣操作起來比較複雜。為了方便我們對數組進行操作,js提供了一些方法,可以快速的操作數組:
-
unshift - 給數組開頭添加一個或多個元素 - 返回數組新長度
var arr = ['a','b','c']; var l = arr.unshift('d') console.log(arr) // ['d','a','b','c'] console.log(l) // 4
-
push - 給數組的末尾添加一個或多個元素 - 返回數組新長度
var arr = ['a','b','c']; var l = arr.push('d') console.log(arr) // ['a','b','c','d'] console.log(l) // 4
-
shift - 刪除數組的第一個元素 - 返回被刪掉的元素
var arr = ['a','b','c']; var ele = arr.shift() console.log(arr) // ['b','c'] console.log(ele) // 'a'
-
pop - 刪除數組最後一個元素 - 返回被刪掉的元素
var arr = ['a','b','c']; var ele = arr.pop() console.log(arr) // ['a','b'] console.log(ele) // 'c'
-
splice - 對數組做增、刪、改的操作
var arr = ['a','b','c'] // 改 - 參數1:開始下標;參數2:刪除的個數;參數3:在刪除的位置放上的新的元素 - 可以是多個 arr.splice(1,1,'d') // ['a','d','c'] // 增 arr.splice(1,0,'d') // ['a','d','b','c'] - 刪除0個,就是不刪除,然後放上新元素 // 刪 - 第三個參數可以省略 arr.splice(1,0) // ['a','c']
-
concat - 數組的拼接
var arr = ['a','b','c']; var brr = ['d','e','f']; // 將arr和brr合成一個更大的數組 var crr = arr.concat(brr) // ['a','b','c','d','e','f'] // 將一個或多個值和數組合併成一個大數組 var crr = arr.concat(1,2,3)// ['a','b','c',1,2,3]
-
sort - 數組的排序
var arr = [9,5,3,7,1,6,4,8,2]; arr.sort() // 預設升序 console.log(arr) // [1,2,3,4,5,6,7,8,9] arr.sort(function(a,b){ // a代表前面的數,b代表後面的數 return a-b; // 升序 - 如果前面的數-後面的數>0,則交換位置 return b-a; // 降序 - 如果後面的數-前面的數>0,則交換位置 })
-
reverse - 數組的反轉
var arr = ['a','b','c']; arr.reverse() console.log(arr) // ['c','b','a']
-
join - 將數組中的元素使用指定的連接符連接在一起
var arr = ['a','b','c']; var str = arr.join('_') // 參數是連接符 console.log(str) // a_b_c var str = arr.join() // 預設使用逗號連接 console.log(str) // a,b,c var str = arr.join('') console.log(str) // abc
-
slice - 截取數組
var arr = ['a','b','c','d','e','f']; // 將數組中的 'b','c','d'截取出來,組成新的數組 var brr = arr.slice(1,4) // 參數1是開始截取的下標,參數2是截取的結束下標,結果中不包含結束下標對應的元素 console.log(brr) // ['b','c','d'] // 如果省略第2個參數,預設從開始下標截取到數組末尾 var crr = arr.slice(1) console.log(crr) // ['b','c','d','e','f']
-
indexOf方法
查找某個元素在數組中第一次出現的位置
語法:
arr.indexOf(元素,[開始查找的起始下標]); # 參數1:將要查找的元素 # 參數2:可選項。從哪個下標開始往後查找 # 返回值:如果找到了,就返回這個元素在數組中的下標,如果沒有找到,就返回-1
例:
var arr = [1,3,5,7,7,5,3,1]; console.log(arr.indexOf(5)); // 2 - 查找數字5在數組中第一次出現的下標 console.log(arr.lastIndexOf(5)); // 5 - 查找數字5在數組中最後一次出現的位置 console.log(arr.indexOf(5,3)); // 5 - 從下標2開始查找數字5在數組中第一次出現的位置 console.log(arr.lastIndexOf(5,4)); // 2 - 從下標4開始查找數字5在數組中最後一次出現的下標 console.log(arr.indexOf("5")); // -1 - 數組中全是數字,找不到字元串5,所以返回-1
-
forEach方法
用於遍曆數組
語法:
arr.forEach(function(值, 下標, 當前數組){ // 代碼段 }); # 在這個方法中需要傳入一個函數參數,這個函數的參數說明如下: # 參數1:數組遍歷出來的每個值 # 參數2:可選項。數組遍歷出來的每個值對應的下標 # 參數3:可選項。被遍歷的當前數組
例:
var arr = [1, 2, 3, 4, 5]; arr.forEach(function(x, index, a){ console.log(x + '|' + index + '|' + (a === arr)); }); // 輸出為: // 1|0|true // 2|1|true // 3|2|true // 4|3|true // 5|4|true
使用說明:
這個方法沒有返回值,返回值為undefined,不會改變原來數組的值。
-
map方法
遍曆數組,並將每個元素經過函數處理後,形成新的元素,所有新元素組成新數組返回
語法:
arr.map(function(值,下標,當前數組){ return 新的值 - 通常新的值是由舊的值處理以後得到 });
例:
var arr = [1, 2, 3, 4, 5]; var arr2 = arr.map(function(item){ return item*item; }); console.log(arr2); //[1, 4, 9, 16, 25]
使用說明:
這個方法主要用於以同樣的規則處理數組中的每個值,並組成新的數組返回
-
filter方法
將數組中滿足指定條件的值,組成新的數組返回
語法:
arr.filter(function(值, 下標, 當前數組){ return 篩選條件 });
例:
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; var arr2 = arr.filter(function(v, index) { return v>5 }); console.log(arr2); //[6, 7, 8, 9, 10]
使用說明:
使用方法和功能跟map方法很像,只是運行規則不一樣。map方法中的函數,用於返回新的元素,而filter方法中的函數,根據返回true或false來篩選元素
-
reduce方法
用於數組求和
語法:
arr.reduce(function(a, b){ return a + b });
其中a第一次的時候,表示第一個元素,第二次開始表示上一次返回的數據,b第一次表示第二個元素,第二個開始表示第三個元素、第四個元素。。。
-
some - 判斷數組中是否至少有一個元素是滿足指定條件的,返回布爾值
語法:
布爾值 = 數組.some(function(v,i,a){ return 條件; }) // 上面的i和a是可選參數
例:判斷所有成績中是否有不及格的成績
var arr = [68,95,78,56,86,63]; var bool = arr.some(function(v,i,a){ return v<60; }); console.log(bool); // true
some內置的原理,遍曆數組,判斷每個值是否滿足條件,有滿足的就返回true,並break迴圈,遍歷完以後都沒有一個是滿足的,返回false
var arr = [68,95,78,56,86,63]; var k = 0 var bool = arr.some(function(v,i,a){ k++ return v<60; }); console.log(bool); // true console.log(k); // 4 var arr = [68,95,78,66,86,63]; var k = 0 var bool = arr.some(function(v,i,a){ k++ return v<60; }); console.log(bool); // false console.log(k); // 6
-
every - 判斷數組中是否所有元素都滿足指定的條件,返回布爾值
語法:
布爾值 = 數組.every(function(){ return 條件 }) // 上面的i和a是可選參數
例:判斷是否所有成績都及格了
var arr = [68,95,78,56,86,63]; var bool = arr.some(function(v,i,a){ return v>60; }); console.log(bool); // false
every內置的原理,遍曆數組,判斷每個值是否滿足條件,有不滿足的就返回false,並break迴圈,遍歷完以後都滿足,返回true
var arr = [68,95,78,56,86,63]; var k = 0 var bool = arr.every(function(v,i,a){ k++ return v>60; }); console.log(bool); // false console.log(k); // 4 var arr = [68,95,78,66,86,63]; var k = 0 var bool = arr.every(function(v,i,a){ k++ return v>60; }); console.log(bool); // true console.log(k); // 6
-
find - 查找數組中第一個滿足指定條件的值,找到返回值,找不到返回undefined
語法:
值 = 數組.find(function(v,i,a){ return 條件 }) // 上面的i和a是可選參數
例:找出所有成績中第一個不及格的成績
var arr = [68,95,78,56,86,63]; var ele = arr.find(function(v,i,a){ return v<60 }) console.log(ele); // 56
find的原理,遍曆數組,判斷每個元素是否滿足條件,滿足就返回這個元素,並break迴圈,如果遍歷完了都沒有滿足條件的,就返回undefined
var arr = [68,95,78,56,55,86,63]; var k = 0 var ele = arr.find(function(v,i,a){ k++ return v<60; }); console.log(ele); // 56 console.log(k); // 4 var arr = [68,95,78,66,86,63]; var k = 0 var ele = arr.find(function(v,i,a){ k++ return v<60; }); console.log(ele); // undefined console.log(k); // 6
-
findIndex - 查找數組中滿足條件的第一個對應的下標,找到返回下標,找不到返回-1
語法:
下標 = 數組.findIndex(function(v,i,a){ return 條件 }) // 上面的i和a是可選參數
例:找出所有成績中第一個不及格的成績的下標
var arr = [68,95,78,56,86,63]; var index = arr.find(function(v,i,a){ return v<60 }) console.log(index); // 3
findIndex的原理,遍曆數組,判斷每個元素是否滿足條件,滿足就返回這個元素的下標,並break迴圈,如果遍歷完了都沒有滿足條件的,就返回-1
var arr = [68,95,78,56,55,86,63]; var k = 0 var index = arr.find(function(v,i,a){ k++ return v<60; }); console.log(index); // 3 console.log(k); // 4 var arr = [68,95,78,66,86,63]; var k = 0 var index = arr.find(function(v,i,a){ k++ return v<60; }); console.log(index); // -1 console.log(k); // 6
七、冒泡排序
相鄰兩個元素進行比較,將一個數組中的數字使用迴圈進行升序或降序的排列
var arr = [3,2,1]; // ---> [1,2,3]
// 相鄰的元素比較,就是下標i的元素跟下標i+1的元素比較 - 所以迴圈要比正常的遍歷少一次
for(var i=0;i<arr.length-1;i++){
// 如果前面的元素比後面的元素大
if(arr[i]>arr[i+1]){
// 則交換位置
var tmp = arr[i]
arr[i] = arr[i+1]
arr[i+1] = tmp
}
}
// 這個迴圈結束後,arr變為:[2,1,3]
// 所以需要繼續排列
for(var i=0;i<arr.length-1;i++){
// 如果前面的元素比後面的元素大
if(arr[i]>arr[i+1]){
// 則交換位置
var tmp = arr[i]
arr[i] = arr[i+1]
arr[i+1] = tmp
}
}
// 這個迴圈結束後,arr變為:[1,2,3]
// 兩個迴圈代碼是重覆的,所以用迴圈處理。3個元素迴圈兩次,4個元素迴圈3次,所以迴圈重覆的次數也是數組長度-1
for(var j=0;j<arr.length-1;j++){
for(var i=0;i<arr.length;i++){
if(arr[i]>arr[i+1]){
var tmp = arr[i]
arr[i] = arr[i+1]
arr[i+1] = tmp
}
}
}
// 如果要降序排序,就將判斷條件中的>改為<即可
八、選擇排序
降序:先找最大值,排在最左邊,再找第二大的值,往左邊靠...,已經排好的,不再參與比較
var arr = [3,2,1]; // ---》 [1,2,3]
// arr[0]放最小的值,所以將arr[0]跟後面所有值比較,如果有比arr[0]更小的,就跟arr[0]交換位置
for(var i=1;i<arr.length;i++){
if(arr[0]>arr[i]){
var tmp = arr[0]
arr[0] = arr[i]
arr[i] = tmp
}
}
// 此時的數組:[1,3,2]
// 第1個位置的數字排好了,排第2個位置上的數字
// arr[1]放剩下的數字中最小的,使用arr[1]跟後面的數字比較,如果有比arr[1]更小的,就跟arr[1]交換位置
for(var i=2;i<arr.length;i++){
if(arr[1]>arr[i]){
var tmp = arr[1]
arr[1] = arr[i]
arr[i] = tmp
}
}
// 此時的數組:[1,2,3]
// 重覆代碼用迴圈處理,3個數排2次,4個數排3次
for(var j=0;j<arr.length-1;j++){
for(var i=j+1;i<arr.length;i++){
if(arr[j]>arr[i]){
var tmp = arr[j]
arr[j] = arr[i]
arr[i] = tmp
}
}
}
// 如果要進行降序排列,就將判斷條件中的>換成<即可