js之数组知识
一.数组的定义(来源于Array.prototype)
1.构造函数方法:
(1)var arr = new Array();//没有参数等价于 var arr = [];
(2)var arr = new Array(length);//创建指定长度的数组;预分配一个数组空间;但数组中没有存储值,甚至数组的索引属性'0','1'等还未定义
(3)var arr=new Array(值1,值2,值3...)
2.字面量:var arr = []; var arr=[1,2,3]
区别:new Array()只有一个参数(不能为小数:非法!报错!)时,会被当成是长度,并成为一个稀松数组;
var arr1 = new Array(4); var arr2 = [4]; console.log(arr1);//[undefined*4] console.log(arr2);//[4] var arr = new Array(3.4); console.log(arr);//Uncaught RangeError: Invalid array length
二.数组的读写(不可溢出读,结果为undefined;可以溢出写)
原理:数组索引仅仅是对象属性名的一种特殊类型,这意味着javascript数组没有'越界错误'的概念,.当试图查询任何对象不存在的属性还是,不会报错,只会得到undefined值.
var arr = [1,2]; console.log(arr[2]);//undefined arr[4] = 5;//溢出写 console.log(arr);//[1,2,undefined,undefined,5]; console.log(arr[3]);//undefined--->实际上是arr['3'] var obj = {}; console.log(obj.age);//undefined var arr = []; console.log(arr['age']);//undefined
注意:数组是对象的特殊形式.使用方括号访问数组就像方括号访问对象的属性一样,javascript将指定的数字索引值转换为字符串---索引1变为'1'---然后将其作为属性名来使用.
数组的特别之处在于:当使用小于等于2^32-2的非负整数作为属性名时,数组会自动维护其length属性值;
arr[Math.pow(2,32)-2] = 67;//索引 arr[Math.pow(2,32)-1] =22;// 属性名
arr[1]--->实际上是arr['1'];
var arr = [1,2,3,4]; console.log(arr); //[1, 2, 3, 4] //0:1 //1:2 //2:3 //3:4 //length:4 console.log(arr[1])//2,实际上是访问数组的'1'属性;
(1)可以用负数或非整数来索引数组.这种情况下,数值转换为字符串,字符串作为属性名来使用(即索引不是非负整数的情况下,只能当做常规的对象属性);
(2)同样,如果凑巧使用了非负整数(即0和正整数)的字符串,它就当做数组索引,而非对象属性.
(3)当使用的一个浮点数和一个整数相等时,也是当做数组索引
即除了(2)和(3)情况,[]内的值都当成对象属性名(转换为字符串)
var arr = [1,2,3,4]; arr[-2] = 'name';//-2当做属性-------(1) arr[1.5] = 9;//1.5当做属性-----------(1) arr['3'] = 15;//数组索引;等价于arr[3]------(2) arr[1.00] = 23//数组索引;等价于arr[1]=23---(3) arr['1.00']=4;//1.00当做属性1.00
arr['age'] = 6;//age:属性
console.log(arr);// [1, 23, 3, 15, -2: "name", 1.5: 9, 1.00: 4,age:6]
console.log(arr.length)//4 索引值为小于2^32的非负整数会自动维护其length值
var obj = {};//空对象或不空的
arr[obj] = '5';//属性名为[object Object]: "5"
三.稀松数组:包含从0开始的不连续索引的数组;length属性值大于元素的个数,可以用Array()构造函数或简单地指定数组的索引值大于当前的的数组长度来创建稀疏数组
1.var arr = new Array(5);//数组没有元素,但a.length = 5
2. a = [];//当前length为0;
a[1000] = 0;//1000>0;稀疏数组,length变为1001;
四.数组的常用方法
(一)改变原数组的:reverse,push,pop,unshift,shift,splice,sort;
(1)reverse()---颠倒数组中元素的顺序并返回新的数组。
var arr=[1,2,3]; var a = arr.reverse(); console.log(arr);//[3,2,1] console.log(a);//[3,2,1]
(2)push()---向数组的末尾添加一个或更多元素,并返回新的长度。
var arr=[1,2,3]; var a = arr.push(4,5); console.log(arr);//[]1,2,3,4,5] console.log(a);//5
(3)pop()---删除并返回数组的最后一个元素(没有形参,写了会被忽略)
var arr=[1,2,3]; var a = arr.pop(4,5);//自动忽略掉参数4,5 console.log(arr);//[1,2] console.log(a);//3
(4)unshift()---向数组的开头添加一个或更多元素,并返回新的长度。
var arr=[1,2,3]; var a = arr.unshift(4,5); console.log(arr);//[4,5,1,2,3] console.log(a);//3
(5)shift()---删除并返回数组的第一个元素
var arr=[1,2,3]; var a = arr.shift();//没有形参,有的话会忽略 console.log(arr);//[2,3] console.log(a);//3
(6)splice()---删除元素,并向数组添加新元素,并返回删除的元素。
它有三个参数,第一个参数时截取开始的位置,第二个参数是截取的长度,第三个参数是一组数据,代表要在截取的位置添加的数据
var arr=[1,2,3]; var a = arr.splice(1,2,4,5)//从第一位开始截取两位数据2,3,并在当前位置添加数据4,5; console.log(arr);//[1,4,5] console.log(a);//[2,3]
var b = arr.splice(1,2,[7,8],9);//这里splice是插入数组本身,区别concat连接数组是数组的元素;
console.log(arr);//[1,[7,8],9];
console.log(b);//[4,5];
var arr=[1,2,3]; var a = arr.splice(-1,2,4,5)//从倒数第一位(第二位)(-1+arr.length=2)开始截取两位数据(这里只有一位数据了)3,并在当前位置添加数据4,5; console.log(arr);//[1,2,4,5] console.log(a);//[3]
var arr = [1,2,,3,4]; var a=arr.sort(); console.log(a);//[1,2,3,4,undefined]
var arr=[1,5,3,9,-7,2]; var a = arr.sort(); console.log(arr);//[-7, 1, 2, 3, 5, 9] console.log(a);//[-7, 1, 2, 3, 5, 9]
var arr=[1,5,3,9,-7,2]; var a = arr.sort().reverse(); console.log(arr);//[9, 5, 3, 2, 1, -7] console.log(a);//[9, 5, 3, 2, 1, -7]
var arr=[1,3,10,2,5]; var a = arr.sort(); console.log(arr);//[1,10,2,3,5]
var arr = [1,2,undefined,null,3,4]; var a=arr.sort(); console.log(a);//[1,2,3,4,null,undefined]--根据ASCII码进行排序
sort()函数有个接口:
注意:
看返回值return:
(1)当返回值为负数时,前面的数在前面
(2)当返回值为正数时,后面的数在前面
var arr=[1,3,10,2,5]; arr.sort(function(a,b){ if(a>b){ return 1;//a>b,b放在a前面,即小的数在前面 }else{ return -1;//a<b,a放在前面,即小的数在前面 } }) console.log(arr);//[1,2,3,5,10]
var arr=[1,3,10,2,5]; arr.sort(function(a,b){ return a-b; }) console.log(arr);//[1,2,3,5,10]
var arr=[1,2,3,4,5]; arr.sort(function(){ return Math.random()-0.5;//Math.random()--->[0,1); }) console.log(arr);
var deng = { name:'deng', age:12 }; var zao={ name:'zao', age:34 }; var li={ name:'li', age:10 } var arr= [deng,zao,li]; arr.sort(function(a,b){ return a.age-b.age;//1.按照年龄进行升序 //return a.name.length - b.name.length;//2.按照名字长度升序 }) console.log(arr);
根据字节长度进行排序
//字节长度,汉字为2;字母为1; function retBytes(str){ var num = str.length; for(var i = 0 ; i< str.length;i++){ if(str.charCodeAt(i) > 255){//返回指定位置的字符的 Unicode 编码; num += 1; } } return num; } var arr = ['Ming','李dang','王明','merheyka']; arr.sort(function(a,b){ return retBytes(a) - retBytes(b); }) console.log(arr);//["Ming", "王明", "李dang", "merheyka"]
(1)concat----连接两个或更多的数组,并返回一个新数组。
它的元素包括调用concat()的原始数组的元素和concat()的每个参数.若这些参数中的任何一个自身是数组,这连接的是数组的元素,而非数组本身;
但注意:concat()不会递归扁平化数组的数组.concat()也不会修改调用的数组;
var arr1 = [1,2,3]; var arr2 = [4,5]; var arr=arr1.concat(arr2);//等价于var arr = [].concat(arr1,arr2);concat可以有一个或多个参数
console.log(arr);//[1,2,3,4,5] console.log(arr1);//[1,2,3] console.log(arr2);//[4,5]
var arr3 = [6,[7,8]];
arr = arr1.concat(arr3);
console.log(arr);//[1,2,3,6,[7,8]];
(2)slice---从某个已有的数组返回选定的元素
slice可以有0个参数,1个参数或者2个参数(参数可以为负数(等价于 负数+数组长度)超出2个的参数会自动被忽略,认为只有2个参数)
第一种情况:0个参数:截取整个数组(用于将类数组转化为数组)
var obj = { '0':'a', '1':'b', 'length':2 } var a=Array.prototype.slice.call(obj); console.log(a);//['a','b']
第二种情况:1个参数:从第几位开始,一直截取到最后一位
var arr = [1,2,3,4,5,6]; var a=arr.slice(3); console.log(a);//[4,5,6]
第三种情况:2个参数:slice(从该位开始截取,截取到该位); 例slice(2,4)从第2位开始截取到第四位(不包括该位),即第二位和第三位
var arr = [1,2,3,4,5,6]; var a=arr.slice(3,5); console.log(a);//[4,5]
(3) join---把数组的所有元素放入一个字符串。元素通过指定的符号进行连接。(可以用这个方法来进行大量字符串的连接工作)
var arr = ['a', 'b', 'c']; var str = arr.join('-'); console.log(str); // "a-b-c"
join--若不传参数(默认为逗号连接) join() 等价于join(',');
拼接字符串:使用arr.join("");
扩展;:split:字符串转换为数组的方法根据符号将字符串拆分为数组
var arr = ['a', 'b', 'c']; var str = arr.join('-'); console.log(str); // "a-b-c" var a = str.split('-'); console.log(a);//['a','b','c']
注意:一个数组通过join()方法和split()后得到的数组与原来的数组不一定是一样的;通过split返回的数组;每个数都是字符串
var arr = [1, 2, 3]; console.log(typeof arr[0]);//number var str = arr.join('-'); console.log(str); // "a-b-c" var a = str.split('-'); console.log(a);//['1','2','3'] console.log(typeof a[0]);//string
小题目:将下面的字符串拼到一起
var str1 = 'tianmao'; var str2 = 'taobao'; var str3 = 'jindong'; var str4 = 'weipinghui'; var str5 = 'shuning'; var str6 = 'pingduoduo';
1.用+运算符去连接字符串---由于字符串时存在栈里面的(先进后出),栈操作消耗性能大
var arr = [str1,str2,str3,str4,str5,str6]; var str = ''; for(var i = 0 ; i < arr.length;i++){ str += arr[i]; } console.log(str);//tianmaotaobaojindongweipinghuishuningpingduoduo
2.用join方法----推荐
var arr = [str1,str2,str3,str4,str5,str6]; str = arr.join(''); console.log(str);//tianmaotaobaojindongweipinghuishuningpingduoduo
(4)toString()----把数组转换为逗号分隔的字符串列表.注意:输出不包括方括号或其他任何形式的包裹数组值的分隔符.
var arr = [1,2,3,4]; var str = arr.toString(); console.log(str);//"1,2,3,4"
[1,[2,3]].toString();//'1,2,c' 这里与不适用任何参数的调用join()返回的结果一样
(5)toLocalString():toString的本地化版本.
它调用元素的toLocalString()的方法将每个数组元素转化为字符串,并使用本地化(和自定义实现的)分隔符将这些字符串连接起来.
(三)ES5中的数组方法
var arr = [1, 2, 3, 4]; arr.forEach(function (ele, index) { arr[index] += 1; }) console.log(arr); // [2, 3, 4, 5]
var arr = [1, 2, 3]; var test = arr.map(function (x) { return x * x; }); console.log(test); // 1 4 9 console.log(arr); // 1 2 3
var a = [1, 2, 3, 4, 5]; var b = a.filter(function (x) { return x > 2; }); console.log(a);//[1,2,3,4,5] console.log(b); // [3,4,5]
同时,filter()会跳过稀疏数组里面缺少的元素,它的返回数组总是稠密的。
var arr = [1,,,,,,3,4]; var b = arr.filter(function () { return true; }) console.log(arr); // [1,3,4]
4.every和some
var arr = [1 ,2 ,3]; console.log(arr.some(function (x) {return x<3;})); //true console.log(arr.every(function (x) {return x<3;})); //false
var arr = [1, 2, 3]; var sum = a.reduce(function (x, y) { return x + y}, 0);// 6------0 + 1 + 2 + 3 = 6; var temp = [1]; var temoOut = a.reduce(function (x, y) {return x * x * y}); // 1 不会调用这个函数,因为数组只有一个值,除非我们设置一个初始值
6.indexOf()和lastIndexOf():搜索整个数组中具体给定值的元素,返回找到的第一个元素的索引或者如果没有找到就返回-1.indexOf()从头到尾搜索,而lastIndexOf()则反向搜索
var a = [0,1,2,1,0]; a.indexOf(1);//1-->a[1] = 1; a.lastIndexOf(1);//3--->a[3] = 1; a.indexOf(3);//-1;没有值
注意:indexOf()和lastIndexOf()不接收一个函数作为其参数(不报错---返回-1);
indexOf()和lastIndexOf()可以有两个参数,第一个是需要搜索的值,第二个是指定数组中的一个索引,从那里开始搜索
---以上知识参考了:javascript权威指南