1. 程式人生 > >js之數組知識

js之數組知識

str1 比較 例子 可選 nsh tr1 color 排序 元素

一.數組的定義(來源於Array.prototype)

1.構造函數方法:

  (1)var arr = new Array();//沒有參數等價於 var arr = [];

  (2)var arr = new Array(length);//創建指定長度的數組;預分配一個數組空間;但數組中沒有存儲值,甚至數組的索引屬性‘0‘,‘1‘等還未定義

  (3)var arr=new Array(值1,值2,值3...)

2.字面量:var arr = []; var arr=[1,2,3]

區別:new Array()只有一個參數(不能為小數:非法!報錯!)時,會被當成是長度,並成為一個稀松數組;

var
arr1 = new Array(4); var arr2 = [4]; console.log(arr1);//[undefined*4] console.log(arr2);//[4] var arr = new Array(3.4); console.log(arr);//Uncaught RangeError: Invalid array length

二.數組的讀寫(不可溢出讀,結果為undefined;可以溢出寫)

原理:數組索引僅僅是對象屬性名的一種特殊類型,這意味著javascript數組沒有‘越界錯誤‘的概念,.當試圖查詢任何對象不存在的屬性還是,不會報錯,只會得到undefined值.

var arr = [1,2];
console.log(arr[2]);//undefined
arr[4] = 5;//溢出寫
console.log(arr);//[1,2,undefined,undefined,5];
console.log(arr[3]);//undefined--->實際上是arr[‘3‘]
var obj = {};
console.log(obj.age);//undefined
var arr = [];
console.log(arr[‘age‘]);//undefined

註意:數組是對象的特殊形式.使用方括號訪問數組就像方括號訪問對象的屬性一樣,javascript將指定的數字索引值轉換為字符串---索引1變為‘1‘---然後將其作為屬性名來使用.

數組的特別之處在於:當使用小於等於2^32-2的非負整數作為屬性名時,數組會自動維護其length屬性值;

arr[Math.pow(2,32)-2] = 67;//索引
arr[Math.pow(2,32)-1] =22;// 屬性名

arr[1]--->實際上是arr[‘1‘];

 var arr = [1,2,3,4];
 console.log(arr);
//[1, 2, 3, 4]
//0:1
//1:2
//2:3
//3:4
//length:4
console.log(arr[1])//2,實際上是訪問數組的‘1‘屬性;

(1)可以用負數或非整數來索引數組.這種情況下,數值轉換為字符串,字符串作為屬性名來使用(即索引不是非負整數的情況下,只能當做常規的對象屬性);

(2)同樣,如果湊巧使用了非負整數(即0和正整數)的字符串,它就當做數組索引,而非對象屬性.

(3)當使用的一個浮點數和一個整數相等時,也是當做數組索引

即除了(2)和(3)情況,[]內的值都當成對象屬性名(轉換為字符串)

var arr = [1,2,3,4];
arr[-2] = ‘name‘;//-2當做屬性-------(1)
arr[1.5] = 9;//1.5當做屬性-----------(1)
arr[‘3‘] = 15;//數組索引;等價於arr[3]------(2)
arr[1.00] = 23//數組索引;等價於arr[1]=23---(3)
arr[‘1.00‘]=4;//1.00當做屬性1.00
arr[‘age‘] = 6;//age:屬性
console.log(arr);// [1, 23, 3, 15, -2: "name", 1.5: 9, 1.00: 4,age:6]
console.log(arr.length)//4 索引值為小於2^32的非負整數會自動維護其length值
var obj = {};//空對象或不空的
arr[obj] = ‘5‘;//屬性名為[object Object]: "5"

三.稀松數組:包含從0開始的不連續索引的數組;length屬性值大於元素的個數,可以用Array()構造函數或簡單地指定數組的索引值大於當前的的數組長度來創建稀疏數組

1.var arr = new Array(5);//數組沒有元素,但a.length = 5

2. a = [];//當前length為0;

 a[1000] = 0;//1000>0;稀疏數組,length變為1001;

四.數組的常用方法

(一)改變原數組的:reverse,push,pop,unshift,shift,splice,sort;

(1)reverse()---顛倒數組中元素的順序並返回新的數組。

var arr=[1,2,3];
var a = arr.reverse();
console.log(arr);//[3,2,1]
console.log(a);//[3,2,1]

(2)push()---向數組的末尾添加一個或更多元素,並返回新的長度。

var arr=[1,2,3];
var a = arr.push(4,5);
console.log(arr);//[]1,2,3,4,5]
console.log(a);//5

(3)pop()---刪除並返回數組的最後一個元素(沒有形參,寫了會被忽略)

var arr=[1,2,3];
var a = arr.pop(4,5);//自動忽略掉參數4,5
console.log(arr);//[1,2]
console.log(a);//3

(4)unshift()---向數組的開頭添加一個或更多元素,並返回新的長度。

var arr=[1,2,3];
var a = arr.unshift(4,5);
console.log(arr);//[4,5,1,2,3]
console.log(a);//3

(5)shift()---刪除並返回數組的第一個元素

var arr=[1,2,3];
var a = arr.shift();//沒有形參,有的話會忽略
console.log(arr);//[2,3]
console.log(a);//3

(6)splice()---刪除元素,並向數組添加新元素,並返回刪除的元素

它有三個參數,第一個參數時截取開始的位置,第二個參數是截取的長度,第三個參數是一組數據,代表要在截取的位置添加的數據

var arr=[1,2,3];
var a = arr.splice(1,2,4,5)//從第一位開始截取兩位數據2,3,並在當前位置添加數據4,5;
console.log(arr);//[1,4,5]
console.log(a);//[2,3]
var b = arr.splice(1,2,[7,8],9);//這裏splice是插入數組本身,區別concat連接數組是數組的元素;
console.log(arr);//[1,[7,8],9];
console.log(b);//[4,5];
var arr=[1,2,3];
var a = arr.splice(-1,2,4,5)//從倒數第一位(第二位)(-1+arr.length=2)開始截取兩位數據(這裏只有一位數據了)3,並在當前位置添加數據4,5;
console.log(arr);//[1,2,4,5]
console.log(a);//[3]
如果不寫要添加的數據的話,這個方法就變成了在數組中刪除數據的作用了。 如果截取的長度是0,然後添加數據的話,這個方法就變成了在數據的特定位置添加數據的作用了。 (7)sort()---從小到大排序---return最後排序後的數組(如果數組包括undefined元素,會被排到數組的尾部)
var arr = [1,2,,3,4];
var a=arr.sort();
console.log(a);//[1,2,3,4,undefined]
var arr=[1,5,3,9,-7,2];
var a = arr.sort();
console.log(arr);//[-7, 1, 2, 3, 5, 9]
console.log(a);//[-7, 1, 2, 3, 5, 9]
在sor後面添加reverse就相當於降序排序:
var arr=[1,5,3,9,-7,2];
var a = arr.sort().reverse();
console.log(arr);//[9, 5, 3, 2, 1, -7]
console.log(a);//[9, 5, 3, 2, 1, -7]
註意:這裏的sort()是按ASCII碼排序的,若要比較數的大小,需要在sort()內部添加函數
var arr=[1,3,10,2,5];
var a = arr.sort();
console.log(arr);//[1,10,2,3,5]
var arr = [1,2,undefined,null,3,4];
var a=arr.sort();
console.log(a);//[1,2,3,4,null,undefined]--根據ASCII碼進行排序

sort()函數有個接口:

註意:

看返回值return:

(1)當返回值為負數時,前面的數在前面

(2)當返回值為正數時,後面的數在前面  

var arr=[1,3,10,2,5];
arr.sort(function(a,b){
    if(a>b){
        return 1;//a>b,b放在a前面,即小的數在前面
    }else{
        return -1;//a<b,a放在前面,即小的數在前面
    }
})
console.log(arr);//[1,2,3,5,10]
上面例子實際上就是a-b>0;返回正數,否則返回負數(升序排序) 將上面的算法進行簡化:
var arr=[1,3,10,2,5];
arr.sort(function(a,b){
  return a-b;
})
console.log(arr);//[1,2,3,5,10]
升序:return a - b; 降序:return b - a 思考:若是有一個有序數組,希望進行亂序,怎麽寫? 理解:當返回值為隨機數(即可能是正,可能是負的情況),進行比較的兩個數的順序是不確定的;
var arr=[1,2,3,4,5];
arr.sort(function(){
  return Math.random()-0.5;//Math.random()--->[0,1);
})
console.log(arr);
sort()不僅僅局限於對數字進行排序,也可以是根據某個屬性對對象,字符串等進行排序
var deng = {
    name:‘deng‘,
    age:12
};
var zao={
    name:‘zao‘,
    age:34
};
var li={
    name:‘li‘,
    age:10
}
var arr= [deng,zao,li];
arr.sort(function(a,b){
    return a.age-b.age;//1.按照年齡進行升序
 //return a.name.length - b.name.length;//2.按照名字長度升序

})
console.log(arr);

根據字節長度進行排序

//字節長度,漢字為2;字母為1;
function retBytes(str){
    var num = str.length;
    for(var i = 0 ; i< str.length;i++){
        if(str.charCodeAt(i) > 255){//返回指定位置的字符的 Unicode 編碼;
            num += 1;
        }
    }
    return num;
}
var arr = [‘Ming‘,‘李dang‘,‘王明‘,‘merheyka‘];
arr.sort(function(a,b){
    return retBytes(a) - retBytes(b);
})
console.log(arr);//["Ming", "王明", "李dang", "merheyka"]
(二)不改變原數組的:concat,slice,join,toString,

(1)concat----連接兩個或更多的數組,並返回一個新數組。

它的元素包括調用concat()的原始數組的元素和concat()的每個參數.若這些參數中的任何一個自身是數組,這連接的是數組的元素,而非數組本身;

但註意:concat()不會遞歸扁平化數組的數組.concat()也不會修改調用的數組;

var arr1 = [1,2,3];
var arr2 = [4,5];
var arr=arr1.concat(arr2);//等價於var arr = [].concat(arr1,arr2);concat可以有一個或多個參數
console.log(arr);
//[1,2,3,4,5] console.log(arr1);//[1,2,3] console.log(arr2);//[4,5]
var arr3 = [6,[7,8]];
arr = arr1.concat(arr3);
console.log(arr);//[1,2,3,6,[7,8]];

(2)slice---從某個已有的數組返回選定的元素

slice可以有0個參數,1個參數或者2個參數(參數可以為負數(等價於 負數+數組長度)超出2個的參數會自動被忽略,認為只有2個參數)

第一種情況:0個參數:截取整個數組(用於將類數組轉化為數組)

var obj = {
    ‘0‘:‘a‘,
    ‘1‘:‘b‘,
    ‘length‘:2
}
var a=Array.prototype.slice.call(obj);
console.log(a);//[‘a‘,‘b‘]

第二種情況:1個參數:從第幾位開始,一直截取到最後一位

var arr = [1,2,3,4,5,6]; 
var a=arr.slice(3);
console.log(a);//[4,5,6]

第三種情況:2個參數:slice(從該位開始截取,截取到該位); 例slice(2,4)從第2位開始截取到第四位(不包括該位),即第二位和第三位

var arr = [1,2,3,4,5,6]; 
var a=arr.slice(3,5);
console.log(a);//[4,5]

(3) join---把數組的所有元素放入一個字符串。元素通過指定的符號進行連接。(可以用這個方法來進行大量字符串的連接工作)

var arr = [‘a‘, ‘b‘, ‘c‘];
var str = arr.join(‘-‘);
console.log(str); // "a-b-c"

join--若不傳參數(默認為逗號連接) join() 等價於join(‘,‘);

拼接字符串:使用arr.join("");

擴展;:split:字符串轉換為數組的方法根據符號將字符串拆分為數組

var arr = [‘a‘, ‘b‘, ‘c‘];
var str = arr.join(‘-‘);
console.log(str); // "a-b-c"
var a = str.split(‘-‘);
console.log(a);//[‘a‘,‘b‘,‘c‘]

註意:一個數組通過join()方法和split()後得到的數組與原來的數組不一定是一樣的;通過split返回的數組;每個數都是字符串

var arr = [1, 2, 3];
console.log(typeof arr[0]);//number
var str = arr.join(‘-‘);
console.log(str); // "a-b-c"
var a = str.split(‘-‘);
console.log(a);//[‘1‘,‘2‘,‘3‘]
console.log(typeof a[0]);//string

小題目:將下面的字符串拼到一起

var str1 = ‘tianmao‘;
var str2 = ‘taobao‘;
var str3 = ‘jindong‘;
var str4 = ‘weipinghui‘;
var str5 = ‘shuning‘;
var str6 = ‘pingduoduo‘;

1.用+運算符去連接字符串---由於字符串時存在棧裏面的(先進後出),棧操作消耗性能大

var arr = [str1,str2,str3,str4,str5,str6];
var str = ‘‘;
for(var i = 0 ; i < arr.length;i++){
    str += arr[i];
}
console.log(str);//tianmaotaobaojindongweipinghuishuningpingduoduo

2.用join方法----推薦

var arr = [str1,str2,str3,str4,str5,str6];
str = arr.join(‘‘);
console.log(str);//tianmaotaobaojindongweipinghuishuningpingduoduo

(4)toString()----把數組轉換為逗號分隔的字符串列表.註意:輸出不包括方括號或其他任何形式的包裹數組值的分隔符.

var arr = [1,2,3,4];
var str = arr.toString();
console.log(str);//"1,2,3,4"

[1,[2,3]].toString();//‘1,2,c‘ 這裏與不適用任何參數的調用join()返回的結果一樣

(5)toLocalString():toString的本地化版本.

它調用元素的toLocalString()的方法將每個數組元素轉化為字符串,並使用本地化(和自定義實現的)分隔符將這些字符串連接起來.

(三)ES5中的數組方法

1.forEach()-----這個方法會改變原數組,它讓數組中的元素從頭到尾遍歷一遍,每一個都調用一下我們在forEach裏面傳遞的方法,中間不會停止 可以有三個參數(數組元素,元素索引,數組本身)
var arr = [1, 2, 3, 4];
arr.forEach(function (ele, index) {
  arr[index] += 1;
})
console.log(arr); // [2, 3, 4, 5]
2.map()-----這個方法和forEach很像,只是map不會改變原數組,而是返回一個新的數組,它也是讓傳遞一個指定的方法,讓數組中的每一個元素都調用一遍這個方法。不過記得map方法最後有返回值。如果是稀疏數組,返回的也是相同方式的稀疏數組,它具有相同的長度,相同的缺失元素
var arr = [1, 2, 3];
var test = arr.map(function (x) {
     return x * x;
 });
console.log(test); // 1 4 9
console.log(arr); // 1 2 3    
3.filter()---------過濾的作用,它同樣不會改變原數組,而是返回一個原數組的子集。我們同樣會傳遞一個方法,每一個元素都會調用一下這個方法,但是只有返回true的元素才會被添加到新數組裏面,返回false的不會被添加到新數組裏面。
var a = [1, 2, 3, 4, 5];
var b = a.filter(function (x) {
     return x > 2;
});
console.log(a);//[1,2,3,4,5]
console.log(b); // [3,4,5]

同時,filter()會跳過稀疏數組裏面缺少的元素,它的返回數組總是稠密的。

var arr = [1,,,,,,3,4];
var b = arr.filter(function () {
      return true;
})
console.log(arr); // [1,3,4]

4.every和some

這兩個方法是數組的邏輯判定,他們對數組應用指定的函數進行判定,返回true或者false。 every是如果每一個元素經過傳遞的方法的判定之後都返回true,那麽最後才返回true。 some是只要有一個元素返回true,那麽就返回true。 根據數學上的慣例,在空數組上調用時,every()返回true,some()返回false
var arr = [1 ,2 ,3];
console.log(arr.some(function (x) {return x<3;})); //true
console.log(arr.every(function (x) {return x<3;})); //false
5.reduce()和reduceRight():使用指定的函數將數組元素進行組合,最後變成一個值,reduce是從左向右,reduceRight是從右向左。有兩個參數,第一個是方法,第二個是可選參數,即我們最後的這個值的初始值。 當我們沒有設置初始值的時候,用數組的第一個元素的值作為初始值。不過當數組為空的時候,不帶初始值就會報錯。 當我們的數組只有一個元素並且沒有指定初始值,或者有一個空數組並且指定一個初始值的情況下,reduce只是簡單地返回那個值,而不會調用函數。
var arr = [1, 2, 3];
var sum = a.reduce(function (x, y) { return x + y}, 0);// 6------0 + 1 + 2 + 3 = 6;
var temp = [1];
var temoOut = a.reduce(function (x, y) {return x * x * y}); // 1 不會調用這個函數,因為數組只有一個值,除非我們設置一個初始值

6.indexOf()和lastIndexOf():搜索整個數組中具體給定值的元素,返回找到的第一個元素的索引或者如果沒有找到就返回-1.indexOf()從頭到尾搜索,而lastIndexOf()則反向搜索

var a = [0,1,2,1,0];
a.indexOf(1);//1-->a[1] = 1;
a.lastIndexOf(1);//3--->a[3] = 1;
a.indexOf(3);//-1;沒有值

註意:indexOf()和lastIndexOf()不接收一個函數作為其參數(不報錯---返回-1);

indexOf()和lastIndexOf()可以有兩個參數,第一個是需要搜索的值,第二個是指定數組中的一個索引,從那裏開始搜索

---以上知識參考了:javascript權威指南

js之數組知識