Array 类型
除了Object 之外,Array 类型也是相当常用的类型了。ECMAScript 数组的每一项可以保存任何类型的数据。且数组大小也能够动态调整的。
创建数组、读取和设置数组的值
创建数组
创建数组的基本方式有两种:
使用Array 构造函数:
var colors = new Array()
;使用数组字面量表示法;
对于第一种方法,如果知道数组要保存多少个项目,也可以给构造函数传递参数,比如要创建length 值为10 的数组:
var colors = Array(10);
//new 操作符可以省略。
也可以向Array 构造函数传递包含的项。如:
var colors = Array("yellow","red","green");
对于第二种方法,数组字面量由方括号表示,用逗号隔开。如:
var colors = [
"red",
"green",
"blue"
]
console.log(colors); //["red", "green", "blue"]
var boys = [];
document.write(boys.length); //0
读取和设置数组的值
使用方括号和基于0 的数字索引。如:
var colors = [
"red",
"blue",
"yellow"
]
document.write(colors[1]); //"blue" 访问第二项
document.write(colors.length); //3
colors[3] = "cc";
document.write(colors.length); //4 创建一个新的项
document.write(colors[3]); //"cc"
length
属性,数组的项数就保存在length 属性中,这个属性返回0 或更大的值。且该属性可写的,可以从数组的末尾移除或增加项。如:
var colors = [
"red",
"blue"
]
colors[colors.length] = "yellow";
console.log(colors); // ["red", "blue", "yellow"] 在末尾增加了一项"yellow"
colors.length = 2;
console.log(colors); // ["red", "blue"] 在末尾减少了一项
colors.length = 3;
console.log(colors); //["red", "blue", undefined × 1] 在末尾增加了一项undefined
利用length
属性,可以方便地在数组末尾添加新项,如:
var colors = ["red"];
colors[colors.length] = "yellow";
《js 高级程序设计》提到:
数组最多可以包含4 294 967 295 个项。
检测数组
使用
instanceof
操作符:if (value instanceof Array) {}
;使用ECMAScript 5 新增的
Array.isArray()
方法:if (Array.isArray(value))
;
检测数组instanceof
操作符的问题,在这里不深究。支持Array.isArray()方法的浏览器有IE9、FIrefox 4+、Safari 5+、Opera 10.5+和Chrome。
数组的转换
通常,用toString()
方法会返回数组中每个值的字符串形式拼接而成的以逗号分隔开来的字符串;用valueOf()
方法则仍然返回数组。
var colors = ["red","yellow"];
var color1 = colors.toString();
document.write(typeof color1); //string 使用toString() 方法,返回的是用逗号分割的字符串;
var color2 = colors.valueOf();
document.write(typeof color2); //object
console.log(color2) //使用valueOf() 方法,返回的仍然是数组;
另外,还可以使用toLocaleString()
方法,如:
var person = {
toLocaleString:function(){
return "Oliver";
},
toString:function(){
return "Troy";
}
};
var age = {
toLocaleString:function(){
return "adult";
},
toString:function(){
return "children";
}
};
var people = [person,age];
document.write(people.toString()); //Troy,children 返回每个数组里面的每个对象的toString 返回的值
document.write(people.toLocaleString()); //Oliver,adult 返回每个数组里面的每个对象的toLocaleString 返回的值
document.write(people.valueOf()); //Troy,children
document.write(people.join(" is a ")); //Troy is a children 改变两个数组链接起来的分隔符
可以使用join()
方法来控制数组的连接符。
栈方法和队列方法
栈方法(表现的像栈一样)
ECMAScript 数组可以表现的像栈一样。栈是一种LIFO(Last-In-First—Out,后进先出),只发生在一个位置——栈的顶部。
有两个方法push()
和pop()
方法。具体的来说,push()
方法可以接收任意数量的参数,把它们逐个添加到数组的末尾,并返回修改后的数组的长度;pop()
方法则可以从数组的末尾移除最后一项,减少数组的length 值,并返回移除的项。如:
添加项:
var array = [1,2,3,4];
console.log(array); //[1, 2, 3, 4] 目前该array 有4项
var count = array.push("str","34"); //末尾增加了一项"str"和一项"34"
console.log(count); //6 这时返回的长度增加2
console.log(array); //[1, 2, 3, 4, "str", "34"]
console.log(array.length); //6
减少项:
var array = [1,2,3,4];
console.log(array); //[1, 2, 3, 4] 目前该array 有4项
var count = array.pop();
console.log(count); //4 减少了一个"4"
console.log(array); //[1, 2, 3]
队列方法
队列数据结构的访问规则是FIFO(First-In-First-Out),结合使用shift()
和push()
方法,可以像使用队列一样使用数组。shift()
可以移除数组中的第一个项,并返回该项。如:
var array = [];
var count = array.push("1","2");
document.write(count);
document.write(array); //[1,2]
count = array.push("3");
document.write(count);
document.write(array); //[1,2,3]
var item = array.shift();
document.write(item); //1
document.write(array); //[2,3]
另外,还有一个叫unshift()
方法,同时使用unshift()
和pop()
方法,可以从相反的方向来模拟队列,即在前端添加项,末端移除项。如:
var array = [];
var count = array.unshift(1,2,3);
document.write(count); //3
document.write(array); //[1,2,3]
count = array.unshift(0);
document.write(count); //4
document.write(array); //[0,1,2,3]
item = array.pop();
document.write(item); //3
document.write(array); //[0,1,2]
需要注意的是:
shift()
返回的是前端删除的项的值;unshift()
返回的是前端增加后数组的长度;pop()
返回的是末端删除的项的值;push()
返回的是末端增加后数组的长度。总的来说就是“删除返回项的值,增加则返回长度”
重排序方法
有两个重排序方法:reverse()
和sort()
。
sort()
方法按照升序排列数组项,如:
var array = [4321,3,43,"56",6543,32,65,765];
array.sort(); //3,32,43,4321,56,65,6543,765
乱七八糟,只比较了第一位数。
比较函数接收两个参数,如果第一个参数应该位于第二个之前,则返回一个复数,如果两个参数相等则返回0,如果第一个参数应该位于第二个参数后面,则返回一个正数。通常返回第二个参数减掉第一个参数的值就可以了(在数值类型或其valueOf()方法返回数值类型的对象类型的情况下)。如:
var array = [3,1,6,"10"];
array.sort(compare);
function compare(value1,value2){
return value1 - value2; //如果value1 - value2 是正数,则说明value1 大于value2,value1 应该排在后面。为升序排列;
};
document.write(array); //[1,3,6,10]
如果想要降序排列,则修改一下compare函数成value2 - value1 就可以了。如:
var array = [3,1,6,"10"];
array.sort(compare);
function compare(value1,value2){
return value2 - value1; //如果value2 - value1 是正数,则说明value2 大于value1,value1 应该排在后面。为降序排列;
};
document.write(array); //[10,6,3,1]
但是如果是任意类型,则不能使用这种方法。而应当对参数进行比较。如:
var array = ["Oliver","Troy",{name:"troy"},"Alice"];
array = array.sort(compare);
document.write(array); //Alice,Oliver,Troy,[object Object]
function compare(x,y){
if(x > y){
return 1;
}else if(x < y){
return -1;
}else{
return 0;
}
}
或者:
var array = ["Oliver","Troy",{name:"troy"},"Alice"];
array = array.sort(compare);
document.write(array); //Alice,Oliver,Troy,[object Object]
function compare(x,y){
if(x < y){
return 1;
}else if(x > y){
return -1;
}else{
return 0;
}
}
如果只是想翻转原来数组的顺序,使用reverse()
方法就行了,如:
var array = [3,1,6,"10"];
array.reverse();
document.write(array); //10,6,1,3
操作方法
concat()
方法,主要作用就是复制当前的数组并返回副本。如:(不影响原始数组)
var array = ["abc",123,{name:"Oliver"}];
var newArray = array.concat("abc",[123,32,{age:18}]);
document.write(newArray); // abc,123,[object Object],abc,123,32,[object Object]
slice()
方法,主要作用是基于当前数组中的一个或多个项创建的一个新数组。如:(不影响原始数组)
var array = ["a","b","c","d"];
var newArray = array.slice(2);
document.write(newArray); //c,d
newArray = array.slice(1,2);
document.write(newArray); //b
如果只有一个参数,返回从该参数指定位置到数组末尾的所有项;如果有两个参数,返回起始位置和结束位置之间的项,但不包括结束位置的项。如果,参数中有负数,则用数组长度加上该数来确定相应的位置。
splice()
的主要用法:
删除,2个参数:要删除的第一项和要删除的项数;
插入,3个参数:起始位置、0(要删除的项数)和要插入的项;
替换,3个参数:起始位置、要删除的项数和要插入的任意数量的项;
该方法始终都会返回一个数组。举个例子:
删除:
var cars = ["宝马","奔驰","沃尔沃"];
var deleteCar = cars.splice(1, 2);
console.log(deleteCar); //["奔驰", "沃尔沃"]
插入:
var cars = ["宝马","奔驰","沃尔沃"];
var addCar = cars.splice(1, 0, "特斯拉","保时捷");
console.log(cars); //["宝马", "特斯拉", "保时捷", "奔驰", "沃尔沃"]
替换:
var cars = ["宝马","奔驰","沃尔沃"];
var replaceCar = cars.splice(1, 1, "保时捷");
console.log(replaceCar); //["奔驰"] 删除了奔驰
console.log(cars); //["宝马", "保时捷", "沃尔沃"] 用保时捷替换了奔驰
位置方法
indexOf()
方法和lastIndexOf()
方法。一个是从数组的开头(位置0)开始向后查找;另一个则是从数组的末尾开始向前查找。有两个参数:要查找的项和表示查找起点的位置索引。在比较第一个参数与数组中的每一项时,会使用全等操作符。如:
var numbers = [1,2,3,4,5,3];
document.write(numbers.indexOf(4)); //3
document.write(numbers.indexOf(4,5)); //-1 从第5索引开始查找,找不到就返回-1
document.write(numbers.lastIndexOf(3)); //5
document.write(numbers.lastIndexOf(3,0)); //-1 从第0索引开始反向查找,找不到就返回-1
document.write(numbers.indexOf(3)); //2 这里有两个3 但是当搜索到第一个时就会停止搜索
Mark!!!!!!
Mark!!!!!!
Mark!!!!!!
var oliver = {name:"oliver"};
var person = [{name:"oliver"}];
var people = [oliver];
document.write(person.indexOf({name:"oliver"})); //-1
document.write(person.indexOf(oliver)); //-1
document.write(people.indexOf({name:"oliver"})); //-1
document.write(people.indexOf(oliver)); //0 必须变量搜索变量
迭代方法和归并方法
迭代方法
有5 个迭代方法,每个方法接收两个参数:要在每一项上运行的函数和作用域对象(可选);传入这些方法中的函数则接收三个参数:数组项的值(item)、索引位置(index)、数组对象本身(array)。
every()
:每一项运行该函数,如果都返回true,则返回true;(返回Noolean)(主要是验证)some()
:每一项运行该函数,如果其中任一项返回true,则返回true;(返回Boolean)(主要是验证)filter()
:每一项运行该函数,对于那些返回true的项,组成一个数组;(返回Array)(主要是验证)map()
:每一项运行该函数,返回的结果组成一个数组;(返回Array)(对数组操作)forEach()
:每一项运行该函数,没有返回值;(不返回)(对数组操作)(本质上与for 语句类似)
下面是例子:
every()
:
var numbers = [1,3,2,5,4];
var result = numbers.every(function(item, index, array){
return item > 0;
});
document.write(result); //都大于零,返回true
some()
:
var numbers = [1,5,4,32];
var result = numbers.some(function(item, index, Array){
return item > 31;
});
document.write(result); //true 数组中至少有一项满足条件,返回true
filter()
:
var array = [123,"Oliver","Troy",true];
var newArray = array.filter(function(item, index, array){
return typeof item == "string";
});
console.log(newArray); //["Oliver", "Troy"] 把满足条件的部分返回一个数组
map()
:
var array = [123,"Oliver","Troy",true];
var newArray = array.map(function(item, index, array){
return item += " (Oliver)";
});
console.log(newArray); //["123 (Oliver)", "Oliver (Oliver)", "Troy (Oliver)", "true (Oliver)"]
forEach()
:
var array = [123,"Oliver","Troy",true];
array.forEach(function(item, index, array){
if (typeof item == "number"){
document.write((item + 877) + "<br/>");
}else if (typeof item == "string"){
document.write("This is a string: " + item + "<br/>")
}else{
document.write(item + "ly")
}
});
/*
1000
This is a string: Oliver
This is a string: Troy
truely
*/
归并方法(ECMAScript 5 新增)
两个方法:reduce()
和reduceRight()
,这两个方法都会迭代数组的所有项,然后构建一个最终返回的值。前者是从数组的第一项开始,后者是从数组的最后一项开始。他们有两个参数:一个在每一项上调用的函数和最为归并基础的初始值。函数则包括4 个参数:前一个值(prev)、当前值(cur)、项的索引(index)、数组本身(array)。如:
var numbers = [1,3,2,4,5,7,6];
var result = numbers.reduce(function(prev, cur, index, array){
return prev + cur;
});
console.log(result); //28
又如:
var array = [321,false,"Oliver",21];
var newArray = array.reduce(function(prev, cur, index, array){
return prev + cur;
});
console.log(newArray); //321Oliver21
newArray = array.reduceRight(function(prev, cur, index, array){
return prev + cur;
});
console.log(newArray); //21Oliverfalse321 这里出现了false 是因为+ 操作符的原因
console.log(21+"oliver"+false+321); //false 被转换成字符串
console.log(321+false+"oliver"+21); //false 被转换成数值
console.log(321+(false+"oliver"+21)); //false 被转换字符串,括号的原因
(今天内容还真是有点多,看007去了,回来再复习)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。