数组
数组是值的有序集合.每个值叫做一个元素,而每个元素在数组中由一个位置,以数字表示,称为索引.数组的元素可以是任意类型,这意味着数组可以表示极为复杂的数据结构.
每一个数组都有一个length属性,对于非稀疏数组而言,length就等于数组元素的个数,对于稀疏数组,length比所有元素的索引要大
创建数组
1.数组直接量
这也是最简单的方法,数组元素用逗号隔开,所有元素用方括号括起来即可.
如果省略数组直接量中的某个值,省略的元素将被赋予undefined值,结尾用逗号忽略
2.调用构造函数Array()
var a = new Array();//该方法创建一个空数组,等同于[]
var a = new Array(10);//指定长度的数组,该方法可以预分配一个数组空间
var a = new Array(5,4,3,2,1,"testing,testing")//显式指定两个或多个数组元素或者数组的一个非数值元素
数组元素的读和写
var a = ["world"];
var value = a[0];//读取第0个元素
a[1] = 3.14 //写第1个元素
数组是对象的特殊形式,使用方括号访问数组元素就像用方括号访问对象的属性一样.
数组的特殊之处在于,当使用小于2的32次方的非负整数作为属性名时数组会自动维护length的值,对于数组而言,所有的索引都是属性名,而只有小于2的32次方的非负整数才是索引.
可以使用负数或非整数来索引数组,,这种情况下,数组转换为字符串,字符串作为属性名来用.而这样只能当作常规的对象属性,而非数组的索引,而如果使用了非负整数的字符串,它就当作数组索引,而非对象属性.
a[-1.23] = true; //创建一个名为-1.23的属性
a["1000"] = 0 ;//这是数组的第1001个元素
a[1.00] //跟a[1]一样
数组索引仅仅是对象属性名的一种特殊类型,数组既然是对象,就可以从原型中继承元素.数组也可以定义元素的getter和setter方法.
稀疏数组
稀疏数组就是包括从0开始的不连续索引的数组.对于稀疏数组而言,length属性值大于元素个数.可以用Array()构造函数或简单地指定数组的索引值大于当前数组长度来创建稀疏数组
a = new Array(5); //数组没有元素,但是a.length为5 ps:创建五个没有元素但是长度为5的数组
a = []; //创建一个空数组,length为0
a[1000] = 0; //赋值添加一个元素,但设置length为1001
数组长度
每一个数组都有length属性,稠密数组的length等于元素个数,稀疏数组的length则大于元素个数,也就是说,length一定大于等于元素的索引值.为了维持此规则不变,数组有两个特殊行为:
1.如果为一个数组元素赋值,它的索引i大于等于当前数组长度时,length属性的值将设置为i+1
2.设置length的属性为一个小于当前长度的数组时,当前数组中的索引值大于等于length的元素会被删除
数组元素的添加和删除
1.为新索引值赋值
a = [];
a[1] = 0;
2.push()方法
a = [1];
a.push(0);//[1,0]
3.unshift()方法
a = [1];
a.unshift(0);//[0,1]
删除对象属性一样使用delete运算符来删除数组
a = [1,2,3]
delete a[1];//[1,3]但length不变依然是3
delete删除数组元素不改变length属性,此数组将变成稀疏数组
数组方法
- join()
Array.join()方法可以将数组中的所有元素转化为字符串并连接在一起,返回最后生成的字符串
var a = [1,2,3];
a.join();//"1,2,3"
a.join(" ");//"1 2 3"
Array.join()方法是String.split()方法的逆向操作,后者是将字符串分割成若干创建一个数组
- reverse()
Array.reverse()方法将数组的元素颠倒顺序,返回逆序的数组,并且它不创建新数组,而是在原先的数组中重新排列它们.
var a = [1,2,3];
a.reverse().join();//"3,2,1"而且这就是a
- sort()
Array.sort()方法将数组中的元素排序并返回排序后的数组.不带参数调用时,数组元素将以字母表顺序排列.
var a = new Array("banana","cherry","apple");
a.sort();
var s = a.join(", ");//s == "apple, banana, cherry"
数组的undefined元素会被排到尾部
第一个参数应该是一个决定排序的函数
var a = [11,22,33,44];
a.sort(function(a,b){return a-b});//11,22,33,44
a.sort(function(a,b){return b-a});//44,33,22,11
- concat()
Array.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]]
- slice()
Array.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()
Array.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]
- push()和pop()
这两方法允许将数组当成栈来使用,push()在数组尾部添加元素并返回新的长度,pop则弹出元素
这两个方法都修改并替换原始数组而非生成一个修改版的新数组.
- unshift()和shift()
类似上一个方法,不同在于是针对数组的头部进行操作.
- toString()和toLocaleString()
数组也是特殊的对象,自然也有该方法,针对数组,该方法将其每个元素转化为字符串并且输出用逗号分隔的字符串列表,效果与不使用参数的join方法一样
除了上述方法外,ES5中定义了9个新的数组方法来遍历,映射,过滤,检测,简化和搜索数组
- forEach()
forEach()方法从头至尾遍历数组,为每个元素调用指定的函数.
var data = [1,2,3,4,5];
var sum = 0;
data.forEach(function(value){sum+=value;})//每个值累加到sum上
forEach()无法在所有元素都传递给函数前结束遍历,所以只能通过抛出异常的方法结束遍历
- map()
map()方法将调用的数组的每个元素传递给指定函数,并返回一个数组,它包含该函数的返回值.
a = [1,2,3];
b = a.map(function(x){return x*x;});//[1,4,9]
map()和forEach()很像,调用方式一样,但传递给map()的函数需要有返回值,而且map()返回的是新数组,它不修改调用的数组,如果是稀疏数组,返回的也是稀疏数组,相同的长度,相同的空缺
- filter()
filter()方法返回的数组元素是调用的数组的一个子集.传递的函数是用来逻辑判定的,返回一个布尔值,为true便成为这个子集的成员
a = [5,4,3,2,1];
smallvalues = a.filter(function(x){return x<3});//[2,1]
everyother = a.filter(fucntion(x,i){return i%2 == 0});//[5,3,1]
该方法返回的是稠密数组,会跳过稀疏数组中缺少的元素
- every()和some()
every()和some()方法是数组的逻辑判定:它们对数组元素应用指定的函数进行判断,返回布尔值
every():当且仅当针对数组中的所有元素调用判断函数都为true时,才返回true
a = [1,2,3,4,5];
a.every(function(x){return x<10});//true
some():当数组中至少有一个元素调用判断函数返回值为true时为true,全为false才为false
a = [1,2,3,4,5];
a.some(function(x){return x%2 == 0});//true
这两个方法当知道要返回什么值时就会停止遍历
- reduce()和reduceRight()
reduce()和reduceRight()方法使用指定的函数将数组元素进行组合,生成单个值.
var a = [1,2,3,4,5];
var sum = a.reduce(function(x,y){return x+y},0);;//求和
var product = a.reduce(function(x,y){return x*y},0);//求积
var max = a.reduce(function(x,y){return (x>y)?x:y})//求最大值
reduce()第一个参数是执行化简操作的函数.第二个参数是传递给函数的初始值,第二个参数不指定时,默认使用数组的第一个元素作为初始值
reduceRight()工作原理和reduce()相同,但是从右往左处理
-
indexOf()和lastIndexOf()
indexOf()和lastIndexOf()搜索整个数组中具有给定值的元素,返回找到的第一个元素的索引或者没有找到就返回-1.indexOf()从头至尾搜索,lastIndexOf()反向搜索
这两个方法可选择两个参数,第一个参数是需要搜索的值,第二个参数可选,它指定数组中的一个索引,从那里开始搜索,而且也可以是负数,表示相对数组末尾的偏移量
数组类型
判断是否是数组可以用Array.isArray()函数来判断,typeof操作符只会返回对象,无法检测,而instanceof操作符只能用于简单的情形,
索引解决的方法是检测对象的类属性.对数组而言该属性的值是Array.(可用Object.prototype.toString()方法)
类数组对象
数组的特性是其他对象没有的:
- 当有新的元素添加到列表中时,自动更新length属性
- 设置length为一个较小值的时候截断数组
- 从Array.prototype中继承方法
- 类属性为Array
将一个常规对象添加元素,索引值为连续从零开始的正整数,长度为元素的个数,这样这个对象就变成了类数组,可以把这个对象当初数组看待.
类数组没有继承自Array.prototype,就不能直接调用数组方法,但可以通过使用Function.call调用
var a = {"0":"a","1":"b","2":"c"};//类数组对象
Array.prototype.join.call(a,"+");//"a+b+c"
作为数组的字符串
字符串也可以使用索引值读取,例如charAt()方法,或者直接用方括号读取,字符串就像只读的数组,但字符串是不可变值,不可以修改.