3. 结构赋值

"Hello World, Hello Blog"

Posted by wudimingwo on December 15, 2018

#阮一峰-变量的解构赋值 大神写得算是相当的友好了. 我感觉基本都不用写笔记了.

把不会的大概记一下.

##数组的结构

  1. new Set([]) 是个什么东西?
    1
    2
    
    let [x, y, z] = new Set(['a', 'b', 'c']);
    x // "a"
    

2. yield ? fuction* ? ``` function* fibs() { let a = 0; let b = 1; while (true) { yield a; [a, b] = [b, a + b]; } }

let [first, second, third, fourth, fifth, sixth] = fibs(); sixth // 5

1
2
3
> ## 对象的结构
这里要注意, `:`可以省略, 但心中一定要把这个冒号补全.

let { foo: foo, bar: bar } = { foo: “aaa”, bar: “bbb” };

1
2
3
4
5
6
> 对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
> 记住= 后面的没有变量, 都是值, 对象,数组,字符串
> = 前面有变量, 但所有形式都是模式.
> : 前面的都是模式, 类似房间号, 而不是变量
> : 后面的才是变量.
> 所以必须找准哪个是变量.哪个是模式, 哪个是值,(哪个又是默认值)

let { foo: baz } = { foo: “aaa”, bar: “bbb” }; baz // “aaa” foo // error: foo is not defined

1
2
3
> 下面语句是否会报错?
> 不会

let {x} = {x: 1};

1
2
3
> 下面语句是否会报错?
> 会

// 错误的写法 let x; {x} = {x: 1}; // SyntaxError: syntax error

1
2
3
4
5
6
7
> 因为 JavaScript 引擎会将{x}理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。

> 问题 { } 能代表的含义有哪些?
> 1. 对象 比如 let obj = {name : 123}
> 2. 代码块 如function () {代码块},if(){代码块},for(){代码块}
> 3. 模式, 类似对象, 用于结构赋值 比如 let {x} = {x: 1};

// 正确的写法 let x; ({x} = {x: 1});

1
2
3
4
5
6
------------
## 字符串的结构赋值
-------------
## 数值和布尔值的结构赋值
> 会把123 先转为 Number(123)
> 把 true 先转为 Boolean(true)

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

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

1
2
3
------------------
函数参数的结构赋值

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

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

一定要分清, 哪些是变量, 哪些是模式, 哪些是传进来的值,默认值

1
> 下面这两个比较,就真的是相当的秀了

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

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

1
> 这个好理解,再看下面的 

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

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

1
2
3
4
5
6
> 原文说的是: 上面代码是为函数move的参数指定默认值,而不是为变量x和y指定默认值,所以会得到与前一种写法不同的结果。
> 合理啊, 因为第一种,我们用的是多重默认值,
第二种,我们只对第一层做了默认值.
> 换言之, 我们可以设置多层的默认值. 这就他娘的读起来也挺费劲的.


1
2
3
  function move({x = 1, y = 1} = { x: 0, y: 0 }) {
    return [x, y];
  } ``` > 但如果我们像上面这么写, x = 1,y = 1 这两个默认值是永远也不会被触发的. > 也就是说, 默认值这个东西是, 外层的会覆盖里层的. > 也就是说, 我们设置默认值的时候, 一定要稍微注意一下

##可以使用圆括号的情况 可以使用圆括号的情况只有一种:赋值语句的非模式部分,可以使用圆括号。

1
2
3
[(b)] = [3]; // 正确
({ p: (d) } = {}); // 正确
[(parseInt.prop)] = [3]; // 正确