一、数组的基本概念
1. 定义:
值的有序集合。
值被称为数组的元素。元素位置称为索引(0-2^32-2);数组是动态的,会根据需要增减。稀疏与稠密数组:length均大于最大的索引号。
2. 创建:
- 数组直接量创建
- 调用构造函数Array():
1. 无参数:var a=new Array();
创建的是空数组,相当于数组直接两[];
2.一个数值参数:var a=new Array(10);
创建的是指定长度的数组;
3.显示指定两个或多个参数:var a=new Array(5,4,3,2,1,"testing,testing")
,构造函数的参数成为新数组的元素。
3.数组的读写:
使用[]操作符来访问数组元素。
注意:属性名与索引:在0-2^32-2范围内的非负整数属性名才是索引,数组会自动维护其length属性值。
4.稀松数组:
包含从0开始的不连续索引的数组。
创建方法:
* 使用一个数值参数的Array构造函数
* 指定数组的索引值大于当前数组长度
* delete操作符
5.数组长度
稠密数组中length=数组中的元素个数;
设置length属性小于当前长度的非负整数值n时,数组中≥n的元素会被删除掉;
6.数组元素的添加和删除:
- 添加:为新索引赋值;push()和unshift()方法在末尾或开头增加数组元素。
- 删除:delete操作,副作用是变为稀松数组;pop()和shift()方法在末尾或开头删除数组元素。
7.数组遍历:
for(var i=0,len=keys.length;i<len;i++){/*语句*/}
在对稀松的数组使用for循环遍历时进行检测;也可使用for/in循环进行遍历。
8.多维数组:
JavaScript不支持多维数组,但可用数组的数组近似获得(即数组的元素为数组)。
二.数组方法:
(一)ECMAScript3在Array.prototype中定义的一些操作数组的函数。
- join():将所有元素转化为字符串并连接在一起,返回最后生成的字符串;
var a=[1,2,3];
a.join(); //=>"1,2,3"
a.join(" ") //=>"1 2 3"
a.join("") //=>"123"
var b=new Array(10); //长度为10的空数组;
b.join('-') //=>'---------':9个连字符组成的字符串
- reverse():将数组中的元素颠倒顺序,返回逆序的数组;
var a=[1,2,3];
a.reverse().join(); //=>"3,2,1",并且现在的a是[3, 2, 1]
- sort():将数组的元素排序并返回排序后的数组。当不带参数时调用按照字母表顺序排序(如包含undefined会被排到尾部);如果按照其他方式,需要传递一个比较函数。这个函数决定了它的两个参数在排好序的数组中的先后顺序。假设第一个参数应该在前,则比较函数应该返回一个小于0的数值;反之,如第一个参数应该在后,则返回大于0的数值;并且假设两个值相等则返回0;
var a=[33,4,1111,222];
a.sort() //=>字母表顺序:[1111, 222, 33, 4]
a.sort(function(a,b){
return a-b;
}) //=>数值顺序:根据返回的正负或0来判断;[4, 33, 222, 1111]
a.sort(function(a,b){
return b-a;
}) //=>数值相反的顺序:[1111, 222, 33, 4]
更复杂的排序:
var a=['ant','Bug','cat','Dog']
a.sort(); //区分大小写的排序:["Bug", "Dog", "ant", "cat"]
a.sort(function(s,t){//不区分大小写的排序
var a=s.toLowerCase();
var b=t.toLowerCase();
if(a<b) return -1;
if(a>b) return 1;
return 0;
}); //=>["ant", "Bug", "cat", "Dog"]
- concat():创建并返回一个数组。它的元素包括调用concat()的原始数组的元素和concat()的每个参数。
注意:如果这些参数中的任何一个自身是数组,则连接的是数组的元素,而非数组本身。但不会递归。
var a=[1,2,3];
a.concat(4,5); //返回[1,2,3,4,5]
a.concat([4,5]); //返回[1,2,3,4,5]
a.concat([4,5],[6,7]);//返回[1,2,3,4,5,6,7]
a.concat(4,[5,[6,7]]);//返回[1,2,3,4,5,[6,7]]
- slice():返回制定数组的一个片段或子数组。它的两个参数分别指定了开始和结束位置。其中负数表示相对于数组中最后一个元素的位置。返回的数组包含第一个参数指定位置到不包含第二个参数之间的所有数组元素。
注意:slice()不会修改调用的数组
var a=[1,2,3,4,5];
a.slice(0,3) //返回[1,2,3]
a.slice(3) //返回[4,5]
a.slice(1,-1) //返回[2,3,4]
a.slice(-3,-2) //返回[3]
- splice():在数组中插入或删除元素的通用方法,会修改调用的数组。
splice()的前两个参数指定了需要删除的数组元素。紧随其后的任一个数的参数指定了需要插入到数组中的元素,从第一个参数的位置开始插入。
splice()返回一个由删除元素组成的数组,或者如果没有删除就返回一个空数组
var a=[1,2,3,4,5,6,7,8];
a.splice(4); //返回[5,6,7,8],a是[1, 2, 3, 4]
a.splice(1,2); //返回返回[2,3],a是[1, 4]
a.splice(1,1); //返回[4],a是[1]
var a=[1,2,3,4,5];
a.splice(2,0,'a','b') //返回[],a是[1, 2, "a", "b", 3, 4, 5]
a.splice(2,2,[1,2],3) //返回["a", "b"],a是[1, 2, [1,2], 3, 3, 4, 5]
- push()与pop():
这两个方法允许将数组当做栈来使用。
- push()方法在数组的尾部添加一个活多个元素,并返回数组的长度。
- pop()方法则相反,它删除数组的最后一个元素,减小数组的长度并返回它删除的值。
注意:会修改并替换原始数组
- unshift()与shift():
这两个方法行为非常类似于push()与pop();不一样的是它是在数组的头部而不是尾部进行元素的插入和删除操作。 - toString()与toLocalString():
数组和其他JavaScript对象一样拥有toString()方法。针对数组,该方法将其每个元素转化为字符串并且用逗号隔开。(和不加任何参数的join()方法返回的字符串一样)。toLocalString是本地化版本。
下列代码在谷歌浏览器打开时,会弹出“Uncaught TypeError: Cannot read property 'toString' of undefined”错误,放到console.log()中不会
[1,2,3].toString() //'生成1,2,3'
["a","b","c"].toString()//生成'a,b,c'
[1,[2,'c']].toString()//生成'1,2,c'
(二)ECMAScript5定义了9个新的数组方法来遍历、映射、过滤、检测、简化和搜索数组。
一般性规律:大部分ES5的数组方法第一个参数都是接收一个函数并对数组的每一个元素进行调用,大多数情况下调用提供的函数使用三个参数:数组元素、数组索引和数组本身。第二个参数是可选的。
- forEach():从头至尾遍历数组,为每个元素指定调用的函数。
var data=[1,2,3,4,5];
//计算数组元素的和值
var sum=0;
data.forEach(function(value){
sum +=value;
})
sum //=>15
- map():将调用的数组的每个元素传递给指定的函数,并返回一个数组,它包含函数的返回值。注意返回的是新数组,不会修改调用的数组
var a=[1,2,3];
b=a.map(function(x){
return x*x
}); //b是[1,4,9]
- filter():返回的数组元素是调用的数组的一个子集。传递的函数事用来做逻辑判定的,该函数返回true或false;
var a=[5,4,3,2,1];
smallvalues=a.filter(function(x){
return x<3
}) //[2,1]
everyother=a.filter(function(x,i){
return i%2==0
}) //[5, 3, 1]
- every()与some()
- reduce()与reduceRight()
- indexOf()与lastIndexOf()
三、数组类型
1.定义:
数组是具有特殊行为的对象。给一个未知的对象,判定它是否为数组非常有用。
- ECMAScript5中可以用Array.isArray()函数来做;
Array.isArray([]); //=>true
Array.isArray({}); //=>false`
- 在ES5之前,typeof帮不上忙对数组仅返回“对象”,instanceof操作符只能用于简单的情形(web多窗体或窗口存在)。
//ES5之前判断对象时数组的方法
var isArray=Function.isArray || function(o){
return typeof o ==="object" &&
Object.prototype.toString.call(o)==="[object Array]"
}
2.类数组对象
- 定义:把拥有一个数值length属性和对应非负整数属性的对象看做一种类型的数组。
Arguments对象就是一个类数组对象,DOM方法如document.getElementsByTagName()也返回类数组对象。
//下面这个函数用来检测类数组对象
//判定o是否为一个类数组对象
//字符串和函数有length属性,但是它们可以用typeof检测将其排除。
//在客户端JavaScript中,DOM文本节点也有length属性,需要额外判断o.nodeType!=3将其排除
function isArrayLike(o){
if(o && //o非null、undefined等
typeof o==="object" && //o是对象
isFinite(o.length) && //o.length是有限数值
o.length >=0 && //o.length为非负值
o.length===Math.floor(o.length)&& //o.length是整数
o.length<4294967296) //o.length<2^32
return true;
else
return false; //否则它不是
}
- 类数组对象没有继承自Array.prototype,不能直接在它们上面调用数组方法,可以间接地使用Function.call方法调用。
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"]
//在Firefox 1.5中将这些方法的版本在Array构造函数上直接定义为函数,这样上述例子可以这样重写
var a={"0":"a","1":"b","2":"c",length:3};
Array.join(a,"+")
Array.slice(a,0)
Array.map(a,function(x){return x.toUpperCase();})
//由于这些不是标准的,可以增加以下代码兼容所有浏览器:
Array.join=Array.join || function(a,sep){
return Array.prototype.join.call(a,sep);
}
Array.slice=Array.slice || function(a,from,to){
return Array.prototype.slice.call(a,from,to);
}
Array.map=Array.map || function(a,f,thisArg){
return Array.prototype.map.call(a,f,thisArg)
}
3.作为数组的字符串
除用charAt()方法访问单个字符以外,可以用方括号。另可将通用的数组方法应用到字符串上。
var s="JavaScript";
Array.prototype.join.call(s," ") //=>J a v a S c r i p t
Array.prototype.filter.call(s,function(x){ //过滤字符串的字符
return x.match(/[^aeiou]/); //只匹配非元音字符
}).join("")
请记住:字符串是不可变值,故把它们看做数组时,它们也是只读的。如push()、sort()、reverse()和splice()等数组方法在字符串上市无效的,且使用数组方法修改字符串导致错误,出错的时候是没有提示的