Array数组
创建数组
- 构造函数
- 无参构造函数,创建一个空数组
var a1 = new Array()
- 一个数字参数构造函数,指定数组长度(由于数组长度可以动态调整,作用不大),创建指定长度的数组
var a2 = new Array(5)
- 带有初始化数据的构造函数,创建数组并初始化参数数据
var a3 = new Array(4,'hello
,new Date());`
- 字面量
- 使用[],创建空数组,等同于调用无参构造函数。
var a4 = [];
- 使用[],并传入初始化数据,等同于调用带有初始化数据的构造函数。
var a5 = [10,11]
- 注意点:
- 使用字面量的方式,无论传入几个参数,都会把参数当做初始化内容。
var a1 = [5];
console.log(a1.length); // 1
var a2 = [4,6];
console.log(a2.length); // 2
- 使用带有初始化参数的方式创建数组的时候,最后的不要带多余的',',因为在不同的浏览器中处理方式不一样。
数组的索引与长度
数组的值可以通过自然数索引访问进行读写操作,下标也可以是一个得出非负整数的变量或表达式
var a1 = [1,2,3,4,5];
console.log(a1[0]); // 1
var i = 1;
console.log(a1[i]); // 2
console.log(a1[i+1]); // 3
console.log(a1[i++]); // 3
console.log(a1[++i]); // 4
数组也是对象,我们可以使用索引的奥秘在于,数组会把索引值转换为对应字符串(1=>”1”)作为对象属性名
console.log(1 in a1);//true
确实是一个属性
所有的索引都是属性名,但只有自然数(有最大值)才是索引,一般我们在使用数组的时候不会出现数组越界错误也正是因为此,数组的索引可以不是连续的,访问index不存在的元素的时候返回undefined
var a = new Array(1,2,3);
a[100] = 100;
console.log(a.length); //101
console.log(a[3]); //undefined
console.log(a[99]); //undefined
console.log(a[100]); 100
虽然直接对a[100]赋值不会影响a[4]或a[99],但数组的长度却受到影响,数组length属性等于数组中最大的index+1,我们知道数组的length属性同样是个可写的属性,当强制把数组的length属性值设置为小于等于最大index值时,数组会自动删除indexd大于等于length的数据,在刚才代码中追加几句
a.length = 2
console.log(a);//[1,2]
这时候会发现a[2]和a[100]被自动删除了,同理,如果把length设置为大于最大index+1的值的时候,数组也会自动扩张,但是不会为数组添加新元素,只是在尾部追加空空间
a.length=5;
console.log(a); //[1,2] //后面没有3个undefined
元素的添加和删除
var arr = [1,2,3];
arr[3] = 4; //直接向数组中添加元素
console.log(arr); // [1,2,3,4]
delete arr[2];
console.log(arr); // 把元素2号位置的元素删除了 [1, 2, empty, 4]
//delete方法删除元素,length的值不变
console.log(arr[2]); // undefined
栈方法和队列方法
- 栈方法:pop和push,先入后出使用数组
var arr = [1,2,3,4];
arr.push(5); //向对尾添加元素
console.log(arr); // [1, 2, 3, 4, 5]
arr.pop(); //pop()没有参数
console.log(arr); // [1, 2, 3, 4]
//pop()和push()对原数组进行了改变
- 队列方法:shift和unshift方法,先入先出使用数组
var arr = [1,2,3,4];
arr.shift(5); //,对头删除了有个元素第一位没有了
console.log(arr); // [2, 3, 4]
arr.unshift(200); //对头添加了一个元素
console.log(arr); // [200, 2, 3, 4]
//shift()和unshift()对原数组进行了改变
slice():法用于一次性解决数组添加、删除,方法有三个参数
- 开始索引
- 删除元素的个数
- 插入的新元素,当然也可以写多个
splice方法返回一个由删除元素组成的新数组,没有删除则返回空数组
var arr = [1,5,6,4]
console.log(arr.splice(2,1))
// 第2个位置开始索引,删除1个元素[6]
console.log(arr); //[1,5,4]
console.log(arr.splice(1,1,8,6,7));
//在1的位置删除1个元素,再加上5,6,7三个元素
//arr.splice()返回的是被删除的数组元素
console.log(arr); // 原数组变成[1,8,6,7,4]
console.log(arr.splice(2,0,400,500));
//在第二个位置删除0个元素,之后在第二个位置**前**加上400,500
console.log(arr); //原数组变成[1,8,400,500,6,7,4];
join(char)
- 这个方法在C#等语言中也有,作用是把数组元素(对象调用其toString()方法)使用参数作为连接符连接成一字符串,不会修改原数组内容
var arr = [1,2,3,4,5,6]
console.log(arr.join('')); // 123456
console.log(arr.join('-')); //1-2-3-4-5-6
console.log(arr); // 原数组不变 [1,2,3,4,5,6]
slice(start,end)
不要和splice方法混淆,slice方法用于返回数组中一个片段或子数组,如果只写一个参数返回参数到数组结束部分,如果参数出现负数,则从数组尾部计数(-3意思是数组倒第三个,一般人不会这么干,但是在不知道数组长度,想舍弃后n个的时候有些用,不过数组长度很好知道,如果start大于end返回空数组,值得注意的一点是slice不会改变原数组,而是返回一个新的数组
var arr = [1,2,3,4,5,6]
console.log(arr.slice(6,3)); // []
console.log(arr.slice(2,5)); //[3,4,5]
console.log(arr.slice(-1,-3)); // []
concat(array)
concat方法用于拼接数组,a.concat(b)返回一个a和b共同组成的新数组,同样不会修改任何一个原始数组,也不会递归连接数组内部数组
var arr1 = [1,2,3,4,5,6]
var arr2 = ['a','d','f','g','h']
console.log(arr1.concat(arr2));
//[1,2,3,4,5,6,'a','d','f','g','h']
console.log(arr1); //原数组不会改变[1,2,3,4,5,6]
console.log(arr2); // 原数组不会改变['a','d','f','g','h']
reverse()
方法用于将数组逆序,与之前不同的是它会修改原数组
var arr1 = [1,2,3,4,5,6]
console.log(arr1.reverse()); // [6, 5, 4, 3, 2, 1]
console.log(arr1); // 原数组被改变 [6, 5, 4, 3, 2, 1]
// 示例:
var str = 'hello jirengu';
console.log(str.split('').reverse().join(''));
// 将字符串逆序,首先将字符串变成数组
sort
sort方法用于对数组进行排序,当没有参数的时候会按字母表升序排序,如果含有undefined会被排到最后面,对象元素则会调用其toString方法,如果想按照自己定义方式排序,可以传一个排序方法进去,很典型的策略模式,同样sort会改变原数组。
var arr = [3,1,-4,8,0]
console.log(arr.sort()); // [-4, 0, 1, 3, 8]
var arr = [3,1,-4,18,0]
console.log(arr.sort()); //[-4, 0, 1, 18, 3]
//因为sort()是按照字母表的Unicode码排序的,
//实际上数字18会当做字符串比较。
//如果真的想实现数字的比较,需要给sort()传递一个方法:
var arr1 = [-4,1,3,28,22,9]
console.log(arr1.sort()); // [-4, 1, 22, 28, 3, 9]
arr1.sort(function(a,b){
return a - b
})//sort中间传递了一个排序函数,得到一个从大到小
// 如果想得到一个从小到大,只需要进行 b - a
console.log(arr1); // [-4, 1, 3, 9, 22, 28]
var student = [
{name: 'c',age: 10},
{name: 'a',age: 20},
{name: 'f',age: 1},
{name: 'b',age: 18}
]
//按照数组的年龄进行排序
student.sort(function(s1,s2){
return s2.age - s1.age;
})
console.log(student);
//(4) [{…}, {…}, {…}, {…}]
//0: {name: "c", age: 20}
//1: {name: "g", age: 18}
//2: {name: "a", age: 10}
//3: {name: "f", age: 1}
//length: 4
//按照Name进行排序,字符串是可以作比较的
student.sort(function(s1,s2){
if(s1.name > s2.name){
return 1
}else{
return -1
}
})
console.log(student);
ES5-Array.isArray(obj)
这是Array对象的一个静态函数,用来判断一个对象是不是数组
var arr = [3,4,5]
console.log(Array.isArray(arr)); // true
// ES3的判断方法
console.log(typeof arr); // object
console.log(arr.toString()); // 3,4,5
console.log(arr instanceof Array); //true
ES5-indexOf(element) / lastIndexOf(elemen)
用于查找数组内指定元素的位置,查找到第一个后返回其索引,没有查找到返回-1,indexOf从头至尾的搜索,lastIndexOf反向搜索。
var arr = [3,4,5]
console.log(arr.indexOf(4));//查找元素4的位置 1
console.log(arr.indexOf(6)); //查找一个不存在的元素,返回-1
ES5-forEach
遍历数组,参数为一个回调函数,回调函数有三个参数:
- 当前元素
- 当前元素的索引值
- 整个数组
var arr = [2,5,7,3,8,9]
arr.forEach(function(value,index){
console.log(value,index) //遍历数组中的每一项以及下标
})
ES5-every和some方法:
- every是所有函数的每个回调都返回true的时候才会返回true,当遇到false的时候终止执行,返回false。
- some函数是存在有一个函数返回true的时候终止执行并返回true,否则返回false。
// every
var arr = [1,6,8,-2,-5,7,-4]
var isPositive = arr.every(function(value){
return value > 0;
})
console.log(isPositive) // false
//some
var arr = [1,6,8,-2,-5,7,-4]
var isPositive = arr.some(function(value){
return value > 0;
})
console.log(isPositive) // true
ES5-map(function(element)
与forEach()类似,遍历数组,回调函数返回值组成一个新数组返回,新数组索引结构和原数组一致,原数组不变。
var arr = [1,6,8,-2,-5,7,-4]
var arr1 = arr.map(function(e){
return e * e;
})
console.log(arr1); // [1, 36, 64, 4, 25, 49, 16]
console.log(arr); // [1, 6, 8, -2, -5, 7, -4]原数组不变
ES5-filter(function(element))
返回数组的一个子集,回调函数用于逻辑判断是否返回,返回true则把当前元素加到返回数组中,false则不加
新数组只包含返回true的值,索引确实的不包括,原数组保持不变。
var arr = [1,6,8,-2,-5,7,-4]
var student = [
{userName: 'aa',age: 20},
{userName: 'bab',age: 10},
{userName: 'cbc',age: 23},
{userName: 'dda',age: 26}
]
//过滤出所有userName包含a的同学
var stu = student.filter(function(student){
return student.userName.indexOf('a') > -1;
})
console.log(stu);
/*(3) [{…}, {…}, {…}]
0: {userName: "aa", age: 20}
1: {userName: "bab", age: 10}
2: {userName: "dda", age: 26}
length: 3
__proto__: Array(0)*/
//过滤出所有的整数
var positiverArr = arr.filter(function(value){
return value > 0
})
console.log(positiverArr); // [1, 6, 8, 7]
console.log(arr); // [1, 6, 8, -2, -5, 7, -4]
ES5-reduce(function(v1,v2),value) / .reduceRight(functio(v1,v2),value)
遍历数组,调用回调函数,将数组元素组合成一个值,reduce从索引最小值开始,reduceRight反向,方法有两个参数
- 回调函数,把两个值合成一个,返回结果
- value,一个初始值,可选
var arr = [1,2,3,4,5,6]
console.log(arr.reduce(function(v1,v2){
return v1 + v2;
})) // 21
//开始是1+2 = 3,之后3+3 =6,之后6+4 =10,之后
//10+5 =15,最后15+6 =21
console.log(arr.reduce(function(v1,v2){
return v1 - v2;
},100)) // 79
//开始的时候100-1=99,之后99-2=97,之后97-3=94,之后
//94-4=90,之后90-5=85,最后85-6=79
length属性
数组的length属性可读可写,可以从数组的末尾移除项或像数组中添加新项。
var arr = [1,4,8];
console.log(arr.length); // 3
arr.length = 2;
console.log(arr); // [1,4]
arr.length = 4;
console.log(arr); // [1, 4, empty × 2]
//由于数组最后一项的索引始终是length-1,因此下一个新项的位置就是length
var a = [3,5,6]
console.log[a.length] = '5';
//当把一个值放在超出当前数组大小的位置上时,数组就会重新计算其长度值
//即长度值等于最后一项的索引+1.
var a1 = [5,8,9,0]
a1[99] = '12';
console.log(a1.length); //100最后一项的索引是99,99+1=100
// 位置4-98返回的都是undefined