第七章、数组
数组是值的集合。
JavaScript数组是无类型的
JavaScript数组是动态的
JavaScript数组是稀疏的
数组继承自Array.prototype中的属性
创建数组
1.数组直接量
var empty = []; //没有元素的数组
var primes = [2,3,4,5,6]; //有5个数值的数组
var misc = [1.1,true,"a", ]; //3个不同类型的元素和结尾的逗号复制代码
(1).数组直接量中的值不一定要是常量;它们可以是任意的表达式
var base = 1024;
var table = [base,base+1,base+2,base+3];复制代码
(2).它可以包含对象直接量或其他数组直接量
var b = [[1,{x:1,y:2}],[2,{x:3,y:4}]];复制代码
(3).如果省略数组直接量中的某个值,省略的元素将被赋予undefined值:
var count = [1,,3]; //数组有3个元素,中间的那个元素值为undefined
var undefs = [,,]; //数组有2个元素,都是undefined复制代码
(4).数组直接量的语法允许有可选的结尾的逗号,故[,,]只有两个元素而非三个
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");复制代码
数组元素的读和写
1.数组的引用位于方括号的左边。方括号中是一个返回非负整数值的任意表达式。
var a = ["world"]; //从一个元素的数组开始
var value = a[0]; //读第0个元素
a[1] = 3.14; //写第1个元素
i = 2;
a[i] = 3; //写第2个元素
a[i + 1] = "hello"; //写第3个元素
a[a[i]] = a[0]; //读第0个和第2个元素,写第3个元素复制代码
2.数组是对象的特殊形式。
o = {};
o[1] = "one"; //用来一个整数来索引它复制代码
3.可以使用负数或非整数来索引数组。数值转换为字符串,字符串作为属性名来用。
a[-1.23] = true; //这将创建一个名为"-1.23"的属性
a["1000"] = 0; //这是数组的第1001个元素
a[1.000]; //和a[1]相等复制代码
4.数组是对象,它们可以从原型中继承元素
稀疏数组
1.稀疏数组就是包含从0开始的不连续索引的数组。
2.数组的length属性值代表数组中元素的个数。
3.如果数组是稀疏的,length属性值大于元素的个数。
a = new Array(5); //数组没有元素,但是a.length是5
a = []; //创建一个空数组,length = 0
a[1000] = 0; //赋值添加一个元素,但是设置length为1001
var a1 = [,,,]; //数组是[unfefined,unfefined,unfefined]
var a2 = new Array(3); //该数组根本没有元素
0 in a1; //=>true:a1在索引0处有一个元素
0 in a2; //=>false:a2在索引0处没有元素复制代码
数组长度
1.每个数组有一个length属性。
[].length; //=>0:数组没有元素
['a','b','c'].length; //=>3:最大的索引为2,length为3复制代码
2.当数组是稀疏的时候,length属性值大于元素的个数
3.设置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)复制代码
4.将数组的length属性值设置为大于当前的长度。实际上这不会向数组中添加新的元素,它只是在数组尾部创建一个空的区域
5.可以用Object.defineProperty()让数组的length属性变成只读的
a = [1,2,3]; //从3个元素的数组开始
Object.defineProperty(a,"length",{
writable:false //让length属性只读
})
a.length = 0; //a不会改变复制代码
数组元素的添加和删除
1.为新索引赋值:
a = []; //开始是一个空数组
a[0] = "zero"; //然后向其中添加元素
a[1] = "one";复制代码
2.push()在数组末尾增加一个或多个元素 ——》pop()
a = []; //开始是一个空数组
a.push("zero"); //在末尾添加一个元素。a = ["zero"]
a.push("one","two"); //再添加两个元素。a = ["zero","one","two"]复制代码
3.unshift()在数组的首部插入一个元素,并且将其他元素依次移到更高的索引处 ——》shift()
4.可以像删除对象属性一样使用delete运算符来删除数组元素
a = [1,2,3];
delete a[1]; //a在索引1的位置不再有元素
1 in a; //=>false:数组索引1并未在数组中定义
a.length; //=>3:delete操作并不影响数组长度复制代码
5.splice()是一个通用的方法来插入,删除或替换数组元素。
数组遍历
1.for()循环
var keys = Object.keys(o); //获得o对象属性名组成的数组
var values = []; //在数组中存储匹配属性的值
for(var i=0;i复制代码
(1).数组的长度应该只查询一次而非每次循环都要查询
for(var i = 0,len = keys.length;i < len;i++){
//循环体仍然不变
}复制代码
(2).使用数组元素之前应该先检测它们。如果想排除null,undefined和不存在的元素
for(var i=0;iif(!a[i]){
continue; //跳过null,undefined和不存在的元素
}
//循环体
}复制代码
(3).如果只想跳过undefined和不存在的元素
for(var i =0;i < a.length;i++){
if(a[i] === undefined){
continue; //跳过undefined +不存在的元素
}
}复制代码
(4).如果只想跳过不存在的元素而仍然要处理存在的undefined元素
for(var i = 0;i < a.length;i++){
if(!(i in a)){
continue; //跳过不存在的元素
}
//循环体
}复制代码
2.for/in循环
for(var index in sparseArray){
var value = sparseArray[index];
//此处可以使用索引和值做一些事情
}复制代码
3.forEach(),按照索引的顺序按个传递给定义的一个函数。
var data = [1,2,3,4,5]; //这是需要遍历的数组
var sumOfSquares = 0; //要得到数据的平方和
data.forEach(function(x){ //把每个元素传递给此函数
sumOfSquares += x*x; //平方相加
})
sumOfSquares; //=>55:1+4+9+16+25复制代码
多维数组
1.访问数组的数组中的元素,只要简单地使用两次[]操作符即可
var table = new Array(10); //表格有10行
for(var i = 0;i < table.length;i++){
table[i] = new Array(10); //每行有10列
//初始化数组
for(var row = 0;row < table.length;row++){
for(var col = 0;col < table[row].length;col++){
table[row][col] = row * col;
}
}
}
//使用多维数组来计算(查询)5*7
var product = table[5][7]; //35复制代码
数组方法
1.join()
(1).Array.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个连字号组成的字符串复制代码
(2).Array.join是String.split()方法的逆向操作,后者是将字符串分割成若干块来创建一个数组
2.reverse()
(1).Array.reverse()方法将数组中的元素颠倒顺序,返回逆序的数组。
var a = [1,2,3];
a.reverse().join(); //=>"3,2,1"并且现在的a是[3,2,1]复制代码
3.sort()
(1).Array.sort()方法将数组中的元素排序并返回排序后的数组。
var a = new Array("banana","cherry","apple");
a.sort();
var s = a.join(", "); // s == "apple, banana, cherry"复制代码
(2).如果数组包含undefined元素,它们会被排到数组的尾部。
var a = [33,4,1111,222];
a.sort(); //字母表顺序:1111,222,33,4
a.sort(function(a,b){ //数值顺序:4,33,222,1111
return a-b; //根据顺序,返回负数,0,正数
})
a.sort(function(a,b){return b-a}); //数值大小相反的顺序复制代码
4.concat()
(1).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]
a.concat(4,[5,[6,7]]); //返回[1,2,3,4,5,[6,7]]复制代码
5.slice()
(1).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]复制代码
6.splice()
(1).Array.splice()方法是数组中插入或删除元素的通用方法。不同于slice()和concat(),splice()会修改调用的数组。
(2).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] 复制代码
(3).splice()的前两个参数指定了需要删除的数组元素。紧随其后的任意个数的参数指定了需要插入到数组中的元素,从第一个参数指定的位置开始插入。
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]复制代码
7.push()和pop()
(1).push()和pop()方法允许将数组当做栈来使用。
(2).push()方法在数组的尾部添加一个或多个元素,并返回数组新的长度。
(3).pop()方法则相反:它删除数组的最后一个元素,减小数组长度并返回它删除的值。
8.unshift()和shift()
9.toString()和toLocaleString()
(1).针对数组,该方法将其每个元素转化为字符串
[1,2,3].toString() //生成'1,2,3'
["a","b","c"].toString() //生成'a,b,c'
[1,[2,'c']].toString() //生成'1,2,c'复制代码
(2).toLocaleString()是toString()方法的本地化版本。
ECMAScript 5中的数组方法
(1).ECMAScript 5定义了9个新的数组方法来遍历,映射,过滤,检测,简化和搜索数组。
(2).forEach()
forEach()方法从头至尾遍历数组,为每个元素调用指定的函数。
- forEach()使用三个参数调用该函数:数组元素,元素的索引和数组本身。
eg:
var data = [1,2,3,4,5];
var sum = 0;
data.forEach(function(value){
sum += value; //=>15
})
data.forEach(function(v,i,a){
a[i] = v +1; //[2,3,4,5,6]
})复制代码
(3).map()
map()方法将调用的数组的每个元素传递给指定的函数,并返回一个数组,它包含该函数的返回值。
map()返回的是新数组,它不修改调用的数组。
eg:
a = [1,2,3];
b = a.map(function(x){
return x * x; //=>b:[1,4,9]
})复制代码
(4).filter()
filter()方法返回的数组元素是调用的数组的一个子集。
filter()传递的函数是用来逻辑判定的;该函数返回true或false
eg:
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]
})复制代码
(5).every()和some()
(6).reduce()和reduceRight()
(7).indexOf()和lastIndexOf()
数组类型
(1).可以使用Array.isArray()函数来判定
Array.isArray([]); //=>true;
Array.isArray({}); //=>false;复制代码
(2).typeof操作符对数组返回"对象"
类数组对象
(1).当有新的元素添加到列表中,自动更新length属性。
(2).设置length为一个较小值将截断数组。
(3).从Array.prototype中继承一些有用的方法。
(4).其类属性为"Array"
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];
}复制代码
(5).Arguments对象就是一个类数组对象。
(6).用来检测类数组对象
//判定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; //o是类数组对象
}else{
return false; //否则它不是
}
}复制代码
(1).
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"]复制代码
(2).
var a = {"0":"a","1":"b","2":"c",length:3} //类数组对象
Array.join.call(a,"+") //=> "a+b+c"
Array.slice.call(a,0) //=>["a","b","c"]:真正数组的副本
Array.map.call(a,function(x){
return x.toUpperCase();
}) //=>["A","B","C"]复制代码
(3).
Array.join = Array.join || function(a,sep){
return Array.prototype.join.call(a,sep)
};
Array.slice = Array.slice || function(a,sep){
return Array.prototype.slice.call(a,sep)
};
Array.map = Array.map || function(a,sep){
return Array.prototype.map.call(a,sep)
}复制代码
作为数组的字符串
(1).字符串的行为类似于只读的数组。除了用charAt()方法来访问单个的字符以外,还可以使用方括号:
var s = "test";
s.charAt(0) //=>"t"
s[1] //=>"e"复制代码
(2).字符串是不可变值,故当把它们作为数组看待时,它们是只读的。
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(" ") //=>"J v S c r p t"复制代码
|版权声明:本文为summer博主原创文章,未经博主允许不得转载。