ES6语法快速入门(2)| 青训营笔记

129 阅读6分钟

这是我参与「第四届青训营 」笔记创作活动的的第5天

ES6快速入门(2)

接上文介绍到对象的解构赋值

变量的解构赋值

对象的解构赋值

解构不仅可以用到数组,还可以用于对象

let [foo,  bar] = {foo: 'aa', bar: 'bb'};

foo // aa
bar // bb

对象的解构与数组有一个重要的不同, 数组的元素是按次序排列的,变量的取值是由它的位置决定的; 而对象的属性没有次序的,变量必须与属性同名才能取到正确的值。

let [bar, foo] =  {foo: 'aa', bar: 'bb'};

foo // "aa"
bar // 'bb'

let [baz] =  {foo: 'aa', bar: 'bb'};

baz // undefined

如果变量名与属性名不一致,必须写成下面这样。

let [foo: baz] =  {foo: 'aa', bar: 'bb'};

baz //  'aa'

复杂嵌套的对象解构,如下代码演示

var node = {
    loc : {
        start:{
            line:1,
            column: 5
        }
    }
};

let {loc, loc: {start}, loc:{start:{line}} } = node;

line // 1 
loc // Object {start: Object}
start // Object {line:1, column: 5}

总之对象解构赋值,匹配原则是

只针对于左侧的解构

  1. 如果是仅有一个变量名,比如上述的loc,相当于loc : loc,在右侧对象中找到为loc的值,赋值给loc
  2. 如果有变量名和相应的映射,比如上述的foo: baz,先在右侧对象中找到foo的值,再赋值给baz
  3. 嵌套的对象解构赋值,看最深层的赋值,比如上述的loc : {start:{line}} , 根据这个匹配规则,逐步在右侧node.loc => node.loc.start => node.loc.start.line,并赋值给line(因为没有相应的映射变量名)

对象解构的默认值设置:

默认值与数组的默认值,几乎相同,默认值生效条件也是对象的属性值严格等于undefined

字符串的解构赋值

字符串也可以解构赋值。 这是因为此时字符串被转换成了一个类似数组的对象。

const [a, b, c, d, e] = 'hello';

a // 'h'
b // 'e'
c // 'l'
d // 'l'
e // 'o'

类似数组的对象都有一个length 属性, 因此还可以对这个属性进行解构赋值。

let {length : len} = 'hello'
len // 5

数值和布尔值的解构和赋值

解构赋值时,如果等号右边是数值和布尔值,则会先转换为对象。

let {toString: s} = 123;

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

s === Boolean.prototype.toString // true

解构赋值的规则是, 只要等号右边的值不是对象或数组, 就先将其转换为对象。

由于undefined 和 null 无法转换为对象或数组,所以对他们无法进行解构赋值

函数参数的解构赋值

函数的参数也可以使用解构赋值的方式

function add([x,y]){
    return x + y;
}

add([1,2]); // 3

上述代码中,当函数add 的参数表面上是一个数组,但在传入参数的那一刻,数组参数就被解构成变量x和y。

对于函数内部的代码来说,它们能使用的参数就是x 和y

函数参数的解构也可以使用默认值

function move({x = 0, y = 0} = {}){
    return [x,y];
}

move({x: 3 , y : 8}); // [3,8]
move({x: 3}); // [3,0]
move({}); // [0,0]
move(); // [0,0]

圆括号() ,在解构赋值的过程中尽量不要使用。

解构赋值的用途

交换变量的值
let x = 1;
let y = 2;
[x,y] = [y,x];

上面代码交换变量x和y 的值,这样的写法不仅简洁,而且容易阅读,语义较为明了

例如: 使用递推求斐波那契数列(体现较为明显)

function fib(n){
    let [x,y] = [0,1];
    for(let i = 2;i <= n; i ++){
        [x,y] = [y,x + y];
    }
    return x;
}
从函数返回多个值

函数只能返回一个值, 如果要返回多个值,只能将它们放在数组或者对象里返回,有了解构赋值,取出这些值就极为方便了

// 返回一个数组

function example(){
    return [1,2,3];
}
函数参数的定义

解构赋值可以方便地将一组参数与变量名对应起来。

// 参数是一组 有次序的值
function f([x,y,z]){
    ...
}
f([1,2,3]) // 调用
// 参数是一组无次序的值
function f({x,y,z}){
    ...
}
f({z: 3, y: 2 , x: 1})
提取JSON数据

解构赋值与提取JSON 对象中的数据尤其有用

let jsonData = {
	id: 42,
    status: 'OK',
    data: [867, 5309]
};

let { id,  status, data: number} = jsonData;

// 42, 'OK', [867, 5309]
遍历map结构

任何部署了Iterator接口的对象都可以使用 for --- of 循环的遍历。 Map 结构 原生支持Iterator 接口,配合变量的解构赋值获取键名和键值就非常方便了

let map = new Map();
// map 里面添加键值对
map.set('first', 'hello')
map.set('second', 'world')

for(let [k, v] of map){
    console.log(k + " is " + v);
}
// first is hello
// second  is world
按需引人模块

加载模块时,往往需要指定输入的方法,解构赋值使得输入语句非常清晰

import { SourceMapConsumer } from 'source-map' 

字符串的ES6新扩展

字符串的Unicode表示

js允许采用 \uxxxx 形式表示一个字符,其中 xxxx 表示字符的Unicode 码点。

"\u0061" === "a"

这种表达方式只限于码点在0000-FFFF 之间的字符, 超出这个范围的字符,必须使用2个字节的形式表达

ES6对于这一点做出了改进,只要将码点放入大括号,就能正确解读该字符

那么有人会知道这个编码的作用是什么?

在仿掘金项目的起初,需要爬取热门文章数据,里面的文章content 部分,链接采用的是这种编码的形式,需要利用正则表达式对content里面的Unicode·部分进行解码之后,才可以正常使用

字符串的遍历器接口

ES6 为字符串添加了遍历器接口,也就是字符串可以比较顺畅地使用for ... of 循环遍历。

for(let code of "hao"){
    console.log(code);
}
// "h"
// "a"
// "o"

字符串的扩展方法

判断一个字符串是否包含在另一个字符串中

传统上,js 中只有indexof 方法可用来确定一个字符串是否包含在另一个字符串中。

调用方式:

str.indexOf(value, start);
// str 是源字符串, value是查找的字符串, start可以用来设置起始的查找位置。

// 返回的是第一次出现的位置,如果找不到返回-1

// 所以我们一般使用下面的方式判断是否存在
str.indexOf(value) != -1

ES6 又提供了3种新方法。

includes() : 返回布尔值,表示是否找到了参数字符串

startsWith(): 返回布尔值, 表示参数字符串是否在源字符串的头部。

endsWith() : 返回布尔值,表示参数字符串是否在源字符串的尾部。

代码举例:


let s = "Hello World";

s.startWith('Hello'); // true
s.endWith('world'); // true
s.includes('o'); // true

这三个方法都支持第二个参数, 表示开始搜索的位置, endsWith 表示针对前n个字符, 而其他的两个方法针对从第n个位置到字符串结束位置之间的字符。

返回一个字符串,将原字符串重复n次

repeat 方法返回一个新字符串,表示将原字符串重复n次。

'x'.repeat(3) // 'xxx'
'hello'.repeat(2) // 'hellohello'

参数如果是小数,会被取整

如果是负数或者Infinity,会报错

但如果参数是0到-1之间的小数,则等同于0,这是因为会先进行取整运算。0到-1 之间的小数取整以后等于-0,repeat 视同为0;

如果参数是字符串,则会先转换为 数字

字符串补全长度函数

ES2017 引入了字符串补全长度的功能, 如果某个字符串不够指定长度,会在头部或尾部补全。

padStart() 用于头部补全, padEnd() 用于尾部补全。

'x'.padStart(5, 'ab') // 'ababx'
'x'.padEnd(4, 'ab') // 'xaba'

分别接受两个参数,第一个参数用来指定字符串的最小长度,第二个参数则是用来补全的字符串

如果原字符串的长度大于或等于指定的最小长度, 则返回原字符串

如果用来补全的字符串与原字符串的长度之和超过了指定的最小长度, 则会截去超出位数的补全字符串

如果省略第二个参数,则会用空格来补全。