数组是JavaScript中一个很重要的概念。
数组是一种特殊的变量,因为它一个变量里面可以存储多个值。
一、创建数组
var array_name = [item1, item2, ...]; 比如: var imgURL=["images/1.jpg","images/2.jpg","images/3.jpg"];
虽然数组也是一种Object对象,但是还是不要用new Array()的方法创建。
二、访问数组
访问数组存储的值是用索引值(下标)。下标从0开始。
var img_0=imgURL[0]; oImg.src=img_0;
数组有一个length属性,可以获得数组的长度。
那么length-1就是数组最后一个值的索引值。
var img_last=imgURL[imgURL.length-1];
三、数组是一种特殊的对象
虽然数组是一种Object,但是它是用索引值的方式来访问元素。
imgURL.0这种面向对象的点语法结构是不行的,因为在JavaScript中,以数字开头的属性不能用点号引用,必须用方括号。或者是属性是一个自定义的属性,并且是一个变量的时候,也需要使用[]方括号。
其实imgURL['2']和imgURL[2]是一样的。 2 会被 JavaScript 解释器通过调用 toString 隐式转换成字符串。
只能使用整数作为索引,而不能使用字符串。这是数组的一大特征。
四、如何判断变量是一个数组
因为typeof不能返回array,只能返回object,所以不能用typeof来判断一个变量是否是数组。
1、isArray()
ES5新增的isArray()函数可以很好的解决这个问题,可惜的是IE8等老浏览器不支持。
Array.isArray(obj) 比如: Array.isArray(imgURL) ;//true
2、自己创建isArray()函数
function isArray(x) { return x.constructor.toString().indexOf("Array") > -1; }
x是变量,表示要检测的对象是否是一个数组。如果是数组返回true。
3、使用istanceof运算符
imgURL instanceof Array; // true
五、数组的属性
1、length
length属性用来返回或者设置数组元素的个数。
imgURL.length;// 3
默认情况下,数组的长度比最大的索引值多一个1.
如果直接为length赋值,则会增加数组的长度。但是对于没有值的元素,会返回undefined。而且,keys值也没有对应的下标属性。
imgURL.length=4; imgURL[3];//undefined Object.keys(imgURL);//['0','1','2']
如果直接为某个超过数组最大下标值的合法下标数字赋值,也会同时修改length的值。
imgURL[5]="images/5.jpg"; imgURL.length;// 6 Object.keys(imgURL);//['0','1','2','5']
如果为length赋了一个更小的值,则会删掉元素。
imgURL.length=2; Object.keys(imgURL);//['0','1']
所以,可以为数组的length赋值为0来清空数组。
注意:imgURL.length=0,清空的是原来的数组,包括所有原数组的引用。而imgURL=[],则是创建一个新数组,产生新的变量的引用。
var imgURL=["images/1.jpg","images/2.jpg","images/3.jpg"]; var num=[1,2,3]; var imgURL2=imgURL; var num2=num; imgURL.length=0; num=[]; console.log(imgURL,imgURL2,num,num2);// [] [] [] [1,2,3]
2、constructor
返回创建数组对象的原型的函数。
在js中,构造函数属性返回对象的构造函数函数。
返回的值不是函数名,而是对函数的引用。
var arr=[]; arr.constructor; //function Array() { [native code] } var num=1; num.constructor;//function Number() { [native code] } var str=''; str.constructor; //function String() {[native code]}
所以,当typeof不能返回array数组对象的时候,可以用该属性返回一个变量是不是数组。
var arr=[]; arr.constructor.toString().indexOf('Array') // 9 .先把构造函数转成一个字符串,再查找字符串中是否有Array字符串,9是Array的索引值
3、prototype
prototype是原型的意思。
利用原型构造函数可以为Array()对象本身添加新的属性和方法,这些新的属性和方法可以被所有的数组实例继承。
prototype是全局构造器,js的所有对象都有这个原型构造函数。
Array.prototype.myUcase=function(){ for(var i=0;i<this.length;i++){ this[i]=this[i].toUpperCase(); //把数组里的每一个元素都转成大写。 } } var arr=['Tom','Daisy','Jenny','Susan']; arr.myUcase(); console.log(arr); //["TOM", "DAISY", "JENNY", "SUSAN"]
六、数组常用的方法
1、push()添加元素到末尾
push()函数返回修改后的数组的长度。
var num=[1,2,3]; num.push(4); //[1,2,3,4] var x=num.push("apple"); x;// 5
2、unshift()添加元素到数组头部
注意:IE8及以下,不能返回新数组的长度,返回undefined。
var students=["王菊","小芳","郝亮"]; var x=students.unshift("花木兰","刘亦菲");// x:5 ,students:["花木兰","刘亦菲","王菊","小芳","郝亮"]
3、pop()删除末尾的元素
pop()函数返回删除的元素。
var city=["成都","重庆","广州"]; var x=city.pop();// "广州"
4、shift()删除数组头部元素。
返回被删除的元素。
var city=["成都","重庆","广州"]; var x=city.shift(); // "成都"
5、修改和扩展数组
var city=["成都","重庆","广州"]; city[2]="北京"; city[city.length]="上海";
6、splice()添加/移除数组内的元素,返回被移除的元素
这个方法还有点点复杂,用法很强。
array.splice(index, howmany, item1, ....., itemX) index: 必须的。一个整数,指定添加/删除项目的位置,使用负值指定数组末尾的位置 howmany: 可选的。要删除的项目数。如果设置为0,则不会删除任何项目 item1, ..., itemX:可选的。要添加到数组的新项目
var city=["成都","重庆","广州"]; var x=city.splice(1,0,"北京"); // x:[],city:["成都","北京","重庆","广州"] var city=["成都","重庆","广州"]; var x=city.splice(1,2,"北京"); //x:["重庆","广州"],city:["成都","北京"] var city=["成都","重庆","广州"]; var x=city.splice(2,1);// x:["广州"],city:["成都","重庆"]
如果要移除的项目个数大于实际的个数,也不会报错,会移除位置后面的全部项目。
//数组去重的小方法 var arr=[1,2,3,3,4,5,4,7,8,7]; // 简单粗暴效率不高方法 for(var i=0;i<arr.length;i++){ for(var j=i+1;j<arr.length;j++){ if(arr[i]==arr[j]){ arr.splice(j,1); j--; } } } // 通过Set对数组去重,再利用Array.from()方法重新返回数组。 var arr1=Array.from(new Set(arr)); // 利用[...]扩展运算符返回数组。 var arr1=[...new Set(arr)]; console.log(arr1);
7、indexOf()、lastIndexOf()通过索引查找元素
这两个方法是通过索引找元素,是ES5新增的方法,IE9及以上支持。和String的两个方法相似。
搜索将从指定位置开始,如果未指定开始位置,则从头开始,并在数组末尾结束搜索。
没有则返回-1.
如果项目多次出现,则indexOf()方法返回第一次出现的位置。
array.indexOf(item, start)
var fruits = ["Banana", "Orange", "Apple", "Mango", "Banana", "Orange", "Apple"]; var a = fruits.indexOf("Apple", 4); //a: 6 var fruits = ["Banana", "Orange", "Apple", "Mango", "Banana", "Orange", "Apple"]; var a = fruits.indexOf("pear"); //a: -1
lastIndexOf()则是从指定位置从数组后面往前面搜索。
var fruits = ["Banana", "Orange", "Apple", "Mango", "Banana", "Orange", "Apple"]; var a = fruits.lastIndexOf("Apple"); // a:6 var fruits = ["Banana", "Orange", "Apple", "Mango", "Banana", "Orange", "Apple"]; var a = fruits.lastIndexOf("Apple",4); //a:2
8、通过索引删除一个或多个元素
var fruits = ["Banana", "Orange", "Apple", "Mango"]; var pos=fruits.indexOf("Orange"); //pos:1 var x=fruits.splice(pos,1); //x:["Orange"] var fruits = ["Banana", "Orange", "Apple", "Mango"]; var pos=fruits.indexOf("Orange"); //pos:1 var n=2; var x=fruits.splice(pos,n); //x:["Orange","Apple"] fruits:["Banana","Mango"]
9、slice()返回选中的元素为新数组
array.slice(start,end)
start是起始位置,end是结束位置,但是不包括结束位置。如果第二个参数省略,则从起始选择到最后。如果为负值,则从右往左索引值分别是0,-1。不包括起始位置。
返回新数组,不会改变原始数组。
var city=["成都","重庆","广州"]; var newCity=city.slice(1,2); //newCity:["重庆"] var city=["成都","重庆","广州"]; var newCity=city.slice(-2,-1); //newCity:["重庆"] var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"]; var myBest = fruits.slice(3); // myBest:["Apple", "Mango"] var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"]; var myBest = fruits.slice(-3); // myBest:["Lemon", "Apple", "Mango"]
10、concat()连接两个或多个数组
返回一个新数组。
array1.concat(array2, array3,..., arrayX)
var hege = ["Cecilie", "Lone"]; var stale = ["Emil", "Tobias", "Linus"]; var kai = ["Robin"]; var children = hege.concat(stale,kai); //children:["Cecilie", "Lone", "Emil", "Tobias", "Linus", "Robin"]
11、join()
将数组的元素连接成一个字符串,并返回字符串。
可以指定连接元素的分隔符。
array.join(separator)
var fruits = ["Banana", "Orange", "Apple", "Mango"]; var energy = fruits.join(" and "); // energy:"Banana and Orange and Apple and Mango"
这个方法和toString()方法还是有点区别。join()可以指定分隔符,数组调用toString()返回的是默认用逗号分割的字符串。
var num=[1,2,3]; num.join();//1,2,3 num.join("");//123 num.toString();//1,2,3
12、sort()排序数组内的元素
排序顺序可以是字母顺序或数字顺序,也可以是升序(向上)或降序(向下)。
默认情况下,sort()方法按字母顺序和升序将值排序为字符串。
排序字符是按照字符的ASCII码升序排列。
并且,会更改原始数组。
var str=["d","a","c","e","f","j","b"]; str.sort(); //str:["a", "b", "c", "d", "e", "f", "j"]
如果排序数字,则会出现问题,比如25和100,因为是按照顺序比较字符的ASCII码,2比1大,则不管后面的数字,25都大于100,这个问题,可以通过compare函数解决。
array.sort(compareFunction)
compareFunction:可选的。定义替代默认排序顺序的函数。该函数应返回负值,零值或正值,具体取决于参数,如:
var num=[102,15,10,200,3.14,45.12]; num.sort(function(a,b){return a-b}); // num: [3.14, 10, 15, 45.12, 102, 200] 升序排列 num.sort(function(a,b){return b-a}) //num:[200, 102, 45.12, 15, 10, 3.14] 降序排列 num[0]; // 最大值 200 num[num.length-1];// 最小值 3.14
当然,如果仅仅想获得最大值和最小值,对全部数组进行排序是很低效的方法。
可以使用Math.max()的方法。
这个方法可以选取给定参数中最大的值。
Math.max(1,5,10,3.15,-12.45); // 10 Math.max('5','10.25','-12.12'); // 10.25
如果要对数组取最大值,则要用Math.max.apply()的方法。
apply([thisObj[,argArray]]);// thisObj必须是一个对象。argArray是要判断的一组数组作为参数被传递到函数。
Math.max.apply(null,[1,12,13.5,-25.25]) ;// 13.5 Math.max.apply(null,['1',12,'13.5',-25.25]) ;// 13.5 Math.max.apply(null,['1','12a','13.5',-25.25]) ;// NaN
取最小值则可以用Math.min(),对应数组则是Math.min.apply()方法。
通过改变compare函数可以得到不同的排序,比如获得随机排序:
var arr=[21,25,2,12,45,-12.5]; arr.sort(function(a,b){return 0.5-Math.random().toFixed(2)}) ;//每次的排序都不一样。Math.random()函数得到0-1的随机小数。 //toFixed(2)是取两位小数,返回的是字符串形式,但是0.5-'0.3',又可以隐式转换成数字类型了。
当然,上面的方法有一些性能的影响,如果想用最快的性能得到最大最小值,可以自定义一个函数。
利用数组循环,将找到的最大最小值与每一个值进行比较。
function myArrayMax(arr){ var len=arr.length; var max=-Infinity; // for(var i=0;i<len;i++){ // if(arr[i]>max){ // max=arr[i]; // } // } while(len--){ if(arr[len]>max){ max=arr[len]; } } return max; } var arr=[1,2,3,4,5,-12,8,20,-50]; console.log(myArrayMax(arr)); // 20
function myArrayMin(arr){ var len=arr.length; var min=Infinity; while(len--){ if(arr[len]<min){ min=arr[len]; } } return min; } var arr=[1,2,3,4,5,-12,8,20,-50,-Infinity,'2']; console.log(myArrayMin(arr)); //-Infinity
数组里面带有单位,可以使用转换函数,比如:
var price=['12.5元','35.8元','0.5元','85.42元'] price.sort(function(a,b){ return parseFloat(b)-parseFloat(a); }) console.log(price); //["85.42元", "35.8元", "12.5元", "0.5元"]
13、reverse()反转数组中元素的顺序
var fruits = ["Banana", "Orange", "Apple", "Mango"]; fruits.sort(); //["Apple","Banana","Mango","Orange"]; fruits.reverse(); //["Orange", "Mango", "Banana", "Apple"]
数组的方法非常多,这些是常用的,几乎没有兼容性问题,在ES5和ES6中又增加了很多新方法,下篇再介绍。
发表评论:
◎请发表你卖萌撒娇或一针见血的评论,严禁小广告。