编入索引的集合是一种数据结构,其中存储元素并
使用编号索引进行访问。存储在编入索引的集合中的值
分配从 0
开始的编号索引,这是一种称为“零索引”的模式。
然后,您可以通过引用
索引
数组
数组是一种容器,可以包含零个或多个任意数据类型的值, 包括复杂对象或其他数组。存储在数组中的值 有时称为“元素”数组的值。
创建数组
与原始数据类型一样,创建数组的方法有两种:如
数组字面量,或者调用 JavaScript 的内置 Array()
构造函数
和new Array()
。为变量分配数组可提供高度可移植性
和可迭代方式来分配
为单个标识符指定多个值。
数组字面量语法使用一对括号 ([]
),将零个或多个值括起来
逗号分隔数据值:
const myArray = [];
数组构造函数语法使用 JavaScript 的内置 Array
对象作为
包含 new
关键字的构造函数:
const myArray = new Array();
数组字面量和数组构造函数语法都允许您使用 但其语法与 值。数组字面量语法在 括号,其外观与生成的数组相同:
const myArray = [ true, null, "String", false ];
myArray;
> [ true, null, "String", false ]
数组构造函数语法将逗号分隔值作为参数,其中 特殊行为异常:
const myArray = new Array( true, null, "String", false );
myArray;
> Array(4) [ true, null, "String", false ]
将单个数值传递给 Array
构造函数时,该值
未分配到结果数组中的第 0 个位置。而是使用数组
使用该数量的空槽创建值。这并不会强加
数组的限制。可以通过同样的方式在文件夹中添加和移除项
与数组字面量一样。
// Firefox:\
const myArray = new Array( 10 );
myArray;
> Array(10) [ <10 empty slots> ]
// Chrome:
const myArray = new Array( 10 );
myArray;
> (10) [empty × 10]
包含空槽位的数组(有时称为“稀疏数组”)是特殊数组
案例为空,而不是包含 undefined
或显式 null
值
slot 经常(但并不总是)被视为 undefined
值
语言。
您可能会不小心使用数组字面量语法创建稀疏数组,方法是 创建数组字面量时省略逗号之间的值:
const myArray = [ true,, true, false ];
myArray;
> Array(4) [ true, <1 empty slot>, true, false ]
尽管空槽位并非在所有上下文中都被视为有意义的值, 会计入数组的总长度,因此可能会导致 遍历时出现意料之外的结果 数组的值:
const myArray = [ 1,, 3, 4 ];
myArray.length;
> 4
for( const myValue of myArray ) {
console.log( myValue + 10 );
}
> 11
> NaN
> 13
> 14
这是 JavaScript 最早的设计决策的一个阻碍。 避免在现代开发中使用稀疏数组。
与基元一样,数组字面量
从相应构造函数继承属性和方法。
由于数组是一种特殊形式的对象,因此数组字面量语法和
new Array()
语法创建功能完全相同的结果:
会从 Array
构造函数继承其原型。
const arrayLiteral = [];
const arrayConstructor = new Array();
typeof arrayLiteral;
> "object"
arrayLiteral;
> Array []
length: 0
<prototype>: Array []
typeof arrayConstructor;
> "object"
arrayConstructor;
> Array []
length: 0
<prototype>: Array []
因为两个结果完全相同,并且数组字面量语法更简洁
和字面量,因此我们强烈建议始终使用数组字面量语法,
new Array()
语法。
访问数组值
您可以使用括号表示法(即
一对括号 ([]
),紧跟在包含
编号:
[ "My string", "My other string" ][ 1 ];
> "My other string"
const myArray = [ "My string", 50, true ];
myArray[ 0 ];
> "My string"
myArray[ 1 ];
> 50
myArray[ 2 ];
> true
JavaScript 中的数组不关联, 这意味着您不能使用任意字符串作为索引。不过,数字 用于访问数组中元素的值被强制转换为后面的字符串值 场景,这意味着您可以使用仅包含数字值的字符串值, 字符:
const myArray = [ "My string", 50, true ];
myArray[ 2 ];
> true
myArray[ "2" ];
> true
尝试访问数组中定义的元素之外的元素会导致
undefined
,而不是错误:
const myArray = [ "My string", 50, true ];
myArray[ 9 ];
> undefined
解构分配
解构赋值是从 数组或对象,并将其分配到 这个过程有时称为“解包”原始数据结构, 但不会修改原始数组或对象。
解构赋值使用一个数组或对象的类标识符列表来
可帮助您跟踪价值最简单的方法就是称为“绑定模式”
解构时,每个值都会从数组或对象中解封,并分配给
相应的变量,使用 let
或 const
(或 var
)进行初始化:
const myArray = [ "A string", "A second string" ];
const [ myFirstElement, mySecondElement ] = myArray;
const myObject = { firstValue: false, secondValue: true };
const { myProp, mySecondProp } = myObject;
myFirstElement;
> "My string"
mySecondElement;
> "Second string"
myProp;
> false
mySecondProp;
> true
大括号 ({}
) 用于解构对象,方括号 ([]
) 用于解构对象
解构数组。
const myArray = [ false, true ];
const myObject = { firstValue: false, secondValue: true };
const [ myProp, mySecondProp ] = myObject;
> Uncaught TypeError: myObject is not iterable
const { myElement, mySecondElement } = myArray;
myElement
> undefined
mySecondElement;
> undefined
数组的解构会按从左到右的顺序依序进行。每个 解构赋值中的标识符对应于 具有相同索引的数组:
const myArray = [ 1, 2, 3 ];
const [ myElement, mySecondElement, myThirdElement ] = myArray;
myElement;
> 1
mySecondElement;
> 2
myThirdElement;
> 3
这也是解构对象时的默认行为。但是,如果 解构赋值中使用的标识符与对象的键 系统会使用相应的属性来填充这些标识符 值,无论它们的指定顺序如何:
const myObject = { firstValue: 1, secondValue: 2, thirdValue 3 };
const { secondValue, thirdValue, firstValue } = myObject;
firstValue;
> 1
secondValue;
> 2
thirdValue;
> 3
您可以通过省略标识符来跳过这些元素:
const myArray = [ 1, 2, 3 ];
const [ firstValue,, secondValue ] = myArray;
firstValue;
> 1
secondValue;
> 3
通过解构语法,您还可以在应用解构时为其分配默认值
值可以是空槽(如稀疏数组),也可以是
undefined
值。
const myArray = [ true, ];
const [ firstValue = "Default string.", secondValue = "Default string." ] = myArray;
firstValue;
> true
secondValue;
> "Default string."
解构不会将值强制转换为特定的类型。这意味着
"falsy" 值,例如空
字符串 (""
) 或 null
仍被视为有意义的解构值:
const myArray = [ false, null, 0, "",, undefined ];
const [ falseValue = true, nullValue = true, zeroValue = true, emptyStringValue = true, emptySlot = true, undefinedValue = true ] = myArray;
falseValue;
> false;
nullValue;
> null
zeroValue;
> 0
emptyStringValue;
> ""
emptySlot;
> true
undefinedValue;
> true
扩散运算符
使用 ES6 中引入的展开运算符 (...
) 来扩展可迭代数据
数组、字符串或对象字面量转换为单个元素。
扩展运算符后面紧跟要扩展的数据结构
或包含该数据结构的变量的标识符。
const myArray = [ 1, 2, 3 ];
console.log( ...myArray );
> 1 2 3
分散语法主要用于复制和组合数组:
const myArray = [ 4, 5, 6 ];
const mySecondArray = [1, 2, 3, ...myArray ];
mySecondArray;
> Array(6) [ 1, 2, 3, 4, 5, 6 ]
您只能在以下上下文中使用展开语法:
对于数组和字符串,展开语法仅适用于零个或零个以上的参数
还是数组中的元素。第一个示例
本部分中的扩展运算符语法之所以有效,是因为它将 ...myArray
作为
内置 console.log
方法的参数。
例如,如果将展开的数据分配给外部变量, 另一个数组:
const myArray = [ 1, 2, 3 ];
const spreadVariable = ...myArray;
> Uncaught SyntaxError: Unexpected token '...'
但复制数组的方式是将原始数组扩展为数组字面量:
const myArray = [ 1, 2, 3 ];
const spreadArray = [ ...myArray ];
spreadArray;
> Array(3) [ 1, 2, 3 ]
如需将构成两个或多个数组的元素合并为一个数组,请执行以下操作:
const myArray = [ 1, 2, 3 ];
const mySecondArray = [ 4, 5, 6 ];
const myNewArray = [ ...myArray, ...mySecondArray ];
myNewArray;
> Array(6) [ 1, 2, 3, 4, 5, 6 ]
或者,将数组的元素作为单个参数在函数调用中传递:
const myArray = [ true, false ];
const myFunction = ( myArgument, mySecondArgument ) => {
console.log( myArgument, mySecondArgument );
};
myFunction( ...myArray );
> true false
扩展运算符扩展, ES2018 中的对象字面量。 与数组一样,您可以使用扩展运算符来复制或合并对象:
const myObj = { myProperty : true };
const mySecondObj = { ...myObj };
mySecondObj;
> Object { myProperty: true }
const myFirstObj = { myProperty : true };
const mySecondObj = { additionalProperty : true };
const myMergedObj = { ...myFirstObj, ...mySecondObj };
myMergedObj;
> Object { myProperty: true, additionalProperty: true }
扩展运算符创建“浅层”副本。也就是说,它不会复制 原始对象的原型和不可枚举 属性。
const myCustomPrototype = { protoProp: "My prototype." };
const myObj = Object.create( myCustomPrototype, {
myEnumerableProp: {
value: true,
enumerable: true
},
myNonEnumerableProp: {
value: false,
enumerable: false
}
});
const myNewObj = { ...myObj };
myObj;
> Object { myEnumerableProp: true, … }
myEnumerableProp: true
myNonEnumerableProp: false
<prototype>: Object { protoProp: "My prototype." }
myNewObj;
> Object { myEnumerableProp: true }
myEnumerableProp: true
<prototype>: Object { … }
请注意,数组和对象不能互换使用。禁止的行为 将对象扩展为数组,或将数组扩展为对象。
休息运算符
虽然运算符本身的语法相同,但其余运算符 (...
)
根据其使用的上下文执行相反的函数。而不是
将可迭代数据结构扩展为单独的元素,
解构赋值,或将其定义为
函数参数不同,其余运算符可将
转换为可迭代数据结构。这个名称源于
用来收集“其余的”一组数据值。
与解构赋值搭配使用时,语法称为“rest 属性” 语法。
const myArray = [ "First", "Second", "Third", "Fourth", "Fifth" ];
[ myFirstElement, mySecondElement, ...remainingElements ] = myArray;
myFirstElement;
> "First"
mySecondElement;
> "Second"
remainingElements;
> Array(3) [ "Third", "Fourth", "Fifth"]
用于为函数提供无限多个参数时, 语法称为“rest 参数”语法:
function myFunction( ...myParameters ) {
let result = 0;
myParameters.forEach( ( myParam ) => {
result += myParam;
});
return result;
};
myFunction( 2, 2 );
> 4
myFunction( 1, 1, 1, 10, 5 );
> 18
myFunction( 10, 11, 25 );
> 46
%TypedArray%
类型化数组是一项 ES6 功能,用于存储结构化二进制数据, 例如处理上传的文件或 WebGL。
与符号一样,%TypedArray%
固有函数(通常记录为 %TypedArray%
或 @@TypedArray
)
因此它不会被误认为是全局属性)
符合常规意义,您不能使用 new
调用它,也不能直接调用它。
相反,%TypedArray%
是指
构造函数,每个构造函数与特定的二进制数据格式兼容。通过
固有 %TypedArray%
父类提供具有以下特征的属性和实用程序方法:
所有 %TypedArray%
构造函数子类及其实例都会继承。
检查您的理解情况
假设 `const myArray = [ 30, 50, 70 ];` `myArray[1]` 是什么 退货?
70
如果 `myArray` 有三个值,`myArray[9]` 会返回什么?
Undefined
9
Null