1. 程式人生 > >js---陣列,類陣列

js---陣列,類陣列

1. 陣列 --- 一種特殊的物件

a 會改變原陣列的API---push unshift pop shift splice sort reverse

var arr=[3,5,2,7,1,9,0,3]
//push(需要新增的引數值1,...,引數值n)---向陣列末尾新增元素(可以是多個引數,就是向陣列新增多個元素)
arr.push(56);console.log(arr)//[3,5,2,7,1,9,0,3,56]

//pop()---刪除陣列末尾的元素(傳引數無效,就是剪下最後一個,因為返回值就是剪切出的結果)
arr.pop();console.log(arr);//[3,5,2,7,1,9,0,3]

//unshift(需要新增的引數值1,...,引數值n)---向陣列首位新增元素(和push一樣,可以傳多個引數)
arr.unshift(4,3);console.log(arr);//[4,3,3,5,2,7,1,9,0,3]

//shift()---剪下掉陣列首位的元素(和pop一樣,傳引數沒用,調一次剪下一次)
arr.shift();console.log(arr)//[3,3,5,2,7,1,9,0,3]

//splice(陣列的第幾位開始擷取,擷取幾位,在切口處新增新的資料)----剪下掉擷取的一段字串,並在截斷的地方新增新的資料
arr.splice(1,3,22,44,55,66);console.log(arr);//[3,22,44,55,66,7,1,9,0,3]
//另外擷取位數可以是0,就是不剪下,只插入,位置根據第n位開始擷取,就在第n位前插入

//sort()---預設按acs碼升序排序
arr.sort(); console.log(arr);//[0, 1, 22, 3, 3, 44, 55, 66, 7, 9]

//reverse()---翻轉順序
arr.reverse();console.log(arr);//[9, 7, 66, 55, 44, 3, 3, 22, 1, 0]

//例子---sort
//由於很多時候,我們並不需要根據acs碼排序,所以sort提供引數便於操作
arr.sort(function(a,b){//sort裡的函式必須是兩個引數;返回負數,就認為a在前;正數就b在前;返回0,就不動
     //if(a<b){
     //   return -1;// a - b < 0
    //}else{
     //   return 1; // a - b > 0
    //}          
    return a-b;//升序
    return b-a;//降序
});

//sort從陣列中取a和b是依照氣泡排序的方式---就是從arr中取第一位和第二位比,再和第三位比,比得過(返回正數)就交換,比不過就不動
//例子---氣泡排序
for(var i=0;i<arr.length;i++){
    for(var j=i+1;j<arr.length;j++){
        if(arr[i] > arr[j]){
            //如果當前拿來對比的值大於之後的值,就交換值,然後拿著交換後的i位置上的值繼續和後面對比
            arr[j]=arr[i]+arr[j];
            arr[i]=arr[j]-arr[i];
            arr[j]=arr[j]-arr[i];
        }
    }
}
//氣泡排序原理
//當i=0的時候,是第一輪對比,將最小的數放在了第一位,每次其實就是在找當前位之後的最小的數放在當前位置
//就是拿著i位置的值去當前位置後面找比i位置的值小的數,找到就交換位置,然後拿著i位置上的新數字(比之前的數小,看看後面還有沒有比它還小的,不斷交換就是找最小的)。
//不交換就證明比當前數小,那就肯定比能交換的數大
例子---給你個有序陣列,請你亂序排列:
var arr[1,2,3,4,5,6];
arr.sort(function(a,b){
    //隨機數會產生開區間0到1
    //減0.5就是-0.5到0.5之間,就是返回可正可負的數,就隨機交換或者不交換了唄
    return Math.random()-0.5;
})

b. 改變不了原陣列的API---concat slice join

var arr=[1,2,3,7,5,4],arr1=[22];
//陣列1.concat(陣列2)---在陣列1的末尾拼接上陣列2
console.log(arr.concat(arr1),arr); //[1, 2, 3, 7, 5, 4, 22] [1, 2, 3, 7, 5, 4]
console.log(arr1.concat(arr),arr1);//[22, 1, 2, 3, 7, 5, 4] [22]

//slice(從第幾位開始擷取,擷取到第幾位之前的數結束)
console.log(arr.slice(1,2),arr);//[2] [1, 2, 3, 7, 5, 4]
console.log(arr.slice(3),arr); //[7,5,4] [1, 2, 3, 7, 5, 4]
//陣列的這類API都是可以寫負引數的,內部會轉換為length+(負的引數) 然後計算出的位置
console.log(arr.slice(-2),arr);//[5,4] [1, 2, 3, 7, 5, 4]

//陣列以某個東西連結
console.log(arr.join('-'),arr); //"1-2-3-7-5-4"
//字串打斷成陣列
var arr3 = arr.join('-');
console.log(arr3.split('-'),arr3); //["1", "2", "3", "7", "5", "4"] "1-2-3-7-5-4"

2. 類陣列:屬性要為索引(數字)屬性,必須有length屬性。最好加上push方法。

另外:一個物件加上splice方法,就會變成陣列的形式---就是從{}形式變成[],但是它依然是物件,只能算是類陣列。

function a(){
   console.log(arguments);//[2,3,1]  這裡的arguments就是形式看上去是[] 但是依然是物件,依然只能算類陣列。你不能給它push等呼叫陣列的API
   arguments.push(2);//error: arguments.push is not a function
}
a(2,3,1);

例子:

var obj={
  "0":"haha",
  "1":"xixi",
  "2":"hehe",
  "name":"xiaoming",
  "length":3,
  "push":Array.prototype.push
}
obj.push("heihei");
console.log(obj); // {0: "haha", 1: "xixi", 2: "hehe", 3: "heihei", name: "xiaoming", length: 4, push: ƒ}

obj.length=1;
console.log(obj);//{0: "haha", 1: "xixi", 2: "hehe", 3: "heihei", name: "xiaoming", length: 1, push: ƒ}
obj.push('oh my god');
console.log(obj);//{0: "haha", 1: "oh my god", 2: "hehe", 3: "heihei", name: "xiaoming", length: 2, push: ƒ}

//上面的現象是由於push的內部處理造成的
//obj呼叫push,其實就是在以length的值為名稱的屬性上賦值,並且length+1,也說明了為什麼類陣列必須有length,且必須有索引才有意義
//所以當直接改變了length的值再push,當然就找錯名字了,然後覆蓋了已經有的值。
Array.prototype.push=function(){
    for(var i=0;i<arguments.length;i++){
    this[this.length] = arguments[i];
    this.length++;
   }
}