陣列是一組依序排列的值,相對地,物件的屬性名稱是無序的。從本質上講,陣列使用數字作為查找鍵,而物件擁有使用者自訂的屬性名稱。 javascript沒有真正的關聯數組,但物件可用來實現關聯的功能
Array()只是一種特殊類型的Object(),也就是說,Array()實例基本上是擁有一些額外功能的Object()實例。陣列可以保存任何類型的值,這些值可以隨時更新或刪除,且陣列的大小是動態調整的
除了物件之外,陣列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]];
有三種方式呼叫建構子
# 【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
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'
#
var a = []; //索引 a['1000'] = 'abc'; a[1000] // 'abc' //索引 a[1.00] = 6; a[1] // 6
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
每個陣列都有一個length屬性,就是這個屬性使其區別於常規的JavaScript對象。針對稠密(也就是非稀疏)數組,length屬性值代表數組中元素的個數,其值比數組中最大的索引大1
[].length //=>0:数组没有元素 ['a','b','c'].length //=>3:最大的索引为2,length为3
[,,,].length; //3 (Array(10)).length;//10 var a = [1,2,3]; console.log(a.length);//3 delete a[1]; console.log(a.length);//3
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
【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循环
有三个常见的类数组对象:
【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']
以上是JavaScript中關於建立和使用array數組的探討的詳細內容。更多資訊請關注PHP中文網其他相關文章!