数组扩展

1,扩展运算符
2,Array.from()
3,Array.of()
4,数组实例的 copyWithin()
5,数组实例的 find() 和 findIndex()
6,数组实例的 fill()
7,数组实例的 entries(),keys() 和 values()
8,数组实例的 includes()
9,数组实例的 flat() ,flatMap()
10,数组的空位

1,扩展运算符

含义

扩展运算符(spread)是三个点 (...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。

console.log(...[1,2,3]);
// 1 2 3
[...document.querySelectorAll('div')]
// [<div>,<div>,<div>]

如果 扩展符后面跟的是一个空数组,那么则不产生任何效果

[...[],1] 
// [1]

注意,如果在括号中使用 扩展运算符 ,那么JavaScript 引擎会认为这是在 函数中调用 扩展运算符,如果这时不是函数调用,就会报错。

(...[1,2,3])
// Uncaught SyntaxError: Unexpected number
console.log(...[1,2,3])
// 不会报错
console.log((...[1,2,3]))
// 会报错 Uncaught SyntaxError: Unexpected number

扩展运算符的应用:
1,复制数组
2,合并数组
3,与解构赋值结合
4,把字符串转换为真正的数组
5,实现了 Iterator 接口的对象

const a1 = [1,2,3];
const a2 = [...a1];
// 这时修改 a2 的值不会改变 a1 的值
const a3 = [...a1,...a2];
// [1,2,3,1,2,3]
const [a4,...a5] = [a3];
// a4 = 1
// a5 = [2,3,1,2,3]
// 解构赋值时 扩展符必须放到最后,不然会报错
[...'hello']
// ['h','e','l','l','o']
[...document.querySelectorAll('div')]
// [<div>,<div>,<div>]
// 任何定义了 遍历器(Iterator)接口的对象,都可以用扩展运算符转为真正的数组

2,Array.from()

Array.from 方法用于将两类对象转为真正的数组:
1,类似数组的对象(array like object)
2,可遍历的对象(set ,map)
下面试一个类似数组的对象, Array.from 将它转为真正的数组

// 类似数组的对象
let likeArray = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    'length': 3
}
let arr = Array.from(likeArray); // ['a','b','c']

实际应用中:Dom 操作返回的 NodeList 集合,函数内部 arguments 对象

let ArrayLike = document.querySelectorAll('div');
let arr = Array.from(ArrayLike);

function foo() {
    var args = Array.from(arguments);
}

Array.from 还可以接受第二个参数,作用类似于数组的map 方法,用来对每个元素进行处理,将处理后的值放入返回的数组。

Array.from(arrayLike, x=>x*x);
// 等同于
Array.from(arrayLike).map(x=>x*x);

Array.from([1,2,3],(x) => x * x);
// [1,4,9]

3,Array.of()

Array.of 方法用于将一组数值,转换为数组

Array.of(3,11,8) // [3,11,8]

基本上 Array.of 可以代替 Array() 生成数组,因为 Array.of() 的行为非常统一

Array.of() // []
Array.of(undefined) // [undefined] 
Array.of(1,2,3) // [1,2,3]
Array.of(3) // [3]

Array(3) // [,,] 这里的 3 指的是数组的长度,所以推荐使用 Array.of()

4,数组实例的 copyWithin()

copyWithin() :在当前数组内部,将指定位置的成员复制到其他位置(覆盖原有成员),然后返回当前数组。使用这个方法,会修改当前数组。

Array.prototype.copyWithin(target,start = 0,end = this.length);

target(必需) 从何处开始替换(数组位置,如果是负数,表示倒数)
start 从该位置开始读取数据,默认为 0 ,如果负数,表示倒数
end 从该位置停止读取数据,默认数组长度,如果负数,表示倒数

[1,2,3,4,5].copyWithin(0,3)
// [4,5,3,4,5]

上面这个代码表示:target=0,start =3,end 默认等于数组长度 5,也就是说从数组第三位开始读取,到 第5位停止,不读取第5位,也就是读取第3,4位的数据 也就是说 读取的数据为 4,5 ,而 target = 0 ,则表示从数组的第 0 位开始替换,这时 4,5 代替了原来的 1,2 ,所以这个数组最终变成了[4,5,3,4,5]

数组实例的 find() 和 findIndex()

find()
find() 方法用于找出第一个符合条件的数组成员,并返回这个数组成员。它的参数是一个回调函数,所有的数组成员依次去 执行这个回调函数,直到找到第一个返回值为 true 的成员,然后返回该成员,如果没有符合条件的成员,则返回 undefined。

[0,0,0,1].find((n) => n != 0)
// 1

上面代码找出第一个不为 0 的数组成员

[1,2,3,4].find(function(value,index,arr){
    return value > 2; 
}) // 3 (找出大于 2 的数组成员)

find() 的回调函数可以接受三个参数,依次是数组成员 value, 该成员的索引 index, 以及原数组 arr(这里value,index可以写成其他值)。

findIndex()

数组实例的 findIndex() 方法与 find() 方法非常类似,只不过 findIndex() 返回的是第一个符合条件的数组成员的位置,如果没有符合条件的数组成员,则返回 -1。

[1,2,3,4,5].findIndex(function(value,index,arr){
    return value > 3
}); // 3 (成员 4 的位置)

第二个参数:对象

find() 和 findIndex() 这两个方法都可以接受第二个参数,用来绑定回调函数的 this 对象。

let obj = {num:2}
[1,2,3,4,5].find(function(v){
    return v > this.num
},obj)// 3

上面代码中find 方法绑定了 obj 这个对象,所以这里 this.num = 2,所以最终的返回值是 3

数组实例的 fill()

fill () 方法使用给定值,填充一个数组。

['a','b','c'].fill(1)
// [1,1,1]
new Array.(2).fill(1)
// [1,1]

上面代码表明 fill() 方法用于空数组的初始化非常方便。数组中已有的元素,会被全部抹去。

fill() 方法还可以接受第二个参数和第三个参数,用于指定填充的 起始位置和结束位置。

['a','b','c'].fill(7,1,2)
// ['a',7,'c']

注意:如果填充的类型为对象,那么被赋值的是同一个内存地址的对象,而不是深度拷贝对象!

let arr = new Array(2).fill({age:18});
arr[0].age = 17;
// [{age:17},{age:17}]

数组实例的 entries() ,keys(),values()

Es6 提供了三个新方法用来遍历数组:

entries() ,keys(),values()

它们都返回一个遍历器对象,可以用 for..of 循环进行遍历,唯一区别是:

keys() 是对键名的遍历,values() 是对键值的遍历,entries() 是键值对的遍历

for (let index of ['a','b'].keys()) {
    console.log(index);
}
// 0
// 1
for (let value of ['a','b'].values()) {
    console.log(values);
}
// a
// b
for(let [index,vlaue] of ['a','b'].entries()) {
    console.log(index,value);
}
// 0,'a'
// 1,'b'

数组实例的 includes()

Array.protoptype.includes 方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的 includes 方法类似。

[1,2,3].includes(2) // true
[1,2,3].includes(4) // false

该方法的第二个参数表示搜索的起始位置,默认为 0,如果第二个参数为负数,则表示倒数的位置,如果这时他大于数组长度,例如(-4),但是数组长度为3,则会重置为从 0 开始。

[1,2,3].includes(3,3)// false
[1,2,3].includes(3,-4) /// true

另外,Map 和 Set 数据结构有一个 has 方法,需要与 includes 区分

​ --Map 结构的 has 方法,是用来查找键名的
--Set 结构的 has 方法,是用来查找值的

数组实例的 flat() ,flatMap()

数组成员有时候还是数组,也就是我们说的多维数组,flat() 用于将嵌套的数组拉平。变成一维的数组。该方法返回的是一个新数组,对原来的数组无影响。

[1,2,[3,4]].flat()
// [1,2,3,4]

这里 flat() 方法默认只会拉平一层,如果想要拉平多层,可以将 flat() 方法的参数写成一个整数,表示想要拉平的层数。

[1,2,[3,[4,5]]].flat()
// [1,2,3,[4,5]]
[1,2,[3,[4,5]]].flat(2)
// [1,2,3,4,5]

如果不管有多少层嵌套,都想要拉平,那么就需要使用 Infinity 关键字作为参数

[1,2,[3,[4,5]]].flat(Infinity)
// [1,2,3,4,5]

如果原数组有空位,则 flat() 会跳过空位

[1,2,,4].flat()
// [1,2,4]

flatMap() 方法对原数组的每个成员执行一个函数(相当于执行Array.prototype.map()) 然后对返回值组成的数组执行 flat() 方法。该方法返回一个新数组,不改变原数组。

// 等价于 [[1,2],[2,4],[3,6]].flat()
[1,2,3].flatMap((x) => [x,x*2]);
// [1,2,2,4,3,6]

flatMap() 只能展开一层数组。

flatMap() 方法参数是一个遍历函数,该遍历函数可以接受三个参数,分别是当前数组成员,当前数组成员的位置(从零开始),原数组。

arr.flatMap(function callback(value,index,arr){},thisArg)

flatMap() 方法还可以有第二个参数,用来绑定遍历函数里面的 this

数组的空位

数组的空位是说数组的某一个位置没有任何值,比如 Array 构造函数返回的数组都是空位。

Array(3); // [,,]

注意,空位不是 undefined ,一个位置的值等于 undefined ,依然是有值的,空位是没有任何值。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • 扩展运算符(spread)是三个点(...) 将一个数组转为用逗号分隔的参数序列。 替代函数的 apply 方法 ...
    好奇男孩阅读 355评论 0 1
  • [JavaScript数组]一篇中介绍了ES6之前的数组方法。本篇介绍一下ES6里新增的数组方法。 keys,va...
    sponing阅读 294评论 0 0
  • 前面的话   数组是一种基础的JS对象,随着时间推进,JS中的其他部分一直在演进,而直到ES5标准才为数组对象引入...
    CodeMT阅读 552评论 0 2
  • ES6数组扩展 1.Array.from() 定义:Array.from()用于将两类对象转换成真正的数组:类数组...
    lijaha阅读 420评论 0 0
  • Thus, the anthropological concept of “culture”, like the ...
    未名吾梦阅读 376评论 0 1