数组的定义
数组(Array)是按次序排列的一组值,每个值的位置都有编号,称为索引,具体表现为数组下标.
数组基本特点:
- 方括号[]是数组的标志,形如[1,‘hello’,{}]的称为字面量数组
- 数组成员可以是任何类型的值(原始类型,对象类型(包括数组),函数类型)
- 如果数组的成员的值也是数组,那么就构成了多维数组.多维数组是变长的.
数组的创建,赋值
-
数组创建的三种方式:
-
使用new+数组构造函数Array():
- new Array()创建一个空数组(使用[]更简洁)
- new Array(len)创建有len个空位的数组(空位在后续内容会介绍)
- new Array(elem1, elem2, …elemN)创建一个数组,它的成员值依次是elem1,elem2,…,elemN
-
使用[]创建数组字面量:(只有字面量方式才能创建既有空位又有实际值的数组)
- 创建无空位的紧密型(dense)数组字面量:
var dense = [1,2,‘good’,{name:‘peter’}];
- 创建有空位的稀疏型(sparse)数组字面量:
var sparse = [1,2,‘good’];
var sparse2 = [1,2,‘good’,];
(逗号之间不谢内容,即为空位.最后一个数组成员之后的逗号不产生空位) - 注意:使用new+构造函数的方法并不能创建既含有空位,又含有实际值的数组.
(这与函数的参数省略部分的规则有关)
- 创建无空位的紧密型(dense)数组字面量:
-
二维数组的创建
- 二维数组的定义:基本的一维数组的每个成员也是一维数组,那么整个数组构成一个二维数组.
- 二维数组的创建:
- 方法一:先创建一维,再创建二维
- 方法二:创建二维数组字面量
var myArray = [[1,2],[1,‘good’]];
- 方法一:先创建一维,再创建二维
- 二维数组的length问题:在后续length部分内容分析
-
-
数组的赋值:for循环统一赋值,单个赋值,字面量直接赋值.
数组的本质
本质上,数组属于一种特殊的对象.typeof运算符返回的也是object.数组的特殊性在于length的特殊属性与一定范围内的数字键名的特殊性.
- 数组键名的特殊性
数组的键名分为两种–数组成员索引和数组属性名.两者都是字符串.都可以用Object.keys()方法返回(属性特性为可枚举的).但数组成员索引又和一般对象的属性名不同.
数组成员索引名的特点:- 只能是纯数字(实际上是纯数字形式的字符串)
- 有取值范围(0到2^(32) - 1的正整数),超出这个范围的数值键名,会被转成字符串,并当作数组的属性而非成员索引存储.
- 索引的不连续性:因为有空位的存在,所以数组的索引名一般是不连续的.
- 数组length属性的特殊性
-
length属性的可变性:
length属性是可变的,会随着数组索引的变化而自动变化.其本质为"最大数组索引+1".- 数组末尾新增一个成员,length加一.(数组若是填补空位,length是保持不变的)
- 强行设置的length若比原有的length小,多出来的成员将被数组自动删除
- 为数组添加新属性,而非数组成员时,length值不受影响
- 为length设置值,如果不合乎要求(例:字符串),js会报错,length值不变.
-
length属性的属性特性:
- length属性可以设置:
length属性值可人为进行设置, - length属性不可枚举:
length的属性特性[[Enumerablel]]是false,因此不会被for…in,Object.keys()等函数遍历到. - length属性不可配置:不可用delete命令删除数组的length属性
- length属性可以设置:
-
length属性的值的有限性:取值的范围
- 因为JS使用一个32位整数,保存数组的元素个数,所以length属性的最大值就是 4294967295(232-1);length属性的最小有效值是0.
- 如果强行给length属性设置上述范围之外的值,JS就会报错;但是,如果给键名取超出上述范围的值时,不会报错,会将该键名当做属性名而非数组索引来进行存储.
-
length属性的不可靠性:
- length属性的本质是"数组最大的索引+1".在密集型dense数组中,length的值就是数组成员个数;但是在稀疏型sparse数组中,length不是数组成员个数,而是成员数目与空位数目的总和.
因此,不建议以length为依据来对数组进行遍历.
- length属性的本质是"数组最大的索引+1".在密集型dense数组中,length的值就是数组成员个数;但是在稀疏型sparse数组中,length不是数组成员个数,而是成员数目与空位数目的总和.
-
二维数组的length值:
二维数组的length值分为两种–高维的length(只有一个)与一维的length(多个).
例:
var myArray2 = [[1,2],[‘good’,‘bad’],[true,false]]
- 高维的length:由“数组名.length” 访问
上例中:
var higherLength = myArray2.length //3
- 一维的length:由”数组名[N].length”调用(N:高维数组的行索引)
上例中,[true,false]的length值为:
var lowerLength = myArray2[2].length
- 高维的length:由“数组名.length” 访问
-
数组/对象通用的方法,运算符
- in 运算符:索引是空位或者不存在,都会返回false(可与length结合使用来返回数组实际的成员数目)
- for…in循环:
不仅会遍历数字键,也会遍历非数字键(新添加的属性).故,不推荐使用for…in遍历数组[注:arrayObj.forEach(function F)方法可用于遍历数组,对数组的每个元素执行一次提供的函数]
数组的空位
-
数组空位的本质:数组中根本不存在该成员.因此无法对其进行访问与遍历.
-
产生空位的三种方式:
- 创建带空位的数组字面量.
var sparse = [1,2, ,‘good’]
- 跳跃地设置length值:
var myArray = [1,2];
myArray.length=100; - 使用delete命令删除数组成员:
var myArray = [1,2,3];
delete myArray[1];
- 创建带空位的数组字面量.
-
空位产生的根本原因:js数组索引的不连续性.
-
数组空位与数组成员值为undefined的区别:
数组的某个位置是空位,与某个位置是undefined,是不一样的。如果是空位,使用数组的forEach方法、for…in结构、以及Object.keys方法进行遍历,空位都会被跳过(因为不存在),而undefined,遍历的时候就不会被跳过.
类似数组的对象(array-like object)
- 定义:如果一个对象的所有键名都是正整数或零,并且有length属性,那么这个对象就很像数组,语法上称为“类似数组的对象”(array-like object)。典型的“类似数组的对象”是函数的arguments对象,以及大多数 DOM 元素集,还有字符串。
- 数组的slice()方法:
数组的slice方法可以将“类似数组的对象”变成真正的数组.你只需将该方法绑定到这个对象上
var arr = Array.prototype.slice.call(arrayLike);
然后将可以使用数组的方法对之进行处理了.