数组 Array
- 为什么要学习数组 ? // 除了对象之外,数组可能是 JavaScript 中最常用的类型了。
之前的数据类型,只能存一个值( 如,Number / String ),如果想存储班级中所有学生的姓名,该怎么办呢?
所谓数组,就是将多个元素(通常是同一类型)按一定顺序排列放到一个集合中,这个集合就称之为数组。
数组是一个有序的列表,可以在数组的每一项中保存任何类型的数据,且数组的大小是可以动态调整的。
[ 重点 ] 数组的常用方法?!— 方法的作用、方法的参数、方法的返回值、代码示例(完成一个demo)
创建数组
[ 数组对象- 稀疏数组 - 类数组 ?!] 有两种创建数组的方法:字面量语法和 Array() 构造函数。
通过数组字面量创建数组,是创建数组最简单的方法;同时,使用Array()构造函数时,可以省略 new 操作符。
var a1 = Array(); var a2 = Array(10); var a3 = Array(1,2,3); console.log(a1,a2,a3); // [] [] [1,2,3]
[1] 通过数组字面量创建数组(推荐):在方括号中将数组元素用逗号隔开即可
var empty = []; //没有元素的数组 var primes = [2,3,5,7,11]; //有5个数值的数组
数组都是数据的有序列表,但与其他语言不同的是:在 JS 中,数组的每一项可以保存任何类型的数据
var misc = [1.1,true, "a"]; //3个不同类型的元素 // 数组字面量中的值不一定要是常量,它们可以是任意的表达式 var base = 1024; var table = [base,base+1,base+2,base+3]; // 它可以包含对象字面量或其他数组字面量 var b = [ [1,{x:1,y:2}],[2,{x:3,y:4}] ];[ 多维数组 ]如果数组的元素还是数组,就形成了多维数组
var a = [[1, 2], [3, 4]];
[2] 使用构造函数创建数组:可以通过 3 种方式调用构造函数
- 没有参数,则会创建一个空数组
// 该方法创建一个没有任何元素的空数组,等同于数组直接量[] var a = new Array();
- 有一个参数,根据该参数类型的不同(数值类型 / 非数值类型)有所区别:
// 若该参数是数值类型,则该参数用于指定数组的长度 var a = new Array(10); console.log(a);//[] console.log(a[0],a.length);//undefined 10 // 若该参数是其他类型(非数值类型),则会创建包含该值的长度为 1 的数组 var a = new Array('10'); console.log(a); // ['10'] console.log(a[0],a.length); // 10 1
- 有多个参数时,参数表示为数组的具体元素
var a = new Array(1,2,3); console.log(a);//[1,2,3] console.log(a[0],a[1],a[2]);//1 2 3
获取数组的长度
length属性值代表数组中元素的个数。每个数组有一个length属性,这使其区别于常规的 JS 对象。
// 索引从0开始,所以length的值比数组中最大的索引大1 [].length //=>0 数组没有元素 ['a','b','c'].length //3 最大的索引为2,length为3
[ 索引 & length ]数组的特殊性主要体现在数组长度是可以动态调整的:
- 如果为一个数组元素赋值,索引i大于等于现有数组的长度时,length属性的值将设置为i+1
var arr = ['a', 'b']; arr.length // 2 arr[2] = 'c'; arr.length // 3 arr[9] = 'd'; arr.length // 10 arr[1000] = 'e'; arr.length // 1001
- 设置length属性为小于当前长度的非负整数n时,当前数组索引值大于等于n的元素将从中删除
a=[1,2,3,4,5]; //从5个元素的数组开始 a.length = 3; //现在a为[1,2,3] a.length = 0; //删除所有的元素。a为[] a.length = 5; //长度为5,但是没有元素,就像new Array(5)[ 清空数组 ]将数组清空的一个有效方法,就是将length属性设为0
var arr = [ 'a', 'b', 'c' ]; arr.length = 0; arr // []
- 将length属性设为大于其当前的长度。实际上不会向数组中添加新的元素,只是在数组尾部创建一个空的区域
var a = ['a']; a.length = 3; console.log(a[1]); // undefined console.log(1 in a); // false
[ 属性 & length ]由于数组本质上是对象,所以可以为数组添加属性,但是这不影响length属性的值
var a = []; a['p'] = 'abc'; console.log(a.length);// 0 a[2.1] = 'abc'; console.log(a.length);// 0
数组的循环遍历
数组的循环遍历,最常见的方式是使用for循环。
var a = [1, 2, 3];
for(var i = 0; i < a.length; i++) {
console.log(a[i]);
}
但如果数组是稀疏数组时,使用for循环,就需要添加一些条件
//跳过不存在的元素
var a = [1,,,2];
for(var i = 0; i < a.length; i++){
if(!(i in a)) continue;
console.log(a[i]);
}
还可以使用for/in循环处理稀疏数组。循环每次将一个可枚举的属性名(包括数组索引)赋值给循环变量。
// 不存在的索引将不会遍历到
var a = [1,,,2];
for(var i in a){
console.log(a[i]);
}
由于for/in循环能够枚举继承的属性名,如添加到Array.prototype中的方法。
由于这个原因,在数组上不应该使用for/in循环,除非使用额外的检测方法来过滤不想要的属性。
var a = [1,,,2]; a.b = 'b'; for(var i in a){ console.log(a[i]);//1 2 'b' }//跳过不是非负整数的i var a = [1,,,2]; a.b = 'b'; for(var i in a){ if(String(Math.floor(Math.abs(Number(i)))) !== i) continue; console.log(a[i]);//1 2 }
数组的乱序
数组乱序( shuffle ),也称为洗牌。一般有如下两种方法:
[1] 给数组原生的sort()方法传入一个函数,此函数随机返回1或-1,达到随机排列数组元素的目的
var array = [1,2,3,4,5];
console.log(array.sort(function(){return Math.random() - 0.5}));//[2,1,5,4,3]
// 代码示例:如果打乱100000个元素的数组,则需要100ms左右
var arr = []; var NUM = 100000; for(var i = 0; i < NUM; i++){ arr.push(i); } var startTime = +new Date(); arr.sort(function(){return Math.random() - 0.5}); console.log(+new Date() - startTime);//100
[2] 依次遍历数组中的每个元素,遍历到的元素与一个随机位置的元素交换值
var arr = [1,2,3,4,5];
for(var i = 0 ; i < arr.length; i++){
var randomIndex = Math.floor(Math.random()*arr.length);
[arr[i],arr[randomIndex]] = [arr[randomIndex],arr[i]];
}
console.log(arr); // [2, 3, 1, 4, 5]
// 代码示例:如果打乱100000个元素的数组,需要13ms左右,因此第二种方法效率较高。
var arr = []; var NUM = 100000; for(var i = 0; i < NUM; i++){ arr.push(i); } var startTime = +new Date(); for(var i = 0 ; i < arr.length; i++){ var randomIndex = Math.floor(Math.random()*arr.length); [arr[i],arr[randomIndex]] = [arr[randomIndex],arr[i]]; } console.log(+new Date() - startTime); // 13