js之數組知識

来源:https://www.cnblogs.com/freefy/archive/2018/08/16/9484604.html
-Advertisement-
Play Games

一.數組的定義(來源於Array.prototype) 1.構造函數方法: (1)var arr = new Array();//沒有參數等價於 var arr = []; (2)var arr = new Array(length);//創建指定長度的數組;預分配一個數組空間;但數組中沒有存儲值, ...


一.數組的定義(來源於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權威指南


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在命令行運行 adb connect 192.168.10.* 時出現如上錯誤 解決辦法: 1、強制結束adb.exe的進程 2、使用adb start-server 重啟adb驅動,啟動成功後重新連接android設備 ...
  • Knowledge Reserve ComputerOperatingSystem 1. "編譯" 2. "靜態庫&動態庫(Linux)" .md) 3. "靜態鏈接&動態鏈接" 4. "記憶體" 5. "內聯函數&巨集" 6. "Static&Const" 7. "死鎖" 8. "線程安全" 9. " ...
  • repo是遠程訪問android源碼的工具,和git一起使用。 repo的遠程安裝經常被屏蔽,你懂得。 sudo apt-get install curl 244 sudo apt-get -f install curl 245 curl https://dl-ssl.google.com/dl/g ...
  • 自定義SurfaceView 主要步驟: 實現SurfaceHolder.Callback介面,創建SurfaceView的生命周期 實現Camera.PreviewCallback介面,創建預覽回調介面 創建Camera打開相機 實例: FrameCallback回調介面 MainActivity ...
  • 1、我們要明白當js操作dom時發生了什麼? 每次對dom的操作都會觸發"重排"(重新渲染界面,發生重繪或迴流),這嚴重影響到能耗,一般通常採取的做法是儘可能的減少 dom操作來減少"重排" 2、什麼是文檔碎片? document.createDocumentFragment() 一個容器,用於暫時 ...
  • 前言 在前後端分離的開發中,通過 Restful API 進行數據交互時,如果沒有對 API 進行保護,那麼別人就可以很容易地獲取並調用這些 API 進行操作。那麼伺服器端要如何進行鑒權呢? Json Web Token 簡稱為 JWT,它定義了一種用於簡潔、自包含的用於通信雙方之間以 JSON 對 ...
  • JavaScript 中常見設計模式 單例模式 策略模式 代理模式 迭代器模式 發佈訂閱模式 命令模式 組合模式 模板方法模式 享元模式 職責鏈模式 中介者模式 裝飾者模式 狀態模式 適配器模式 各設計模式關鍵詞 看完了上述設計模式後,把它們的關鍵詞特點羅列出來,以後提到某種設計模式,進而聯想相應的 ...
  • 什麼是狀態模式? 定義:將事物內部的每個狀態分別封裝成類,內部狀態改變會產生不同行為。 主要解決:對象的行為依賴於它的狀態(屬性),並且可以根據它的狀態改變而改變它的相關行為。 何時使用:代碼中包含大量與對象狀態有關的條件語句。 如何解決:將各種具體的狀態類抽象出來。 應用實例: 1、打籃球的時候運 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...