集合引用类型之Array方法(一)

348 阅读4分钟

这是我参与8月更文挑战的第20天,活动详情查看:8月更文挑战

这部分并不是很常用,但还是把它们记下来吧;

创建数组

在使用Array构造函数创建数组时,可以省略new操作符,结果也是一样的,也可以使用数组字面量表示法,与对象一样,在使用数组字面量标识法创建数组不会调用Array构造函数;Array构造函数在ES6新增两个用于创建数组的静态方法:from()of()from用于将类数组结构转换为数组实例;

Array.from()

Array.from()的第一个参数是一个类数组对象,即任何可迭代的结构,或者有一个length属性和可索引元素的结构。这种方式可用于很多场合;

  • 字符串拆分为单字符数组

    console.log(Array.from('Mannqo'));  // ["M","a","n","n","q","o"]
    
  • 将集合和映射转换为一个新数组

    const m = new Map().set(1, 2).set(3, 4); 
    const s = new Set().add(1).add(2).add(3).add(4);
    console.log(Array.from(m));   // [[1, 2], [3, 4]]
    console.log(Array.from(s));   // [1, 2, 3, 4]
    

    对m映射、s集合打印如下:

    from.png

  • 对现有数组执行浅复制

    const a1 = [1,2,3,4];
    const a2 = Array.from(a1);
    console.log(a1 === a2);  // false
    
  • 可以使用任何可迭代对象

    const iter = {
        *[Symbol.iterator]() {
            yield 1; yield 2; yield 3; yield 4;
        }
    }
    console.log(Array.from(iter));  // [1,2,3,4]
    
  • arguments对象可以被转换为数组

  • 转换带有必要属性的自定义对象

Array.from()可以接收第二个可选的映射函数参数,这个参数可以直接增强数组的值;还可以接收第三个可选参数,用于指定映射函数中this的值,当这个重写的this在箭头函数中不适用。

const a1 = [1, 2, 3, 4];
const a2 = Array.from(a1, x => x**2)
const a3 = Array.from(a1, function (x) { return x ** this.x }, { x: 2 })
// 此时a2、a3的打印结果都为[1, 4, 9, 16]

Array.of()

Array.of()可以把一组参数转换为数组,用于替代Arrray.prototype.slice.call(arguments)

console.log(1, 2, 3, 4);  // [1, 2, 3, 4]

数组空位

使用数组字面量初始化数组时,可以使用一串逗号来创建空位。ECMAScript会将逗号之间相应索引位置的值当成空位;es6新增方法普遍将这些空位当成存在的元素,只不过值为undefined;

const arr = [, , , , ,];
console.log(arr.length);  // 5  

实践中要闭麦了使用数组空位,如果要使用,用undefined代替;

数组索引

通过索引号在数组中取出某个元素,通过length属性可以给某个数组末尾添加元素;数组中最多可以包含4 294 967 295个元素;如果超出这个范围会导致抛出错误;以这个最大值作为初始值创建数组,可能导致脚本运行时间过长的错误;

检测数组

instanceof&Array.isArray

判断一个对象是不是数组,在只有一个网页(一个全局作用域)的情况下,使用instanceof操作符即可;

console.log(arr instanceof Array);  // arr为自定义数组

但是在网页有多个框架的时候,会存在有多个版本的Array构造函数的情况;这个时候可以使用Array.isArray()方法;

迭代器方法

keys()&values()&entries()

es6中,Array的原型上暴露了3个用于检索数组内容的方法:keys()values()entries()keys()返回数组索引的迭代器;values()返回数组元素的迭代器,而entries()返回 索引/值对 的迭代器;

const a = ["a", "b", "c", "d"];
const aKeys = Array.from(a.keys());
const aValues = Array.from(a.values());
const aEntries = Array.from(a.entries());

对其结果做出打印如下:迭代器方法.png

复制和填充方法

es6中新增了两个方法:批量复制方法copyWithin()和填充数组方法fill();这两个方法都需要指定数组实例的一个范围,包含开始索引,不包含结束索引的元素。使用这个方法不会改变数组的大小;

fill()

第一个参数是填充的值,第二个参数index1和第三个参数index2是可选的,表示填充范围(index1<index2),填充索引大于index1小于index2的元素;填充个数n为index2-index1

const arr = [0, 0, 0, 0, 0];
arr.fill(5);   // [5, 5, 5, 5, 5]
arr.fill(6, 3);   // [0, 0, 0, 5, 5]
arr.fill(6, 1, 3);   // [0, 5, 5, 5, 5]

索引过低、过高、方向(即index1>index)时会被忽略;如果索引部分有用,则填充可用部分;

copyWithin()

fill()不同,copyWithin()会按照指定范围浅复制数组中的部分内容,然后将它们插入到指定索引开始的位置;开始索引和结束索引则与fill()使用同样的计算方法;

  • 第一个参数insert是插入位置的索引值,第二个参数index1是开始复制位置的索引值(默认为0);第三个参数index2是结束复制的索引值,复制个数n为index2-index1

  • 只有第一个参数的话,默认的起始复制位置就是[0,insert)

  • 对于一个数组arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];分别执行下面的操作

    arr.copyWithin(5);  // [0, 1, 2, 3, 4, 0, 1, 2, 3, 4] 
    arr.copyWithin(0, 5);  // [5, 6, 7, 8, 9, 5, 6, 7, 8, 9]
    arr.copyWithin(4, 0, 3);  // [0, 1, 2, 3, 0, 1, 2, 7, 8, 9]
    

fill()相同,索引过低、过高、方向(即index1>index)时会被忽略;如果索引部分有用,则填充可用部分;