JavaScript关键知识点汇总(2):Array

来源:互联网 发布:caffe 安装python用 编辑:程序博客网 时间:2024/06/05 10:51

1、本质上,Array也是一种Object,对Array值进行typeof运算,会得到字符串"object"。


2、Array对象(值)的创建

2.1、使用Array常量

有别于C语言的元素级数组定义形式,JavaScript的Array常量允许我们以一种宏观的、整体性的方式去表示一个数组,而并没有将之局限于数组的初始化阶段。

在JavaScript中,Array常量是以方括号([])界定并以逗号(,)分隔的若干个值或表达式的组合。Array常量的使用与原始类型常量的使用完全相同。例如:

变量arr1的值是一个数组,该数组长度为3,每个数组元素均为Number值,其中arr1[0]的值为1,arr1[1]的值为2,arr1[2]的值为3。再如:

arr2的值仍然是一个数组,只不过该数组不包含任何元素,长度为0,称为“空数组”。注意,并非“空值”(null)。又如:

用来为arr3赋值的Array常量[1,,3,]虽然怪异,但仍然是合法的。arr3包含4个元素,虽然我们只指定了其中两个的值,但JavaScript会自动为另外两个我们没有指定值的元素赋值为undefined。arr3的最终元素值为:arr1[0]的值为1,arr1[1]的值为undefined,arr1[2]的值为3,arr1[3]的值为undefined。又如:

数组arr4的赋值说明,构成Array常量的不一定都是常量,还可以是有变量参与的表达式。

2.2、使用构造函数Array()

通过Array的构造函数,我们可以动态地创建所需要的数组值。与C#相似,构造函数Array()必须由运算符new调用。

2.2.1、无参调用Array()

无参调用Array()会创建一个长度为0的Array对象,等效于Array常量[]。

2.2.2、多参数调用Array()

当使用多个参数调用Array()时,JavaScript会将所有参数按顺序作为数组元素值来构建数组对象,数组的长度即为参数的个数。当使用此方法时,以下几点需要注意:

首先,用来初始化数组元素的参数列表,必须置于构造函数名之后的圆括号内,而不能像Array常量似的使用方括号,也不能采用类似于C#在定义数组阶段采用花括号({})初始化数组元素的方法;

其次,应该明确,位于构造函数名Array之后圆括号之内的是构造函数的参数列表,而参数列表中的每一个实参必须是具体的,不允许出现空缺。即参数列表中任何两个实参值之间只能以一个逗号分割,且第一个实参之前和最后一个实参之后均不能出现逗号。所以,类似于Array常量[1, ,3, ]的书写形式(1,,3,)并不适用于参数列表,否则会招致语法错误;

再次,表达式的值作为参数列表当然也是合法的。

2.2.3、单一Number值作为参数调用Array()

当使用唯一的Number值作为实参调用Array()时,实参的意义和构造函数的行为与使用单一非Number值调用Array()是截然不同的。请与如下情况进行比较:

数组arr8的构造过程与2.2.2一致,arr8的值是一个长度为1的数组,数组元素a[0]的值为'Single String value',这种构造函数的调用方式等效于Array常量['Single String value']。而arr7的值却是一个长度为5,每个元素值都为undefined的数组。使用唯一的Number值5去调用Array()时,5所代表的不再是元素值,而是数组的长度。此调用方式等效于Array常量[,,,,]。

之所以在此强调单一Number值作为参数调用Array()时,构造函数行为上的差异,是为了避免不必要的代码失误。尤其是在使用ASP.NET Page对象ClientScript属性(ClientScriptManager对象)的RegisterArrayDeclaration方法向客户端注册JavaScript数组声明时。MSDN中,关于RegisterArrayDeclaration的说明如下: 

参数:

arrayName

类型:System.String

要注册的数组名。

arrayValue

类型:System.String

要注册的数组值。

 

MSDN在此并没有详细阐述由于arrayValue的差别而给客户端代码行为带来的严重影响。当然,这不是ASP.NET造成的,归根到底还是JavaScript的问题。特此提醒大家注意。

如下C#代码会在客户端注册2.2.2所示JavaScript数组声明:

而以下C#代码会在客户端注册2.2.3所示JavaScript数组声明:

出现在客户端JavaScript代码中String常量的界定符,在C#字符串中要使用转义。


 

3、数组元素的值

与普通变量一样,数组元素本身也是无类型的,其类型由所存储的值决定,而JavaScript并没有像其它程序设计语言(例如C)一样要求一个数组的所有元素值必须隶属于同一类型。在JavaScript的一个数组中,数组元素可以用来存储不同类型的值,例如:

上述两个JavaScript数组是完全合法且可访问的。


 

4、数组元素的访问

与C语言相同,JavaScript对数组元素的访问也是通过运算符[]和一个基于0的整数索引值(下标)实现的。

JavaScript规定,用于访问数组元素的下标值必须是大于等于0且小于232-1的整数(数组元素有效下标的最大值是232-2)。对于该范围之外的任何数据,包括负数、浮点数、Boolean值或其它数据,JavaScript引擎会将其转换为字符串,并用该字符串作为属性名,把数组当作一个对象去访问。虽然表面上还是下标访问的语法,但实际上访问的不是数组的元素,而是数组对象的属性。如果数组对象包含与该字符串值相同的属性名,则返回(读)或更新(写)该属性的值,否则,返回undefined(读)或动态添加以该字符串为名称的属性并为其赋值(写)。例如:

分析:上述代码第1行通过一个数组常量定义了一个长度为3的数组变量。第2行将"newProp"作为下标访问数组,由于字符串"newProp"并不是一个合法的下标值,因此JavaScript引擎为数组对象arr添加属性newProp,并将其赋值为100。第3行和第4行代码分别以不同的方式对新添加的属性进行了访问,尤其是第4行,充分证明了newProp作为arr属性存在的客观性和真实性。第6行代码以一个负的浮点数作为下标对数组进行访问,-1.2同样不是一个合法的下标值,JavaScript引擎将其转换为字符串形式"-1.2",并创建以此字符串为名的属性,然后为其赋值为'A value of negative float property'。第7行和第8行代码印证了JavaScript引擎对非法下标值进行隐式字符串类型转换的事实。需要注意的是,对于以"-1.2"为名称的属性来说,类似于arr.newProp的访问形式是非法的。因为-1.2是一个非法的标识符,所以只能通过运算符[]对此类属性进行访问。第10行和第11行代码向我们透露两方面信息:首先,第2行和第6行代码确实没有对数组元素进行任何修改。其次,对于Array预定义的属性,也可以将其名称字符串作为下标以访问相应属性值。

本文开篇第1点就明确指出,Array也是一种Object,我们之所以能够通过下标语法来访问数组对象的属性,其根源在于Object。有关此部分详细内容以及数组元素与数组对象属性的关系,将另行撰文介绍。

 


5、数组的性质

5.1、变长数组

在某些编译型程序设计语言(例如C)中,数组的长度必须在其定义阶段决定,并且在该数组值的生存期内,其长度不可更改,对数组元素的访问也不能突破长度的限制。虽然以C语言为代表的某些程序设计语言并不对数组下标进行越界检查,但是越界访问会招致不可预料的结果,几乎所有的C语言教程都不建议这么做。在另外一些程序设计语言中,如C#,更是视下标越界为洪水猛兽。它们通过严格的越界检查来彻底杜绝这一情况的发生,从而将数组元素的访问限定在数组长度范围之内。在JavaScript中却不是这样。

在JavaScript中定义或创建数组值时,同样需要显式或隐式指定其长度。例如:

此时的长度仅仅表示数组的初始长度,我们可以根据需要在数组值生存期的任何时候,动态地更改其长度,从而使其能够容纳更多的元素。实现此目的最直接有效的方法是使用一个大于或等于该数组当前长度的整数值作为下标去访问数组元素并为其赋值。赋值动作发生后,数组的长度即被更新为此下标值加1。由于前后两个长度值不连续所跨越的数组元素,JavaScript引擎自动为其赋值为undefined。例如:

上述代码首先将arr5定义为一个长度为3的数组,随后跨越arr3[3]、arr3[4],直接为arr5[5]赋值。最终,arr5的长度变为6,有效元素只是arr5[0],arr5[1],arr5[2]和arr5[5],arr5[3]和arr5[4]的值均为undefined。等价于数组常量[0,1,2,,,'Extra value']。

5.2、稀疏数组

JavaScript数组另一个显著的特点是稀疏数组。JavaScript并不像C语言那样为每一个数组元素分配存储空间,而是仅仅为有效元素分配。例如:

当上述代码执行后,JavaScript解释器只为下标0和100分配存储空间,而忽略其间的99个元素,但这并不代表这99个元素不可用,当以1~99之间任意整数作为下标为数组元素赋值时,JavaScript解释器仍然会为其分配存储空间。

数组长度作为数组的重要属性,是使用循环访问所有元素的重要依据。但是因为JavaScript数组的稀疏数性质,决定了数组长度不再是有效元素数目的指示器,而仅仅用以指示最后一个有效元素的下一个位置。

原创粉丝点击