Skip to content

Commit cb02581

Browse files
committed
docs(proposals): 增加 最新提案 一章
1 parent eefe534 commit cb02581

File tree

4 files changed

+120
-62
lines changed

4 files changed

+120
-62
lines changed

docs/function.md

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,41 +1329,3 @@ clownsEverywhere(
13291329

13301330
这样的规定也使得,函数参数与数组和对象的尾逗号规则,保持一致了。
13311331

1332-
## catch 语句的参数
1333-
1334-
ES2018 [允许](https://github.com/tc39/proposal-optional-catch-binding)`try...catch`结构的`catch`语句不带有参数。这个提案跟参数有关,也放在这一章介绍。
1335-
1336-
传统的写法是`catch`语句必须带有参数,用来接收`try`代码块抛出的错误。
1337-
1338-
```javascript
1339-
try {
1340-
// ···
1341-
} catch (error) {
1342-
// ···
1343-
}
1344-
```
1345-
1346-
上面代码中,即使没有用到`error`,传统写法也是不允许省略。
1347-
1348-
新的写法允许省略`catch`后面的参数,而不报错。
1349-
1350-
```javascript
1351-
try {
1352-
// ···
1353-
} catch {
1354-
// ···
1355-
}
1356-
```
1357-
1358-
新写法只在不需要错误实例的情况下有用,因此不及传统写法的用途广。
1359-
1360-
```javascript
1361-
let jsonData;
1362-
try {
1363-
jsonData = JSON.parse(str);
1364-
} catch {
1365-
jsonData = DEFAULT_DATA;
1366-
}
1367-
```
1368-
1369-
上面代码中,`JSON.parse`报错只有一种可能:解析失败。所以一旦报错,基本上不需要用到错误实例,所以可以省略`catch`后面的参数。

docs/let.md

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -435,30 +435,6 @@ if (true)
435435
function f() {}
436436
```
437437

438-
### do 表达式
439-
440-
本质上,块级作用域是一个语句,将多个操作封装在一起,没有返回值。
441-
442-
```javascript
443-
{
444-
let t = f();
445-
t = t * t + 1;
446-
}
447-
```
448-
449-
上面代码中,块级作用域将两个语句封装在一起。但是,在块级作用域以外,没有办法得到`t`的值,因为块级作用域不返回值,除非`t`是全局变量。
450-
451-
现在有一个[提案](http://wiki.ecmascript.org/doku.php?id=strawman:do_expressions),使得块级作用域可以变为表达式,也就是说可以返回值,办法就是在块级作用域之前加上`do`,使它变为`do`表达式,然后就会返回内部最后执行的表达式的值。
452-
453-
```javascript
454-
let x = do {
455-
let t = f();
456-
t * t + 1;
457-
};
458-
```
459-
460-
上面代码中,变量`x`会得到整个块级作用域的返回值(`t * t + 1`)。
461-
462438
## const 命令
463439

464440
### 基本用法

docs/proposals.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# 最新提案
2+
3+
本章介绍一些尚未进入标准、但很有希望的最新提案。
4+
5+
## do 表达式
6+
7+
本质上,块级作用域是一个语句,将多个操作封装在一起,没有返回值。
8+
9+
```javascript
10+
{
11+
let t = f();
12+
t = t * t + 1;
13+
}
14+
```
15+
16+
上面代码中,块级作用域将两个语句封装在一起。但是,在块级作用域以外,没有办法得到`t`的值,因为块级作用域不返回值,除非`t`是全局变量。
17+
18+
现在有一个[提案](https://github.com/tc39/proposal-do-expressions),使得块级作用域可以变为表达式,也就是说可以返回值,办法就是在块级作用域之前加上`do`,使它变为`do`表达式,然后就会返回内部最后执行的表达式的值。
19+
20+
```javascript
21+
let x = do {
22+
let t = f();
23+
t * t + 1;
24+
};
25+
```
26+
27+
上面代码中,变量`x`会得到整个块级作用域的返回值(`t * t + 1`)。
28+
29+
`do`表达式的逻辑非常简单:封装的是什么,就会返回什么。
30+
31+
```javascript
32+
// 等同于 <表达式>
33+
do { <表达式>; }
34+
35+
// 等同于 <语句>
36+
do { <语句> }
37+
```
38+
39+
`do`表达式的好处是可以封装多个语句,让程序更加模块化,就像乐高积木那样一块块拼装起来。
40+
41+
```javascript
42+
let x = do {
43+
if (foo()) { f() }
44+
else if (bar()) { g() }
45+
else { h() }
46+
};
47+
```
48+
49+
上面代码的本质,就是根据函数`foo`的执行结果,调用不同的函数,将返回结果赋给变量`x`。使用`do`表达式,就将这个操作的意图表达得非常简洁清晰。而且,`do`块级作用域提供了单独的作用域,内部操作可以与全局作用域隔绝。
50+
51+
值得一提的是,`do`表达式在 JSX 语法中非常好用。
52+
53+
```javascript
54+
return (
55+
<nav>
56+
<Home />
57+
{
58+
do {
59+
if (loggedIn) {
60+
<LogoutButton />
61+
} else {
62+
<LoginButton />
63+
}
64+
}
65+
}
66+
</nav>
67+
)
68+
```
69+
70+
上面代码中,如果不用`do`表达式,就只能用三元判断运算符(`?:`)。那样的话,一旦判断逻辑复杂,代码就会变得很不易读。
71+
72+
## throw 表达式
73+
74+
JavaScript 语法规定`throw`是一个命令,用来抛出错误,不能用于表达式之中。
75+
76+
```javascript
77+
// 报错
78+
console.log(throw new Error());
79+
```
80+
81+
上面代码中,`console.log`的参数必须是一个表达式,如果是一个`throw`语句就会报错。
82+
83+
现在有一个[提案](https://github.com/tc39/proposal-throw-expressions),允许`throw`用于表达式。
84+
85+
```javascript
86+
// 参数的默认值
87+
function save(filename = throw new TypeError("Argument required")) {
88+
}
89+
90+
// 箭头函数的返回值
91+
lint(ast, {
92+
with: () => throw new Error("avoid using 'with' statements.")
93+
});
94+
95+
// 条件表达式
96+
function getEncoder(encoding) {
97+
const encoder = encoding === "utf8" ?
98+
new UTF8Encoder() :
99+
encoding === "utf16le" ?
100+
new UTF16Encoder(false) :
101+
encoding === "utf16be" ?
102+
new UTF16Encoder(true) :
103+
throw new Error("Unsupported encoding");
104+
}
105+
106+
// 逻辑表达式
107+
class Product {
108+
get id() {
109+
return this._id;
110+
}
111+
set id(value) {
112+
this._id = value || throw new Error("Invalid value");
113+
}
114+
}
115+
```
116+
117+
上面代码中,`throw`都出现在表达式里面。
118+
119+
语法上,`throw`表达式里面的`throw`不再是一个命令,而是一个运算符。为了避免与`throw`命令混淆,规定`throw`出现在行首,一律解释为`throw`语句,而不是`throw`表达式。

sidebar.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
1. [编程风格](#docs/style)
3333
1. [读懂规格](#docs/spec)
3434
1. [ArrayBuffer](#docs/arraybuffer)
35+
1. [最新提案](#docs/proposals)
3536
1. [参考链接](#docs/reference)
3637

3738
## 其他

0 commit comments

Comments
 (0)