Skip to content

Commit 6c33968

Browse files
committed
edit string & promise
1 parent 8ef1e5a commit 6c33968

File tree

5 files changed

+220
-66
lines changed

5 files changed

+220
-66
lines changed

docs/arraybuffer.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
# 二进制数组
22

3-
二进制数组(ArrayBuffer对象、TypedArray对象、DataView对象)是JavaScript操作二进制数据的一个接口。这些对象早就存在,属于独立的规格,ES6将它们纳入了ECMAScript规格,并且增加了新的方法。
3+
二进制数组(ArrayBuffer对象、TypedArray视图和DataView视图)是JavaScript操作二进制数据的一个接口。这些对象早就存在,属于独立的规格,ES6将它们纳入了ECMAScript规格,并且增加了新的方法。
44

55
这个接口的原始设计目的,与WebGL项目有关。所谓WebGL,就是指浏览器与显卡之间的通信接口,为了满足JavaScript与显卡之间大量的、实时的数据交换,它们之间的数据通信必须是二进制的,而不能是传统的文本格式。文本格式传递一个32位整数,两端的JavaScript脚本与显卡都要进行格式转化,将非常耗时。这时要是存在一种机制,可以像C语言那样,直接操作字节,将4个字节的32位整数,以二进制形式原封不动地送入显卡,脚本的性能就会大幅提升。
66

77
二进制数组就是在这种背景下诞生的。它很像C语言的数组,允许开发者以数组下标的形式,直接操作内存,大大增强了JavaScript处理二进制数据的能力,使得开发者有可能通过JavaScript与操作系统的原生接口进行二进制通信。
88

9-
二进制数组由三个对象组成
9+
二进制数组由三类对象组成
1010

1111
**(1)ArrayBuffer对象**:代表内存之中的一段二进制数据,可以通过“视图”进行操作。“视图”部署了数组接口,这意味着,可以用数组的方法操作内存。
1212

13-
**(2) TypedArray对象**用来生成内存的视图,通过9个构造函数,可以生成9种数据格式的视图,比如Uint8Array(无符号8位整数)数组视图, Int16Array(16位整数)数组视图, Float32Array(32位浮点数)数组视图等等。
13+
**(2) TypedArray视图**共包括9种类型的视图,比如Uint8Array(无符号8位整数)数组视图, Int16Array(16位整数)数组视图, Float32Array(32位浮点数)数组视图等等。
1414

15-
**(3)DataView对象**用来生成内存的视图,可以自定义格式和字节序,比如第一个字节是Uint8(无符号8位整数)、第二、三个字节是Int16(16位整数)、第四个字节开始是Float32(32位浮点数)等等。
15+
**(3)DataView视图**可以自定义复合格式的视图,比如第一个字节是Uint8(无符号8位整数)、第二、三个字节是Int16(16位整数)、第四个字节开始是Float32(32位浮点数)等等,此外还可以自定义字节序
1616

17-
简单说,ArrayBuffer对象代表原始的二进制数据,TypedArray对象代表确定类型的二进制数据,DataView对象代表不确定类型的二进制数据。它们支持的数据类型一共有9种(DataView对象支持除Uint8C以外的其他8种)。
17+
简单说,ArrayBuffer对象代表原始的二进制数据,TypedArray视图用来读写简单类型的二进制数据,DataView视图用来读写复杂类型的二进制数据。
18+
19+
TypedArray视图支持的数据类型一共有9种(DataView视图支持除Uint8C以外的其他8种)。
1820

1921
数据类型 | 字节长度 | 含义 | 对应的C语言类型
2022
--------|--------|----|---------------
@@ -134,13 +136,13 @@ var v = new Int32Array(buffer);
134136
ArrayBuffer.isView(v) // true
135137
```
136138

137-
## TypedArray对象
139+
## TypedArray视图
138140

139141
### 概述
140142

141-
`ArrayBuffer`对象作为内存区域,可以存放多种类型的数据。同一段内存,不同数据有不同的解读方式,这就叫做“视图”(view)。`ArrayBuffer`有两种视图,一种是TypedArray视图,另一种是DataView视图,两者的区别主要是字节序,前者的数组成员都是同一个数据类型,后者的数组成员可以是不同的数据类型。
143+
`ArrayBuffer`对象作为内存区域,可以存放多种类型的数据。同一段内存,不同数据有不同的解读方式,这就叫做“视图”(view)。`ArrayBuffer`有两种视图,一种是TypedArray视图,另一种是DataView视图前者的数组成员都是同一个数据类型,后者的数组成员可以是不同的数据类型。
142144

143-
目前,TypedArray对象一共提供9种类型的视图,每一种视图都是一种构造函数。
145+
目前,TypedArray视图一共包括9种类型,每一种视图都是一种构造函数。
144146

145147
- **Int8Array**:8位有符号整数,长度1个字节。
146148
- **Uint8Array**:8位无符号整数,长度1个字节。
@@ -152,7 +154,7 @@ ArrayBuffer.isView(v) // true
152154
- **Float32Array**:32位浮点数,长度4个字节。
153155
- **Float64Array**:64位浮点数,长度8个字节。
154156

155-
这9个构造函数生成的对象,统称为TypedArray对象。它们很像普通数组,都有`length`属性,都能用方括号运算符(`[]`)获取单个元素,所有数组的方法,在TypedArray数组上面都能使用。普通数组与TypedArray数组的差异主要在以下方面。
157+
这9个构造函数生成的数组,统称为TypedArray视图。它们很像普通数组,都有`length`属性,都能用方括号运算符(`[]`)获取单个元素,所有数组的方法,在它们上面都能使用。普通数组与TypedArray数组的差异主要在以下方面。
156158

157159
- `TypedArray`数组的所有成员,都是同一种类型。
158160
- `TypedArray`数组的成员是连续的,不会有空位。

docs/iterator.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ yield*后面跟的是一个可遍历的结构,它会调用该结构的遍历
322322
```javascript
323323
let generator = function* () {
324324
yield 1;
325-
yield* [2,3,4]; //use an iterable, is looped, and added as yields
325+
yield* [2,3,4];
326326
yield 5;
327327
};
328328

docs/module.md

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,29 @@ import { stat, exists, readFile } from 'fs';
2222

2323
上面代码的实质是从`fs`模块加载3个方法,其他方法不加载。这种加载称为“编译时加载”,即ES6可以在编译时就完成模块编译,效率要比CommonJS模块的加载方式高。
2424

25-
需要注意的是,ES6的模块自动采用严格模式,不管你有没有在模块头部加上`"use strict"`
25+
## 严格模式
26+
27+
ES6的模块自动采用严格模式,不管你有没有在模块头部加上`"use strict"`
28+
29+
严格模式主要有以下限制。
30+
31+
- 变量必须声明后再使用
32+
- 函数的参数不能有同名属性,否则报错
33+
- 不能使用`with`语句
34+
- 不能对只读属性赋值,否则报错
35+
- 不能使用前缀0表示八进制数,否则报错
36+
- 不能删除不可删除的属性,否则报错
37+
- 不能删除变量`delete prop`,会报错,只能删除属性`delete global[prop]`
38+
- `eval`不会在它的外层作用域引入变量
39+
- `eval``arguments`不能被重新赋值
40+
- `arguments`不会自动反映函数参数的变化
41+
- 不能使用`arguments.callee`
42+
- 不能使用`arguments.caller`
43+
- 禁止`this`指向全局对象
44+
- 不能使用`fn.caller``fn.arguments`获取函数调用的堆栈
45+
- 增加了保留字(比如`protected``static``interface`
46+
47+
上面这些限制,模块都必须遵守。
2648

2749
## export命令
2850

@@ -60,9 +82,9 @@ export function multiply (x, y) {
6082
};
6183
```
6284

63-
上面代码对外输出一个函数multiply
85+
上面代码对外输出一个函数`multiply`
6486

65-
通常情况下,export输出的变量就是本来的名字,但是可以使用as关键字重命名
87+
通常情况下,`export`输出的变量就是本来的名字,但是可以使用`as`关键字重命名
6688

6789
```javascript
6890
function v1() { ... }
@@ -79,6 +101,24 @@ export {
79101

80102
最后,`export`命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错,下面的`import`命令也是如此。
81103

104+
```javascript
105+
function foo () {
106+
export default 'bar' // SyntaxError
107+
}
108+
foo()
109+
```
110+
111+
上面代码中,`export`语句放在函数之中,结果报错。
112+
113+
`export`语句输出的值是动态绑定,绑定其所在的模块。
114+
115+
```javascript
116+
export var foo = 'bar';
117+
setTimeout(() => foo = 'baz', 500);
118+
```
119+
120+
上面代码输出变量`foo`,值为`bar`,500毫秒之后变成`baz`
121+
82122
## import命令
83123

84124
使用`export`命令定义了模块的对外接口以后,其他JS文件就可以通过`import`命令加载这个模块(文件)。
@@ -139,6 +179,14 @@ export v from "mod";
139179
export {v} from "mod";
140180
```
141181

182+
`import`语句会执行所加载的模块,因此可以有下面的写法。
183+
184+
```javascript
185+
import 'lodash'
186+
```
187+
188+
上面代码仅仅执行`lodash`模块,但是不输入任何值。
189+
142190
## 模块的整体加载
143191

144192
除了指定加载某个输出值,还可以使用整体加载,即用星号(`*`)指定一个对象,所有输出值都加载在这个对象上面。

docs/promise.md

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,23 @@ var p2 = new Promise(function(resolve, reject){
134134
})
135135
```
136136

137-
上面代码中,p1和p2都是Promise的实例,但是p2的resolve方法将p1作为参数,即一个异步操作的结果是返回另一个异步操作。
137+
上面代码中,`p1``p2`都是Promise的实例,但是`p2``resolve`方法将`p1`作为参数,即一个异步操作的结果是返回另一个异步操作。
138138

139-
注意,这时p1的状态就会传递给p2,也就是说,p1的状态决定了p2的状态。如果p1的状态是Pending,那么p2的回调函数就会等待p1的状态改变;如果p1的状态已经是Resolved或者Rejected,那么p2的回调函数将会立刻执行。
139+
注意,这时`p1`的状态就会传递给`p2`,也就是说,`p1`的状态决定了`p2`的状态。如果`p1`的状态是`Pending`,那么`p2`的回调函数就会等待`p1`的状态改变;如果`p1`的状态已经是`Resolved`或者`Rejected`,那么`p2`的回调函数将会立刻执行。
140+
141+
```javascript
142+
var p1 = new Promise(function (resolve, reject) {
143+
setTimeout(() => reject(new Error('fail')), 3000)
144+
})
145+
var p2 = new Promise(function (resolve, reject) {
146+
setTimeout(() => resolve(p1), 1000)
147+
})
148+
p2.then(result => console.log(result))
149+
p2.catch(error => console.log(error))
150+
// Error: fail
151+
```
152+
153+
上面代码中,`p1`是一个Promise,3秒之后变为`rejected``p2`的状态由`p1`决定,1秒之后,`p2`调用`resolve`方法,但是此时`p1`的状态还没有改变,因此`p2`的状态也不会变。又过了2秒,`p1`变为`rejected``p2`也跟着变为`rejected`
140154

141155
## Promise.prototype.then()
142156

@@ -349,19 +363,19 @@ someAsyncThing().then(function() {
349363
350364
## Promise.all()
351365
352-
Promise.all方法用于将多个Promise实例,包装成一个新的Promise实例。
366+
`Promise.all`方法用于将多个Promise实例,包装成一个新的Promise实例。
353367
354368
```javascript
355369
var p = Promise.all([p1,p2,p3]);
356370
```
357371
358-
上面代码中,Promise.all方法接受一个数组作为参数,p1、p2、p3都是Promise对象的实例。(Promise.all方法的参数不一定是数组,但是必须具有iterator接口,且返回的每个成员都是Promise实例。)
372+
上面代码中,`Promise.all`方法接受一个数组作为参数,`p1`、`p2`、`p3`都是Promise对象的实例,如果不是,就会先调用下面讲到的`Promise.resolve`方法,将参数转为Promise实例,再进一步处理。(`Promise.all`方法的参数不一定是数组,但是必须具有iterator接口,且返回的每个成员都是Promise实例。)
359373
360-
p的状态由p1、p2、p3决定,分成两种情况。
374+
`p`的状态由`p1`、`p2`、`p3`决定,分成两种情况。
361375
362-
(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数
376+
(1)只有`p1`、`p2`、`p3`的状态都变成`fulfilled`,`p`的状态才会变成`fulfilled`,此时`p1`、`p2`、`p3`的返回值组成一个数组,传递给`p`的回调函数
363377
364-
(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数
378+
(2)只要`p1`、`p2`、`p3`之中有一个被`rejected`,`p`的状态就变成`rejected`,此时第一个被`reject`的实例的返回值,会传递给`p`的回调函数
365379
366380
下面是一个具体的例子。
367381
@@ -379,15 +393,30 @@ Promise.all(promises).then(function(posts) {
379393
```
380394
## Promise.race()
381395
382-
Promise.race方法同样是将多个Promise实例,包装成一个新的Promise实例。
396+
`Promise.race`方法同样是将多个Promise实例,包装成一个新的Promise实例。
383397
384398
```javascript
385399
var p = Promise.race([p1,p2,p3]);
386400
```
387401
388-
上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的Promise实例的返回值,就传递给p的回调函数。
402+
上面代码中,只要`p1`、`p2`、`p3`之中有一个实例率先改变状态,`p`的状态就跟着改变。那个率先改变的Promise实例的返回值,就传递给`p`的回调函数。
403+
404+
`Promise.race`方法的参数与`Promise.all`方法一样,如果不是Promise实例,就会先调用下面讲到的`Promise.resolve`方法,将参数转为Promise实例,再进一步处理。
405+
406+
下面是一个例子,如果指定时间内没有获得结果,就将Promise的状态变为`reject`,否则变为`resolve`。
407+
408+
```javascript
409+
var p = Promise.race([
410+
fetch('/resource-that-may-take-a-while'),
411+
new Promise(function (resolve, reject) {
412+
setTimeout(() => reject(new Error('request timeout')), 5000)
413+
})
414+
])
415+
p.then(response => console.log(response))
416+
p.catch(error => console.log(error))
417+
```
389418
390-
如果Promise.all方法和Promise.race方法的参数,不是Promise实例,就会先调用下面讲到的Promise.resolve方法,将参数转为Promise实例,再进一步处理
419+
上面代码中,如果5秒之内`fetch`方法无法返回结果,变量`p`的状态就会变为`rejected`,从而触发`catch`方法指定的回调函数
391420
392421
## Promise.resolve()
393422
@@ -397,7 +426,15 @@ var p = Promise.race([p1,p2,p3]);
397426
var jsPromise = Promise.resolve($.ajax('/whatever.json'));
398427
```
399428
400-
上面代码将jQuery生成deferred对象,转为一个新的Promise对象。
429+
上面代码将jQuery生成的`deferred`对象,转为一个新的Promise对象。
430+
431+
`Promise.resolve`等价于下面的写法。
432+
433+
```javascript
434+
Promise.resolve('foo')
435+
// 等价于
436+
new Promise(resolve => resolve('foo'))
437+
```
401438
402439
如果Promise.resolve方法的参数,不是具有then方法的对象(又称thenable对象),则返回一个新的Promise对象,且它的状态为Resolved。
403440
@@ -428,17 +465,17 @@ p.then(function () {
428465
429466
## Promise.reject()
430467
431-
Promise.reject(reason)方法也会返回一个新的Promise实例,该实例的状态为rejected。Promise.reject方法的参数reason,会被传递给实例的回调函数。
468+
`Promise.reject(reason)`方法也会返回一个新的Promise实例,该实例的状态为`rejected`。`Promise.reject`方法的参数`reason`,会被传递给实例的回调函数。
432469
433470
```javascript
434-
435471
var p = Promise.reject('出错了');
472+
// 等同于
473+
var p = new Promise((resolve, reject) => reject('foo'))
436474
437475
p.then(null, function (s){
438476
console.log(s)
439477
});
440478
// 出错了
441-
442479
```
443480
444481
上面代码生成一个Promise对象的实例p,状态为rejected,回调函数会立即执行。

0 commit comments

Comments
 (0)