写在前面
本系列为在我读完阮一峰老师的《ES6标准入门》第二版之后,所做的阅读笔记的整理。
许多初学ES6, 同时和我一样初次阅读阮老师的这本书的时候, 读第一遍会越发的困惑, 因为阮老师上面说的很多的定义,方法,之前都是没有见过的, 读到后面才发现, 哦~原来是这样.
有一句话叫做”大神的世界我们不懂”, 所以我在初读第一遍《ES6标准入门》这本书的时候,也是踩了不少坑,读书的时候查阅了不少的资料.
所以,在这一系列的笔记教程中,我会从一个初学者的角度,向您讲述ES6的相关知识,在后面介绍的知识我会尽量不提前用,即使提前使用,也会同时做好标注,避免了阅读时各种查阅资料的烦恼.
系列博客将采用一个一个的样例,来说明书中的精华部分(当然,这只是我认为的),同时引导新手,快速入门ES6,并逐步将其投入到生产实践中。
同时,在阅读前也提醒您, 为了系统连贯性的学习ES6的基础知识,建议您从我的博客第一章开始阅读,当然,如果您对对应的知识已经有所了解,那么可以跳转到任意章节阅读,每一篇博客名中均有介绍该博客中涉及到的ES6的内容.
阮一峰老师的这本书是开源的,在其官方博客就可以下载到,但是我强烈建议大家去购买一本书, 一是方便自己查阅ES6中新增的众多API, 二也是表达一下对大神的敬仰.
新增的API–Array.from()
Array.from() 方法将两类对象转为真正的数组:类数组对象和可遍历对象
1 | let arrayLike = { |
可见,在将类数组转换为数组的过程中,使用ES6定义的新方法能够更好且更简单地将类数组转换为真正的数组.
在实际应用中,我们最常见的对象是DOM操作返回的NodeList集合,同样的,使用这个方法就可以实现将相应的类数组对象转换为数组
1 | let nameSet = new Set(['a', 'b']) |
注: Set是ES6中的新的数据结构, 类似于数组, 但是成员的值都是唯一的, 没有重复的值, 这是Set结构的最大特征.
如果对象是一个真的数组,那么使用Array.from() 方法会返回一个和原来一模一样的新数组
1 | let a = [1, 2, 3] |
扩展运算符也可以将某些数据结构转为数组
那么,我们可以对函数的变量arguments进行相应的处理,让其变成真正的数组
1 | function foo() { |
那么同样的,我们也可以对HTML的元素对象进行相应的操作
1 | [...document.querySelectorAll('div')] |
扩展运算符背后调用的是遍历器接口Iterator, 如果一个对象没有部署该接口就无法进行转换, Iterator将在后面详细讲解.
但是,所有的转换,一个最大的前提条件是,必须要有一个length对象,保存一个数值,没有这个属性的话是没有办法转为数组的
对于没有部署Array.from() 方法的浏览器,我们可以使用对应的老方法和新方法进行结合模拟
1 | const toArray = (() => |
注: 箭头函数也是ES6中新定义的方法, 其实是一种语法糖,方便我们进行编程而已.() => console.log(1)
等价于 function() {console.log(1)}
Array.from 方法还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,并将处理后的值放入返回的数组
1 | let arrayLike = { |
利用这个特性,可以很容易地将数组的空位置零
1 | let a = Array.from([1,,2,,5], (x) => x || 0) |
数组的Array.of()方法
Array.of() 方法用于将一组值转换为数组
1 | console.log(Array.of(1, 8, 3)) // [1,8,3] |
其实这个方法的主要目的,是弥补构造函数Array的不足, 因为参数的不同会导致Array的行为有所差异
1 | console.log(Array()) // [] |
因此, 不同于直接使用Array方法, 使用Array.of()方法不论你传入的是一个数,还是几个数,其实最后都是返回的数组对象, 而不同于使用Array, 会产生不同的行为.
数组的copyWithin() 方法
数组的copyWithin()方法, 主要的作用是在当前数组内部将指定位置的成员复制到其他位置, 此方法接受三个参数
target 必需值,从该位置开始替换数据, 也就是说, 从这个地方开始要更改数组了
atart 可选值,从该位置开始读取数据,默认为0 , 若为负值,则表示倒数, 也就是说, 我要更改数组,总得找个东西替换这些个之前的数组呀. 那么我就从这个位置开始截取数组的值,把它放到要更改的地方
end 到该位置前停止读取数据,默认等于数组长度,如果为负值,表示倒数, 也就是说,截取也不能截取个没完嘛,所以需要在这个地方停止截取, 然后就把截取的值丢到target的那个位置了.
1 | let a = [1, 2, 3, 4, 5] |
由上可见,其实copyWithin()最终更改了, 第四个位置, 也就是a[3] 的值
数组的find() 方法和findIndex() 方法
数组的find() 方法,用于找出第一个符合条件的数组成员.数组成员依次执行其后的回调函数,直到找出第一个匹配的成员,否则返回undefined
下面的代码找出了数组中小于0 的成员, 并将其打印出来
1 | let a = [1, 2, 3, -4, 3] |
find方法可以接受三个参数, 依次为当前值, 当前位置和原数组.
1 | let b = [1, 5, 10, 15].find((value, index, arr) => value > 9) |
数组的findeIndex() 方法返回第一个符合条件的数组成员的位置, 如果所有成员都不符合条件,则返回-1
这两个方法还可以接受第二个参数,用来绑定回调函数的this对象
还有重要的一点是,这两个方法都可以发现NaN,弥补了之前NaN支持的不足
1 | let a = [NaN].indexOf(NaN) |
注: Object.is() 用来比较两个值是否严格相等. 它与全等运算符表现基本一致, 但增加了NaN的支持.
数组的fill() 方法
数组实例的fill() 该方法使用给定值填充数组
1 | console.log(['a', 'b', 'c'].fill(1)) // [1, 1, 1] |
这样对数组进行初始化非常的方便,该方法还可接受另外两个可选参数,规定填充的起始和结束位置
数组遍历
ES6提供了三个新方法用于遍历数组
keys() 对键名的遍历
values() 对键值的遍历
entries() 对键值对的遍历
1 | for (let index of ['a', 'b'].keys()) { |
注: for…of 遍历也是对循环的一种补充,与for…in类似,但不会枚举出对象上的可枚举属性
数组的includes()
includes() 方法返回一个实例,表示某数组是否包含给定的值
1 | let a = [1, 2, 3] |
当浏览器不兼容的时候,可以使用indexOf方法进行替代
但是indexOf有一个弊端,原因是indexOf内部使用的是全等操作符进行匹配,所以这个时候当我们判定NaN的时候,是无法判定成功的, 因为NaN!==NaN
1 | console.log([NaN].indexOf(NaN)) // -1 |
数组的空位
ES5在很多情况下,对于数组的空位是直接忽略的,例如forEach filter every some 等方法会跳过空位, map 会跳过空位,但会保留这个值, join 和 toString 会将空位视为undefined 而undefined和null会被处理为字符串
下面是ES5下的方法
1 | [, 'a'].forEach((x, i) => console.log(i)); |
但在ES6中,空位会被明确转为undefined
1 | console.log([...['a', , 'b']]) |
copyWithin()会连空位一起复制
1 | [, 'a', 'b', ,].copyWithin(2, 0) //[empty × 1, "a", empty × 1, "a"] |
fill()会将空位视为正常的数组位置
1 | new Array(3).fill('a') // ['a', 'a', 'a'] |
for…of循环也会遍历空位, 而map却不会遍历空位
1 | let arr = [, ,] |
数组推导
数组推导是ES7中的新方法,允许直接通过现有数组生成新数组.
本来TC39是计划将其放入ES6的,但TC39仍然想完善它,让其支持所有数组结构. 所以推迟到了ES7.
1 | let a1 = [1, 2, 3, 4] |
(完)