学习js时,发现js的数组有很多有用的方法,下面记录一下。
一、创建数组
1.使用Array构造函数
var test1 = new Array();//创建一个空数组
var test2 = new Array(3);//length属性,数组有3项,每一个都是undefined
var test3 = new Array("3");//数组的项
使用Array()构造函数时可以不带参数,也可以带参数,带参数时有两种情况,如果只有一个参数并且是一个正整数,那么这个整数就会变成数组的length的值,数组的项都是undefined。这里的在逻辑上表现不一致.
2.使用数组字面量表示法
var colors = ["red", "blue", "green"];
var names = [];
var names = [3];//这里的逻辑表现是一致的
二、index与length
1.index是基于数字0的索引,可以用来访问数组中的元素(array[0])。
index小于0会报err,大于数组的最大的索引时会增加数组项,没赋值的时候值为undefined
2.length是数组的长度,表示数组的项数,是从1开始的。可以通过设置数组的length实现数组的增加和删除。
三、检测数组
1.对于一个网页或者一个全局作用域,使用instanceof就可以。
return array instanceof Array ? true : false;(这种方法假设只有一个全局作用域,是因为这里的Array存在全局作用域中,如果有多个全局作用域,就不知道是哪一个Array了,导致判断失败)。
2.为了解决上面的问题,ECMAScript5新增了isArray()方法。
return Array.isArray(array) ? true : false;
这个方法的对象Array的原生方法,不能继承,即假如var array = new Array();array.isArray()是错误的。
这是新增的方法,要考虑浏览器兼容问题。
3.如果项目中使用了JQuery,使用$.isArray(array)是最安全的方法。
4.没有使用jquery时的最安全的方法。
在任何值上调用Object原生的toString()方法,都会返回一个[object NativeConstructorName]格式的字符串。每个类在内部都有一个[[Class]]属性,这个属性中就指定了上述字符串的构造函数名。
return Object.prototype.toString.call(array) === "[object Array]";
四、转换方法
1.array.toString()//逗号分割返回字符串
2.array.valueOf()//返回原来的数组
3.array.join(",")//最容易的方法
五、栈方法(后进先出,压弹夹模拟,push压入,pop弹出),总是对数组末尾进行操作。
1.后进
var length = array.push(value);//添加到数组末尾,返回数组长度
array[array.length] = value;
2.先出
var item = array.pop();//删除数组末尾的项,返回该项
六、队列方法(先进先出,银行排队办业务模拟,shift()前面删除),push是对数组末尾的操作,这里只要有对数组前面的删除操作就可以了。
1.先出
var item = array.shift();//删除数组前面的项,返回该项
2.先进
js中还有一个unshift()方法,作为shift()方法的对应方法,即在数组前端添加项目,并且返回数组的长度。
var length = array.unshift(value);
注意:栈方法和队列方法要压入的值如果是数组的话是不会拆分的,会直接把数组当作数组的一个项。
栈方法操作数组最后一个元素,队列方法操作数组第一个元素
var array = ["a","b","c"];
var value1 = ["d", "e"];
var item1 = array.push(value1);//数组为["a","b","c",["d", "e"]]
var item2 = array.push("d", "e");//数组为["a","b","c","d", "e"]
七、排序方法
1.reverse()反转方法
var array = [1,2,3,4,5];
array.reserve();
alert(array);//5,4,3,2,1
几乎没什么用,不够灵活
2.sort()排序
- 不带参数时默认升序排列数组项,但sort方法比较的是字符串,即使项是数值也比较字符串。
var array = [0,1,5,10,15];
array.sort();
alert(array);//0,1,10,15,5所以一般不直接使用sort方法
- 带一个比较函数comparefn作为参数,sort方法的实现原理可以看我的其他blog。
比较函数应该具有两个参数 a 和 b,其返回值如下:
若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。
若 a 等于 b,则返回 0。
若 a 大于 b,则返回一个大于 0 的值。
上面是W3C给出的解释,sort方法内部判断的是大于0的情况下就移动,简单来说,升序时return a-b,降序时return b-a;
注意:reserve方法和sort方法都是在原来的数组上进行重新排序,不会产生副本·,2个方法的返回值是排序后的数组。
八、操作方法
1、创建数组副本并添加元素的concat()方法
concat方法首先创建数组副本,有参数的情况下还会在副本后面添加元素。
与push方法的区别在于concat的参数是数组的情况下,会拆分数组,将数组中的每一项添加在副本后面,而push方法参数如果是数组时,只会把数组当做一项,而且push不创建副本
2、截取数组的slice方法
slice方法有一个或者2个参数,一个参数时默认到数组末尾(index)。根据参数截取数组,创建新的数组,不影响原来的数组。包含开始值,不包含结束值。
var colors = ["red", "green", "blue", "yellow", "purple"];
var colors2 = colors.slice(1);//["green", "blue", "yellow", "purple"]
var colors3 = colors.slice(1,4);//["green", "blue", "yellow"]
注意:1、开始位置 > 结束位置,返回空数组。2、参数有负值时数组length加上该值重新计算
3、最强大的方法splice方法(改变原来数组)
splice方法始终返回一个数组,该数组中包含从原始数组中删除的项,如果没有删除项目则返回一个空数组。
splice方法之删除:两个参数,起始位置及要删除的项数,返回的是被删除的数组元素组成的数组
var array = [0,1,10,15,5];
var tmp = array.splice(1,2);
console.log(array);//0,15,5
console.log(tmp);//1,10
splice方法之插入:三个参数,起始位置,0(要删除的项数),要插入的项目(多个项目加参数,不能是数组),返回的是空数组
var array = [0,1,10,15,5];
var tmp = array.splice(1,0,2);
console.log(array);//0,2,1,10,15,5
console.log(tmp);//undefined
注意:插入时起始位置就是要插入项目的位置
splice方法之替换:三个参数,起始位置,要删除的项数,要插入的任意数量的项目(不必与删除的项目数相同),返回的是被删除的数组元素组成的数组
var array = [0,1,10,15,5];
var tmp = array.splice(1,2,2);
console.log(array);//0,2,15,5
console.log(tmp);//1,10
九、位置方法
位置方法有两个参数:要查找的项和(可选)搜索起点位置的索引
返回值:找到时返回要查找的项在数组中的位置,没找到时返回-1
作用:查找位置,判断元素是否在数组中
indexOf()从前开始搜索,lastIndexOf()从后开始搜索
return array.indexOf(value) != -1 ? true : false;
十、遍历方法
5个遍历方法,没个方法都可以接受两个参数。要在没一项上运行的函数和(可选)运行该函数的作用域对象,这个对象影响this的值
传进去的函数有三个参数,当前数组项的值,当前数组项的位置(index),数组对象,即(item, index, array)
分为三类:
! 返回boolean。用来判断数组中的项是否满足条件
array.every(callbackfn) 对数组中每一项运行函数,如果所有项都返回true,则返回true。
let array = [0,1,2,3,45,5,8,5];
let ord1 = 0;
let ord2 = 0;
let every = array.every((item, index, array) => {
++ord1;
(typeof item === 'number') && (++ord2);
return typeof item === 'number';
});
console.log(ord1);//8
console.log(ord2);//8
console.log(every);//true
let array = [0,"1",2,3,45,5,8,5];
let ord1 = 0;
let ord2 = 0;
let every = array.every((item, index, array) => {
++ord1;
(typeof item === 'number') && (++ord2);
return typeof item === 'number';
});
console.log(ord1);//2
console.log(ord2);//1
console.log(every);//false
可以看到使用every方法有false就直接跳出循环了。
array.some(callbackfn) 对数组中每一项运行函数,如果任一项返回true,则返回true。
let array = [0,"1",2,3,45,5,8,5];
let ord1 = 0;
let ord2 = 0;
let some= array.some((item, index, array) => {
++ord1;
(typeof item === 'number') && (++ord2);
return typeof item === 'number';
});
console.log(ord1);//1
console.log(ord2);//1
console.log(some);//true
可以看到使用some方法有true就也直接跳出循环了。
let array = ["0","1","2","3","45","5","8","5"];
let ord1 = 0;
let ord2 = 0;
let some = array.some((item, index, array) => {
++ord1;
(typeof item === 'number') && (++ord2);
return typeof item === 'number';
});
console.log(ord1);//8
console.log(ord2);//0
console.log(some);//false
!!返回数组,用于过滤和按照条件重组数组
filter方法,过滤数组,对数组中每一项运行函数,返回函数返回值为true的项组成的新数组。
let array = [0,1,"2","3","45","5","8","5"];
let ord1 = 0;
let ord2 = 0;
let filter = array.filter((item, index, array) => {
++ord1;
(typeof item === 'number') && (++ord2);
return typeof item === 'number';
});
console.log(ord1);//8
console.log(ord2);//2
console.log(filter);//[0,1]
let array = ["0","1","2","3","45","5","8","5"];
let ord1 = 0;
let ord2 = 0;
let filter = array.filter((item, index, array) => {
++ord1;
(typeof item === 'number') && (++ord2);
return typeof item === 'number';
});
console.log(ord1);//8
console.log(ord2);//0
console.log(filter);//[]
如果没有匹配返回空数组
map方法重组数组
let array = ["0","1","2","3","45","5","8","5"];
let ord1 = 0;
let map = array.map((item, index, array) => {
++ord1;
return "test" + item;
});
console.log(ord1);//8
console.log(map);//["test0","test1","test2","test3","test45","test5","test8","test5"]
!!!没有返回值,用于对数组中每一项进行特定的操作
forEach方法用于对数组中每一项执行函数,是比较常用的方法
let array = ["0","1","2","3","45","5","8","5"];
array.forEach((item, index, array) => {
console.log(item);
});//输出数组每一项
十一、迭代方法
迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。
reduce()方法从数组的第一项开始遍历到最后,reduceRight()方法从数组最后一项开始遍历到第一项,其他没区别
方法接受两个参数:一个在每一项上调用的函数fn和(可选)作为迭代基础的初始值。
函数fn接受4个参数:前一个值,当前值,当前值的索引和数组对象,即(prev, cur, index, array)
使用reduce时,第一次迭代发生在数组第2项上,然后把第一次的函数的返回值当作第2次函数的第一个参数,以此类推。
let array = [1,2,3,4,5,6,7,8,9,10];
let sum = array.reduce((prev, cur, index, array) => {
console.log("第" + index + "次:prev=" + prev + ",cur=" + cur + ",return =" + (prev + cur));//第一次迭代发生在数组第2项上,然后把第一次的函数的返回值当作第2次函数的第一个参数
return prev + cur
});
console.log(sum);
第1次:prev=1,cur=2,return =3
第2次:prev=3,cur=3,return =6//函数的返回值当作下一次函数的第一个参数
第3次:prev=6,cur=4,return =10
第4次:prev=10,cur=5,return =15
第5次:prev=15,cur=6,return =21
第6次:prev=21,cur=7,return =28
第7次:prev=28,cur=8,return =36
第8次:prev=36,cur=9,return =45
第9次:prev=45,cur=10,return =55
55
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ES5中数组方法基本没了,对于数组的循环已经不再使用for了,(虽然js的源代码也应该使用的for循环,不过经理说过,能用封装好的就不要自己写)
接下来就应该是对象了,慢慢来吧
我的微信是t230124,欢迎打扰吐槽及打LOL