数组是数据的有序列表,与其他语言不同的是,ECMAScript 数组的每一项可以保存任何类型的数据。也就是说,可以用数组的第一个位置来保存字符串,用第二位置来保存数值,用第三个位置来保存对象, 以此类推
牢记:
Javascript中的数组并不像我们在C或java等语言中遇到的常规数组,在js中数组并不是起始地址+长度构成的一片连续的地址空间。
Javascript中数组其实就是个对象,只不过会自动管理一些数字属性和length属性罢了。
说的更直接一点,Javascript中的数组根本没有索引,因为索引应该是数字,而Javascript中数组的索引其实是字符串
创建数组
构造函数方式
1.无参构造函数,创建一空数组
var colors = new Array();
2.创建指定长度的数组,一个数字参数构造函数,指定数组长度(由于数组长度可以动态调整,作用并不大)
var colors = new Array(5);
3.带有初始化数据的构造函数,创建数组并初始化参数数据
var colors = new Array(red, blue, green);
使用Array构造函数是可以省略new操作符,如下:
var colors = Array(3); // 创建一个包含 3 项的数组var names = Array("Greg"); // 创建一个包含 1 项,即字符串"Greg"的数组
注意,这里有个坑!同样是使用构造函数的方式,并传递一个值,new Array(2)与new Array("2")是有区别的
new Array(2) // ["undefined", "undefined"]new Array("2") // ["2"]
字面量方式
数组字面量由一对包含数组项的方括号表示,多个数组项之间以逗号隔开,如下所示:
var colors = ["red", "blue", "green"]; // 创建一个包含 3 个字符串的数组var names = []; // 创建一个空数组var values = [1,2,]; // 不要这样!这样会创建一个包含 2 或 3 项的数组var optiOns= [,,,,,]; // 不要这样!这样会创建一个包含 5 或 6 项的数组
字面量方式创建数组的兼容问题
字面量数组长度IE8及以下IE8以上[red, blue, green]33[red, blue, , green]44[red, blue, green, ,]43[, , , , ,]65数组 VS 对象
Javascript中数组其实就是个对象,只不过会自动管理一些数字属性和length属性
var a1=[1,2,3,4];console.log(a1[0]); //1var i=1;console.log(a1[i]); //2console.log(a1[++i]); //3
数组也是对象,我们可以使用索引的奥秘在于,数组会把索引值转换为对应字符串(1=>”1”)作为对象属性名,验证:
console.log(1 in a1);//true,确实是一个属性
索引特殊性在于数组会自动更新length属性,当然因为Javascript语法规定数字不能作为变量名,所以我们不能显示使用array.1这样的格式。由此可见其实负数,甚至非数字”索引“都是允许的,只不过这些会变成数组的属性,而不是索引
var a = new Array(1,2,3);a[-10] = "a[-10]";a["sss"] = "sss";console.log(a); // [1, 2, 3, -10: "a[-10]", sss: "sss"]
为对象添加数组方法
var blankArray = [];var obj = { splice: blankArray.splice, push: blankArray.push, unshift: blankArray.unshift, pop: blankArray.pop, shift: blankArray.shift};obj.push();obj.unshift();obj.pop();obj.shift();
数组中的length属性
数组的length属性不是只读的1.通过设置这个属性,可以从数组的末尾移除项或向数组中添加新项
var colors = ["red", "blue", "green"]; // 创建一个包含 3 个字符串的数组 colors.length = 2;alert(colors[2]); //undefined
2.利用 length 属性也可以方便地在数组末尾添加新项
var colors = ["red", "blue", "green"]; // 创建一个包含 3 个字符串的数组colors[colors.length] = "black"; //(在位置3)添加一种颜色colors[colors.length] = "brown"; //(在位置4)再添加一种颜色
3.利用length属性删除/清空数组
var arr = [1,2,3,4];arr.length = 2;console.log(arr[2]); // "undefined"arr.length = 0;console.log(arr); // []
密集数组与稀疏数组
密集数组:在Java和C语言中,数组是一片连续的存储空间,有着固定的长度。加入数组其实位置是address,长度为n,那么占用的存储空间是address[0],address[1],address[2].address[n-1]。即数组元素之间是紧密相连的,不存在空隙。如下的js代码创建的就是一个密集数组
var data = [3,1,6,9,2];
稀疏数组:与密集数组相反,Javascript并不强制要求数组元素是紧密相连的,即允许间隙的存在。如下的js代码是合法的:
var sparse = new Array(); sparse[0] = 0; sparse[3] = 3; alert(sparse[0]);//输出0 alert(sparse[1]);//输出undefined
密集数组的创建: var dense = Array.apply(null, Array(3));
稀疏数组与密集数组便利区别:
// 稀疏数组 var array = new Array(3); array[2] = "name"; for(var a in array){ console.log("index=" + a + ",value=" + array[a]); } // 密集数组 var dense = Array.apply(null, Array(3)); dense[2] = "name"; for(var a in dense){ console.log("index=" + a + ",value=" + dense[a]); }// 结果// 稀疏数组:index=2,value=name// 密集数组:index=0,value=undefined// index=1,value=undefined// index=2,value=name
差别:稀疏数组只遍历了已存在元素的次数,密集数组遍历了arr.length次
伪数组(类数组)
特点:1.具有length属性;2.按索引方式存储数据;3.不具有数组的push()、pop()等方法;
伪数组无法直接调用数组方法或期望length属性有什么特殊的行为,不具有数组的push()、pop()等方法,但仍可以对真正数组遍历方法来遍历它们。
常见的伪数组类型:1.function内的arguments对象;2.调用getElementsByTagName, document.childNodes之类的,返回的NodeList对象都属于伪数组;3.自定义对象的伪数组;
如何将伪数组转换成数组?1.声明一个空数组,通过遍历伪数组把它们重新添加到新的数组(不推荐)
var links = document.querySelectorAll('a');var arr = [];for (var i = 0; i arr[arr.length] = links[i]}
2.使用数组的slice()方法 它返回的是数组,使用call或者apply指向伪数组
var arr = Array.prototype.slice.call(links);
3.原型继承
links.__proto__ = Array.prototype;
4.ES6中数组的新方法 from()
var arr = Array.from(links);
清空数组的几种方式
1.length赋值为0
var arr = [1,2,3,4];arr.length = 0;console.log(arr); // 输出 [],空数组,即被清空了
2.splice
var arr = [1,2,3,4];arr.splice(0,arr.length);console.log(arr); // 输出 [],空数组,即被清空了
3.赋值为[]
var arr = [1,2,3,4];arr = []; // 赋值为一个空数组以达到清空原数组