javascript第三弹——数组

时间:2022-04-14 13:04:38

什么是数组

数组是值的有序集合。每个值叫做元素,每个元素在数组中都有数字位置编号,也就是索引。JS中的数组是弱类型的,数组中可以含有不同类型的元素。数组元素甚至可以是对象或其它数组。数组的长度是动态的。可以执行增删改查等操作。

数组的原型是Array.prototype

创建数组

1、字面量创建

var arr = [];

2、构造器创建

var arr  = new Array();

数组的操作

一、添加元素

1、通过索引添加

var arr = [];
arr[0] = 0;
arr[1] = 1;
arr; //[0,1]

2、通过长度添加

length 属性可设置或返回数组中元素的数目。

var arr = [0,1];
arr[arr.length] = 2; //数组的length属性的值是数组最后一个元素的下一个元素所在位置的索引。
arr; //[0,1,2]

3、通过push方法向数组的末尾添加一个或多个元素

push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。

var arr = [0,1,2];
arr.push(3); //添加一个元素
arr; //[0,1,2,3]
arr.push(4,5); //添加多个元素
arr; //[0,1,2,3,4,5]

4、通过unshift方法向数组的开头添加一个或多个元素

unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。

var arr = [0,1,2,3,4,5];
arr.unshift(-1); //添加一个元素
arr; //[-1,0,1,2,3]
arr.unshift(-3,-2); //添加多个元素
arr; //[-3,-2,-1,0,1,2,3,4,5]

二、删除元素

1、delete删除

var arr = [0,1,2,3];
delete arr[1];
arr; //[0,undefined,2,3]
arr.length; //3

上述例子需要注意的是,通过delete删除后,输出arr.length得到的数组长度仍然为3,因为undefined会占位。

下面使用in操作符来查看刚才删除的元素所在的索引值,结果会返回false

1 in arr;    //false

如果把undefined添加到上述例子中索引值为1的位置后,再用in操作符来查看的话,结果就会返回true

arr[1] = undefined;
1 in arr; //true

2、通过数组长度自建议的方式删除最后一个元素

var arr = [0,1,2];
arr.length -= 1;
arr; //[0, 1]

3、通过pop方法删除数组的最后一个元素

pop() 方法用于删除并返回数组的最后一个元素。

var arr = [0,1,2];
arr.pop();
arr;

4、通过shift方法删除数组的第一个元素

shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。

var arr = [0,1,2];
arr.shift();
arr //[1,2]

数组增删

三、数组的遍历与枚举

1、使用for循环来遍历数组

var i = 0;
var arr = [0,1,2,3,4,5];
for(;i<arr.length;i++){
console.log(arr[i]); //0,1,2,3,4,5
}

2、使用for in来枚举数组

var i = 0;
var arr = [0,1,2,3,4,5];
for(i in arr){
console.log(arr[i]); //0,1,2,3,4,5
}

数组也是对象,也有原型,如果把数组对象的原型添加一个属性为x并且赋值,然后在通过for in来枚举arr数组,看下会返回什么。

var i = 0;
var arr = [0,1,2,3,4,5];
Array.prototype.x = 'last';
for(i in arr){
console.log(arr[i]); //0,1,2,3,4,5,last
}

运行上述例子后,返回0,1,2,3,4,5,last;这是因为for in会把原型上的属性也给枚举出来;如果不想枚举原型上的属性,可以通过hasOwnProperty来判断下,把原型上的属性过滤掉;

for(i in arr){
if(arr.hasOwnProperty(i)){
console.log(arr[i]); //0,1,2,3,4,5
}
}

对象是否可枚举

四、数组转字符串

数组转字符串是通过join方法操作的

join() 方法用于把数组中的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。

var arr = [1,2,3,4,5];
var str = arr.join(); //不加分隔符的,默认为分隔符为‘,’;
console.log(str); //1,2,3,4,5
var str = arr.join('|'); //自定义分隔符的
console.log(str); //1|2|3|4|5

数组转字符串

五、数组序列化

1、逆序

reverse() 方法用于颠倒数组中元素的顺序。

var arr = [1,2,3,4,5];
arr.reverse();
arr; //[5, 4, 3, 2, 1]

2、数组排序

sort() 方法用于对数组的元素进行排序。

sort() 方法会改写原数组。

//例子1:
var arr = [1,4,3,2,5];
arr.sort();
arr; //[1, 2, 3, 4, 5] //例子2:
var arr=[4,26,51,30,15];
arr.sort();
arr; //[15, 26, 30, 4, 51];注:此处并没有按照数字的大小去排序,而是先把数组转换为字符串,然后按照数字的个位数进行排序;

若想将上述例子2中的数字按照大小排序的话,则需要使用排序函数

var arr=[4,26,51,30,15];
arr.sort(function(x,y){
return x - y; //正序
}) //[4, 15, 26, 30, 51] arr.sort(function(x,y){
return x - y; //倒序
}) //[51, 30, 26, 15, 4] arr.sort(function(x,y){
return y = x; //正序
}) //[4, 15, 26, 30, 51] arr.sort(function(x,y){
return x = y; //倒序
}) //[51, 30, 26, 15, 4]

数组排序

六、 数组合并

concat() 方法用于连接两个或多个数组。

该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。

//例子1:
var arr = [1,2,3,4,5];
arr.concat(6,7,8,9,0); //[1, 2, 3, 4, 5, 6, 7, 8, 9, 0] //例子2:
var arr = [1,2,3,4,5];
arr.concat(6,7,8,[9,0]); //[1, 2, 3, 4, 5, 6, 7, 8, 9, 0] 注:这里以数组作为参数的话,输出时数组会被拉平。 //例子3:
var arr = [1,2,3,4,5];
arr.concat([6,7,8,[9,0]]); //[1, 2, 3, 4, 5, 6, 7, 8, [9, 0]] 注:若数组的元素还是数组,则不会拉平两次。

七、返回数组中的部分元素

slice() 方法可从已有的数组中返回选定的元素。slice() 方法不会修改原数组

该方法有两个参数

start:必需。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。

end:可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start 到数组结束的所有元素。如果这个参数是负数,那么它规定的是从数组尾部开始算起的元素。

上面的定义理解起来或许会有点绕,我理解的end就是想要返回的结尾元素的下一个位置;

var arr = [0,1,2,3,4,5];
arr.slice(0,3); //[0,1,2]

如上代码展示的是想要返回从下标为0的元素开始到下标为2的元素结束的这部分数组元素,那么end就传入元素下标为2的下一个元素的下标;

下面举例参数为负值的情况;

var arr = [0,1,2,3,4,5];
arr.slice(-2,5); //[4] var arr = [0,1,2,3,4,5];
arr.slice(-5,-1); //[1,2,3,4]

八、数组拼接

splice() 方法向/从数组中添加/删除项目,然后以数组的形式返回被删除的项目。

splice() 方法会改变原始数组。

var arr = [1,2,3,4,5];
arr.splice(1,2); //[2, 3]
arr; //[1, 4, 5] var arr = [1,2,3,4,5];
arr.splice(2); //[3, 4, 5]
arr; //[1, 2] var arr = [1,2,3,4,5];
arr.splice(0,2,"a","b"); //[1, 2]
arr; //["a", "b", 3, 4, 5]

数组拼接

ES5中数组原型对象的属性

一、forEach方法。

Array.prototype.forEach ( callbackfn [ , thisArg ] )

callbackfn 有三个参数,第一个是遍历的数组元素的值,第二个是对应数组元素的索引,第三个是数组本身。

thisArg 参数, 它会被当作 this 值传给每个 callbackfn 调用。如果没提供它,用 undefined 替代。

forEach 方法的 length 属性是 1。

forEach方法是用来循环遍历数组的,可以替代for、for in。

var arr = [1,2,3,4,5];
arr.forEach(function(v,i,a){
console.log(v+'|-|'+i+'|-|'+a);
})
//1|-|0|-|1,2,3,4,5
//2|-|1|-|1,2,3,4,5
//3|-|2|-|1,2,3,4,5
//4|-|3|-|1,2,3,4,5
//5|-|4|-|1,2,3,4,5 arr.forEach(function(v,i,a){
console.log(v+'|-|'+i+'|-|'+a);
console.log(this.test);
},{test:'test'})
//1|-|0|-|1,2,3,4,5
//test
//2|-|1|-|1,2,3,4,5
//test
//3|-|2|-|1,2,3,4,5
//test
//4|-|3|-|1,2,3,4,5
//test
//5|-|4|-|1,2,3,4,5
//test

二、map方法

Array.prototype.map ( callbackfn [ , thisArg ] )

callbackfn 有三个参数,第一个是遍历的数组元素的值,第二个是对应数组元素的索引,第三个是数组本身。

thisArg 参数, 它会被当作 this 值传给每个 callbackfn 调用。如果没提供它,用 undefined 替代。

map方法的 length 属性是 1。

map方法主要是对数组做一些映射。可以对数组内的元素进行操作。

var arr = [1,2,3,4,5];
arr.map(function(v){
return v*10
}) //[10, 20, 30, 40, 50]

三、filter方法

Array.prototype.filter ( callbackfn [ , thisArg ] )

callbackfn 有三个参数,第一个是遍历的数组元素的值,第二个是对应数组元素的索引,第三个是数组本身。

thisArg 参数, 它会被当作 this 值传给每个 callbackfn 调用。如果没提供它,用 undefined 替代。

filter方法的 length 属性是 1。

filter方法可以根据逻辑运算符筛选出想要返回的数组元素。

var arr = [1,2,3,4,5];
arr.filter(function(v,x,a){
return v === 4||x===4
}) //[4, 5]

四、数组判断:every()和some()

1、every()

Array.prototype.every ( callbackfn [ , thisArg ] )

callbackfn 有三个参数,第一个是遍历的数组元素的值,第二个是对应数组元素的索引,第三个是数组本身。

thisArg 参数, 它会被当作 this 值传给每个 callbackfn 调用。如果没提供它,用 undefined 替代。

every 方法的 length 属性是 1。

every方法会遍历数组中的每一个元素是否都满足callbackfn中的逻辑

var arr = [1,2,3,4,5];
arr.every(function(x){
return x < 10;
}) //true arr.every(function(x){
return x < 3;
}) //false

2、some()

Array.prototype.some ( callbackfn [ , thisArg ] )

callbackfn 有三个参数,第一个是遍历的数组元素的值,第二个是对应数组元素的索引,第三个是数组本身。

thisArg 参数, 它会被当作 this 值传给每个 callbackfn 调用。如果没提供它,用 undefined 替代。

some 方法的 length 属性是 1。

some方法只要数组中有任意一个元素满足callbackfn中的逻辑,就会返回true

var arr = [1,2,3,4,5];
arr.some(function(x){
return x === 2;
}) //true var arr = [1,2,3,4,5];
arr.some(function(x){
return x === 6;
}) //false

五、reduce方法和reduceRight方法

1、reduce方法

Array.prototype.reduce ( callbackfn [ , initialValue ] )

调用 callbackfn 时将传入四个参数:previousValue(initialValue 的值或上次调用 callbackfn 的返回值),currentValue(当前元素值),currentIndex,和遍历的对象。第一次调用回调函数时,previousValue 和 currentValue 的取值可以是下面两种情况之一。如果为 reduce 调用提供了一个 initialValue,则 previousValue 将等于 initialValue 并且 currentValue 将等于数组的首个元素值。如果没提供 initialValue,则 previousValue 将等于数组的首个元素值并且 currentValue 将等于数组的第二个元素值。如果数组里没有元素并且没有提供 initialValue,则抛出一个 TypeError 异常。

reduce 方法是从左到右对数组遍历的。

reduce 方法可以根据运算符等方式来对数组的元素进行两两的操作。

var arr = [1,2,3,4,5];
arr.reduce(function(x,y){
return x+y
}) //15

上面例子的算法是先拿数组的第一个元素和第二个元素相加,然后在拿它们相加后得到的值作为第一个元素和后面没有进行相加的操作的第一个元素相加,以此类推。也就是1加2等于3,3加3等于6,6加4等于10,10加5等于15;

reduce方法根据逻辑运算符例子:

var arr = [1,3,5,7,9];
arr.reduce(function(x,y){
console.log(x+'<'+y);
return x > y ? x : y;
})
//1<3
//3<5
//5<7
//7<9
//9

2、reduceRight方法

Array.prototype.reduceRight ( callbackfn [ , initialValue ] );

调用 callbackfn 时将传入四个参数:previousValue(initialValue 的值或上次调用 callbackfn 的返回值),currentValue(当前元素值),currentIndex,和遍历的对象。第一次调用回调函数时,previousValue 和 currentValue 的取值可以是下面两种情况之一。如果为 reduceRight 调用提供了一个 initialValue,则 previousValue 将等于 initialValue 并且 currentValue 将等于数组的最后一个元素值。如果没提供 initialValue,则 previousValue 将等于数组的最后一个元素值并且 currentValue 将等于数组的倒数第二个元素值。如果数组里没有元素并且没有提供 initialValue,则抛出一个 TypeError 异常。

reduceRight方法是从右到左对数组进行遍历

把上述例子换成用reduceRight方法来操作

var arr = [1,2,3,4,5];
arr.reduceRight(function(x,y){
return x+y
}) //15
var arr = [1,3,5,7,9];
arr.reduceRight(function(x,y){
console.log(x+'>'+y);
return x > y ? x : y;
})
//9>7
//9>5
//9>3
//9>1
//9

总结:reduce和reduceRight方法是把整个数组通过各种运算或者逻辑聚合成一个结果。

六、数组检索:indexOf()和lastIndexOf()

1、indexOf()

Array.prototype.indexOf ( searchElement [ , fromIndex ] )

indexOf 按照索引的升序比较 searchElement 和数组里的元素们,它使用内部的严格相等比较算法 (11.9.6),如果找到一个或更多这样的位置,返回这些位置中第一个索引;否则返回 -1。

可选的第二个参数 fromIndex 默认是 0(即搜索整个数组)。如果它大于或等于数组长度,返回 -1,即不会搜索数组。如果它是负的,就把它当作从数组末尾到计算后的 fromIndex 的偏移量。如果计算后的索引小于 0,就搜索整个数组。

indexOf()方法是从左到右检索的

var arr = [1,3,5,3,1];
arr.indexOf(3); //查找元素为3在数组中的索引;返回1
arr.indexOf(3,2); //从索引2开始查找元素为3在数组中的位置;返回3
arr.indexOf(3,1); //从索引1开始查找元素为3在数组中的位置;返回1
arr.indexOf(99); //数组元素中没用99这个元素;返回-1
arr.indexOf(1,-1); //从索引为-1(数组的最后一个元素)开始查找元素为1在数组中的位置;返回4

2、lastIndexOf()

Array.prototype.lastIndexOf ( searchElement [ , fromIndex ] )

lastIndexOf 按照索引的降序比较 searchElement 和数组里的元素们,它使用内部的严格相等比较算法 (11.9.6),如果找到一个或更多这样的位置,返回这些位置中最后一个索引;否则返回 -1。

可选的第二个参数 fromIndex 默认是数组的长度减一(即搜索整个数组)。如果它大于或等于数组长度,将会搜索整个数组。如果它是负的,就把它当作从数组末尾到计算后的 fromIndex 的偏移量。如果计算后的索引小于 0,返回 -1。

lastIndexOf()从右到左检索的

var arr = [1,3,5,3,1];
arr.lastIndexOf(3); //从右往左开始查找元素为3在数组中的位置;返回3
arr.lastIndexOf(3,2); //从索引为2的元素开始从右往左查找元素为3在数组中的位置;返回1
arr.lastIndexOf(1,-2); //从索引为-2的元素开始从右往左查找元素为1在数组中的位置;返回0

Array构造器属性

Array.isArray ( arg )——判断是否为数组

isArray 函数需要一个参数 arg,如果参数是个对象并且 class 内部属性是 "Array", 返回布尔值 true;否则它返回 false。

  • 如果 Type(arg) 不是 Object, 返回 false。
  • 如果 arg 的 [[Class]] 内部属性值是 "Array", 则返回 true。
  • 返回 false.
var arr = [];
Array.isArray(arr); //true