開始本章之前,先給出上一節的答案,參考答案地址:
http://www.xiaotublog.com/demo.html?path=homework/03/index2
1.JS數組的三大特性
在JavaScript中,數組和其他編程語言中的數組有所不同。首先體現在,在一般的編程語言中,數組的索引只能是數字,而js數組中,它的索引可以是任意類型。比如,你可能會看到這樣的代碼:
var arr=[]; //新建一個數組 arr['name']='rose'; arr['age']=12; alert(arr['name']); alert(arr['age']);
這個例子說明,在js中,數組的索引不一定只能是數字,但是,如果用數字作為索引的話,效率無疑會比較高一點,它內部必然做了優化。Js數組除了這一點比較特殊之外,還有一個需要注意的地方,就是它可以是動態的。我們知道,在Java中,要使用數組,必須要先對其進行初始化,也就是說,我得先規定好,這個數組的容量是多大,然后,我才能使用這個數組。在使用的過程中,要時刻注意好,不能超出數組的容量。如果數組要擴容,不管怎樣,我都只好重新申請一塊空間,new一個新的數組,然后把老數組中的那部分,嫁接拷貝到新的數組里面去。這就是Java數組的擴容概念。而在js中,數組的擴容變得毫不費力,因為它本來就是動態的。所以,你往往會看到這樣的代碼:
var arr=[]; //新建一個數組,長度為0 arr[0]=100; //動態擴容,現在長度為1 arr[1]=200; //動態擴容,現在長度為2 alert(arr.length);
很好用吧,在這一點上,js數組是非常靈活的。最后,js數組就像一個籃子,隨便你放什么都可以。小到一個數字,字符串,大到對象,函數,隨便你放什么,都可以的。
var arr=[]; //新建一個數組,長度為0 arr[0]=100; //動態擴容,現在長度為1 arr[1]=200; //動態擴容,現在長度為2 arr[2]="我是一個字符串"; arr[3]=function(){ alert('哈哈'); }; alert(arr);
在索引為3的地方,我們放入了一個函數,還是那句話,我現在問,這個函數有沒有打括號,是不是還沒有。好的,既然沒有打括號,那么這個函數就不會被執行。也就是說,這個函數目前來看,就是和數字,字符串差不多的東西,還沒有什么攻擊力!我們可以這樣去調用它:
arr[3]();
這樣應該很好理解吧。當然了,這里我不太愿意像背字典一樣,把每一個細節都講一遍,我覺得那樣沒有太大意義。就算現在你記住了,過一段時間你說不定又忘記了。還是那句話,通過不斷地寫,不斷地寫,持續不斷地寫項目,在項目中把這些知識點練起來,這才是你真正可以獲得的。
2.給數組賦值
在上面的例子中,我們可以通過這樣的方式給數組賦值:
var arr=[]; //新建一個數組,長度為0 arr[0]=100; //動態擴容,現在長度為1 arr[1]=200; //動態擴容,現在長度為2 arr[2]="我是一個字符串";
這就是給數組賦值的第一種方式,通過數組擴容的方式,即刻賦值。其實還有另一種方式,就是通過push方法來給數組賦值。我們用這種方式把上面的代碼重寫一遍,無非就是這樣:
var arr=[]; //新建一個數組,長度為0 arr.push(100); //動態擴容,現在長度為1 arr.push(200); //動態擴容,現在長度為2 arr.push("我是一個字符串"); alert(arr);
這樣是不是也可以呢?好,現在我就想要請問一下了,push是什么。你不要把它想得太復雜了,我就問你,它后面有沒有括號,有,好的。什么東西可以打括號?是不是方法呀,只有方法才可以打括號,打了括號就是去把它執行掉了。接下來再問,什么東西可以調用方法,是不是對象呀?OK,那么我們寫的這個:
var arr=[];
這個arr是什么,是不是一個對象呀?好的,理解了這一點就好辦多了。其實在JS中,數組其實有一個構造函數的。他就是Array,所以,上面這句代碼,其實是這么一回事:
var arr=new Array();
Array是js自帶的一個函數,它是一個構造函數,相當于Java中類的概念。我們可以通過new一個函數的方式,來獲得一個實實在在的對象。在這個例子中,arr就是一個實實在在的對象了。我再強調一遍,不要把簡單的東西弄復雜了,如果你腦袋里只想著復雜,那么就永遠看不到簡單。只有對象才可以調用屬性和方法。在這個例子中,arr固然是一個對象,所以,它可以調用一個叫做push的方法。
push的意思就是動態地給數組擴容一個單位,并且把對應的值放進去,就這么簡單。
有了塞東西進去的方法,當然還有把東西拿出來的方法, 沒錯就是pop。
var arr=new Array(); //新建一個數組,長度為0 arr.push(100); //動態擴容,現在長度為1 arr.push(200); //動態擴容,現在長度為2 arr.push("我是一個字符串"); arr.pop(); alert(arr);
pop可以理解為彈出,彈出的就是最后一次push進去的值。
3.數組常用方法
接下來,介紹一些數組的常用方法。
3.1 如何復制一個數組
為什么要復制數組呢?因為在實際項目中,你可能會遇到這樣的問題。我拿到一個數組,需要臨時保存下來,怎么辦?你可能會寫這樣的代碼:
var arr=new Array(); //新建一個數組,長度為0 arr.push(100); //動態擴容,現在長度為1 arr.push(200); //動態擴容,現在長度為2 var arr2=arr; arr.pop(); arr.pop(); alert(arr2);
你希望通過arr2來把arr的數據保存下來,結果,一旦arr改變了,arr2也跟著改變了。
不好意思,沒有。這是因為arr2和arr都是指向了同一塊內存區間,一個改變,另一個也就跟著改變了。那怎么辦呢?用slice就可以啦。
var arr=new Array(); //新建一個數組,長度為0 arr.push(100); //動態擴容,現在長度為1 arr.push(200); //動態擴容,現在長度為2 var arr2=arr.slice(); arr.pop(); arr.pop(); alert(arr2);
這樣就可以了。
3.2 如何把數組轉換成字符串
這個需求也經常會碰到,最常見的就是頁面需要做一個批量操作,列表上勾選N條數據,一般來說,是拿到一個JSON數組。比如這樣的:
var rows=[{id:1,name:'aaa'},{id:2,name:'bbb'}];
現在,我要拿到這些id,通過ajax傳遞到后臺,然后后臺通過這些id去做某些操作。那換做是你,你打算怎么做呢?有一種辦法,就是手動拼接這些id,用逗號分隔一下,做成一個字符串,然后傳遞到后臺,后臺再用splite方法進行解析。
你可能會這么做:
var rows=[{id:1,name:'aaa'},{id:2,name:'bbb'}]; var ids=''; //拼接id for(var i=0;i<rows.length;i++){ if(i==rows.length - 1){ ids +=rows[i].id }else{ ids +=rows[i].id + ','; } } alert(ids);
這樣做自然是可以的咯,可是,如果用數組的話,我們可以使用join方法。
var rows=[{id:1,name:'aaa'},{id:2,name:'bbb'}]; var ids=[]; //拼接id for(var i=0;i<rows.length;i++){ ids.push(rows[i].id); } ids=ids.join(','); //轉換成用逗號分隔的字符串 alert(ids);
3.3 如何去除數組中的重復元素
我這邊封裝了一個簡單的方法,可以去重:
var arr=[1,2,3,4,5,1]; function unique(arr){ //新建一個數組,用來存放原數組中所有不重復的數據 var afterUnique=[]; //新建一個JSON對象 var obj={}; //定義一個常量 var EXIST=1; //循環這個數組 for(var i=0;i<arr.length;i++){ /* obj[arr[i]]的意思是在obj中,key為arr[i]的值 如果不等于EXIST,表示不存在,那么就把該數據push到數組中 同時,將這個數據標記為已存在==> obj[item]=EXIST; */ if(obj[arr[i]] !=EXIST){ afterUnique.push(arr[i]); obj[arr[i]]=EXIST; } } return afterUnique; } alert(unique(arr));
當然,這個方法里面也用到了JSON。下一節,我們就來學習一下JSON吧。在本節中,有些地方我故意沒有細講,但凡是我覺得可以通過自行百度來解決的問題,就沒有必要在博客中寫明了,我也推薦大家能夠有目的地去百度一些資料,自己學習。我的博客只講一些關鍵的點,以及很多我認為重要的東西,絕對不會像翻字典一樣面面俱到,因為我覺得那樣沒意義,時間一長,還不是忘掉了。只有當你自己真的在項目中遇到了,才會真正的記住。我不希望把讀者思維局限在我的文章里面,所以我只講關鍵的,常用的。其他東西,留給大家自己去百度,自己去提升。把思路放開來,你會收獲更多。
組是用于儲存多個相同類型數據的集合,平時在數據的處理中用到最多,JavaScript 中常用的操作方法
1、concat()
concat() 方法用于連接兩個或多個數組。該方法不會改變現有的數組,僅會返回被連接數組的一個副本。
var arr1=[1,2,3];
var arr2=[4,5];
var arr3=arr1.concat(arr2);
console.log(arr1); //[1, 2, 3]
console.log(arr3); //[1, 2, 3, 4, 5]
2、join()
join() 方法用于把數組中的所有元素放入一個字符串。元素是通過指定的分隔符進行分隔的,默認使用','號分割,不改變原數組。
var arr=[2,3,4];
console.log(arr.join()); //2,3,4
console.log(arr.join('.')); //[2.3.4]
3、push()
push() 方法可向數組的末尾添加一個或多個元素,并返回新的長度。末尾添加,返回的是長度,會改變原數組。
var a1=[2,3,4];
var a2=a1.push(5);
console.log(a1); //[2,3,4,5]
console.log(a2); //4
4、pop()
pop() 方法用于刪除并返回數組的最后一個元素。返回最后一個元素,會改變原數組。
var arr=[2,3,4];
console.log(arr.pop()); //4
console.log(arr); //[2,3]
5、shift()
shift() 方法用于把數組的第一個元素從其中刪除,并返回第一個元素的值。返回第一個元素,改變原數組。
var arr=[2,3,4];
console.log(arr.shift()); //2
console.log(arr); //[3,4]
6、unshift()
unshift() 方法可向數組的開頭添加一個或更多元素,并返回新的長度。返回新長度,改變原數組。
var arr=[2,3,4,5];
console.log(arr.unshift(10,100)); //6
console.log(arr); // [10, 100, 2, 3, 4, 5]
7、slice()
返回一個新的數組,包含從 start 到 end (不包括該元素)的 arrayObject 中的元素。返回選定的元素,該方法不會修改原數組。
var arr=[2,3,4,5];
console.log(arr.slice(1,3)); //[3,4]
console.log(arr); //[2,3,4,5]
8、splice()
splice() 方法可刪除從 index 處開始的零個或多個元素,并且用參數列表中聲明的一個或多個值來替換那些被刪除的元素。如果從 arrayObject 中刪除了元素,則返回的是含有被刪除的元素的數組。splice() 方法會直接對數組進行修改。
語法:array.splice(index,howmany,item1,.....,itemX)
Index必需。規定從何處添加/刪除元素
howmany必需。規定應該刪除多少元素
item1可選。要添加到數組的新元素
var a=[5,6,7,8];
console.log(a.splice(1,0,9)); //[]
console.log(a); // [5, 9, 6, 7, 8]
var b=[5,6,7,8];
console.log(b.splice(1,2,3)); //[6, 7]
console.log(b); //[5, 3, 8]
9、substring() 和 substr()
相同點:如果只是寫一個參數,兩者的作用都一樣:都是是截取字符串從當前下標以后直到字符串最后的字符串片段。
substr(startIndex);
substring(startIndex);
var str='123456789';
console.log(str.substr(2)); // "3456789"
console.log(str.substring(2)) ;// "3456789"
不同點:第二個參數
substr(startIndex,lenth): 第二個參數是截取字符串的長度(從起始點截取某個長度的字符串);
substring(startIndex, endIndex): 第二個參數是截取字符串最終的下標 (截取2個位置之間的字符串,‘含頭不含尾’)。
console.log("123456789".substr(2,5)); // "34567"
console.log("123456789".substring(2,5)) ;// "345"
10、sort 排序
按照 Unicode code 位置排序,默認升序
var a=['red', 'blue', 'green'];
a.sort(); // ["blue", "green", "red"]
var num=[1, 10, 21, 2];
num.sort(); // [1, 10, 2, 21]
11、reverse()
reverse() 方法用于顛倒數組中元素的順序。返回的是顛倒后的數組,會改變原數組。
var arr=[2,3,4];
console.log(arr.reverse()); //[4, 3, 2]
console.log(arr); //[4, 3, 2]
12、indexOf 和 lastIndexOf
都接受兩個參數:查找的值、查找起始位置
不存在,返回 -1 ;存在,返回位置。indexOf 是從前往后查找, lastIndexOf 是從后往前查找。
indexOf
var a=[2, 9, 9];
a.indexOf(2); // 0
a.indexOf(7); // -1
if (a.indexOf(7)===-1) {}
lastIndexOf
var numbers=[2, 5, 9, 2];
numbers.lastIndexOf(2); // 3
numbers.lastIndexOf(7); // -1
numbers.lastIndexOf(2, 3); // 3
numbers.lastIndexOf(2, 2); // 0
numbers.lastIndexOf(2, -2); // 0
numbers.lastIndexOf(2, -1); // 3
13、every
對數組的每一項都運行給定的函數,每一項都返回 ture,則返回 true
function fun(element) {
return element < 10;
}
[2, 5, 8, 3, 4].every(fun); // true
function fun(element) {
return element < 10;
}
[2, 5, 11, 3, 4].every(fun); // false
14、filter
對數組的每一項都運行給定的函數,返回 結果為 ture 的項組成的數組
var arr=[1,2,3,4,5];
var a=arr.filter(function(item){
return item !=3;
});
console.log(a) //[1,2,4,5]
15、forEach 數組遍歷
var arr=[1, 2, 3];
var arr2=[];
arr.forEach(function(item){
arr2.push(item+1)
});
console.log(arr2) // [2, 3, 4]
感謝大家的支持,小編給粉絲們準備了書籍+視頻資料哦。麻煩轉發+關注。私信我“資料".
擊右上方紅色按鈕關注“小鄭搞碼事”,每天都能學到知識,搞懂一個問題!
如何實現深拷貝?
就是遞歸調用淺拷貝方法。
基本類型值的拷貝屬于深拷貝,然而,值的分析的是數組和對象的深拷貝實現問題。兩者的分析思路完全類同,包含代碼實現和方法利用。所以,今天先來總結一下數組的深拷貝問題。主要看看有哪些是你我想到一塊去的地方。
通過逐個拷貝數組中的元素來實現一維數組的深拷貝。
來看一段代碼:
上面這段代碼,從執行結果來看,實現了一個一維數組的深拷貝,拷貝后的數組和源數組完全是獨立的。
以二維為例子,比一維稍微復雜點,實現思路就是遞歸一維的代碼,來保證每次拷貝的都是基本類型值。
數組中的slice和concat方法,對于數組元素為基本數據類型的情況,可以實現數組的深拷貝。相信大家都會用。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。