diff --git a/docs/arraybuffer.md b/docs/arraybuffer.md index 8c4e65d..08e8e8e 100644 --- a/docs/arraybuffer.md +++ b/docs/arraybuffer.md @@ -963,3 +963,88 @@ bitmap.pixels = new Uint8Array(buffer, start); ``` 至此,图像文件的数据全部处理完成。下一步,可以根据需要,进行图像变形,或者转换格式,或者展示在`Canvas`网页元素之中。 + +## SharedArrayBuffer + +目前有一种场景,需要多个进程共享数据:浏览器启动多个WebWorker。 + +```javascript +var w = new Worker('myworker.js'); +``` + +上面代码中,主窗口新建了一个 Worker 进程。该进程与主窗口之间会有一个通信渠道,主窗口通过`w.postMessage`向 Worker 进程发消息,同时通过`message`事件监听 Worker 进程的回应。 + +```javascript +w.postMessage('hi'); +w.onmessage = function (ev) { + console.log(ev.data); +} +``` + +上面代码中,主窗口先发一个消息`hi`,然后在监听到 Worker 进程的回应后,就将其打印出来。 + +Worker 进程也是通过监听`message`事件,来获取主窗口发来的消息,并作出反应。 + +```javascript +onmessage = function (ev) { + console.log(ev.data); + postMessage('ho'); +} +``` + +主窗口与 Worker 进程之间,可以传送各种数据,不仅仅是字符串,还可以传送二进制数据。很容易想到,如果有大量数据要传送,留出一块内存区域,主窗口与 Worker 进程共享,两方都可以读写,那么就会大大提高效率。 + +现在,有一个[`SharedArrayBuffer`](https://github.com/tc39/ecmascript_sharedmem/blob/master/TUTORIAL.md)提案,允许多个 Worker 进程与主窗口共享内存。这个对象的 API 与`ArrayBuffer`一模一样,唯一的区别是后者无法共享。 + +```javascript +// 新建 1KB 共享内存 +var sab = new SharedArrayBuffer(1024); + +// 主窗口发送数据 +w.postMessage(sab, [sab]) +``` + +上面代码中,`postMessage`方法的第一个参数是`SharedArrayBuffer`对象,第二个参数是要写入共享内存的数据。 + +Worker 进程从事件的`data`属性上面取到数据。 + +```javascript +var sab; +onmessage = function (ev) { + sab = ev.data; // 1KB 的共享内存,就是主窗口共享出来的那块内存 +}; +``` + +共享内存也可以在 Worker 进程创建,发给主窗口。 + +`SharedArrayBuffer`与`SharedArray`一样,本身是无法读写,必须在上面建立视图,然后通过视图读写。 + +```javascript +// 分配 10 万个 32 位整数占据的内存空间 +var sab = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 100000); + +// 建立 32 位整数视图 +var ia = new Int32Array(sab); // ia.length == 100000 + +// 新建一个质数生成器 +var primes = new PrimeGenerator(); + +// 将 10 万个质数,写入这段内存空间 +for ( let i=0 ; i < ia.length ; i++ ) + ia[i] = primes.next(); + +// 向 Worker 进程发送这段共享内存 +w.postMessage(ia, [ia.buffer]); +``` + +Worker 收到数据后的处理如下。 + +```javascript +var ia; +onmessage = function (ev) { + ia = ev.data; + console.log(ia.length); // 100000 + console.log(ia[37]); // 输出 163,因为这是第138个质数 +}; +``` + diff --git a/docs/let.md b/docs/let.md index 87bf199..80c86e4 100644 --- a/docs/let.md +++ b/docs/let.md @@ -587,13 +587,13 @@ window.b // undefined 上面代码中,全局变量`a`由`var`命令声明,所以它是顶层对象的属性;全局变量`b`由`let`命令声明,所以它不是顶层对象的属性,返回`undefined`。 -## 顶层对象 +## global 对象 ES5的顶层对象,本身也是一个问题,因为它在各种实现里面是不统一的。 -- 浏览器里面,顶层对象是`window`,但Node和Web Worker没有`window`。 -- 浏览器和Web Worker里面,`self`也指向顶层对象,但是Node没有`self`。 -- Node里面,顶层对象是`global`,但其他环境都不支持。 +- 浏览器里面,顶层对象是`window`,但 Node 和 Web Worker 没有`window`。 +- 浏览器和 Web Worker 里面,`self`也指向顶层对象,但是Node没有`self`。 +- Node 里面,顶层对象是`global`,但其他环境都不支持。 同一段代码为了能够在各种环境,都能取到顶层对象,现在一般是使用`this`变量,但是有局限性。 diff --git a/docs/regex.md b/docs/regex.md index cdd7899..faf21c7 100644 --- a/docs/regex.md +++ b/docs/regex.md @@ -133,7 +133,7 @@ codePointLength(s) // 2 **(5)i修饰符** -有些Unicode字符的编码不同,但是字型很相近,比如,`\u004B`与`\u212A`都是大写的K。 +有些Unicode字符的编码不同,但是字型很相近,比如,`\u004B`与`\u212A`都是大写的`K`。 ```javascript /[a-z]/i.test('\u212A') // false @@ -142,7 +142,7 @@ codePointLength(s) // 2 上面代码中,不加`u`修饰符,就无法识别非规范的K字符。 -## y修饰符 +## y 修饰符 除了`u`修饰符,ES6还为正则表达式添加了`y`修饰符,叫做“粘连”(sticky)修饰符。 @@ -366,6 +366,51 @@ escape('hi. how are you?'); // "hi\\. how are you\\?" ``` +## s 修饰符:dotAll 模式 + +正则表达式中,点(`.`)是一个特殊字符,代表任意的单个字符,但是行终止符(line terminator character)除外。 + +以下四个字符属于”行终止符“。 + +- U+000A 换行符(`\n`) +- U+000D 回车符(`\r`) +- U+2028 行分隔符(line separator) +- U+2029 段分隔符(paragraph separator) + +```javascript +/foo.bar/.test('foo\nbar') +// false +``` + +上面代码中,因为`.`不匹配`\n`,所以正则表达式返回`false`。 + +但是,很多时候我们希望匹配的是任意单个字符,这时有一种变通的写法。 + +```javascript +/foo[^]bar/.test('foo\nbar') +// true +``` + +这种解决方案毕竟不太符合直觉,所以现在有一个[提案](https://github.com/mathiasbynens/es-regexp-dotall-flag),引入`/s`修饰符,使得`.`可以匹配任意单个字符。 + +```javascript +/foo.bar/s.test('foo\nbar') // true +``` + +这被称为`dotAll`模式,即点(dot)代表一切字符。所以,正则表达式还引入了一个`dotAll`属性,返回一个布尔值,表示该正则表达式是否处在`dotAll`模式。 + +```javascript +const re = /foo.bar/s; +// 另一种写法 +// const re = new RegExp('foo.bar', 's'); + +re.test('foo\nbar') // true +re.dotAll // true +re.flags // 's' +``` + +`/s`修饰符和多行修饰符`/m`不冲突,两者一起使用的情况下,`.`匹配所有字符,而`^`和`$`匹配每一行的行首和行尾。 + ## 后行断言 JavaScript语言的正则表达式,只支持先行断言(lookahead)和先行否定断言(negative lookahead),不支持后行断言(lookbehind)和后行否定断言(negative lookbehind)。