数组 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