JS数组(一) - Javascript中的数组Array对象

数组就是一组数据的有序集合,它用一组连续的内存空间,来存储一组数据,数组中的一个数据叫做元素,每个元素在数组中的位置称为索引或下标,数组的起始元素索引默认是0。

对于每一门编程语言来说数组都是重要的数据结构之一,数据结构是计算机存储、组织数据的方式,是相互之间存在一种或多种特定关系的数据元素的集合。
数组作为数据结构,需要了解其增加、修改、删除、遍历、排序等方法。

如何创建数组

  • 隐式创建(采用数组字面量方式创建)
    var arr=[值1,值2…]
  • 直接实例化
    var arr1=new Array(值1,值2…)
    var arr2=new Array(length)
    PS:通过new Array()构造一个数组时,传入一个参数表示构造一个这样长度的空数组,多个参数表示构造一个含这些元素的数组。
//采用数组字面量方式创建
  var arr1=[1,'a'];
  var arr2=[];
  arr2[0]=1;  //通过下标添加元素
  arr2[1]='a';  //通过下标添加元素
  //调用构造函数Array()创建数组
  var arr3=new Array(1,'a');
  var arr4=new Array(2);   //只有一个参数时,代表数组的长度
  console.log(arr1,arr2,arr3,arr4);  //[1, "a"] [1, "a"] [1, "a"] [empty × 2]

JS中数组的特点

  • 在JS中数组可以同时存储不同类型的值
  • 定义时可以无需指定数组长度
  • 数组中的元素之间可以有空隙(稀疏数组),并不强制要求数组元素是紧密相连的
  • JS中数组是个对象,数组的索引可以使用字符串作为下标,使用文本下标的元素不会被记入数组的length属性

数组的成员和length属性

每个数组都有一个length属性,其值是数组成员的最大的索引加一,对于紧密数组length属性能够代表数组的成员数。而稀疏数组中length属性不能真实的代表数组的成员数。

  var arr1=[1,'a'];   //2个成员
  var arr2=[];
  arr2[3]=1;          //1个成员
  var arr3=[];
  arr3['title']='标题';   //1个成员,使用字符串作为下标定义数组元素,不能通过索引访问
  console.log(arr1.length,arr2.length,arr3.length)    //2  4  0

多维数组

二维数组:数组内每一个元素都是一个一维数组
三维数组:数组内每一个元素都是一个二维数组
以此类推…

 var arr1=[1,2,3];
 //二维数组
 var arr2=[['a','b','c'],arr1];
 //三维数组
 var arr3 = [
   [
     [1, 2, 3], ['a', 'b', 'c']
   ],
   arr2,
 ];
 console.log(arr1,arr2,arr3);   [1, 2, 3]  [Array(3), Array(3)] [Array(2), Array(2)]

数组的读写

通过下标(索引)可以读取和修改数组中的元素

var arr=[1,'a'];
console.log(arr[0]); //获取了索引为0的元素值
arr[1]=2;   //修改了索引为1的元素
console.log(arr);

数组的方法

在控制台中打印数组的构造函数,结果见下图,可以看到数组的原型上有很多的方法,也就是我们所说的实例方法,对于数组来说主要研究它的实例方法。
在这里插入图片描述
这些方法大致可以分为3类
1、会改变原数组的方法
2、不会改变原数组的方法
3、数组的遍历方法

一)会改变原数组的方法

1、新增元素 ① push() 和 ② unshift(),返回修改后数组的长度

var arr=[2];
arr.push(3);   //向数组末尾添加新的元素,返回值新数组的长度
arr.unshift(1);  //向数组开头位置添加元素,返回值是新数组的长度
console.log(arr);   //[1, 2, 3]

2、删除元素 ③pop()和 ④ shift(),没有参数,返回删除的元素

var arr=[1,2,3];
arr.pop();   //返回[3] 删除数组最后一项,没有参数,返回值删除项
console.log(arr);  //[1,2]
arr.shift();  //返回[1]  删除数组第一项,没有参数,返回值删除项
console.log(arr);  //[2]

3、⑤splice()实现数组的插入、删除和替换
arrayObject.splice(index,howmany,item1,…,itemX)

参数描述
index必需。整数,规定添加/删除项目的位置
howmany可选。要删除的元素数量。如果不设置,删除到最后,如果设置为 0,则不会删除项目。
item1, …, itemX可选。向数组添加的新项目。

返回值:如果从 arrayObject 中删除了元素,则返回的是含有被删除的元素的数组。

var arr=[1,2,3,4];
//删除元素
arr.splice(1,3);  //[2,3,4] 从索引1开始、删除3个元素,返回被删除的[2,3,4]
console.log(arr);  //[1]
//新增元素
arr.splice(1,0,'a'); //[] 从索引1开始、删除0个元素、把'a'添加到删除的位置
console.log(arr);   // [1, "a"]
//替换元素
arr.splice(1,1,'b');  //[a] 从索引1开始、删除1个元素'a'、把'b'添加到删除的位置
console.log(arr);   //[1, "b"]
//清空元素
arr.splice(0);      //[1, "b"] 从索引0开始,删除所有元素,相当于原数组清空,返回一个和原来一样的新数组
console.log(arr);   //[]

4、颠倒数组元素 ⑥reverse(),没有参数,返回颠倒后的数组

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

5、对数组元素排序 ⑦ sort() ,参数可选,返回值是排序后的数组。
默认排序顺序是根据字符串UniCode码。

var arr1 = [10,1,5,30,3,100];
var arr2=['w','你','一','a'];
arr1.sort();  // 默认把数组元素都转化成字符串,进行排序
console.log(arr1);          //[1, 10, 100, 3, 30, 5]
arr2.sort();  //["a", "w", "一", "你"],"一"是第一个汉字,UniCode码小于"你"的UniCode码
console.log(arr2);

sort排序允许接受一个函数作为参数(比较函数),该函数要比较两个值,接受2个形参a,b,并且通过冒泡的方式比较。通过函数的返回值规定排序顺序。
当返回值为0时,参数的位置不动,当返回值不为0时,火狐浏览器返回值为负数时,a和b代表的元素在数组中的位置不动,为正数值,互换位置;谷歌浏览器则相反,但上面的例子中排序的结果是一样的,这是因为在这两种浏览器中a和b代表的元素是不同的。

 //正序排列
 var arr1 = [10,1,5,30,3,100];
 arr1.sort(function (a,b) {
   return a-b;   
 });
 console.log(arr1);   //[1, 3, 5, 10, 30, 100]
 //降序
 arr1.sort(function (a,b) {
   return b-a;
 });
 console.log(arr1);   //[100, 30, 10, 5, 3, 1]
 //自定义比较函数,本例是按照年龄的升序排列
 var arr2 = [{id:1,age:11},{id:3,age:10},{id:6,age:9}];
 arr2.sort(function(a,b){
   return a.age - b.age;
 })
 console.log(arr2);   //[{id:6,age:9},{id:3,age:10},{id:1,age:11}]
var arr= [2,1,3];
console.log(arr);
var i=0;
arr.sort(function(a,b){
   i++;
   var temp = a-b;
   console.log('第'+i+'次比较'+a+'和'+b,a+'-'+b+'=' +temp);
   return temp;
 });
 console.log('排序结果:'+arr);

在这里插入图片描述

二)不会改变原数组的方法

1、concat() 合并两个或多个数组,返回新数组
参数:可以是任意多个具体的值或数组对象。

[1,2,3].concat(4,'5',['a','b'])     //[1, 2, 3, 4, "5", "a", "b"]
[1,2,3].concat([4],['5'],['a','b'])   //[1, 2, 3, 4, "5", "a", "b"]

2、join() 将数组所有元素连接成一个字符串,返回连接后的字符串。
参数可选。指定要使用的分隔符。如果省略该参数,则使用逗号作为分隔符。

[1,2,3].join();	//"1,2,3"
[1,'a'].join('-');  //"1-a"

3、 toString() 将数组所有元素连接成一个字符串,返回用逗号连接的字符串。
无参数,返回值与没有参数的 join() 方法返回的字符串相同。

[1,2,3].join();	//"1,2,3"
[1,2,3].toString();	//"1,2,3"

4、slice(start,end) 在数组中截取从start到end的元素到新数组中,返回新数组
参数:①开始位置 ②截止位置,可选(不包含该元素),如果参数是负值,代表倒数第n个元素
PS:数组的slice方法和字符串的slice方法,用法基本相同

var arr= [1,2,3,4,5];
console.log(arr.slice(1,3)); //[2,3]  从第2个元素,截止到第4个元素
console.log(arr.slice(-3,3));  //[3] 从数组倒数第3个元素,截止到第4个元素
console.log(arr.slice(1)); //[2,3,4,5] 从数组第2个元素到数组结束的所有元素

5、indexOf() 在数组中从前往后查找一个元素,并返回索引,找不到则返回-1
参数:①要查找的元素 ②开始查找的起始位置,默认从位置0开始查找
PS:数组的indexOf方法和字符串的indexOf方法,用法基本相同

var arr= [1,2,3,1,2];
console.log(arr.indexOf(2));      //1,从前到后找到的第一个2的索引是1
console.log(arr.indexOf(2,4));    //4,从第5个元素开始查收元素2,找到的元素的索引是4
console.log(arr.indexOf(4))       //-1,没有到元素4

6、lastIndexOf() 在数组中从后向前查找一个元素,并返回索引,找不到则返回-1
参数:①要查找的元素 ②开始查找的起始位置,默认从位置0开始查找
PS:数组的lastIndexOf方法和字符串的lastIndexOf方法,用法基本相同

var arr= [1,2,3,1,2];
console.log(arr.lastIndexOf(2))   //4,从后到前找到的第一个2的索引是4

三)数组的遍历方法

既可以不数组的实例方法遍历数组,也可以用for循环语句遍历数组

for循环
  • 普通for循环,利用数组下标和length作为循环条件遍历数组。
let str1='普通for循环';
var arr=['a','b','c'];
//普通for循环,利用数组元素的索引和length作为循环条件遍历数组,i是索引,类型是number
for(var i = 0;i<arr.length;i++) {
  str1+='\n索引:'+i+' 值:'+arr[i];
}
console.log(str1);

打印出的结果是:

普通for循环
索引:0 值:a
索引:1 值:b
索引:2 值:1

  • for of 循环
let str3='for of循环';
var arr=['a','b','c'];
//for…of ES6新增,item实际是元素的值
for(let item of arr){
  str3+= '值:'+item;
}
console.log(str3);

打印出的结果是:

for of循环
值:a
值:b
值:1

ES5中的方法
1、 迭代方法

ES5中新增了数组的迭代方法,有5个,每个方法都会接受两个参数:(1)要在每一项上运行的函数(2)运行该函数的作用域——this的值(可选)。传入方法中的函数会接受三个参数:(1)当前数组元素的值(2)当前数组元素的索引(可选)(3)数组本身(可选)。

  • forEach(),用来遍历数组中的每一项,并运行给定的函数,但没有返回值,对原数组没有影响
  • map(),用来遍历数组中的每一项,返回在函数中处理过的数组,对原数组没有影响
  • filter(),用来遍历数组中的每一项,返回过滤后的结果数组,对原数组没有影响
  • every(),用来遍历数组中的每一项,对数组中的每一个元素进行比对,结果全部为true,返回true,否则返回false
  • some(),对数组中的元素进行比对,只要有结果为true,返回true,全部为false,返回false

array.forEach(function(currentValue, index, array), thisValue)
array.map(function(currentValue, index, array), thisValue)
array.filter(function(currentValue, index, array), thisValue)
array.every(function(currentValue, index, array), thisValue)
array.some(function(currentValue, index, array), thisValue)
作为参数的函数

1、forEach()方法

//forEach方法,遍历数组value是当前元素,index是当前元素索引,arr代表数组本身,一般省略
//forEach方法不能使用break语句中断循环
var str4='foreach循环';
var arr=['a','b','c'];
arr.forEach(function(value,index,arr){
  str4+='\n下标:'+index+' 类型:'+typeof value+' 值:'+value;
});
console.log(str4);
PS:这里的数组遍历是最简单的情况,如果遇到==稀疏数组==和包含==文本下标的数组==for循环的结果可能不是预期的结果。
由于篇幅所限,详细内容请参考《[js数组遍历-for、for in、for of、 foreach的区别](https://blog.csdn.net/dreamingbaobei3/article/details/101781830)》

2、map()方法
这个方法不会对原始的数组产生影响(当数组项是引用类型时可能会被改变),而是相当于把原数组克隆一份,把克隆的数组中的对应项改变了。
map方法中,return的是什么,相当于把原数组的项加工成什么。

var arr1=[1,2,3,4,5];
var arr2=arr1.map(function (value,index,arr1) {
  return value*value
});
console.log(arr1);  //[1, 2, 3, 4, 5]
console.log(arr2);  //[1, 4, 9, 16, 25]
var arr1 = [
  { id: 1, age: 11 },
  { id: 8, age: 10 },
];
var arr2=arr1.map(function(item,i){
   item=JSON.parse(JSON.stringify(item));  //如果没有这行代码arr1将同时被改变
   item.children=[];
   return item;
})
console.log(arr1) 
console.log(arr2) 

3、filter()方法
遍历数组中的每一项,返回过滤后的结果(数组),对原数组没有影响

var arr1=[1,2,3,4,5];
var arr2=arr1.filter(function (value,index,arr1) {
  return value>3;
});
console.log(arr1);  //[1, 2, 3, 4, 5]
console.log(arr2);  //[4, 5]

4、 every()方法
遍历数组中的每一项,对数组中的每一个元素进行比对,结果全部为true,返回true,否则返回false

var arr1=[1,2,3,4,5];
var result=arr1.every(function (value,index,arr1) {
  return value>3;
});
console.log(arr1);  //[1, 2, 3, 4, 5]
console.log(result);  //false

5、 some()方法

var arr1=[1,2,3,4,5];
var res=arr1.some(function (value,index,arr1) {
  return value>3;
});
console.log(arr1);  //[1, 2, 3, 4, 5]
console.log(res);  //true
2、归并方法

数组还有两个归并的方法:reduce和reduceRight。归并方法接受一个函数作为累加器,数组中的每个值(从左到右或从右到左)开始缩减,最终为一个值。

参数是两个,
①调用的函数
该函数又接受4个参数:上一次迭代的值,当前值,项索引,数组本身。
函数返回的值都会作为第一个参数自动传给下一项
②归并基础的初始值
如果没有给定初始值,初始值默认为数组第一个值,第一次迭代从数组第2项开始;
如果给定了初始值,第一次迭代从数组第1项开始

  • reduce(),从数组第一项开始遍历到最后
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
  • reduceRight(),从数组最后一项开始遍历到第一项
var res1 = [1,2,3].reduce(function(prev, cur, index) {
  console.log('索引:'+index+',前一次的返回值:'+prev+',当前值:'+cur)
  return prev + cur;
},100);
console.log(res1) //106 迭代3次
var res2 = [1,2,3].reduce(function(prev, cur, index) {
  console.log('索引:'+index+',前一次的返回值:'+prev+',当前值:'+cur)
  return prev + cur;
});
console.log(res2) //6 迭代2次
var res3 = [1,2,3].reduceRight(function(prev, cur, index) {
  console.log('索引:'+index+',前一次的返回值:'+prev+',当前值:'+cur)
  return prev + cur;
},100);
console.log(res3) //106 迭代3次
var res4 = [1,2,3].reduce(function(prev, cur, index) {
  console.log('索引:'+index+',前一次的返回值:'+prev+',当前值:'+cur)
  return prev + cur;
});
console.log(res4) //6 迭代2次
ES6 提供的新方法

1、find()方法
用于返回数组中第一个满足要求的元素的值,如果没有满足要求的元素,则返回undefined,参数同样是一个函数。

var arr1=[1,2,3,4,5];
var res=arr1.find(function (value,index,arr1) {
  return value>3;
});
console.log(arr1);  //[1, 2, 3, 4, 5]
console.log(res);  //4

2、findIndex()方法
用于返回数组中第一个满足要求的元素的索引,如果没有满足要求的元素,则返回-1,参数同样是一个函数。

var arr1=[1,2,3,4,5];
var res=arr1.findIndex(function (value,index,arr1) {
  return value>3;
});
console.log(arr1);  //[1, 2, 3, 4, 5]
console.log(res);  //3

3、可以配合for…of循环的entries(),keys()和values(),用于遍历数组
entries(),keys()和values()都返回一个遍历器对象(Array Iterator),可以用for…of循环进行遍历。

  • keys()是对键名的遍历,这里的键名实际上就是数组项的索引,字符串下标的元素遍历不出来
  • values()是对键值的遍历
  • entries()是对键值对的遍历。
var arr1=['a','b','c'];
console.dir(arr1.entries());  //Array Iterator
for(let index of arr1.keys()){
  console.log('index:'+index+',value:'+arr1[index]);
}
for(let value of arr1.values()){
  console.log('value:'+value);
}
for(let [index,value] of arr1.entries()){
  console.log('index:'+index+',value:'+value);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值