javascript類型系統——數組array

来源:http://www.cnblogs.com/xiaohuochai/archive/2016/07/18/5679605.html
-Advertisement-
Play Games

[1]創建 [2]本質 [3]稀疏 [4]長度 [5]遍歷 [6]類數組 ...


×
目錄
[1]創建 [2]本質 [3]稀疏[4]長度[5]遍歷[6]類數組

前面的話

  除了對象之外,數組Array類型可能是javascript中最常用的類型了。而且,javascript中的數組與其他多數語言中的數組有著相當大的區別。本文將介紹javascript中的數組Array類型

 

創建數組

  有兩種創建數組的方法:使用字面量語法和使用Array()構造函數

【字面量】

  使用數組字面量是創建數組最簡單的方法,在方括弧中將數組元素用逗號隔開即可

var empty = [];                    //沒有元素的數組
var primes = [2,3,5,7,11];         //有5個數值的數組

  雖然javascript數組與其他語言中的數組都是數據的有序列表,但與其他語言不同的是,javascript數組的每一項可以保存任何類型的數據

var misc = [1.1,true, "a"];           //3個不同類型的元素

  數組字面量中的值不一定要是常量,它們可以是任意的表達式

var base = 1024;
var table = [base,base+1,base+2,base+3];

  它可以包含對象字面量或其他數組字面量

var b = [ [1,{x:1,y:2}],[2,{x:3,y:4}] ];

  如果數組的元素還是數組,就形成了多維數組

var a = [[1, 2], [3, 4]];

  [註意]使用數字字面量表示法時,不會調用Array構造函數

【構造函數】

  有三種方式調用構造函數

  【1】沒有參數,創建一個空數組

//該方法創建一個沒有任何元素的空數組,等同於數組直接量[]
var a = new Array();

  【2】有一個數值參數,該參數用於指定數組的長度

var a  = new Array(10);
console.log(a);//[]
console.log(a[0],a.length);//undefined 10

  [註意]若存在一個其他類型的參數,則會創建包含那個值的只有一項的數組

var a  = new Array('10');
console.log(a);//['10']
console.log(a[0],a.length);//10 1

  【3】有多個參數時,參數表示為數組的具體元素

var a = new Array(1,2,3);
console.log(a);//[1,2,3]
console.log(a[0],a[1],a[2]);//1 2 3

  使用Array()構造函數時,可以省略new操作符

var a1 = Array();
var a2 = Array(10);
var a3 = Array(1,2,3);
console.log(a1,a2,a3);//[] [] [1,2,3]

 

數組本質

  數組是按次序排列的一組值,本質上,數組是一種特殊的對象

typeof [1, 2, 3] // "object"

  數組的特殊性體現在,它的鍵名是按次序排列的一組整數(0,1,2…)。由於數組成員的鍵名是固定的,因此數組不用為每個元素指定鍵名,而對象的每個成員都必須指定鍵名

var arr = ['a', 'b', 'c'];
console.log(Object.keys(arr));// ["0", "1", "2"]

var obj = {
    name1: 'a',
    name2: 'b',
    name3: 'c'
};

  數組是對象的特殊形式,使用方括弧訪問數組元素就像用方括弧訪問對象的屬性一樣

  javascript語言規定,對象的鍵名一律為字元串,所以,數組的鍵名其實也是字元串。之所以可以用數值讀取,是因為非字元串的鍵名會被轉為字元串,然後將其作為屬性名來使用

o={};       //創建一個普通的對象
o[1]="one"; //用一個整數來索引它

//數值鍵名被自動轉成字元串
var arr = ['a', 'b', 'c'];
arr['0'] // 'a'
arr[0] // 'a'

  但是,一定要區分數組索引和對象的屬性名:所有的索引都是屬性名,但只有在0~232-2(4294967294)之間的整數屬性名才是索引

var a = [];

//索引
a['1000'] = 'abc';
a[1000] // 'abc'

//索引
a[1.00] = 6;
a[1] // 6

  [註意]單獨的數值不能作為標識符(identifier)。所以,數組成員只能用方括弧法表示

var arr = [1, 2, 3];
arr[0];//1
arr.0;//SyntaxError

  可以使用負數或非整數來索引數組。但由於其不在0~2的32次方-2的範圍內,所以其只是數組的屬性名,而不是數組的索引,明顯的特征是不改變數組的長度

var a = [1,2,3];

//屬性名
a[-1.23]=true;
console.log(a.length);//3

//索引
a[10] = 5;
console.log(a.length);//11

//屬性名
a['abc']='testing';
console.log(a.length);//11

 

稀疏數組

  稀疏數組就是包含從0開始的不連續索引的數組

  【1】製造稀疏數組最直接的方法就是使用delete操作符

var a = [1,2,3,4,5];
delete a[1];
console.log(a[1]);//undefined
console.log(1 in a);//false

  【2】數組的逗號之間可以省略元素值,通過省略元素值也可以製造稀疏數組

var a =[1,,3,4,5];
console.log(a[1]);//undefined
console.log(1 in a);//false

  [註意]省略的元素值和值為undefined的元素值是有區別的

var a =[1,,3,4,5];
console.log(a[1]);//undefined
console.log(1 in a);//false

var a =[1,undefined,3,4,5];
console.log(a[1]);//undefined
console.log(1 in a);//true

  如果在數組的末尾使用逗號時,瀏覽器之間是有差別的。標準瀏覽器會忽略該逗號,而IE8-瀏覽器則會在末尾添加undefined值

//標準瀏覽器輸出[1,2],而IE8-瀏覽器輸出[1,2,undefined]
var a = [1,2,];
console.log(a);

//標準瀏覽器輸出2,而IE8-瀏覽器輸出3
var a = [,,];
console.log(a.length);

  足夠稀疏的數組通常在實現上比稠密的數組更慢,記憶體利用率更高,在這樣的數組中查找元素的時間與常規對象屬性的查找時間一樣長

 

數組長度

  每個數組有一個length屬性,就是這個屬性使其區別於常規的JavaScript對象。針對稠密(也就是非稀疏)數組,length屬性值代表數組中元素的個數,其值比數組中最大的索引大1

[].length     //=>0:數組沒有元素
['a','b','c'].length   //=>3:最大的索引為2,length為3

  當數組是稀疏數組時,length屬性值大於元素的個數,同樣地,其值比數組中最大的索引大1

[,,,].length; //3
(Array(10)).length;//10
var a = [1,2,3];
console.log(a.length);//3
delete a[1];
console.log(a.length);//3

  數組的特殊性主要體現在數組長度是可以動態調整的:

  【1】如果為一個數組元素賦值,索引i大於等於現有數組的長度時,length屬性的值將設置為i+1

var arr = ['a', 'b'];
arr.length // 2

arr[2] = 'c';
arr.length // 3

arr[9] = 'd';
arr.length // 10

arr[1000] = 'e';
arr.length // 1001

  【2】設置length屬性為小於當前長度的非負整數n時,當前數組索引值大於等於n的元素將從中刪除

a=[1,2,3,4,5];   //從5個元素的數組開始
a.length = 3;    //現在a為[1,2,3]
a.length = 0;    //刪除所有的元素。a為[]
a.length = 5;    //長度為5,但是沒有元素,就像new Array(5)

  [註意]將數組清空的一個有效方法,就是將length屬性設為0

var arr = [ 'a', 'b', 'c' ];
arr.length = 0;
arr // []    

  【3】將數組的length屬性值設置為大於其當前的長度。實際上這不會向數組中添加新的元素,它只是在數組尾部創建一個空的區域

var a = ['a'];
a.length = 3;
console.log(a[1]);//undefined
console.log(1 in a);//false

  如果人為設置length為不合法的值(即0——232-2範圍以外的值),javascript會報錯

// 設置負值
[].length = -1// RangeError: Invalid array length

// 數組元素個數大於等於2的32次方
[].length = Math.pow(2,32)// RangeError: Invalid array length

// 設置字元串
[].length = 'abc'// RangeError: Invalid array length

  由於數組本質上是對象,所以可以為數組添加屬性,但是這不影響length屬性的值

var a = [];

a['p'] = 'abc';
console.log(a.length);// 0

a[2.1] = 'abc';
console.log(a.length);// 0

 

數組遍歷

  使用for迴圈遍曆數組元素最常見的方法

var a = [1, 2, 3];
for(var i = 0; i < a.length; i++) {
  console.log(a[i]);
}

  當然,也可以使用while迴圈

var a = [1, 2, 3];
var i = 0;
while (i < a.length) {
  console.log(a[i]);
  i++;
}

var l = a.length;
while (l--) {
  console.log(a[l]);
}

  但如果數組是稀疏數組時,使用for迴圈,就需要添加一些條件

//跳過不存在的元素
var a = [1,,,2];
for(var i = 0; i < a.length; i++){
    if(!(i in a)) continue;
    console.log(a[i]);
}

  還可以使用for/in迴圈處理稀疏數組。迴圈每次將一個可枚舉的屬性名(包括數組索引)賦值給迴圈變數。不存在的索引將不會遍歷到

var a = [1,,,2];
for(var i in a){
    console.log(a[i]);
}

  由於for/in迴圈能夠枚舉繼承的屬性名,如添加到Array.prototype中的方法。由於這個原因,在數組上不應該使用for/in迴圈,除非使用額外的檢測方法來過濾不想要的屬性

var a = [1,,,2];
a.b = 'b';
for(var i in a){
    console.log(a[i]);//1 2 'b'
}
//跳過不是非負整數的i
var a = [1,,,2];
a.b = 'b';
for(var i in a){
    if(String(Math.floor(Math.abs(Number(i)))) !== i) continue;
    console.log(a[i]);//1 2
}

  javascript規範允許for/in迴圈以不同的順序遍歷對象的屬性。通常數組元素的遍歷實現是升序的,但不能保證一定是這樣的。特別地,如果數組同時擁有對象屬性和數組元素,返回的屬性名很可能是按照創建的順序而非數值的大小順序。如果演算法依賴於遍歷的順序,那麼最好不要使用for/in而用常規的for迴圈

 

類數組

  擁有length屬性和對應非負整數屬性的對象叫做類數組(array-like object)

//類數組演示
var a = {};
var i = 0;
while(i < 10){
    a[i] = i*i;
    i++;
}
a.length = i;

var total = 0;
for(var j = 0; j < a.length; j++){
    total += a[j];
}

  有三個常見的類數組對象:

  【1】arguments對象

// arguments對象
function args() { return arguments }
var arrayLike = args('a', 'b');
arrayLike[0] // 'a'
arrayLike.length // 2
arrayLike instanceof Array // false

  【2】DOM方法(如document.getElementsByTagName()方法)返回的對象

// DOM元素
var elts = document.getElementsByTagName('h3');
elts.length // 3
elts instanceof Array // false

  【3】字元串

// 字元串
'abc'[1] // 'b'
'abc'.length // 3
'abc' instanceof Array // false

  [註意]字元串是不可變值,故當把它們作為數組看待時,它們是只讀的。如push()、sort()、reverse()、splice()等數組方法會修改數組,它們在字元串上是無效的,且會報錯

var str = 'abc';
Array.prototype.forEach.call(str, function(chr) {
  console.log(chr);//a b c
});

Array.prototype.splice.call(str,1);
console.log(str);//TypeError: Cannot delete property '2' of [object String]

  數組的slice方法將類數組對象變成真正的數組

var arr = Array.prototype.slice.call(arrayLike);

  javascript數組方法是特意定義為通用的,因此它們不僅應用在真正的數組而且在類數組對象上都能正確工作。在ECMAScript5中,所有的數組方法都是通用的。在ECMAScript3中,除了toString()和toLocaleString()以外的所有方法也是通用的

var a = {'0':'a','1':'b','2':'c',length:3};
Array.prototype.join.call(a,'+');//'a+b+c'
Array.prototype.slice.call(a,0);//['a','b','c']
Array.prototype.map.call(a,function(x){return x.toUpperCase();});//['A','B','C']

 

參考資料

【1】 ES5/array對象 https://www.w3.org/html/ig/zh/wiki/ES5/builtins#Array_.E5.AF.B9.E8.B1.A1
【2】 阮一峰Javascript標準參考教程——基本語法 http://javascript.ruanyifeng.com/grammar/array.html
【3】《javascript權威指南(第6版)》第7章 數組
【4】《javascript高級程式設計(第3版)》第5章 引用類型
【5】《javascript DOM編程藝術(第2版)》第2章 javascript語法
【6】《javascript語句精粹》第6章 數組


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

-Advertisement-
Play Games
更多相關文章
  • 頂求網首頁是一個web2.0博客類的網站首頁,在該網站中用戶可以發表博客,也可以推薦圖書給其他用戶。所以,在首頁中主要分三個板塊——文章、圖書、用戶。另外,網站的頭部和尾部還要有導航(navigator,固定在頭部)和腳註(footer),而這些元素也是整個網站都要用到的,具體實現時可以把它們放在網... ...
  • /*去重*/ <script> function delRepeat(arr){ var newArray=new Array(); var len=arr.length; for(var i=0;i<len;i++){ for(var j=i+1;j<len;j++) { if(arr[i]==a ...
  • [1]typeof [2]instanceof [3]toString [4]isArray ...
  • 通過jQuery獲取頁面中的所有radio對象,遍歷頁面中的radio,取消選中的標簽,因為使用到jQuery時間,因此引用到了網上公共的js,這隻是本人的一些總結,大神勿噴。 文中使用3中獲取radio對象的方式,前兩種使用的比較多,第三種直接通過type標簽獲取對象,有可能獲取到頁面中所有的ra ...
  • 1.鏈接樣式設置 設置鏈接樣式時需考慮鏈接是否已被訪問過: 2.小尖角 目前只會一種從網上搜索來的方法: 當 width:0; height:0; 時,各邊會呈現徑向三角形態,可設置各邊高、虛實、顏色,形成小尖角。 ...
  • 線上預覽 源碼下載 這是一組使用CSS3製作的超酷滑鼠滑過圖片標題動畫特效。這組特效中共有8種不同的滑鼠滑過效果,它們都是通過CSS3 transform來製作遮罩層的各種動畫特效。 使用方法 在頁面中引入imghover.css文件。 1 <link rel="stylesheet" type=" ...
  • split() 方法用於把一個字元串分割成字元串數組。<script type="text/javascript"> var str="How are you doing today?" document.write(str.split(" ") + "<br />")document.write( ...
  • 表單校驗是頁面開發中非常常見的一類需求,相信每個前端開發人員都有這方面的經驗。網上有很多成熟的表單校驗框架,雖然按照它們預設的設計,用起來沒有多大的問題,但是在實際工作中,表單校驗有可能有比較複雜的個性化的需求,使得我們用這些插件的預設機制並不能完成這些功能,所以要根據自己的需要去改造它們(畢竟自己 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...