说明

是引用类型,数组名储存在栈空间,数组元素储存在堆空间

作用

1、方便保存相似的数据
2、方便遍历这些数据

创建

  1. var a = [];
  2. //和java不一样,没那么严格,可以不同数据类型
  3. //但建议保存相同数据类型的数据,保存多个不同类型的,用对象
  4. //真实开发,是把多个对象放一个数组里面
  5. var b = [1,"2",3,4,true];
  6. var c = new Array(1,3,true,"4");

浏览器中显示:
image.png
嵌套:
image.png

解构赋值

  1. const arr = [1, 2, 3, 4];
  2. // bad
  3. const first = arr[0];
  4. const second = arr[1];
  5. // good
  6. const [first, second] = arr;

ES6 展开运算符创建

image.png
创建了一个新数组
image.png image.png

因此可以通过这个方式进行数组的浅拷贝

  1. const a = [1,2,3]
  2. const b = [...a] // b = [1,2,3]
  3. a == b;// false

引用

通过数组的索引值/下标index 引用

  1. a[0]; //数组a的第一个元素,也叫索引值,或者下标index
  2. a[1][2]; //多维数组,a第2个元素是个数组,这个数组中的第3个元素
  3. a[-1] //undefined,不支持负数

数组长度

给数组的长度属性赋值,会改变数组

  1. var arr = [1, 2, 3];
  2. arr.length; // 3
  3. arr.length = 6;
  4. arr; // arr变为[1, 2, 3, undefined, undefined, undefined]
  5. arr.length = 2;
  6. arr; // arr变为[1, 2]

不建议下标越界:

  1. var arr = [1, 2, 3];
  2. arr[5] = 'x';
  3. arr; // arr变为[1, 2, 3, undefined, undefined, 'x']

简单的追加元素方法

  1. var fruits = ["Banana", "Orange", "Apple", "Mango"];
  2. fruits[fruits.length] = "Kiwi"; // 向 fruits 追加 "Kiwi"

数组空位(避免)

由于行为不一致和存在性能隐患,因此实践中要避免使用数组空位。

如果确实需要空位,则可以显式地用 undefined 值代替

  1. const options = [,,,,,]; // 创建包含 5 个元素的数组
  2. console.log(options.length); // 5
  3. console.log(options); // [,,,,,]

=================

定型数组

定型数组(typed array)是 ECMAScript 新增的结构,目的是提升向原生库传输数据的效率。
1、有符号的8位整数(int8)
2、无符号的8位整数(uint8)
3、有符号的16位整数(int16)
4、无符号的16位整数(uint16)
5、有符号的32位整数(int32)
6、有符号的32位整数(uint32)
7、32位浮点数(float32)
8、64位浮点数(float64)
image.png

  1. // 创建一个7个元素的无符号的定型数组,每个元素都是8位的,也就是每个元素最高不超过2**8=256
  2. const typedArray1 = new Uint8Array(7);
  3. typedArray1[0] = 32;
  4. // Uint8Array [32, 0, 0, 0, 0, 0, 0]
  5. typedArray1[1] = 256;
  6. // Uint8Array [32, 0, 0, 0, 0, 0, 0]
  7. typedArray1[2] = 257;
  8. // Uint8Array [32, 0, 1, 0, 0, 0, 0]

ArrayBuffer

在使用定型数组之前,需要为其分配内存空间,这个内存空间就叫数组缓冲区;一经创建就不能再调整大小。

  1. const buf = new ArrayBuffer(16); // 在内存中分配 16 字节
  2. alert(buf.byteLength); // 16

DataView

通过视图来操作数组缓冲区,包括读取和写入

  1. const buff1= new ArrayBuffer(10);
  2. // 创建视图
  3. const view1= new DataView(buff1);
  4. // 构造函数接收一个可选的字节偏移量和字节长度
  5. // byteOffset=0 表示视图从缓冲起点开始
  6. // byteLength=8 限制视图为前 8 个字节
  7. const firstHalfDataView = new DataVi
  8. const firstHalfDataView = new DataView(buf, 0, 8);

操作

  1. // 创建长度为 8 的 int16 数组
  2. const container = new Int16Array(8);
  3. // 把定型数组复制为前 4 个值
  4. // 偏移量默认为索引 0
  5. container.set(Int8Array.of(1, 2, 3, 4));
  6. console.log(container); // [1,2,3,4,0,0,0,0]
  7. // 把普通数组复制为后 4 个值
  8. // 偏移量 4 表示从索引 4 开始插入
  9. container.set([5,6,7,8], 4);
  10. console.log(container); // [1,2,3,4,5,6,7,8]
  11. // 溢出会抛出错误
  12. container.set([5,6,7,8], 7);
  13. // RangeError
  1. const source = Int16Array.of(2, 4, 6, 8);
  2. // 把整个数组复制为一个同类型的新数组
  3. const fullCopy = source.subarray();
  4. console.log(fullCopy); // [2, 4, 6, 8]
  5. // 从索引 2 开始复制数组
  6. const halfCopy = source.subarray(2);
  7. console.log(halfCopy); // [6, 8]
  8. // 从索引 1 开始复制到索引 3
  9. const partialCopy = source.subarray(1, 3);
  10. console.log(partialCopy); // [4, 6]

=================

数组方法

https://www.runoob.com/jsref/jsref-obj-array.html

把数组转换为字符串

toString( ) 把数组转换为数组值(逗号分隔)的字符串
join( “符号”) 所有数组元素,通过特定的符号分隔,结合为一个字符串

添加元素

unshift( 元素值 ) (在开头)向数组添加新元素,返回新数组长度
push( 元素值 ) (结尾处)向数组添加新的元素,返回新数组长度
push( …数组名 ) (结尾处)向数组添加其他数据的所有元素,返回新数组长度
数组[ 数组.length ] = 元素值 (结尾处)向数组添加新的元素
splice(新元素的位置); 从特定位置,删除后面所有元素,并返回一个包含已删除项的数组
splice( 新元素的位置 , 应删除多少元素 , 新元素1 , 新元素2 , … ,新元素n) 方法可用于向数组添加新项,返回一个包含已删除项的数组
数组1.concat( 数组2 , 数组3 ) 通过合并(连接)现有数组来创建返回一个新数组,数组2会在后面,数组3在最后面
Array.of(1, 2, 3, 4); // [1, 2, 3, 4]

删除元素 / 提取

shift( ) 删除首个数组元素,返回被删除的值
pop( ) 删除最后一个元素,返回被删除的值
delete 数组[下标]; 删除指定下标的元素,但是会留下未定义的空间
splice(新元素的位置 , 应删除多少元素); 从特定位置,删除多少个元素,返回一个包含已删除项的数组
splice(0) 清空数组

更改元素

数组[下标] = 新元素值
splice(新元素的位置 , 应删除多少元素); 从特定位置,选择多少个元素,返回一个新的数组

查找

indexOf(元素值); 返回元素值首次出现的位置下标,不存在就是-1
lastIndexOf(元素值); 返回元素值最后一次出现的位置下标
使用的都是全等(===)比较

是否包含某个元素

indexOf(元素值); 返回元素值首次出现的位置下标,不存在就是-1(无法判断NaN)
includes(元素值);是否有某个元素,有就是true,ES7新增(可以判断NaN)

条件查找

断言函数接收 3 个参数:元素、索引和数组本身。
其中元素是数组中当前搜索的元素,
索引是当前元素的索引,
而数组就是正在搜索的数组。

断言函数返回真值,表示是否匹配。

  1. const people = [
  2. {
  3. name: "Matt",
  4. age: 27
  5. },
  6. {
  7. name: "Nicholas",
  8. age: 29
  9. }
  10. ];
  11. alert(people.find((element, index, array) => element.age < 28));
  12. // {name: "Matt", age: 27}
  13. alert(people.findIndex((element, index, array) => element.age < 28));
  14. // 0

找到匹配项后,这两个方法都不再继续搜索。

遍历(迭代)

访问一遍数组的各个元素

  1. var a = ['A', 'B', 'C'];
  2. //方法1:for循环
  3. for(i=0 ; i < a.length ; i++){
  4. console.log(i + ', index = ' ,a[i]);
  5. }
  6. //方法2:for in 循环
  7. for(i in a){
  8. console.log(a[i]); //下标 in 数组
  9. }
  10. //方法3:for of循环
  11. for(i of a){
  12. console.log(i); //元素 of 数组
  13. }
  14. //方法4:数组内置的方法,没有返回值
  15. a.forEach(function (element, index, array) {
  16. // element: 指向当前元素的值
  17. // index: 指向当前索引
  18. // array: 指向Array对象本身
  19. console.log(element + ', index = ' + index);
  20. });

检查元素

every:如果对每一项函数都返回 true,则这个方法返回 true。
some:如果有一项函数返回 true,则这个方法返回 true

  1. let numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];
  2. let everyResult = numbers.every((item, index, array) => item > 2);
  3. alert(everyResult); // false
  4. let someResult = numbers.some((item, index, array) => item > 2);
  5. alert(someResult); // true

处理所有元素

和forEach()方法很像,但是forEach()方法没有返回值,map有返回值

  1. let numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];
  2. let mapResult = numbers.map((item, index, array) => item * 2);
  3. alert(mapResult); // 2,4,6,8,10,8,6,4,2

fill 填充

  1. const zeroes = [0, 0, 0, 0, 0];
  2. // 用 5 填充整个数组
  3. zeroes.fill(5);
  4. console.log(zeroes); // [5, 5, 5, 5, 5]
  5. zeroes.fill(0); // 重置
  6. // 用 6 填充索引大于等于 3 的元素
  7. zeroes.fill(6, 3);
  8. console.log(zeroes); // [0, 0, 0, 6, 6]
  9. // 用 7 填充索引大于等于 1 且小于 3 的元素
  10. zeroes.fill(7, 1, 3);
  11. console.log(zeroes); // [0, 7, 7, 0, 0];
  12. // 用 8 填充索引大于等于 1 且小于 4 的元素
  13. // (-4 + zeroes.length = 1)
  14. // (-1 + zeroes.length = 4)
  15. zeroes.fill(8, -4, -1);
  16. console.log(zeroes); // [0, 8, 8, 8, 0];
  17. //fill()静默忽略超出数组边界、零长度及方向相反的索引范围:
  18. const zeroes = [0, 0, 0, 0, 0];
  19. // 索引过低,忽略
  20. zeroes.fill(1, -10, -6);
  21. console.log(zeroes); // [0, 0, 0, 0, 0]
  22. // 索引过高,忽略
  23. zeroes.fill(1, 10, 15);
  24. console.log(zeroes); // [0, 0, 0, 0, 0]
  25. // 索引反向,忽略
  26. zeroes.fill(2, 4, 2);
  27. console.log(zeroes); // [0, 0, 0, 0, 0]
  28. // 索引部分可用,填充可用部分
  29. zeroes.fill(4, 3, 10)
  30. console.log(zeroes); // [0, 0, 0, 4, 4]

copyWithin 复制

  1. ints = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
  2. ints.copyWithin(5); // 从 ints 中复制索引 0 开始的内容,插入到索引 5 开始的位置,在源索引或目标索引到达数组边界时停止
  3. console.log(ints); // [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]
  4. ints.copyWithin(0, 5);
  5. console.log(ints); // [5, 6, 7, 8, 9, 5, 6, 7, 8, 9] // 从 ints 中复制索引 5 开始的内容,插入到索引 0 开始的位置
  6. // 从 ints 中复制索引 0 开始到索引 3 结束的内容
  7. // 插入到索引 4 开始的位置
  8. ints.copyWithin(4, 0, 3);
  9. alert(ints); // [0, 1, 2, 3, 0, 1, 2, 7, 8, 9]
  10. // JavaScript 引擎在插值前会完整复制范围内的值
  11. // 因此复制期间不存在重写的风险
  12. ints.copyWithin(2, 0, 6);
  13. alert(ints); // [0, 1, 0, 1, 2, 3, 4, 5, 8, 9]
  14. // 支持负索引值,与 fill()相对于数组末尾计算正向索引的过程是一样的
  15. ints.copyWithin(-4, -7, -3);
  16. alert(ints); // [0, 1, 2, 3, 4, 5, 3, 4, 5, 6]
  17. copyWithin()静默忽略超出数组边界、零长度及方向相反的索引范围:
  18. let ints,
  19. reset = () => ints = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
  20. // 索引过低,忽略
  21. ints.copyWithin(1, -15, -12);
  22. alert(ints); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
  23. // 索引过高,忽略
  24. ints.copyWithin(1, 12, 15);
  25. alert(ints); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
  26. // 索引反向,忽略
  27. ints.copyWithin(2, 4, 2);
  28. alert(ints); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
  29. // 索引部分可用,复制、填充可用部分
  30. ints.copyWithin(4, 7, 10)
  31. alert(ints); // [0, 1, 2, 3, 7, 8, 9, 7, 8, 9];

浅复制(浅拷贝)

  1. // Array.from()对现有数组执行浅复制
  2. const a1 = [1, 2, 3, 4];
  3. const a2 = Array.from(a1);
  4. alert(a1 === a2); // false

截取

  1. var names = ["abc", "cba", "nba", "dna"]
  2. var newNames1 = names.slice(0, 2) // 原始数组不会被改变
  3. console.log(newNames1) // ["abc", "cba", "nba"]
  4. console.log(names) // ["abc", "cba", "nba", "dna"]

数字排序

1、sort方法排序

reverse是相反的sort

  1. var points = [40, 100, 1, 5, 25, 10];
  2. points.sort(); //[1, 10, 100, 25, 40, 5] 按字符串来排序
  3. function compare(value1, value2) {
  4. if (value1 < value2) {
  5. return -1;
  6. } else if (value1 > value2) {
  7. return 1;
  8. } else {
  9. return 0;
  10. }
  11. }
  12. points.sort(compare);
  13. //1,5,10,25,40,100
  14. //当 sort() 函数比较两个值时,会将值发送到比较函数,
  15. //并根据所返回的值(负、零或正值)对这些值进行排序。
  16. points.sort((a, b) => a < b ? 1 : a > b ? -1 : 0); //箭头函数简写
  17. points.sort((a, b) => a-b); //箭头函数简写

2、冒泡排序

不断得前面元素和后一个元素比较,大的排后面。
image.png

3、选择排序

用第一个元素,和后面每个元素进行比较。
再用第二个元素,和后面每个元素进行比较。
再用第三个元素,和每个元素进行比较。
…..

排序对象数组

  1. var cars = [
  2. {type:"Volvo", year:2016},
  3. {type:"Saab", year:2001},
  4. {type:"BMW", year:2010}];
  5. //数字排序
  6. cars.sort(function(a, b){return a.year - b.year});
  7. //字母排序
  8. cars.sort(function(a, b){
  9. var x = a.type.toLowerCase();
  10. var y = b.type.toLowerCase();
  11. if (x < y) {return -1;}
  12. if (x > y) {return 1;}
  13. return 0;
  14. });

反向排序 reverse

  1. let values = [1, 2, 3, 4, 5];
  2. values.reverse();
  3. alert(values); // 5,4,3,2,1

最大最小值

sort();方法排序后,可以得到首尾的最大最小值,但是效率不高。
可以用数据Math的方法

  1. var x = Math.max.apply(null,array);
  2. var x = Math.min.apply(null,array);

filter 过滤函数

image.png

Array.from 遍历处理函数

  1. const a1 = [1, 2, 3, 4];
  2. const a2 = Array.from(a1, x => x**2);
  3. const a3 = Array.from(a1, function(x) {return x**this.exponent}, {exponent: 2});
  4. console.log(a2); // [1, 4, 9, 16]
  5. console.log(a3); // [1, 4, 9, 16]

map 遍历处理函数

image.png

reduce 遍历汇总函数

reduceRight() 从右边开始
image.png

  1. let values = [1, 2, 3, 4, 5];
  2. // 上一个归并值、当前项、当前项的索引和数组本身
  3. let sum = values.reduce((prev, cur, index, array) => prev + cur);
  4. alert(sum); // 15

from 拆分、转换

  1. // 字符串会被拆分为单字符数组
  2. console.log(Array.from("Matt")); // ["M", "a", "t", "t"]
  3. // 可以使用 from()将集合和映射转换为一个新数组
  4. const m = new Map().set(1, 2)
  5. .set(3, 4);
  6. const s = new Set().add(1)
  7. .add(2)
  8. .add(3)
  9. .add(4);
  10. console.log(Array.from(m)); // [[1, 2], [3, 4]]
  11. console.log(Array.from(s)); // [1, 2, 3, 4]
  12. // Array.from()对现有数组执行浅复制
  13. const a1 = [1, 2, 3, 4];
  14. const a2 = Array.from(a1);
  15. console.log(a1); // [1, 2, 3, 4]
  16. alert(a1 === a2); // false
  17. // arguments 对象可以被轻松地转换为数组
  18. function getArgsArray() {
  19. return Array.from(arguments);
  20. }
  21. console.log(getArgsArray(1, 2, 3, 4)); // [1, 2, 3, 4]
  22. // from()也能转换带有必要属性的自定义对象
  23. const arrayLikeObject = {
  24. 0: 1,
  25. 1: 2,
  26. 2: 3,
  27. 3: 4,
  28. length: 4
  29. };
  30. console.log(Array.from(arrayLikeObject)); // [1, 2, 3, 4]
  31. //新数组批量变化
  32. const a1 = [1, 2, 3, 4];
  33. const a2 = Array.from(a1, x => x**2);
  34. const a3 = Array.from(a1, function(x) {return x**this.exponent}, {exponent: 2});
  35. console.log(a2); // [1, 4, 9, 16]
  36. console.log(a3); // [1, 4, 9, 16]

ES10 降低维度

把多维数组降低维度,默认是降低1个维度(就是解掉一个中括号[ ])
image.png
image.png

image.png
image.png

遍历再降维
image.png
image.png