JavaScript 定义(创建或者声明)数组的方法有两种:构造数组和数组直接量。
使用 new 运算符调用 Array() 类型函数时,可以构造一个新数组。
直接调用 Array() 函数,不传递参数,可以创建一个空数组。
var a = new Array(); //空数组
传递多个值,可以创建一个实数组。
var a = new Array(1, true, "string", [1,2], {x:1,y:2}); //实数组
每个参数指定一个元素的值,值得类型没有限制。参数的顺序也是数组元素的顺序,数组的 length 属性值等于所传递参数的个数。
传递一个数值参数,可以定义数组的长度,即包含元素的个数。
var a = new Array(5); //指定长度的数组
参数值等于数组 length 的属性值,每个元素的值默认值为 undefined。
如果传递一个参数,值为 1,则 JavaScript 将定义一个长度为 1 的数组,而不是包含一个元素,其值为 1 的数组。
var a = new Array(1);
console.log(a[0]);
数组直接量的语法格式:在中括号中包含多个值列表,值之间用逗号分隔。
下面代码使用数组直接量定义数组。
var a = []; //空数组
var a = [1, true, "0", [1,0], {x:1,y:0}]; //包含具体元素的数组
推荐使用数组直接量定义数组,因为数组直接量是定义数组最简便、最高效的方法。
空位数组就是数组中包含空元素。所谓空元素,就是在语法上数组中两个逗号之间没有任何值。出现空位数组的情况如下。1) 直接量定义
var a = [1, , 2];
a.length; //返回3
如果最后一个元素后面加逗号,不会产生空位,与没有逗号时效果一样。
var a = [1, 2, ];
a.length; //返回2
2) 构造函数定义
var a = new Array(3); //指定长度的数组
a.length(); //返回3,产生3个空元素
3) delete 删除
var a = [1, 2, 3];
delete a[1];
console.log(a[1]); //undefined
console.log(a.length); //3
上面代码使用了 delete 命令删除了数组的第 2 个元素,这个位置就形成了空位。
空元素可以读写,length 属性不排斥空位。如果使用 for 语句和 length 属性遍历数组,空元素都可以被读取,空元素返回值为 undefined。
var a = [, , ,];
for (var i = 0; i < a.length; i++) {
console.log(a[i]); //返回3个undefined
空元素与元素的值为 undefined 是两个不同的概念,即使空元素的返回值也是 undefined。JavaScript 在初始化数组时,只有真正存储有值得元素才可以分配内存。
使用 forEach() 方法、for/in 语句以及 Object.keys() 方法进行遍历时,空元素都会被跳过,但是值为 undefined 元素,能够被正常迭代。
var a = [, , undefined];
for (var i in a) {
console.log(i); //返回2,仅读取了第3个元素
}
console.log(a.length); //返回3,包含3个元素
如果数组的下标值超出范围,如负数、浮点数、布尔值、对象或其他值,JavaScript 会自动把它转换为一个字符串,并定义为关联数组。
关联数组就是与数组关联的对象,简单的说就是数组对象,字符串下标就是数组对象的属性。
在下面示例中,数组下标 false、true 将不会被强制转换为数值 0、1,JavaScript 会把变量 a 视为对象,false 和 true 转换的字符串被视为对象的属性名。
var a = []; //声明数组
a[false] = false;
a[true] = true;
console.log(a[0]); //返回undefined
console.log(a[1]); //返回undefined
console.log(a[false]); //返回false
console.log(a[true]); //返回true
console.log(a["false"]); //返回false
console.log(a["true"]); //返回true
关联数组是一种数据格式,被称为哈希表。哈希表的数据检索速度要优于数组。
var a = [["张三",1],["李四",2],["王五",3]]; //二维数组
for (var i in a) { //遍历二维数组
if (a[i][0] == "李四") console.log(a[i][1]); //检索指定元素
}
如果使用文本下标会更为高效。
var a = []; //定义空数组
a["张三"] = 1; //以文本下标来存储元素的值
a["李四"] = 2;
a["王五"] = 3;
console.log(a["李四"]); //快速定位检索
对象也可以作为数组下标,JavaScript 会试图把对象转换为数值,如果不行,则把它转换为字符串,然后以文本下标的形式进行操作。
var a = []; //数组直接量
var b = function () { //函数直接量
return 2;
}
a[b] = 1; //把对象作为数组下标
console.log(a.length); //返回长度为0
console.log(a[b]); //返回1
可以这样读取元素值。
var s = b.toString(); //获取对象的字符串
console.log(a[s]); //利用文本下标读取元素的值
还可以这样设计下标,此时为数组的元素,而不是关键属性了。
a[b()] = 1;
console.log(a[2]);
console.log(a.length);
伪类数组,也称为类数组,即类似数组结构的对象。简单的说,就是对象的属性名为非负整数,且从 0 开始,有序递增,同时包含 length 属性,还应确保其值与有序下标属性个数保持动态一致,以方便对伪类数组进行迭代操作。大家所熟知的 jQuery 对象就是一个伪类数组。
在下面示例中,obj 是一个对象直接量,当使用数组下标为其赋值时,JavaScript 不再把它看作是数组下标,而是把它看作对象的属性名。
var obj = {}; //定义对象直接量
obj[0] = 0;
obj[1] = 1;
obj[2] = 2;
obj.length = 3;
console.log(obj["2"]); //返回2
它相当于一个对象直接量。
var obj = {
0 : 0,
1 : 1,
2 : 2,
length : 3
};
由于数字是非法的标识符,所以不能使用点语法来读写属性。
console.log(obj.0);
而应该使用中括号语法来读写属性。
console.log(obj["2"]);
数组是复合型数据,数组名称是一个指向数组的引用型变量,因此数组属于引用型对象。
访问数组就是访问数组元素。元素相当于变量,数组的元素是一组有序排列的变量,它们没有标识符,以下标进行索引,下标从 0 开始,有序递增。注意,数组下标是非负整数型表达式,或者是字符型数字,不可以为其他类型的值或表达式。
使用中括号[]可以读写数组。中括号左侧是数组名称,中括号内为数组下标。
下标表达式是值为非负整数的表达式。
下面代码使用中括号为数组写入数据,然后再读取数组元素的值。
var a = []; //声明一个空数组
a[0] = 0; //为第一个元素赋值为0
a[2] = 2; //为第三个元素赋值为2
console.log(a[0]); //读取第一个元素,返回值为0
console.log(a[1]); //读取第二个元素,返回值为undefined
console.log(a[2]); //读取第三个元素,返回值为2
在上面代码中仅为 0 和 2 下标位置的元素赋值,下标为 1 的元素为空,读取时为空的元素返回值默认为 undefined。
下面代码使用 for 语句批量为数组赋值,其中数组下标是一个递增表达式。
var a = new Array();
for (var i = 0; i < 10; i ++) {
a[i ++] = ++ i;
}
console.log(a);
设计有两个变量,不需要其他变量的帮助实现值互换。
一般情况下实现变量交换,需要定义一个临时变量做中转。
var a = 10, b = 20; //变量初始化
var temp = a; //定义临时变量存储a
a = b; //把b的值赋值给a
b = temp; //把临时变量的值赋值给b
利用数组就可以这样设计。
var a = 10, b = 20; //变量初始化
a = [b, b = a][0]; //通过数组快速交换数据
数组的元素允许使用表达式,表达式的值与元素的值是两个不同的概念,本质上元素也是一个变量,标识符是下标编号。在一个匿名数组中,把变量 b 的值传递给第 1 个元素,然后在第 2 个元素中以赋值表达式运算的方式把变量 a 的值赋值给变量 b,再把变量 b 的值传递给第 2 个元素。这个过程是按顺序执行的,变量 b 的值被重写,同时数组也被添加了两个元素,最后使用中括号语法读取第 1 个元素的值,并赋值给变量 a,从而实现值互换。