ES6学习笔记:数组

创建数组

在ES5之前,创建数组主要存在两种方式:Array构造器和数组字面量,但这两种方式都需要将数组的项分别列出。
为了使数组创建更容易,ES6添加了以下两种新方法

Array.of()

ES6 为数组新增创建方法的目的之一,是帮助开发者在使用 Array 构造器时避开 JS 语言的一个怪异点。
调用 new Array() 构造器时:

  • 如果使用多个参数(无论是否为数值类型)来调用,这些参数会成为目标数组的项
  • 若传入单个数值类型的参数,数组的长度会被设置为该参数;
  • 如果使用单个的非数值型参数来调用,该参数就会成为目标数组的唯一项;

Array.of()的出现正是为了修复这个怪异点。
Array.of( )总是会创建一个包含所有传入参数的数组,而不管参数的数量与类型。

let items = Array.of(1, 2);
console.log(items.length);          // 2
console.log(items[0]);              // 1
console.log(items[1]);              // 2

items = Array.of(2);
console.log(items.length);          // 1
console.log(items[0]);              // 2

Array.from()

将类数组转换为数组,在ES5中一般这么做:

Array.prototype.slice.call(arguments);

它能正常工作是因为将 slice() 方法的 this 设置为类数组对象, slice() 只需要有数值类型的索引长度属性就能正常工作,而类数组对象能满足这些要求。

ES6增加了Array.from()用于明确完成将类数组转换为数组的工作:

var arr = Array.from(arguments);

此处调用 Array.from() 方法,使用 arguments 对象创建了一个新数组 arr ,它是一个数组实例,并且包含了 arguments 对象的所有项,同时还保持了项的顺序。

映射转换

如果你想实行进一步的数组转换,可以向Array.from()传递第二个参数,which is 映射函数。此函数会将类数组对象的每一个值转换为目标形式,并将其存储在目标数组的对应位置上。

function translate(){
    return Array.from(arguments,(value)=>value+1);
}

let numbers = translate(1,2,3);
//2,3,4

此代码将 (value) => value + 1 作为映射函数传递给了 Array.from() 方法,对每个项进行了一次 +1 处理。

如果映射函数需要在对象上工作,你可以手动传递第三个参数给 Array.from() 方法,从而指定映射函数内部的 this 值。

let helper = {
    diff: 1,

    add(value) {
        return value + this.diff;
    }
};

function translate() {
    return Array.from(arguments, helper.add, helper);
}

let numbers = translate(1, 2, 3);

console.log(numbers);               // 2,3,4

这个例子使用了 helper.add() 作为映射函数。由于该函数使用了 this.diff 属性,你必须向 Array.from() 方法传递第三个参数用于指定 this 。借助这个参数, Array.from() 就可以方便地进行数据转换,而无须调用 bind() 方法、或用其他方式去指定 this 值。

在可迭代对象上使用

Array.from()不仅可以用于类数组对象,也可用于可迭代对象,这意味着该方法可以将任意包含Symbol.iterator属性的对象转换为数组:

let numbers = {
    *[Symbol.iterator](){
        yield 1;
        yield 2;
        yield 3;
    }
}
let numbers2 = Array.from(numbers,value=>value+1);
//2,3,4

由于代码中的 numbers 对象是一个可迭代对象,你可以把它直接传递给 Array.from() 方法,从而将它包含的值转换为数组。映射函数对每个数都进行了 +1 处理,因此目标数组的内容就是 2 、 3 、 4 .

如果一个对象既是类数组对象,又是可迭代对象,那么迭代器就会使用 Array.from() 方法来决定需要转换的值。

新方法

find、findIndex

对于检索数组,ES5增加了indexOf与lastIndexOf方法,从而允许开发者在数组中查找特定值。
但是这两个方法只能查找特定只,若想在一系列的数中间查找第一个偶数,你必须自己写代码来实现这个意图。

find与findIndex方法均接受两个参数:

  • 回调函数,接收三个参数:item、index、array
  • (可选)指定回调函数内部的this

find、findeIndex接收的回调函数形式与map、forEach等相同。此回调函数应当在元素满足条件时返回true,find与findIndex均会在回调函数第一次返回true时停止查找。

二者唯一的区别是,find()方法会返回匹配的值,findIndex则会返回匹配值的位置索引。

let numbers = [25, 30, 35, 40, 45];

numbers.find(n=>n>33);  //35
numbers.findIndex(n=>n>33); //2

这段代码使用了 find() 与 findIndex() 方法在 numbers 数组中查找第一个大于 33 的元素,前者返回 35 ,而后者返回 2 (也就是 35 这个元素在数组中的索引值)。

find() 与 findIndex() 方法在查找满足特定条件的数组元素时非常有用
但若想查找特定值,则使用 indexOf() 与 lastIndexOf() 方法会是更好的选择。

fill

fill方法能使用特定值填充数组中的一个或多个参数。

  • 当只使用一个参数时,该方法会用该参数填充整个数组:
let numbers = [1, 2, 3, 4];
numbers.fill(1);
//[1,1,1,1]

此代码中的 numbers.fill(1) 调用将 numbers 数组中的所有元素都填充为 1.

  • 若你不想改变数组中的所有元素,而只想改变其中一部分,那么可以使用可选的起始位置与结束位置。
let numbers = [1, 2, 3, 4];
numbers.fill(1,2)
//[1,2,1,1]

numbers.fill(0,1,3);
//[1,0,0,4]

number.fill(1,2)的第二个参数指定起始位置,即从索引为2处开始填充为1.
numbers.fill(0, 1, 3)则指定了起始位置与结束位置(不包括结束位置),也就是将索引1,2的元素填充为0.

如果提供的起始位置或结束位置为负数,则它们会被加上数组的长度来算出最终的位置。

copyWithin

copyWithin() 方法与 fill() 类似,可以一次性修改数组的多个元素。不过,与 fill() 使用单个值来填充数组不同, copyWithin() 方法允许你在数组内部复制自身元素。

为此你要传递两个参数给copyWithin()方法:从什么位置开始填充,以及被用来复制的数据的起始位置索引。
例如,将数组的前两个元素复制到数组的最后两个位置:

let numbers = [1, 2, 3, 4];

numbers.copyWithin(2,0);
//[1,2,1,2]

numbers.copyWithin(2,0);表示从索引2的位置开始粘贴,从索引0的位置开始复制数据。

默认情况下, copyWithin() 方法总是会一直复制到数组末尾,不过你还可以提供一个可选参数指定了复制停止的位置(不包含该位置自身):

let numbers = [1, 2, 3, 4];
numbers.copyWithin(2,0,1);
//[1,2,1,4]

表示从索引为2的位置开始覆盖,从索引0到索引1的位置复制数据,其实这里就是1这一项被复制到了索引为2那里。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值