接着之前的 Object 类型,这篇梳理的是 Array 类型
1、数组中每一项都可以是js中的任何数据类型的数据
2、数组的长度是可以动态调整的,可以随着数据的添加删除而自动改变数组长度
创建数组方式
1、使用 Array 构造函数
let arr = new Array()
如果知道需要保存的项目的数量,也可以在创建数组的时候,将数量传递进去,传递的数量就是创建的数组的长度,但是此时数组中的每一项都是空的,打印的时候可以看到,数组中每一项都是 undefined
let arr = new Array(5)
console.log(arr.length) // 5
console.log(arr) // [,,,,]
console.log(arr[1]) // undefinde
同样的,如果知道数组中具体应该包括哪几项,也可以在创建数组的时候,直接传递进去
let arr = new Array("a","b","c","d")
console.log(arr) // ["a", "b", "c", "d"]
在使用构造函数的时候,可以省略 new 关键字
let arr = new Array(3)
let arr = Array(3)
2、使用字面量方式创建:使用数组字面量创建时,不会调用 Array 构造函数
let arr = ["1","2","3"] //创建包含1,2,3三个元素的数组
let arr1 = [] //创建一个空数组
let arr2 = [1,2,] //不要这样创建,在ie8以及更早的版本会创建包含3项元素的数组,现代浏览器中会创建包含两项元素的数组
let arr3 = [,,,,] //同上
数组的读取和设置
在读取和设置数组的值时,需要使用方括号,并提供相应的索引值,索引值基于0开始,上限不设置,可以超出数组现有长度,超出现有长度的部分,数组会自动增加到该索引值加1的长度。
let arr = ["1","2","3"] //创建包含1,2,3三个元素的数组
arr[0] // 1 查看数组第一项
arr[1] = "aaa" //修改数组第二项
arr[3] = "qqq" //新增数组第四项
console.log(arr) //["1","aaa","3","qqq"]
数组length
数组的 length 属性是数组中非常重要的一个属性,这个属性是可读可写的,也就是说我们可以通过 length 属性来向数组的末尾移除或者添加新的元素。
let arr = ["1", "2", "3"]; //创建包含1,2,3三个元素的数组
arr[0]; // 1 查看数组第一项
arr[1] = "aaa"; //修改数组第二项
arr[3] = "qqq"; //新增数组第四项
console.log(arr); //["1","aaa","3","qqq"]
arr.length = 2; //设置数组长度为2
console.log(arr); //["1", "aaa"]得到只有两项的数组,其余项目都被删除
console.log(arr[3]); //undefined 因为数组现在已经只有两项,所以访问的时候会显示undefined
arr.length = 5; //设置数组长度为5
console.log(arr); // 当设置的length超过了数组原本长度,新增的每一项都是空,打印的时候都是undefined 值,["1", "aaa", empty × 3]
检测数组
检测一个变量是否是一个数组,有两种比较精确的方法
instanceof :局限是只能在单一的执行环境中使用,如果网页中包含多个框架,那就存在多个Array构造函数,框架之间传递数组的时候,数组具有不同的构造函数
[] instanceof Array // true
Array.isArray() : 为了解决 instanceof 多框架之间数组传递的问题,新增了 Array.isArray() 方法,更简单精确的检测。
Array.isArray([]) //true
转换方法
toString() :数组中的每一项都会转换成字符串形式,且以逗号分隔
valueOf() :返回的还是一个数组
toLocaleString() : 这个比较多变,具体需要看方法内部传递什么参数,详情可以参考这篇文章。https://blog.csdn.net/qq_40792800/article/details/106140866
join() : 这个方法可以让我们自定义字符串的分隔符号,需要将分隔符号传递到方法中
let arr = ["1", "2", "3"];
console.log(arr.toString()); //字符串 1,2,3
console.log(arr.valueOf()); //数组 ["1", "2", "3"]
console.log(arr.toLocaleString());
console.log(arr.join("||")); //字符串 1||2||3
栈方法和队列方法
栈方法:类似栈的行为,可以限制插入和删除的数据结构,只能发生在栈的顶部。
push(),向数组末尾添加不定项的元素,返回修改后的数组长度。
pop() ,删除数组中的最后一项元素 ,返回被删除的元素
let arr = ["1", "2", "3"]; //创建包含1,2,3三个元素的数组
arr.push("4") //4 向数组末尾添加一项 ,此时数组长度为 4
arr.push("5","6","7") //7 在当前数组长度为4的基础上,继续添加三项,此时数组长度为7
arr.pop() //7 移除数组最后一项且返回该项
队列方法:在数组末端添加,前端移除
shift:移除数组第一项,且返回移除项
unshift:在数组前端添加不定项,且返回改变后的数组长度
let arr = ["1", "2", "3"];
console.log(arr.shift()); // 1 返回当前被删除的元素
console.log(arr.length()); // 2 删除之后,数组长度减少1,为2
console.log(arr.unshift("q", "w")); // 4 在数组前端添加一个元素,返回新的数组的长度
数组排序
数组中已经存在两个可以直接调用来排序的方法:reserve() 和 sort()。
reserve() : 反转数组,不论数组元素是什么类型
let arr = ["1", 2, true, undefined, null, {}, function name(params) {}];
console.log(arr.reverse()); // [ƒ, {…}, null, undefined, true, 2, "1"]
sort() : 默认情况下,按升序排列,从小到大排列。但是在排序的过程中,数组每隔元素会隐式的调用 toString() 方法,然后比较得到的字符串,技术数组中每一项都是数值,也会转化为字符串进行比较
这是高程上面的实例,我最开始一直没懂为啥 5 会排在最后面,后来看到别人写的答案的时候才明白
简单说,就是引擎把数组的每一项当做一个字符串,先比较每个字符串的第一个字符,按照B>A,3>1这种方式排。如果第一个字符一样,就比较第二个,以此类推。
例子中的五个数首字母分别是“0”,“1”,“5”,“1”,“1”:
0自然排第一个,5排最后一个。
然后就是1,10和15了。1的第二位没有字符,10的第二位是0, 15的第二位是5。
所以排序结果为0,1,10,15,5
var values = [0,1,5,10,15]
values.sort();
alert(values); //0,1,10,15,5
这种情况下,排序肯定不是我们想要的结果,所以 sort() 方法还可以接收 一个比较函数作为参数,在函数内部进行比较排序处理。
这个比较函数会接收两个参数,,然后这两个参数进行比较,通过 return 负数(习惯性为-1)、0、正数(习惯性为1) 这几个数值,来判断当前比较的排序
升序排列
let arr = ["1", "2", "3", "4"];
function name(val1, val2) {
if (val1 < val2) {
return -1;
} else if (val1 > val2) {
return 1;
} else {
return 0;
}
}
console.log(arr.sort(name)); // ["1", "2", "3", "4"]
降序排列 : 只用将返回的 -1和1调换位置即可得到降序排列的效果
let arr = ["1", "2", "3", "4"];
function name(val1, val2) {
if (val1 < val2) {
return 1;
} else if (val1 > val2) {
return -1;
} else {
return 0;
}
}
console.log(arr.sort(name)); // ["4", "3", "2", "1"]
对于数值或者其 valueOf() 方法,会返回数值类型的对象类型,可以使用比较简单的比较函数,只需要使用第二个值减第一个值即可。不同的情况返回值不同,但是也是只分为正数、负数、0这三类来实现排序效果
let arr = ["1", "2", "3", "4"];
function name(val1, val2) {
val2 - val1;
}
console.log(arr.sort(name)); // ["1", "2", "3", "4"]
function name(val1, val2) {
val1 - val2;
}
console.log(arr.sort(name)); // ["4", "3", "2", "1"]
数组操作方法
concat() : 数组拼接,数组1.concat(数组2,数组3….):数组拼接 可以拼接多个 ,但是现在多用 ... 扩展运算符,[...数组1, ...数组2, ...数组3]
返回:拼接后的新数组 ,不改变原数组
var d = [1,2,3]; //创建新数组
var e = ["aa","bb"]; //创建新数组
var h = [2234]; //创建新数组
var g = d.concat(e,h); //拼接数组,变量接收
console.log(g); //打印改变后的数组。显示[1, 2, 3, "aa", "bb", 2234]
var a = [...d, ...e, ...h]; //扩展运算符
console.log(a); //[1, 2, 3, "aa", "bb", 2234]
slice() : 数组截取,接收一个或两个参数,能基于当前数组中的一项或多项( 主要看接收的参数 )创建一个新的数组。
返回:如果只有一个参数则返回从该参数指定位置开始(包含开始位置)到数组结束位置的所有项。
如果有两个参数,则返回起始位置和结束位置之间的所有项--但是不包括结束位置项
如果参数中存在负数,用数组长度加上这个负数就能得到当前这个负数应该在数组哪一项
var q = [1,2,3,4,5,6]; //创建新数组
var w = q.slice(2,4); //截取数组,变量接收
console.log(w); //打印截取数组,显示[3, 4]
console.log(q); //打印原数组,显示[1,2,3,4,5,6]
var q = [1,2,3,4,5,6]; //创建新数组
var w = q.slice(2); //截取数组,变量接收
console.log(w); //打印截取数组,显示[3, 4, 5, 6]
console.log(q); //打印原数组,显示[1,2,3,4,5,6]
splice() : 数组.splice(a,b,c,d,e,f…..) 任意位置,可删除(删除个数也可以是0) ,可添加,可替换
这个方法差不多是数组是最强大的了,可以替代之前的对于数组的操作。
删除:可以删除任意项,只需指定两个参数,要删除的第一项的位置和需要删除的元素个数
var q = [1, 2, 3, 4, 5, 6]; //创建新数组
var w = q.splice(2, 2); // 删除数组
console.log(w); //返回删除的元素,显示[3, 4]
console.log(q); //打印原数组,显示[1,2,3,4,5,6]
插入:可以插入任意项,传入3个参数,起始位置,0(代表不用删除数组元素)或者(要删除的元素数量),需要增加的项
var arr = [1, 2, 3, 4, 5]; //创建新数组
arr.splice(2, 1, 6, 7, 8, 9); //删除数组中索引值为2的那个值,且在其位置上添加6,7,8,9四个新元素
console.log(arr); //打印显示[1,2,6,7,8,9,4,5];
替换:替换的情况与插入类似,只是第二个参数不能为0,必须要删除部分元素,增加的项与删除的项可以不相同
查找元素在数组中的位置
indexOf() : 接收两个参数 要查找的元素和从数组中查找起点位置的索引(可选),从数组开头向后查找
lastIndexOf() : 接收两个参数 要查找的元素和从数组中查找起点位置的索引(可选),从数组末尾向前查找
返回:都是该元素在数组中的索引值,或者在没有找到该元素的情况下返回 -1,且在查找时,数组元素和需要查找的元素是按 全等判断的
var arr = [1, 2, 3, 4, 5, 4, 3, 2, 1, 0];
let a = arr.indexOf(5); //查找元素5在数组中的位置
console.log(arr.indexOf(5)); //4
console.log(arr.lastIndexOf(5)); //4
// 严格判断全等的情况下,字符串5和数字5是不全等的,数组中查询不到该元素,返回 -1
console.log(arr.indexOf("5")); //-1
console.log(arr.lastIndexOf("5")); //-1
数组遍历(迭代方法)
forEach() : 接收一个函数,数组中每一项元素都执行传入的方法,没有返回值
let arr = [1, 2, 3];
arr.forEach((item, indx) => {
//处理数据
console.log(item, indx);
});
filter() : 过滤,不改变原数组。接收一个函数,数组中每一项元素都执行传入的方法,当数组中的每一项元素调用传入的方法后返回true之后,会将这个元素放到一个新的数组中。返回传入的函数会返回true的项组成的数组
let arr = [1, 2, 3, 4];
let newArr = arr.filter((item, index) => {
return item < 4 && item > 1;
});
console.log(newArr); // [2, 3]
console.log(arr); // [1, 2, 3, 4]
map() : 不改变原数组,接收一个函数,数组中每一项元素都执行传入的方法,返回每次调用这个函数的结果组成的新数组。
let arr = [1, 2, 3, 4];
let newArr = arr.map((item, index) => {
return item + 1;
});
console.log(newArr); // [2, 3, 4, 5]
console.log(arr); // [1, 2, 3, 4]
every() : 不改变原数组,接收一个函数,数组中每一项都执行传入的函数 ,只有每一项调用之后都返回true,该every() 才会返回true,否则返回 false
let arr = [1, 2, 3, 4];
let newArr = arr.every((item, index) => {
return item < 5;
});
console.log(newArr); //false
console.log(arr); //[1, 2, 3, 4]
let newArr = arr.every((item, index) => {
return item < 4; //改变条件
});
console.log(newArr); //true
console.log(arr); //[1, 2, 3, 4]
some() : 不改变原数组,接收一个函数,数组中每一项都执行传入的函数 ,只要有一项调用之后都返回true,该some() 会返回true,否则返回 false
let arr = [1, 2, 3, 4];
let newArr = arr.some((item, index) => {
return item < 4;
});
console.log(newArr); //true
console.log(arr); //[1, 2, 3, 4]
let newArr = arr.some((item, index) => {
return item < 0;
});
console.log(newArr); //false
console.log(arr); //[1, 2, 3, 4]