网站首页 > 技术文章 正文
在日常工作中我们经常会与数组打交道,因此需要熟练掌握数组操作的相关方法,ES6中关于数组的操作,又给我们带来了哪些惊喜呢,Array数组操作又添加了哪些新方法?
本篇文章将从以下几个方面进行介绍:
- Array.from()
- Array.of()
- fill()
- includes()
- find()&findIndex()
- copyWithin()
- entries(), keys()&values()
本篇文章预计10分钟
Array.from()
Array.from()方法实现了把可迭代的对象(比如:Set,Map,Array)或类数组对象(一个拥有length属性且其它属性键值为数字的对象)转换成数组的功能。Array.from()语法定义如下:
Array.from(arrayLike[, mapFn[, thisArg]])
三个参数对应的含义如下:
- arrayLike:类数组或可迭代的对象
- mapFn:可选参数,回调函数实现元素迭代的功能(类似Map函数)
- thisArg:可选参数,map函数中this属性指向这个对象。
接下来我们来看几个例子:
Map转换
其函数功能就是将Map对象转换成一个一位数组,类似[key1,value1,key2,value2,key3,value3.....],如下段代码所示
const map1 = new Map(); map1.set('k1', '前'); map1.set('k2', '端'); map1.set('k3', '达'); map1.set('k4', '人'); console.log('%s', Array.from(map1)) //outputs //k1,前,k2,端,k3,达,k4,人
Set转换
其函数功能将Set对象转换成一个一位数组,如下段代码所示:
const set1 = new Set(); set1.add(1).add(2).add(3); console.log('%s', Array.from(set1)); //outputs //1,2,3
字符串转换
其函数功能可以将一个字符串或unicode字符串转换成一个字符数组,如下段代码所示:
console.log('%s', Array.from('hello world')); console.log('%s', Array.from('\u524d\u7aef\u8fbe\u4eba')); //outputs //h,e,l,l,o, ,w,o,r,l,d //前,端,达,人
类数组对象转换
一个类数组对象必须有length属性,且它的属性名必须是数值或者可以转换成数值的字符。 注意:属性名代表了数组的索引号,如果没有这个索引号,转出来的数组中对应的元素就为空。
如下代码所示:
console.log('%s', Array.from({ 0: '0', 1: '1', 3: '3', length:4 })); //outputs //0,1,,3
如果不带length属性,数组对象为空,如下段代码所示,没有任何输出:
console.log('%s', Array.from({ 0: 0, 1: 1 }))
对象的属性名不能转换成索引号时,如下段代码所示,没有任何输出:
console.log('%s', Array.from({ a: '1', b: '2', length:2 }));
mapFn函数转换
接下我们来看下如何使用map函数的使用,我们创建了一个接收可变参数的函数(arguments类数组对象),并返回一个针对参数处理过的数组,如下段代码所示:
function double(arr) { return Array.from(arguments, function(elem) { return elem * 2; }); } const result = double(1, 2, 3, 4); console.log(result); //outputs //[ 2, 4, 6, 8 ]
第三个参数对象,mapFn函数的this指向
该参数是非常有用的,我们精彩会将被处理的数据和处理对象进行分离,将各种不同的处理数据的方法封装到不同的的对象中去,处理方法采用相同的名字。
在调用Array.from对数据对象进行转换时,可以将不同的处理对象按实际情况进行注入,以得到不同的结果,适合解耦。这种做法是模板设计模式的应用,有点类似于依赖注入。如下段代码所示:
let diObj = { handle: function(n){ return n + 2 } } console.log('%s', Array.from( [1, 2, 3, 4, 5], function (x){ return this.handle(x) }, diObj))
处理Dom对象的应用
在实际开发过程中,我们经常会处理Dom对象,针对对象进行循环迭代处理,如下段所示:
const arr = document.querySelectorAll('div'); /* arr.forEach( item => console.log(item.tagName) ) */ // => wrong Array.from(arr).forEach( item => console.log(item.tagName) ); // correct”
有上述代码我们看出,arr.forEach无法运行,是因为DOM对象是类数组对象,并非真实数组,我们需要使用Array.from()方法进行数组转换。
Array.of()
在ES6之前,我们使用 Array(...)方法声明一个数组,此方法接收一个参数,即此参数代表数组的长度而不是一个包含此数字的数组,声明后会构建一个此长度的空数组,有时候会产生难以发现的错误。因此ES6推出了Array.of()用于解决此问题,成为数组的推荐函数构造器。如下段代码代码所示:
let arr1 = Array(2); let arr2 = Array.of(1,2,3); console.log(arr1.length); console.log(arr1); console.log(arr2.length) console.log(arr2);
上述代码将会输出:
2 [ <2 empty items> ] 3 [ 1, 2, 3 ]
由此可见使用 Array.of() 更能体现构建数组的意图,更清晰直白。
fill()
fill()函数用来将数值填充到指定的数组中,我们可以定义被填充数组的开始位置和结束位置,其使用语法定义如下:
Array.prototype.fill(value[, start[, end]])
- value:要填充的数值,必填
- start:填充的开始位置,选填
- end:填充的结束位置,不包含此项,选填
注:如果只有value参数,即数组中所有的内容为此项;如果没有end参数,则其默认值为数组的长度;如果start或end为负数,其对应的值为当前数值+数组的长度
为了更好理解此函数,我们先来一段代码,如下所示:
let arr1 = [1, 2, 3, 4]; let arr2 = [1, 2, 3, 4]; let arr3 = [1, 2, 3, 4]; let arr4 = [1, 2, 3, 4]; let arr5 = [1, 2, 3, 4]; arr1.fill(5); arr2.fill(5, 1, 2); arr3.fill(5, 1, 3); arr4.fill(5, -3, 2); arr5.fill(5, 0, -2); console.log(arr1); console.log(arr2); console.log(arr3); console.log(arr4); console.log(arr5);
上述代码将会输出:
[ 5, 5, 5, 5 ] [ 1, 5, 3, 4 ] [ 1, 5, 5, 4 ] [ 1, 5, 3, 4 ] [ 5, 5, 3, 4 ]
includes()
includes()方法用来判断数组中是否含有某元素,如果存在返回true,不存在返回false,如下段代码所示:
const arr = [0, 1, 1, 2, 3, 5, 8, 13]; arr.includes(0); // true arr.includes(13); // true arr.includes(21); // false
与indexOf()方法的区别
indexof()方法用来判断数组中是否含有某元素,但是返回结果是此元素在数组的索引位置,如果不存在则返回-1,如下段代码所示:
const arr = ['apple', 'mango', 'banana']; console.log(arr.indexOf('前端达人')); // -1 console.log(arr.indexOf('apple')); // 0 console.log(arr.indexOf('mango')); // 1 console.log(arr.indexOf('apple') >= 0); // true console.log(arr.includes('apple')); // true console.log(arr.indexOf('pineapple') >= 0); // false console.log(arr.includes('pineapple')); // false
如果你还要问还有什么区别,还有一个不太常用的关于NaN的判断,示例代码如下:
const arr = ['Some elements I like', NaN, 1337, true, false, 0017]; console.log(arr.includes(NaN)); // true console.log(arr.indexOf(NaN) >= 0); // false
因为index.of()的使用严格匹配(===)进行判断,我们可以使用console.log(NaN===NaN)进行确认,运行结果为false。
find()&findIndex()
find()
find()函数用来在数组中查找目标元素,找到就返回该元素(找到一个即可,不再寻找其它),找不到返回undefined。其语法定义如下:
arr.find(callback[, thisArg]);
- callback:回调的函数
- thisArg:执行回调函数时的this指向,可选
在callback回调函数上一共有三个参数:
- 每一次迭代查找的数组元素
- 每一次迭代查找的数组元素索引
- 被查找的数组
为了更好的理解这个函数,我们来看如下代码,示例如下:
const arr = [1, 2, 3, 4]; const result = arr.find(function(elem) { return elem > 2; }); console.log(result); //ourputs //3
上述输出结果只返还了一项,其实满足条件的有两项,但是find函数的功能,只要找到一项内容就返回。
findIndex()
findIndex()和find()类似,差别就是返回该元素在数组中对应的索引,只返回最先满足条件的元素的索引。如下段代码所示:
const arr = [1, 3, 4, 5]; const result = arr.findIndex(function(elem) {return elem > 3;}); console.log(result); //outputs //2
数组中满足大于3的元素有4,5两项,由于此函数只返还最先满足大于3的元素的索引,元素4的索引为2,因此返回2。
copyWithin()
copyWithin()方法浅复制数组的一部分到同一数组中的另一个位置,覆盖这个位置所有原来的值,并返回它,不会改变原数组的长度。其语法定义如下:
arr.copyWithin(target[, start[, end]])
- target:在当前数组,定义要从什么位置开始复制的索引。如果数值大于等于数组长度,数组不会进行拷贝,保持原样。
- start: 在当前数组,选取要复制的数组内容的起始索引,如果为负值,对应的值则为当前值+数组的长度
- end:在当前数组,选取要复制的数组内容的结束索引,不包含此项内容。如果为负值,对应的值则为当前值+数组的长度,此参数可选。如果没提供,其值默认为数组的长度
注:索引从0开始
为了更好的理解此方法,笔者用下图进行示意:
接下来为了理解这些参数,我们来看一段代码,示例代码如下:
const arr1 = [1, 2, 3, 4, 5]; const arr2 = [1, 2, 3, 4, 5]; const arr3 = [1, 2, 3, 4, 5]; const arr4 = [1, 2, 3, 4, 5]; arr1.copyWithin(1, 2, 4); arr2.copyWithin(0, 1); arr3.copyWithin(1, -2); arr4.copyWithin(1, -2, -1); console.log(arr1); console.log(arr2); console.log(arr3); console.log(arr4);
上述代码的输出结果:
[1,3,4,4,5] [2,3,4,5,5] [1,4,5,4,5] [1,4,3,4,5]
entries(), keys()&values()
entries()方法返回一个Array Iterator对象,该对象包含数组中每个索引的键/值对,类似[key1,value1,key2,value2,key3,value3.....]
keys()方法返回一个包含数组中每个索引键的Array Iterator对象。
values()方法返回一个新的 Array Iterator 对象,该对象包含数组每个索引的值。 注意:使用这些方法返回的是可迭代的Array Iterator对象而不是数组。
const arr = ['a', 'b', 'c']; const entries = arr.entries(); const keys = arr.keys(); const values = arr.values(); console.log(...entries); console.log(...keys); console.log(...values);
上述代码输出结果:
0,a 1,b 2,c 0 1 2 a b c
小节
由于内容篇幅有限,今天的文章就介绍到这里,下篇文章笔者将继续介绍Array数组迭代的新方法——map(),filter(),forEach(),some(),reduce()等,敬请期待。
更多精彩内容,请微信关注“前端达人”公众号
- 上一篇: JavaScript数组方法速查手册极简版
- 下一篇: 前端系列——获取数组中的最大值(最小值)
猜你喜欢
- 2024-09-30 JavaScript数组_数组方法「二」(二十七)
- 2024-09-30 table组件,前端如何使用table组件打印数组数据
- 2024-09-30 前端数组改字符串方法 前端数组改字符串方法是什么
- 2024-09-30 javascript复制数组的三种方式 javascript复制粘贴
- 2024-09-30 第21节 检测数组、类数组及多维数组-Web前端开发之Javascript
- 2024-09-30 前端系列——ES6中循环数组的方法
- 2024-09-30 前端已死?请用TS写出20个数组方法的声明
- 2024-09-30 springboot项目中,前端如何传递一个自定义对象数组给后端
- 2024-09-30 带你走进javascript数组的世界 javascript数组操作方法
- 2024-09-30 每天学点 ES6 —— 数组(二) es6数组处理方法
你 发表评论:
欢迎- 05-10VS Code当中的15个神仙插件,值得收藏
- 05-10如何自己开发一个Google浏览器插件?
- 05-10前端流行框架Vue3教程:14. 组件传递Props效验
- 05-10吃了一年的SU,最好用的插件都在这了
- 05-10前端必看!这款神器让网站界面告别千篇一律
- 05-10程序员请收好:10个非常有用的 Visual Studio Code 插件
- 05-10前端资源-实用的JS插件(前端代码规范插件)
- 05-105款好用Office插件,一定不要错过
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端md5加密 (49)
- 前端路由 (55)
- 前端数组 (65)
- 前端定时器 (47)
- 前端懒加载 (45)
- 前端接口 (46)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle查询数据库 (45)
- oracle约束 (46)
- oracle 中文 (51)
- oracle链接 (47)
- oracle的函数 (57)
- mac oracle (47)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)