一、数组(array)是一个有序的数据集合,我们可以通过数组名称(name)和索引(index)进行访问。
【实例1】定义了一个数组emp,数组中的每个元素包含了一个雇员的名字以及其作为索引的员工号。那么emp[1]将会代表1号员工,emp[2]将会代表2号员工,以此类推。
二、JavaScript中没有明确的数组数据类型。但是,我们可以通过使用内置Array对象和它的方法对数组进行操作。
三、数组是一种特殊的对象,适用于存储和管理有序的数据项。
内部
一、数组是一种特殊的对象。使用方括号来访问属性arr[0]实际上是来自于对象的语法。它其实与obj[key]相同,其中arr是对象,而数字用作键(key)。
二、它们扩展了对象,提供了特殊的方法来处理有序的数据集合以及length属性。但从本质上讲,它仍然是一个对象。
【示例1】它是通过引用来复制的:
let fruits = ["Banana"]
let arr = fruits; // 通过引用复制 (两个变量引用的是相同的数组)
alert( arr === fruits ); // true
arr.push("Pear"); // 通过引用修改数组
alert( fruits ); // Banana, Pear — 现在有 2 项了
三、数组真正特殊的是它们的内部实现。JavaScript 引擎尝试把这些元素一个接一个地存储在连续的内存区域,就像插图显示的一样,而且还有一些其它的优化,以使数组运行得非常快。
四、但是,如果我们不像“有序集合”那样使用数组,而是像常规对象那样使用数组,这些就都不生效了。
【示例1】从技术上讲,我们可以这样做:
let fruits = []; // 创建一个数组
fruits[99999] = 5; // 分配索引远大于数组长度的属性
fruits.age = 25; // 创建一个具有任意名称的属性
1、这是可以的,因为数组是基于对象的。我们可以给它们添加任何属性。
2、但是 Javascript 引擎会发现,我们在像使用常规对象一样使用数组,那么针对数组的优化就不再适用了,然后对应的优化就会被关闭,这些优化所带来的优势也就荡然无存了。
五、数组误用的几种方式:
- 添加一个非数字的属性,比如arr.test = 5。
- 制造空洞,比如:添加arr[0],然后添加arr1000。
- 以倒序填充数组,比如arr[1000],arr[999]等等。
1、请将数组视为作用于有序数据的特殊结构。它们为此提供了特殊的方法。
2、数组在 JavaScript 引擎内部是经过特殊调整的,使得更好地作用于连续的有序数据,所以请以正确的方式使用数组。
3、如果你需要任意键值,那很有可能实际上你需要的是常规对象{}。
Array对象的属性
属性 | 描述 |
---|---|
length | 数组长度 |
正则表达式操作其他属性 |
length
一、JavaScript实际上是将元素作为标准的对象属性来存储,把数组索引作为属性名。
二、长度属性是特殊的,它总是返回最后一个元素的索引值加1。
1、JavaScript数组索引是基于0的:他们从0开始,而不是1。这意味着数组长度属性将比最大的索引值大1
var cats = []
cats[30] = ['Dusty']
console.log(cats.length) // 31
三、可以分配length属性 / length属性是可写的。
1、写一个小于数组元素数量的值会缩短数组,该过程是不可逆的。
2、写0会彻底清空数组,这是清空数组最简单的方法。
var cats = ['Dusty', 'Misty', 'Twiggy']
console.log(cats.length) // 3
cats.length = 2
console.log(cats) // ['Dusty', 'Misty']
cats.length = 0
console.log(cats) // []
cats.length = 3
console.log(cats) // [undifind, undefined, undefined]
四、当我们修改数组的时候,length属性会自动更新。准确来说,它实际上不是数组里元素的个数,而是最大的数字索引值加一。
【示例1】一个数组只有一个元素,但是这个元素的索引值很大,那么这个数组的length也会很大:
let fruits = [];
fruits[123] = "Apple";
alert( fruits.length ); // 124
数组的方法(array methods)
【见】数组的方法:https://www.yuque.com/tqpuuk/yrrefz/dzgb6c
创建数组(creating an array):[], new Array(), Array()
创建数组的3种方式
一、创建数组的3种方式:数组字面值 / 数组初始化器 / 括号语法 / 字面值、构造函数法、Array()
数组字面值/数组初始化器 / 括号语法 / 字面值
一、字面值(literal)的方式不仅比其他方式更便捷,同时不易采坑,通常是首选。
var arr = [element0, element1, ..., elementN]
new Array() / 构造函数法
一、语法
var arr = new Array();
var arr = new Array(size); size是具体的数字,表示创建一个size个元素的数组,也就是arr.length = size , var arr = new Array(0); 是清空数组
var arr = new Array(element0, element1, ..., elementN); // 创建新数组并给数组默认值
| 【示例】```javascript var arr = new Array(‘let’, ‘test’) // [‘let’, ‘test’] var arr = new Array(4) // 4指的是长度
|
| --- |
<a name="bys8Z"></a>
### Array()
```javascript
var arr = Array(element0, element1, ..., elementN)
使用场景
一、创建长度不为0,但是又没有任何元素的数组
var arr = new Array(arrayLength);
var arr = Array(arrayLength);
var arr = [];
arr.length = arrayLength;
1、数组长度(arrayLength)必须为一个数字(Number)。否则,将会创建一个只有单个元素的数组。
2、调用arr.length会返回数组长度,但是数组实际上包含了空的(undefined)元素。因此在数组上使用for…in循环,将不会返回任何的值。
二、用单个元素初始化一个数组,而这个元素恰好又是数字,那么必须使用括号语法。
var arr = [42] // 创建一个只有唯一元素的数组
1、当单个的数字(Number)传递给Array()构造函数时,将会被解释为数组长度,并非单个元素。
var arr = Array(42) // 创建一个没有元素的数组,但是数组的长度被设置成42
// 以上代码等同于
var arr = []
arr.length = 42
(1)new Array(number)创建的数组的所有元素都是undefined
let arr = new Array(2); // 不会创建一个 [2] 的数组。而是创建了一个长度为2,却没有任何项的数组
alert( arr[0] ); // undefined!没有元素。
alert( arr.length ); // length 2
(2)如果N不是一个整数,调用Array(N)将会报RangeError错误
var arr = Array(9.3) // RangeError: Invalid array length
三、如果要创建任意类型的单元素数组,安全的方式是使用字面值。或者在向数组添加单个元素之前先创建一个空的数组。
填充数组(populating an array)
一、可以通过给元素赋值来填充数组
var emp = []
emp[0] = 'Casey Jones'
emp[1] = 'Phil Lesh'
emp[2] = 'August West'
1、如果给数组操作符的是一个非整形数组,那么将作为一个代表数组的对象的属性(property)创建,而非作为数组的元素。
var arr = []
arr[3.4] = 'Oranges'
consoe.log(arr.length) // 0
console.log(arr.hasOwnProperty(3.4)) // true
二、可以在创建数组的时候填充
var myArray = new Array('Hello', myVar, 3.14159)
var myArray = ['Mango', 'Apple', 'Orange']
引用数组元素(referring to array elements)
一、可以使用元素的序号来引用数组的元素
var myArray = ['Wind', 'Rain', 'Fire']
myArray[0] // 引用第一个元素
myArray[1] // 引用第二个元素
1、元素的索引是从0开始的。
二、数组操作符(方括号[])也可以用来访问数组的属性
var arr = ['one', 'two', 'three']
arr[2] // three
arr['length'] // 3
多维数组(multi-dimensional arrays)
一、数组是可以嵌套的,这就意味着一个数组可以作为一个元素被包含在另外一个数组里面
【示例1】存储矩阵
let matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
alert( matrix[1][1] ); // 最中间的那个数
二、创建一个二维数组
var a = new Array(4);
for (i = 0; i < 4; i++) {
a[i] = new Array(4);
for (j = 0; j < 4; j++) {
a[i][j] = "[" + i + "," + j + "]";
}
}
// [["[0,0]", "[0,1]", "[0,2]", "[0,3]"], ["[1,0]", "[1,1]", "[1,2]", "[1,3]"], ["[2,0]", "[2,1]", "[2,2]", "[2,3]"], ["[3,0]", "[3,1]", "[3,2]", "[3,3]"]]
数组和正则表达式
一、当一个数组作为一个字符串和正则表达式的匹配结果时,该数组将会返回相关匹配信息的属性和元素。
RegExp.exec(),String.match()和String.split()的返回值是一个数组。
数组推导式(Array comprehensions)
一、计划在ECMAScript7被规范化。
二、用来实现如何在另一个数组的基础上构造一个新的数组。
三、推导式可以经常被用在那些需要调用 map() 和 filter()函数的地方,或作为一种结合这两种方式。
【实例1】创建一个数字数组并且创建一个新的数组,数组的每个元素都是原来数值的两倍
var numbers = [1, 2, 3, 4];
var doubled = [for (i of numbers) i * 2];
console.log(doubled); // [2,4,6,8]
1、这与下面的map()方法的操作是等价的
var doubled = numbers.map(function(i){return i * 2;});
【实例2】推导式也可以用来筛选满足条件表达式的元素。下面的推导式用来筛选是2的倍数的元素
var numbers = [1, 2, 3, 21, 22, 30];
var evens = [i for (i of numbers) if (i % 2 === 0)];
console.log(evens); // [2,22,30]
1、filter()也可以达到相同的目的
var evens = numbers.filter(function(i){return i % 2 === 0;});
四、map()和filter()类型的操作可以被组合(等效)为单个数组推导式
【实例1】过滤出偶数,创建一个它的倍数数组的例子
var numbers = [1, 2, 3, 21, 22, 30];
var doubledEvens = [i * 2 for (i of numbers) if (i % 2 === 0)];
console.log(doubledEvens); // logs 4,44,60
1、数组推导式隐含了块作用域。新的变量(如例子中的i)类似于是采用 [let](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let)
声明的。这意味着他们不能在推导式以外访问。
五、数组推导式的输入不一定必须是数组; 迭代器、生成器 、字符串也可以用来作为输入;
【实例1】实现filter或者map行为 (参考上面类似数组行为的对象)如下:
var str = 'abcdef';
var consonantsOnlyStr = [c for (c of str) if (!(/[aeiouAEIOU]/).test(c)) ].join(''); // 'bcdf'
var interpolatedZeros = [c+'0' for (c of str) ].join(''); // 'a0b0c0d0e0f0'
1、输入形式是不能保存的,所以我们要使用join()回复到一个字符串。