Skip to content

Latest commit

 

History

History
109 lines (78 loc) · 3.67 KB

10.4.md

File metadata and controls

109 lines (78 loc) · 3.67 KB

10.4 模式是如何获取到内部的数据的?

在赋值中 pattern = someValuepattern 是如何获取 someValue 内部的数据的?

10.4.1 对象模式必须要数据是对象

在获取属性之前,对象模式将源解构成对象。这意味着解构对原始值也有效:

let {length : len} = 'abc'; // len = 3
let {toString: s} = 123; // s = Number.prototype.toString

10.4.1.1 对象解构过程中,值转换失败

转换成对象的过程不是通过 Object() 的,而是通过内部的 ToObject() 操作。 Object() 从不失败:

> typeof Object('abc')
'object'
> var obj = {};
> Object(obj) === obj
true
> Object(undefined)
{}
> Object(null)
{}

如果转换目标是 undefined 或者 null ,则 ToObject() 会抛出一个 TypeError 异常。因此,下面的解构过程在获取属性之前就失败了:

let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError

因此,可以使用空的对象模式 {} 去检测一个值在解构过程中是否可转换成一个对象。就像上面看见的,仅 undefinednull 不能转换:

({} = [true, false]); // OK, Arrays are coercible to objects
({} = 'abc'); // OK, strings are coercible to objects

({} = undefined); // TypeError
({} = null); // TypeError

表达式两侧的括号是必要的,因为在 JavaScript 中语句不能以大括号开始。

10.4.2 数组模式通过可迭代工作

数组解构使用迭代器获取源的元素。因此,可以用数组的方式解构任何一个可迭代的值。让我们看一看可迭代的值的示例。

字符串是可迭代的:

let [x,...y] = 'abc'; // x='a'; y=['b', 'c']

别忘了,字符串的迭代器返回代码点( code points )(“ Unicode 字符”,21位),而不是代码单元(“ JavaScript 字符”,16位)。(更多关于 Unicode 的信息,参考“ Speaking JavaScript ”的“ Chapter 24. Unicode and JavaScript ”章)例如:

let [x,y,z] = 'a\uD83D\uDCA9c'; // x='a'; y='\uD83D\uDCA9'; z='c'

不能通过索引下标获取一个 Set 集合的元素,但是可以通过迭代器获取。因为,数组解构对 Set 有效:

let [x,y] = new Set(['a', 'b']); // x='a'; y='b’;

Set 迭代器返回元素的顺序与元素插入的顺序一致,这就是为什么上述的解构结果总是一样的。

无穷序列。解构同样对无穷序列有效。生成器函数 allNaturalNumbers() 返回一个迭代器,生成0,1,2,...。

function* allNaturalNumbers() {
  for (let n = 0; ; n++) {
    yield n;
  }
}

下面的解构获取该无穷序列前面的三个元素。

let [x, y, z] = allNaturalNumbers(); // x=0; y=1; z=2

10.4.2.1 数组解构过程中,值转换失败

如果一个值有一个方法,该方法有一个键是 Symbol.iterator ,键值是一个对象,那么该值就是可迭代的。如果要解构的对象不可迭代,那么数组解构时就会抛出 TypeError 错误:

let x;
[x] = [true, false]; // OK, Arrays are iterable
[x] = 'abc'; // OK, strings are iterable
[x] = { * [Symbol.iterator]() { yield 1 } }; // OK, iterable

[x] = {}; // TypeError, empty objects are not iterable
[x] = undefined; // TypeError, not iterable
[x] = null; // TypeError, not iterable

在获取迭代元素之前 TypeError 异常就会抛出,这意味着可以使用空的数组模式 [] 来检查一个值是否可迭代:

[] = {}; // TypeError, empty objects are not iterable
[] = undefined; // TypeError, not iterable
[] = null; // TypeError, not iterable