javascript基础系列之Array

数组是一种类列表对象,它的原型中提供了遍历和修改元素的相关操作。因数组的长度是随时可变,所以数组在内存中的存储是不连续的。

常见操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// 创建数组
var fruits = ["apple", "banana", "pear"];
console.log(fruits);
console.log(fruits.length);

// 通过索引访问数组元素
var first = fruits[0];
var last = fruits[fruits.length-1];
console.log(first, last);

// 遍历数组
fruits.forEach((item, index, array)=> {
console.log(item, index, array);
});

// 数组模拟栈(操作栈顶)-后进先出
console.log(fruits);
fruits.push("melons"); // 添加元素到数组末尾,入栈
console.log(fruits);
fruits.pop(); // 删除最后一个元素,出栈
console.log(fruits);

// 数组模拟队列,先进先出
console.log(fruits);
fruits.unshift("grape"); // 添加元素到数组头部
console.log(fruits);
fruits.shift(); // 删除数组头部元素
console.log(fruits);

// 找出元素在数组中的索引
console.log(fruits.indexOf("banana"));

// 通过索引删除某个元素
console.log(fruits.splice(fruits.indexOf("banana"), 2)); // ["banana", "pear"]
console.log(fruits); // ["apple"]

// 复制数组
var fruits1 = fruits.slice();
fruits1.push("watermelon");
console.log(fruits); // fruits1数组新增元素不会影响到fruits

console.log(fruits[10]); // undefined

// 以数字开头的属性不能用点号引用,必须用方括号
fruits.0 // Uncaught SyntaxError: Unexpected number

var years = [2001, 2002, 2003, 2004, 2005];
console.log(years[2] != years["02"]); // true years[2]方括号中属性名number会被javascript解释器调用toString隐性转换为字符串

// // 给数组一个超出当前数组大小的下标赋值,javascritp解释器会同时修改length的值
fruits[7] = "persimmon";
console.log(Object.keys(fruits)); // ['0', '1', '2', '7']
console.log(fruits.length); // 8 数组长度被修改

// // 直接给数组length赋值一个更大的值,会初始化数组,没有默认值的直接empty占位符
fruits.length = 10;
console.log(fruits); // ['apple', 'banana', 'pear', empty × 7]

// 给数组的length赋一个更小的值则会删掉一部分元素
fruits.length = 2;
console.log(fruits); // ['apple', 'banana']

修改原数组的方法

push, splice

静态属性

get Array[@@species]

1
2
3
4
5
6
7
8
9
// Array[@@species]  返回Array的构造函数
console.log(Array[Symbol.species]); // ƒ Array() { [native code] }

class MyArray extends Array { // 重写MyArray的构造函数为Array
// 重写 MyArray 的 species 属性到父类 Array 的构造函数
static get [Symbol.species]() { return Array; }
}
var myarr = new MyArray();
console.log(MyArray[Symbol.species]); // ƒ Array() { [native code] }

静态方法

Array.from

定义:类数组转成数组

1
2
3
4
5
6
7
 // Array.from
function fn(a, b, c) {
console.log(arguments); // Arguments(4) [1, 2, 3, 4, callee: ƒ, Symbol(Symbol.iterator): ƒ]
console.log(Array.from(arguments)); // [1,2,3,4] 类数组转数组
console.log(Array.isArray(arguments)); // false
}
fn(1, 2, 3, 4);

Array.isArray

定义:判断变量是不是数组对象

1
2
var obj = [1,2,3];
console.log(Array.isArray(obj));

Array.of

定义:根据一组参数来创建新的数组实例,支持任意的参数数量和类型,和Array构造函数类似。Array.of() 和 Array 构造函数之间的区别在于处理整数参数,实例代码如下:

1
2
3
4
5
Array.of(7);   // [7]  value值为7的数组
Array(7); // [empty × 7] 7个空数据占位符

Array.of(1,2,3)和Array(1,2,3)是类似的

实例属性

Array.prototype[@@unscopables]

1
2
3
4
5
6
7
8
9
10
// Array.prototype[@@unscopables] 
// 包含es6中新定义的且未被ECMAScript收纳的属性名,这些属性被排除在由with语句绑定的环境中
var keys = [];
with(Array.prototype) { // 因为@@unscopables, keys会去作用域中找,不会在js环境查找。如果没有@@unscopables, keys.push会报错
keys.push("something");
}
console.log(Object.keys(Array.prototype[Symbol.unscopables]));
// ["copyWithin", "entries", "fill", "find", "findIndex",
// "includes", "keys", "values"]
console.log(keys);

Array.prototype.length

数组长度

1
2
3
// length
var arr = [2,3,4];
console.log(arr.length); // 3

正则匹配结果所返回的数组

正则匹配返回的数组如下

1
2
3
4
// inputs
const myRe = /d(b+)(d)/i;
const myArray = myRe.exec('cdbBdbsbz');
console.log(myArray);
属性或元素 说明 示例
input 正则表达式所匹配的原始字符串 cdbBdbsbz
index 匹配字串在原始字符串中的索引 1
[0] 最后匹配到字串 dbBd
[1], …,[n] 分组所匹配到的字符串 [1]: bB [2]: d

图片

实例方法

Array.prototype.at

通过索引返回数组中的值

1
2
3
4
// at  根据索引返回数组中对应的值
var arr = [5, 6, 7, 8];
console.log(arr.at(1)); // 6
console.log(arr.at(-1)); // 8

Array.prototype.concat

合并两个或多个数组

1
2
3
4
5
// concat合并两个或多个数组
var arr1 = [5, {a: 6}, [1,2], 7];
var arr2 = arr1.concat();
// console.log(arr1 == arr2); // false, 复制生成一个新数组
// console.log(arr1.concat([1,2,3], [10,12])); //[5, {a: 6}, [1,2], 7, 1,2,3,10,12] // 多个数组合并

Array.prototype.copyWithin

arr.copyWithin(target[, start[, end]])
浅复制数组的一部分到同一个数组的另一个位置,并返回它,不会改变原数组的长度

1
2
3
// copyWithin  浅复制数组的一部分到同一个数组的另一个位置
var arr1 = [2,3,4,5,6];
// console.log(arr1.copyWithin(1, 2, 3)); // [2,4,4,5,6]

Array.prototype.entries

1
2
3
4
5
6
7
// entries iterator对象, 获取对象的枚举值
var arr3 = [5, 6, 7, 8, 9];
var iterator1 = arr3.entries();
console.log(iterator1.next().value); // [0, 5]
console.log(iterator1.next().value); // [1, 6]
console.log(iterator1.next().value); // [2, 7]
console.log(iterator1.next().value); // [3, 8]

Array.prototype.every

1
2
3
4
5
6
7
// every 测试数组内的所有元素是否能通过某个指定函数的测试
var arr4 = [5, 6, 7, 8];
var result = arr4.every(function(item, index){
// console.log(item, index);
return item <= 8;
});
console.log(result); // true

Array.prototype.fill

1
2
3
4
// fill 用一个固定值填充一个数组中从起始索引到终止索引内的全部元素
// arr.fill(value[, start[, end]])
var arr5 = [5, 6, 7, 8, 9, 10];
console.log(arr5.fill(1, 2, 4)); // 从2至结尾用1填充 [5,6,1,1,9,10]

Array.prototype.filter

1
2
3
4
5
6
7
// filter 创建新数组,其包含通过函数测试的所有元素
var arr6 = [5,6,7,8,9];
var result = arr6.filter(function(item, index){
// console.log(item, index);
return item <=7;
});
console.log(result); // [5,6,7]

Array.prototype.find

1
2
3
4
5
6
// find 通过函数找到数组中的第一个元素
var arr = [5,6,7,8];
var result = arr.find(function(item, index){
return item % 2 === 0;
});
console.log(result); // 6

Array.prototype.findIndex

1
2
3
4
5
6
// findIndex, 和find类似,通过函数找到数组中的第一个元素的下标值
var arr = [5,6,7,8];
var result = arr.findIndex(function(item, index){
return item % 2 === 0;
});
console.log(result); // 1

Array.prototype.flat

1
2
3
// flat 嵌套数组扁平化
var arr = [[2,3,4], [5,6,[7], [8,9]], 10];
console.log(arr.flat(2));

Array.prototype.flatMap

1
2
3
4
// flatMap 返回一个新数组,其每个元素都通过函数扁平化处理
var arr = [1,2,3,4];
var result = arr.flatMap(x=>[x, x*2]); //
console.log(result); // [1, 2, 2, 4, 3, 6, 4, 8]

Array.prototype.forEach

1
2
3
4
5
6
// forEach 对数组的每个元素用指定函数处理, 没有返回值
var arr = [4,5,6,7,8];
var result1 = arr.forEach(function(item){
console.log(item)
});
console.log(result1); // undefined

Array.prototype.includes

1
2
3
// includes, 在数组中检索是否有指定值,有返回true,跟find类似
var arr = [15,16,17,18];
console.log(arr.includes(17)); //true

Array.prototype.indexOf

1
2
3
// indexOf, 找数组中给定元素的第一个索引,不存在返回-1
var arr = [15,16,17,18];
console.log(arr.indexOf(16)); // 1

Array.prototype.join

1
2
3
// join 用一个字符串把数组所有的元素连接起来, 如果是`,`和Array.prorotype.toString类似
var arr = [5,6,7,8];
console.log(arr.join(",")); // 5,6,7,8

Array.prototype.keys

1
2
3
4
5
6
// keys 返回包含数组中每个索引键的Array Iterator对象 
var arr = [5,6,7,8,9];
var iterators = arr.keys();
for (const iterator of iterators) {
// console.log(iterator); //0,1,2,3,4
}

Array.prototype.lastIndexOf

1
2
3
4
// lastIndexOf, 从后往前查找,和IndexOf类似,返回索引值,找不到返回-1
var arr = [5,6,7,8,6,9];
console.log(arr.lastIndexOf(6)); // 4
console.log(arr.indexOf(6)); // 1

Array.prototype.map

1
2
3
4
5
6
// map 返回一个新数组,其结果是每个元素调用处理函数返回值组合而来的数组
var arr = [5,6,7,8];
var result = arr.map(function(item){
return item * 2;
});
console.log(result); // [10,12,14,16]

Array.prototype.pop

1
2
3
// pop  删除数组最后一个元素,并返回该值, 数组为空返回undefined
var arr = [5,6,7,8];
console.log(arr.pop()); // 8

Array.prototype.push

1
2
3
// push 在数组末尾新增元素,返回数组长度
var arr = [5,6,7,8];
console.log(arr.push(9)); // 5

Array.prototype.reduce

1
2
3
4
5
6
7
8
// reduce 对数组中的每个元素执行提供的reducer函数,将结果汇总为单个返回值,第二个参数为初始值
console.log("_______reduce_______")
var arr = [1,2,3,4];
var result = arr.reduce(function(result, value){ // result是上次处理结果值,value是当前待处理值
// console.log(value); // 1,2,3,4
return result + value;
}, 5);
console.log(result); // 15

Array.prototype.recudeRight

1
2
3
4
5
6
7
// reduceRight, 和reduce类似,不过函数处理从右到左
var arr = [1,2,3,4];
var result = arr.reduceRight(function(result, value){ // result是上次处理结果值,value是当前待处理值
// console.log(value); // 4,3,2,1
return result + value;
}, 5);
console.log(result);

Array.prototype.reverse

1
2
3
// reverse 把数组元素顺序反转
var arr = [10, 2,13,7,9];
console.log(arr.reverse()); // [9,7,13,2,10]

Array.prototype.shift

1
2
3
4
// shift 删除数组中第一个元素,并返回该函数
var arr= [1,2,3,4];
console.log(arr.shift()); //1
console.log(arr); //[2,3,4]

Array.prototype.slice

1
2
3
4
// slice 提取原数组的一部分并返回一个新数组
// arr.slice([begin[, end]]) 包含开始,不包含结束
var arr = [1,2,3,4,5];
console.log(arr.slice(2,3)); // [3]

Array.prototype.some

1
2
3
4
5
6
// some 测试数组中是否至少一个元素通过了函数测试
var arr = [1,2,3,4,5];
var result = arr.some(function(item){
return item >= 5;
});
console.log(result); // true

Array.prototype.sort

1
2
3
// sort 对原数组排序,并返回此数组
var arr = [5,8,2,4,3];
console.log(arr.sort()); //[2,3,4,5,8]

Array.prototype.splice

1
2
3
4
5
6
7
8
9
10
11
// splice 在数组内删除或替换元素,或者新增元素来修改原数组,以数组形式返回被修改的内容
// array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
// 删除元素,第二个参数是删除数量
var arr = [1,2,3,4,5];
console.log(arr.splice(2,3));// [3,4,5]
console.log(arr); // [1,2]

// 新增元素
var arr = [1,2,3,4,5];
console.log(arr.splice(2,1,10,11)); // [3], 错误答案:[10,11],返回删除的元素数组集合
console.log(arr); // [1,2,10,11,4,5]

Array.prototype.toLocaleString

1
2
3
// toLocaleString 返回一个字符串表示数组中的元素
var arr = [1,"b", new Date("2022-03-02")];
console.log(arr.toLocaleString()); // 1,b,2022/3/2 08:00:00

Array.prototype.toString

1
2
3
// toString 和toLocaleString区别是对日期的处理,如下示例
var arr = [1,"b", new Date("2022-03-02")];
console.log(arr.toString()); // 1,b,Wed Mar 02 2022 08:00:00 GMT+0800 (中国标准时间)

Array.prototype.unshift

1
2
3
4
// unshift 数组头部新增一个元素, 返回新数组的长度
var arr = [2,3,4,5];
console.log(arr.unshift(1)); // 5
console.log(arr); // [1,2,3,4,5]

Array.prototype.values

1
2
3
4
5
6
// values 返回一个Array Iterator对象,包含数组每个索引的值
var arr = [5,6,7,8];
var iters = arr.values();
for (const iterator of iters) {
// console.log(iterator); // [5,6,7,8]
}

Array.prototype[@@iterator]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// @@iterator属性和 Array.prototype.values() 属性的初始值是同一个函数对象。
var arr = ['a', 'b','c'];
var iters2 = arr[Symbol.iterator]();
// 遍历迭代器
for (const iterator of iters2) {
// console.log(iterator); // ['a','b','c']
}
// 另一种迭代
var arr = ['a', 'b', 'c'];
var eArr = arr[Symbol.iterator]();
console.log(eArr.next().value); // a
console.log(eArr.next().value); // bf
console.log(eArr.next().value); // c
console.log(eArr.next().value); // undefined

参考文档

Array