ES6小计(1)

1. letconst

es6中通过letconst声明的变量有了块级作用域的变化,letconst无变量提升,必须先声明再使用,且不能重复声明。先使用再声明会报变量未声明错误。const声明的变量需要立即赋值,声明后不能再次赋值。

2. 解构赋值

解构赋值用处主要在于变量的声明。当多变量声明的时候,比较方便快捷。

2.1 数组的解构赋值

let [a, b, c] = [1, 2, 3]
// a = 1; b = 2; b = 3;
let [a, ...b] = [1, 2, 3]
// a = 1; b = [2, 3];
let [x = 1] = [undefined]
// x = 1
let [x = 1] = [null]
// x = null

解构为从左到右依次声明解构对象。若解构不成功,对应的变量为undefined。设定默认值时,当解构失败或者解构对应成员严格等于undefined的时候,解构才会使用默认值。

2.2 对象的解构赋值

let {foo, bar} = {foo: 'aaa', bar: 'bbb'}
// foo = 'aaa'; bar = 'bbb'
let {foo: f} = {foo: 'aaa', bar: 'bbb'}
// f = 'aaa'
let {x, y = 5} = {x: 1}
// x = 1; y = 5

对象的解构赋值其实就是同名属性名的定义与赋值,因为es6中,对象的属性名与变量名相同时,可以简写。当然,数组解构与对象解构可以嵌套。对象解构的默认值与数组解构一致,对象的属性严格等于undefined或者解构失败时才会生效。

var x;
{x} = {x: 1}

上述写法会报错,js解析时,会将 {x} 看成一个代码块,’=’ 赋值没有变量,报错。注意不要将大括号写在首行!

2.3 字符串的解构赋值

let [a, b, c, d, length] = '1234'
// a = '1'; b = '2'; c = '3'; d = '4'; length = 4;

字符串对象转化为类数组对象后进行的解构。

2.4 数值和布尔型对象的解构赋值

let {toString: s} = 123;
// s === Number.prototype.toString 

数值和布尔型会转化为对应的对象后再进行解构。123 => new Number(123), true => new Boolean(true)
nullundefined不能进行对象化,故用nullundefined进行解构会报错。

2.5 函数的解构赋值

函数的解构赋值使用情况不多,不易阅读,且完全可以在函数内进行,故不做多余说明。

2.6 圆括号的使用

解构赋值时,大部分情况不能使用(),可以使用圆括号的情况只有一种:赋值语句的非模式部分可以使用圆括号。故使用时,推荐直接不使用圆括号。

2.7 解构赋值的妙用

[x, y] = [y, x] // 交换变量的值
let {a, b, c} = object // 从对象中取出特点属性的值
function test({a = 1, b = 2}) {} // 设定参数的初始化值

3. 字符串扩展

字符串扩展使用较少,主要变化为UTF-8存储变为UTF-16,将2个字节存储不下的编码用4个字节去存储,写法用{}扩起来,如\u{20BB7}。同时扩展了一些对于4个字节存储的字符串的相应的方法。

3.1 扩展方法

3.1.1 s.codePointAt()返回字符串位置字符的十进制编码值。
3.1.2 s.fromCodePoint()用编码值获取对应的字符。
3.1.3 添加了字符串遍历接口for...of。相较于for循环来说,for...of可以识别两个字节存储的字符,长度不会出错。但不能记录循环的索引,需要自己处理。
3.1.4 s.at()返回索引位置的字符,可以处理UTF-16,chatAt只能处理UTF-8。
3.1.5 s.includes()类似于s.indexOf(),返回布尔值,表示是否找到该字符串。第二个字符串表示检测开始位置。
3.1.6 s.startsWith()返回布尔值,表示参数字符串是否在源字符串头部。第二个字符串表示检测开始位置。
3.1.7 s.endsWith()返回布尔值,表示参数字符串是否在源字符串结尾。第二个字符串表示检测开始位置。
3.1.8 s.repeat()返回新字符串,将源字符串重复n次。
3.1.9 s.padStart()返回新字符串,字符串头补全。x.padStart(4, 'ab') // abax
3.1.10 s.padEnd()返回新字符串,字符串尾补全。
3.1.11 反引号模板。${}用于变量传参。${}内的表达式会执行eval操作。

4. 正则扩展

正则表达式在ES6内,构造函数RegExp从值接受字符串作为参数,变为可接受正则表达式作为参数。
matchreplacesearchsplit方法添加到RegExp实例上。
添加u修饰符,用于对UTF-16编码的识别。添加y修饰符,类似于g修饰符,不过y修饰符每次匹配都是从上次匹配的头开始匹配,自带^匹配。
正则对象添加sticky属性,用于记录正则对象是否设置了y修饰符。
正则对象添加flags属性,返回正则对象的修饰符。
正则对象中有source属性,用于返回正常表达式的正文。

5. 数值扩展

二进制0b,八进制0o,十六进制0x
Number.isFinite()返回数值是否非无穷。除非无穷数值外,其余均返回false
Number.isNaN()返回数值是否是NaN
Number.parseInt()parseInt()
Number.parseFloat()parseFloat()
Number.isInteger()判断数值是否是整数。
添加Number.EPSILON常量,表示很小的可接受的误差范围。
Number.isSafeInteger()判断是否是安全整数,-2^53-2^53之间。
Math.trunc()返回一个数的整数部分。
Math.sign()判断一个数是整数、负数、还是0。Math.sign(1) == 1; Math.sign(-1) == -1; Math.sign(0) == 0; Math.sign(-0) == 0; Math.sign('x') == NaN
Math对象上还新增了一些其他方法,如三角函数、立方等。
新增**指数运算符,2 ** 3 // 8

6. 数组扩展

6.1 Array.from(),真数组变化

Array.from()将类数组对象与可遍历对象转化为真数组。要求类数组对象要有length属性。该方法还可以接受第二个参数,类似于map方法,用于对每个元素进行处理,将处理后的值放入返回数组。

let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
}
let newSet = new Set(['a', 'b', 'a'])
var arr1 = [].slice.call(arrayLike) // ['a', 'b', 'c']
var arr2 = Array.from(arrayLike) // ['a', 'b', 'c']
var arr3 = Array.from(newSet) // ['a', 'b']
var arr4 = Array.from('hello') // ['h', 'e', 'l', 'l', 'o']
Array.from([1, 2, 3], (x) => x * x) // [1, 4, 9]
function countSymbols(str) { // 避免js将UTF-16的字符算为2个字符长度
    return Array.from(str).length
}

6.2 Array.of()将一组数值转化为数组

注意同Array()的区别。

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

6.3 Array.prototype.copyWithin(targetIndex, copyStart, copyEnd)数组内部复制

将数组从targetIndex位置,用copyStart(默认为0)位置到copyEnd(默认为数组长度)位置的内容进行覆盖。

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

6.4 数组实例的find()findIndex()方法

find()用于找出第一个符合条件的数组成员,并返回该成员,不存在则返回undefinedfindIndex()用于找出第一个符合条件的数组成员的索引,不存在则返回-1。

let arr = [1, 4, -5, 10]
console.log(arr.find((value, index, arr) => value < 0)) // -5
console.log(arr.findIndex((value, index, arr) => value < 0)) // 2

6.5 数组实例的fill()方法

fill(schar, startIndex, endIndex)将数组从设定位置startIndex开始(默认为0),到endIndex之前为止(默认为数组长度),用特定字符填充,会覆盖设定位置的数组值,会修改原数组。

[1, 2, 3].fill(7) // [7, 7, 7]
new Array(3).fill(7) // [7, 7, 7]

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

entries()keys()values()用于遍历数组,返回一个遍历器对象(以0,1,2,3…为键名的对象,可用for...of遍历)。keys()是对键名的遍历,values()是对键值的遍历,entries()是对键值对的遍历。感觉意义不大。

for (let index of ['a', 'b'].keys()) { console.log(index) }
for (let elem of ['a', 'b'].values()) { console.log(elem) }
for (let [index, elem] of ['a', 'b'].entries()) { console.log(index, elem) } // 解构赋值

6.7 数组实例的includes()

Array.prototype.includes()返回一个布尔值,表示该数组是否包含该给定的值。类似于字符串的includes()includes()可以检测NaN

[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
[1, 2, NaN].includes(NaN) // true
[1, 2, 3].includes(2, 2) // false,第二个参数为检索起始位置

6.8 数组空位

es6后,数组空位会被处理为undefined,如Array.from()方法。

6.9 数组推导

利用for...of对现有数组遍历后做简单处理,并返回新数组的效果,类似于map方法。会看即可。

var a1 = [1, 2, 3, 4]
var a2 = [for (i of a1) i * 2] // [2, 4, 6, 8],对于返回的表达式,还可以使用if语句表达式

6.10 数组实例遍历方法回顾

every()对数组中每一项进行处理,若函数每一项都返回true,则表达式返回true
filter()对数组中每一项进行处理,函数返回返回值为true的项目的数组;
forEach()对数组中每一项进行处理,无返回值,单纯遍历处理;
map()对数组中每一项进行处理,函数返回返回值构成的数组;
some()对数组中每一项进行处理,若函数任意一项返回true,则表达式返回true

6.11 数组其余常用方法

push()往数组后添加数据,返回数组长度;
pop()数组末尾出队列,返回出队列项;
shift()数组头出队列,返回出队列项;
unshift()数组头入队列,返回数组长度;
sort()数组排序,返回值大于0,升序;小于0,降序;
reverse()数组顺序翻转;
concat()数组合并或者添加项到末尾,返回新数组;
slice()数组截取,返回指定位置的数组;
splice()数组删除或者修改,返回删除掉的片段数组;
reduce()数组正向归并,有四个参数,第一个为上一个处理的返回值,第二个为当前值,第三个为当前索引,第四个为数组对象;
reduceRight()数组反向归并,有四个参数,第一个为上一个处理的返回值,第二个为当前值,第三个为当前索引,第四个为数组对象;
indexOf()查找数组内对象,返回查找到的索引值或-1,不能查找NaN;

TO BE CONTINUED!