From 8dec66df72b26beabeb7b0bce0406b9ea27bfb2d Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sat, 8 Apr 2023 00:17:12 +0800 Subject: [PATCH 01/38] =?UTF-8?q?docs(operator):=20#!=20=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/operator.md | 42 ++++++++++++++++++++++++++++++++++++++++++ docs/proposals.md | 42 ------------------------------------------ 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/docs/operator.md b/docs/operator.md index 6d72c66..fea9e90 100644 --- a/docs/operator.md +++ b/docs/operator.md @@ -307,3 +307,45 @@ function example(opts) { } ``` +## `#!`命令 + +Unix 的命令行脚本都支持`#!`命令,又称为 Shebang 或 Hashbang。这个命令放在脚本的第一行,用来指定脚本的执行器。 + +比如 Bash 脚本的第一行。 + +```bash +#!/bin/sh +``` + +Python 脚本的第一行。 + +```python +#!/usr/bin/env python +``` + +[ES2023](https://github.com/tc39/proposal-hashbang) 为 JavaScript 脚本引入了`#!`命令,写在脚本文件或者模块文件的第一行。 + +```javascript +// 写在脚本文件第一行 +#!/usr/bin/env node +'use strict'; +console.log(1); + +// 写在模块文件第一行 +#!/usr/bin/env node +export {}; +console.log(1); +``` + +有了这一行以后,Unix 命令行就可以直接执行脚本。 + +```bash +# 以前执行脚本的方式 +$ node hello.js + +# hashbang 的方式 +$ ./hello.js +``` + +对于 JavaScript 引擎来说,会把`#!`理解成注释,忽略掉这一行。 + diff --git a/docs/proposals.md b/docs/proposals.md index 447151a..cfa19bc 100644 --- a/docs/proposals.md +++ b/docs/proposals.md @@ -482,48 +482,6 @@ class FakeWindow extends Realm { 上面代码中,`FakeWindow`模拟了一个假的顶层对象`window`。 -## `#!`命令 - -Unix 的命令行脚本都支持`#!`命令,又称为 Shebang 或 Hashbang。这个命令放在脚本的第一行,用来指定脚本的执行器。 - -比如 Bash 脚本的第一行。 - -```bash -#!/bin/sh -``` - -Python 脚本的第一行。 - -```python -#!/usr/bin/env python -``` - -现在有一个[提案](https://github.com/tc39/proposal-hashbang),为 JavaScript 脚本引入了`#!`命令,写在脚本文件或者模块文件的第一行。 - -```javascript -// 写在脚本文件第一行 -#!/usr/bin/env node -'use strict'; -console.log(1); - -// 写在模块文件第一行 -#!/usr/bin/env node -export {}; -console.log(1); -``` - -有了这一行以后,Unix 命令行就可以直接执行脚本。 - -```bash -# 以前执行脚本的方式 -$ node hello.js - -# hashbang 的方式 -$ ./hello.js -``` - -对于 JavaScript 引擎来说,会把`#!`理解成注释,忽略掉这一行。 - ## JSON 模块 import 命令目前只能用于加载 ES 模块,现在有一个[提案](https://github.com/tc39/proposal-json-modules),允许加载 JSON 模块。 From 7653c68140866c35a080df87cb5de45fcb8fd783 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 9 May 2023 14:00:30 +0800 Subject: [PATCH 02/38] docs(style): edit text --- docs/style.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/style.md b/docs/style.md index fc23e2f..95fe4c9 100644 --- a/docs/style.md +++ b/docs/style.md @@ -285,7 +285,7 @@ const boundMethod = (...params) => method.apply(this, params); 简单的、单行的、不会复用的函数,建议采用箭头函数。如果函数体较为复杂,行数较多,还是应该采用传统的函数写法。 -所有配置项都应该集中在一个对象,放在最后一个参数,布尔值不可以直接作为参数。 +所有配置项都应该集中在一个对象,放在最后一个参数,布尔值最好不要直接作为参数,因为代码语义会很差,也不利于将来增加其他配置项。 ```javascript // bad From 18f6c301f0509fdae8a8feed653363736e8cf25a Mon Sep 17 00:00:00 2001 From: qijizh Date: Mon, 15 May 2023 02:51:11 +0800 Subject: [PATCH 03/38] docs(generator): update example --- docs/generator.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/generator.md b/docs/generator.md index 7d18278..283b844 100644 --- a/docs/generator.md +++ b/docs/generator.md @@ -552,26 +552,26 @@ g.throw(1); 上面代码中,`g.throw(1)`执行时,`next`方法一次都没有执行过。这时,抛出的错误不会被内部捕获,而是直接在外部抛出,导致程序出错。这种行为其实很好理解,因为第一次执行`next`方法,等同于启动执行 Generator 函数的内部代码,否则 Generator 函数还没有开始执行,这时`throw`方法抛错只可能抛出在函数外部。 -`throw`方法被捕获以后,会附带执行下一条`yield`表达式。也就是说,会附带执行一次`next`方法。 +`throw`方法被内部捕获以后,会附带执行到下一条`yield`表达式,这种情况下等同于执行一次`next`方法。 ```javascript var gen = function* gen(){ try { - yield console.log('a'); + yield 1; } catch (e) { - // ... + yield 2; } - yield console.log('b'); - yield console.log('c'); + yield 3; } var g = gen(); -g.next() // a -g.throw() // b -g.next() // c +g.next() // { value:1, done:false } +g.throw() // { value:2, done:false } +g.next() // { value:3, done:false } +g.next() // { value:undefined, done:true } ``` -上面代码中,`g.throw`方法被捕获以后,自动执行了一次`next`方法,所以会打印`b`。另外,也可以看到,只要 Generator 函数内部部署了`try...catch`代码块,那么遍历器的`throw`方法抛出的错误,不影响下一次遍历。 +上面代码中,`g.throw`方法被内部捕获以后,等同于执行了一次`next`方法,所以返回`{ value:2, done:false }`。另外,也可以看到,只要 Generator 函数内部部署了`try...catch`代码块,那么遍历器的`throw`方法抛出的错误,不影响下一次遍历。 另外,`throw`命令与`g.throw`方法是无关的,两者互不影响。 From 55af576a7f5a8001e2f1a8d36ae6a7a0d0661081 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 6 Jun 2023 16:14:47 +0800 Subject: [PATCH 04/38] docs(set-map): fixed #1155 --- docs/set-map.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/set-map.md b/docs/set-map.md index da23a68..cb21460 100644 --- a/docs/set-map.md +++ b/docs/set-map.md @@ -118,7 +118,7 @@ s.delete(2) // true s.has(2) // false ``` -下面是一个对比,看看在判断是否包括一个键上面,`Object`结构和`Set`结构的写法不同。 +下面是一个对比,判断是否包括一个键,`Object`结构和`Set`结构写法的不同。 ```javascript // 对象的写法 @@ -142,7 +142,7 @@ if (properties.has(someName)) { } ``` -`Array.from`方法可以将 Set 结构转为数组。 +`Array.from()`方法可以将 Set 结构转为数组。 ```javascript const items = new Set([1, 2, 3, 4, 5]); From 6b3812e13ed4f2fadf350ca26a8c97382b1255c5 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 15 Jun 2023 13:18:56 +0800 Subject: [PATCH 05/38] docs(module): fixed #1157 --- docs/module.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/module.md b/docs/module.md index 0f24815..5d68da6 100644 --- a/docs/module.md +++ b/docs/module.md @@ -162,6 +162,8 @@ function f() {} export {f}; ``` +目前,export 命令能够对外输出的就是三种接口:函数(Functions), 类(Classes),var、let、const 声明的变量(Variables)。 + 另外,`export`语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。 ```javascript From 8afac589823c749bab210e7ca707a7d27813bb44 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 27 Jun 2023 15:03:55 +0800 Subject: [PATCH 06/38] docs(class): edit text --- docs/class.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/class.md b/docs/class.md index cbdde3b..a37947a 100644 --- a/docs/class.md +++ b/docs/class.md @@ -1006,7 +1006,7 @@ class Foo {} } ``` -上面的代码不会报错,因为`Bar`继承`Foo`的时候,`Foo`已经有定义了。但是,如果存在`class`的提升,上面代码就会报错,因为`class`会被提升到代码头部,而`let`命令是不提升的,所以导致`Bar`继承`Foo`的时候,`Foo`还没有定义。 +上面的代码不会报错,因为`Bar`继承`Foo`的时候,`Foo`已经有定义了。但是,如果存在`class`的提升,上面代码就会报错,因为`class`会被提升到代码头部,而定义`Foo`的那一行没有提升,导致`Bar`继承`Foo`的时候,`Foo`还没有定义。 ### name 属性 From d9183de442462f363993b9fd9a784cdc7204f976 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 13 Jul 2023 16:27:54 +0800 Subject: [PATCH 07/38] docs(class): fix private field #1159 --- docs/class.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/class.md b/docs/class.md index a37947a..c27bb2f 100644 --- a/docs/class.md +++ b/docs/class.md @@ -844,7 +844,7 @@ class C { } ``` -上面示例中,`in`运算符判断某个对象是否有私有属性`#foo`。它不会报错,而是返回一个布尔值。 +上面示例中,`in`运算符判断某个对象是否有私有属性`#brand`。它不会报错,而是返回一个布尔值。 这种用法的`in`,也可以跟`this`一起配合使用。 @@ -853,12 +853,21 @@ class A { #foo = 0; m() { console.log(#foo in this); // true - console.log(#bar in this); // false } } ``` -注意,判断私有属性时,`in`只能用在类的内部。 +注意,判断私有属性时,`in`只能用在类的内部。另外,判断所针对的私有属性,一定要先声明,否则会报错。 + +```javascript +class A { + m() { + console.log(#foo in this); // 报错 + } +} +``` + +上面示例中,私有属性`#foo`没有声明,就直接用于`in`运算符的判断,导致报错。 子类从父类继承的私有属性,也可以使用`in`运算符来判断。 From 8191859f54dc664ddf80b846c74c2a56f6173c10 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 13 Jul 2023 16:42:50 +0800 Subject: [PATCH 08/38] chore: update dependencies --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b24bfe7..e6abe7f 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "author": "Ruan yifeng", "license": "ICC BY-SA 4.0", "dependencies": { - "gh-pages": "^3.2.3", + "gh-pages": "5.x", "husky": "^4.3.8", "loppo": "^0.6.24", "loppo-theme-wangdoc": "^0.6.1" From 289f7e1cfca4248d5235bd7afc5138df7df15e4f Mon Sep 17 00:00:00 2001 From: ruanyf Date: Mon, 17 Jul 2023 16:22:27 +0800 Subject: [PATCH 09/38] docs(regex): fix typo #1160 --- docs/regex.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/regex.md b/docs/regex.md index 157778a..729eab3 100644 --- a/docs/regex.md +++ b/docs/regex.md @@ -376,7 +376,7 @@ JavaScript 语言的正则表达式,只支持先行断言(lookahead)和先 ```javascript /(?<=\$)\d+/.exec('Benjamin Franklin is on the $100 bill') // ["100"] -/(? Date: Thu, 20 Jul 2023 14:36:44 +0800 Subject: [PATCH 10/38] docs(array): fix .group() #1161 --- docs/array.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/array.md b/docs/array.md index 054ce62..7d705af 100644 --- a/docs/array.md +++ b/docs/array.md @@ -941,7 +941,7 @@ array.group((num, index, array) => { 下面是另一个例子。 ```javascript -[6.1, 4.2, 6.3].groupBy(Math.floor) +[6.1, 4.2, 6.3].group(Math.floor) // { '4': [4.2], '6': [6.1, 6.3] } ``` From d567558df1035ce6392902d59825daf578463ea2 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 26 Jul 2023 19:06:24 +0800 Subject: [PATCH 11/38] docs(set-map): fix Symbol() as WeakSet/WeakMap key #1162 --- docs/set-map.md | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/docs/set-map.md b/docs/set-map.md index cb21460..c5fa699 100644 --- a/docs/set-map.md +++ b/docs/set-map.md @@ -308,17 +308,15 @@ set = new Set(Array.from(set, val => val * 2)); WeakSet 结构与 Set 类似,也是不重复的值的集合。但是,它与 Set 有两个区别。 -首先,WeakSet 的成员只能是对象,而不能是其他类型的值。 +首先,WeakSet 的成员只能是对象和 Symbol 值,而不能是其他类型的值。 ```javascript const ws = new WeakSet(); -ws.add(1) -// TypeError: Invalid value used in weak set -ws.add(Symbol()) -// TypeError: invalid value used in weak set +ws.add(1) // 报错 +ws.add(Symbol()) // 不报错 ``` -上面代码试图向 WeakSet 添加一个数值和`Symbol`值,结果报错,因为 WeakSet 只能放置对象。 +上面代码试图向 WeakSet 添加一个数值和`Symbol`值,结果前者报错了,因为 WeakSet 只能放置对象和 Symbol 值。 其次,WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。 @@ -633,7 +631,7 @@ m.has(undefined) // true **(5)Map.prototype.delete(key)** -`delete`方法删除某个键,返回`true`。如果删除失败,返回`false`。 +`delete()`方法删除某个键,返回`true`。如果删除失败,返回`false`。 ```javascript const m = new Map(); @@ -646,7 +644,7 @@ m.has(undefined) // false **(6)Map.prototype.clear()** -`clear`方法清除所有成员,没有返回值。 +`clear()`方法清除所有成员,没有返回值。 ```javascript let map = new Map(); @@ -928,21 +926,16 @@ wm2.get(k2) // "bar" `WeakMap`与`Map`的区别有两点。 -首先,`WeakMap`只接受对象作为键名(`null`除外),不接受其他类型的值作为键名。 +首先,`WeakMap`只接受对象(`null`除外)和 [Symbol 值](https://github.com/tc39/proposal-symbols-as-weakmap-keys)作为键名,不接受其他类型的值作为键名。 ```javascript const map = new WeakMap(); -map.set(1, 2) -// TypeError: 1 is not an object! -map.set(Symbol(), 2) -// TypeError: Invalid value used as weak map key -map.set(null, 2) -// TypeError: Invalid value used as weak map key +map.set(1, 2) // 报错 +map.set(null, 2) // 报错 +map.set(Symbol(), 2) // 不报错 ``` -上面代码中,如果将数值`1`和`Symbol`值作为 WeakMap 的键名,都会报错。 - -不过,现在有一个[提案](https://github.com/tc39/proposal-symbols-as-weakmap-keys),允许 Symbol 值也可以作为 WeakMap 的键名。一旦纳入标准,就意味着键名存在两种可能:对象和 Symbol 值。 +上面代码中,如果将数值`1`和`null`作为 WeakMap 的键名,都会报错,将 Symbol 值作为键名不会报错。 其次,`WeakMap`的键名所指向的对象,不计入垃圾回收机制。 From e0822f477327b9154b6c3d1159c7c78b2cc6a3b5 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Mon, 7 Aug 2023 12:19:30 +0800 Subject: [PATCH 12/38] docs: edit README --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 64a0ea4..5e058d4 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,11 @@ 本书覆盖 ES6 与上一个版本 ES5 的所有不同之处,对涉及的语法知识给予详细介绍,并给出大量简洁易懂的示例代码。 -本书为中级难度,适合已经掌握 ES5 的读者,用来了解这门语言的最新发展;也可当作参考手册,查寻新增的语法点。如果你是 JavaScript 语言的初学者,建议先学完[《JavaScript 语言入门教程》](https://wangdoc.com/javascript/),再来看本书。 +本书为中级难度,适合已经掌握 ES5 的读者,用来了解这门语言的最新发展;也可当作参考手册,查寻新增的语法点。如果你是 JavaScript 语言的初学者,建议先学完[《JavaScript 语言教程》](https://wangdoc.com/javascript/),再来看本书。 -全书已由电子工业出版社出版,2017年9月推出了第三版,书名为《ES6 标准入门》。纸版是基于网站内容排版印刷的。 +全书已由电子工业出版社出版,2017年9月推出了第三版,书名为《ES6 标准入门》。纸版内容截止到出版时,网站内容一直在修订。 - [淘宝](https://s.taobao.com/search?q=ES6%E6%A0%87%E5%87%86%E5%85%A5%E9%97%A8+%E7%AC%AC3%E7%89%88) - [京东](https://search.jd.com/Search?keyword=ES6%E6%A0%87%E5%87%86%E5%85%A5%E9%97%A8%20%E7%AC%AC3%E7%89%88&enc=utf-8&wq=ES6%E6%A0%87%E5%87%86%E5%85%A5%E9%97%A8%20%E7%AC%AC3%E7%89%88) - [当当](http://product.dangdang.com/25156888.html) -- [亚马逊](https://www.amazon.cn/ES6%E6%A0%87%E5%87%86%E5%85%A5%E9%97%A8-%E9%98%AE%E4%B8%80%E5%B3%B0/dp/B0755547ZZ) -- [China-pub](http://product.china-pub.com/6504650) From 66d4b4f08bc3da794d30d64dc7759198996ea640 Mon Sep 17 00:00:00 2001 From: thinkasany <117748716+thinkasany@users.noreply.github.com> Date: Wed, 16 Aug 2023 11:25:40 +0800 Subject: [PATCH 13/38] Delete .DS_Store --- .DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 8907f9d4c290ebfabd3b25042a56c8678e2b71f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHLF;4<96n=%n5RK#ri<>t)7}*_8g1-PZVuFAH4d^iUwT{wnw>-jyHo|#+_R;#Uk*uuU%)MvBd=wZ+1 zJKyqA&v-X9Z!s0Ja0n4Zma5a(N*Gh~>bl|HjPFTP=LKP+m}V_Kcck>%Fo1!j2i~Kc zQ8K1p>7tY9X*SVIvz8w0ke&k_2mx~~#r49g$(fp)Z|{k(I@es~GTzcHc%-|6pJjmF zcHwA2ySO`DrTjk098+(R zvvhLLq{Hzu2XN1($ge5nnjK&V*nv+6=>6bfA@nuI3gxQ Date: Sat, 19 Aug 2023 15:31:01 +0800 Subject: [PATCH 14/38] docs(class): add Chrome 111 devtool supporting private field access --- docs/class.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/class.md b/docs/class.md index c27bb2f..4a2d53a 100644 --- a/docs/class.md +++ b/docs/class.md @@ -681,6 +681,8 @@ counter.#count = 42 // 报错 上面示例中,在类的外部,读取或写入私有属性`#count`,都会报错。 +注意,[从 Chrome 111 开始](https://developer.chrome.com/blog/new-in-devtools-111/#misc),开发者工具里面可以读写私有属性,不会报错,原因是 Chrome 团队认为这样方便调试。 + 另外,不管在类的内部或外部,读取一个不存在的私有属性,也都会报错。这跟公开属性的行为完全不同,如果读取一个不存在的公开属性,不会报错,只会返回`undefined`。 ```javascript From 7c2b334fef8d7d618710cc276e377c3684c94de9 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 22 Aug 2023 18:57:53 +0800 Subject: [PATCH 15/38] docs(symbol): fixed #1166 Symbol.toStringTag --- docs/symbol.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/symbol.md b/docs/symbol.md index 2297e10..281c818 100644 --- a/docs/symbol.md +++ b/docs/symbol.md @@ -846,7 +846,7 @@ String(obj) // 'str' ### Symbol.toStringTag -对象的`Symbol.toStringTag`属性,指向一个方法。在该对象上面调用`Object.prototype.toString`方法时,如果这个属性存在,它的返回值会出现在`toString`方法返回的字符串之中,表示对象的类型。也就是说,这个属性可以用来定制`[object Object]`或`[object Array]`中`object`后面的那个字符串。 +对象的`Symbol.toStringTag`属性,返回一个字符串。在目标对象上面调用`Object.prototype.toString`方法时,如果`Symbol.toStringTag`属性存在,它的返回值会出现在`toString`方法返回的字符串之中,表示对象的类型。也就是说,这个属性可以用来定制`[object Object]`或`[object Array]`中`object`后面的那个字符串。 ```javascript // 例一 From a8a1f1daf9cf907ca424a04b3923df7e9e91ab21 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 24 Aug 2023 14:01:03 +0800 Subject: [PATCH 16/38] docs(symbol): edit Symbol.toStringTag #1166 --- docs/symbol.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/symbol.md b/docs/symbol.md index 281c818..4693410 100644 --- a/docs/symbol.md +++ b/docs/symbol.md @@ -846,7 +846,7 @@ String(obj) // 'str' ### Symbol.toStringTag -对象的`Symbol.toStringTag`属性,返回一个字符串。在目标对象上面调用`Object.prototype.toString`方法时,如果`Symbol.toStringTag`属性存在,它的返回值会出现在`toString`方法返回的字符串之中,表示对象的类型。也就是说,这个属性可以用来定制`[object Object]`或`[object Array]`中`object`后面的那个字符串。 +对象的`Symbol.toStringTag`属性,用来设定一个字符串(设为其他类型的值无效,但不报错)。在目标对象上面调用`Object.prototype.toString()`方法时,如果`Symbol.toStringTag`属性存在,该属性设定的字符串会出现在`toString()`方法返回的字符串之中,表示对象的类型。也就是说,这个属性可以用来定制`[object Object]`或`[object Array]`中`object`后面的那个大写字符串。 ```javascript // 例一 From 8818bb2f4463b6f0323dba1b247f900627ed4686 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 24 Aug 2023 14:16:36 +0800 Subject: [PATCH 17/38] docs(proxy): fixed #1167 Proxy get() --- docs/proxy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/proxy.md b/docs/proxy.md index a65ec7d..5885094 100644 --- a/docs/proxy.md +++ b/docs/proxy.md @@ -286,7 +286,7 @@ const proxy = new Proxy({}, { proxy.getReceiver === proxy // true ``` -上面代码中,`proxy`对象的`getReceiver`属性是由`proxy`对象提供的,所以`receiver`指向`proxy`对象。 +上面代码中,`proxy`对象的`getReceiver`属性会被`get()`拦截,得到的返回值就是`proxy`对象。 ```javascript const proxy = new Proxy({}, { From 947957e7fa0da6b56aea5a74fbbded65e72eb0ce Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 9 Nov 2023 19:38:57 +0800 Subject: [PATCH 18/38] docs(intro): fix #1170 --- docs/intro.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/intro.md b/docs/intro.md index 880cf08..ea16959 100644 --- a/docs/intro.md +++ b/docs/intro.md @@ -68,9 +68,9 @@ ES6 从开始制定到最后发布,整整用了 15 年。 2015 年 6 月,ECMAScript 6 正式通过,成为国际标准。从 2000 年算起,这时已经过去了 15 年。 -目前,各大浏览器对 ES6 的支持可以查看[kangax.github.io/compat-table/es6/](https://kangax.github.io/compat-table/es6/)。 +目前,各大浏览器对 ES6 的支持可以查看[https://compat-table.github.io/compat-table/es6/](https://compat-table.github.io/compat-table/es6/)。 -Node.js 是 JavaScript 的服务器运行环境(runtime)。它对 ES6 的支持度更高。除了那些默认打开的功能,还有一些语法功能已经实现了,但是默认没有打开。使用下面的命令,可以查看 Node.js 默认没有打开的 ES6 实验性语法。 +Node.js 是 JavaScript 的服务器运行环境(runtime)。它对 ES6 的支持度更高。除了那些默认打开的功能,还有一些语法功能已经实现了,但是默认没有打开。使用下面的命令,可以查看 Node.js 默认没有打开的实验性语法。 ```bash // Linux & Mac From 0e36e208f3c2f64925c009e8e975660c2a3c5bb3 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sat, 30 Dec 2023 14:42:23 +0800 Subject: [PATCH 19/38] docs(class-extends): fix typo --- docs/class-extends.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/class-extends.md b/docs/class-extends.md index d7ccb3d..0946d8b 100644 --- a/docs/class-extends.md +++ b/docs/class-extends.md @@ -183,7 +183,7 @@ B.hello() // hello world 上面代码中,`hello()`是`A`类的静态方法,`B`继承`A`,也继承了`A`的静态方法。 -注意,静态属性是通过软拷贝实现继承的。 +注意,静态属性是通过浅拷贝实现继承的。 ```javascript class A { static foo = 100; } From c2a9e9c6ca7298e6411c6253f35505cb4c148fed Mon Sep 17 00:00:00 2001 From: liliangrong777 <58727146+liliangrong777@users.noreply.github.com> Date: Wed, 10 Apr 2024 17:32:06 +0800 Subject: [PATCH 20/38] Update module-loader.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: 内容修正 --- docs/module-loader.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/module-loader.md b/docs/module-loader.md index ce8082c..ecea115 100644 --- a/docs/module-loader.md +++ b/docs/module-loader.md @@ -397,7 +397,7 @@ import submodule from './node_modules/es-module-package/private-module.js'; } ``` -由于`exports`字段只有支持 ES6 的 Node.js 才认识,所以可以用来兼容旧版本的 Node.js。 +由于`exports`字段只有支持 ES6 的 Node.js 才认识,所以可以用`main`字段来兼容旧版本的 Node.js。 ```javascript { From 5e7e24ee2b6ff2ea299873888019708b5b594352 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 10 Apr 2024 18:04:27 +0800 Subject: [PATCH 21/38] docs(module-loader): edit text --- docs/module-loader.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/module-loader.md b/docs/module-loader.md index ecea115..31dd685 100644 --- a/docs/module-loader.md +++ b/docs/module-loader.md @@ -397,7 +397,7 @@ import submodule from './node_modules/es-module-package/private-module.js'; } ``` -由于`exports`字段只有支持 ES6 的 Node.js 才认识,所以可以用`main`字段来兼容旧版本的 Node.js。 +由于`exports`字段只有支持 ES6 的 Node.js 才认识,所以可以搭配`main`字段,来兼容旧版本的 Node.js。 ```javascript { From efb65ca40b2fe882a05bacd60485bd16d56b2e4e Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 15 May 2024 13:57:19 +0800 Subject: [PATCH 22/38] =?UTF-8?q?docs(regex):=20=E6=AD=A3=E5=88=99?= =?UTF-8?q?=E5=8C=B9=E9=85=8D=20Emoji=20=E5=AD=97=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/regex.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/regex.md b/docs/regex.md index 729eab3..87c3410 100644 --- a/docs/regex.md +++ b/docs/regex.md @@ -464,6 +464,9 @@ regex.test('ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ') // true // 匹配所有空格 \p{White_Space} +// 匹配十六进制字符 +\p{Hex_Digit} + // 匹配各种文字的所有字母,等同于 Unicode 版的 \w [\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\p{Join_Control}] @@ -471,7 +474,7 @@ regex.test('ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ') // true [^\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\p{Join_Control}] // 匹配 Emoji -/\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F/gu +/\p{Extended_Pictographic}/u // 匹配所有的箭头字符 const regexArrows = /^\p{Block=Arrows}+$/u; From f8a8ea6394e5596eb2b9343b28c9ed1969a845bc Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 22 May 2024 12:24:13 +0800 Subject: [PATCH 23/38] =?UTF-8?q?docs(class):=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E6=8F=8F=E8=BF=B0=EF=BC=88in=20=E8=BF=90?= =?UTF-8?q?=E7=AE=97=E7=AC=A6=E5=88=A4=E6=96=AD=E7=BB=A7=E6=89=BF=E7=9A=84?= =?UTF-8?q?=E7=A7=81=E6=9C=89=E5=B1=9E=E6=80=A7=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/class.md | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/docs/class.md b/docs/class.md index 4a2d53a..0906a0f 100644 --- a/docs/class.md +++ b/docs/class.md @@ -871,46 +871,6 @@ class A { 上面示例中,私有属性`#foo`没有声明,就直接用于`in`运算符的判断,导致报错。 -子类从父类继承的私有属性,也可以使用`in`运算符来判断。 - -```javascript -class A { - #foo = 0; - static test(obj) { - console.log(#foo in obj); - } -} - -class SubA extends A {}; - -A.test(new SubA()) // true -``` - -上面示例中,`SubA`从父类继承了私有属性`#foo`,`in`运算符也有效。 - -注意,`in`运算符对于`Object.create()`、`Object.setPrototypeOf`形成的继承,是无效的,因为这种继承不会传递私有属性。 - -```javascript -class A { - #foo = 0; - static test(obj) { - console.log(#foo in obj); - } -} -const a = new A(); - -const o1 = Object.create(a); -A.test(o1) // false -A.test(o1.__proto__) // true - -const o2 = {}; -Object.setPrototypeOf(o2, a); -A.test(o2) // false -A.test(o2.__proto__) // true -``` - -上面示例中,对于修改原型链形成的继承,子类都取不到父类的私有属性,所以`in`运算符无效。 - ## 静态块 静态属性的一个问题是,如果它有初始化逻辑,这个逻辑要么写在类的外部,要么写在`constructor()`方法里面。 From 154b0a1f3a9ac584bb3d999edb52c96b12b8e64b Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sat, 8 Jun 2024 17:32:38 +0800 Subject: [PATCH 24/38] refactor: update dependencies --- package.json | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index e6abe7f..38605d9 100644 --- a/package.json +++ b/package.json @@ -13,11 +13,6 @@ "chapter": "loppo chapter", "server": "loppo server" }, - "husky": { - "hooks": { - "pre-push": "npm update" - } - }, "keywords": [ "wangdoc", "es6", @@ -26,9 +21,8 @@ "author": "Ruan yifeng", "license": "ICC BY-SA 4.0", "dependencies": { - "gh-pages": "5.x", - "husky": "^4.3.8", + "gh-pages": "6.x", "loppo": "^0.6.24", - "loppo-theme-wangdoc": "^0.6.1" + "loppo-theme-wangdoc": "^0.7.1" } } From 2a3dfdfc1b96053f01ccd404e9b84ff8626e05c7 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sat, 8 Jun 2024 17:37:39 +0800 Subject: [PATCH 25/38] refactor: update github action script --- .github/workflows/wangdoc.yml | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/.github/workflows/wangdoc.yml b/.github/workflows/wangdoc.yml index 9601c5e..d879bfe 100644 --- a/.github/workflows/wangdoc.yml +++ b/.github/workflows/wangdoc.yml @@ -10,29 +10,28 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: persist-credentials: false - name: Setup Node.js - uses: actions/setup-node@main + uses: actions/setup-node@v4 with: - node-version: '14' + node-version: 'latest' - name: Install dependencies run: npm install - name: Build pages run: npm run build - name: Deploy to website - uses: JamesIves/github-pages-deploy-action@3.7.1 + uses: JamesIves/github-pages-deploy-action@v4 with: - GIT_CONFIG_NAME: wangdoc-bot - GIT_CONFIG_EMAIL: yifeng.ruan@gmail.com - REPOSITORY_NAME: wangdoc/website - ACCESS_TOKEN: ${{ secrets.WANGDOC_BOT_TOKEN }} - BASE_BRANCH: master - BRANCH: master # The branch the action should deploy to. - FOLDER: dist # The folder the action should deploy. - TARGET_FOLDER: dist/es6 - CLEAN: true # Automatically remove deleted files from the deploy branch - COMMIT_MESSAGE: update from ES6 tutorial + git-config-name: wangdoc-bot + git-config-email: yifeng.ruan@gmail.com + repository-name: wangdoc/website + token: ${{ secrets.WANGDOC_BOT_TOKEN }} + branch: master + folder: dist # The folder the action should deploy. + target-folder: dist/es6 + clean: true # Automatically remove deleted files from the deploy branch + commit-message: update from ES6 tutorial From 3e32b889ab17f30ccd5499e72a22a561db2d54a1 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sat, 8 Jun 2024 17:43:05 +0800 Subject: [PATCH 26/38] docs(array): fixed #22 --- docs/array.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/array.md b/docs/array.md index 7d705af..7a3cda6 100644 --- a/docs/array.md +++ b/docs/array.md @@ -881,9 +881,7 @@ sentence.at(100) // undefined ## 实例方法:toReversed(),toSorted(),toSpliced(),with() -很多数组的传统方法会改变原数组,比如`push()`、`pop()`、`shift()`、`unshift()`等等。数组只要调用了这些方法,它的值就变了。现在有一个[提案](https://github.com/tc39/proposal-change-array-by-copy),允许对数组进行操作时,不改变原数组,而返回一个原数组的拷贝。 - -这样的方法一共有四个。 +很多数组的传统方法会改变原数组,比如`push()`、`pop()`、`shift()`、`unshift()`等等。数组只要调用了这些方法,它的值就变了。[ES2023](https://github.com/tc39/proposal-change-array-by-copy)引入了四个新方法,对数组进行操作时,不改变原数组,而返回一个原数组的拷贝。 - `Array.prototype.toReversed() -> Array` - `Array.prototype.toSorted(compareFn) -> Array` From 73fbb5bbe82cca1ad38d4bf634181ebfb0357acd Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 19 Jul 2024 17:47:06 +0800 Subject: [PATCH 27/38] docs(generator): fixed typo --- docs/generator.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/generator.md b/docs/generator.md index 283b844..f93604c 100644 --- a/docs/generator.md +++ b/docs/generator.md @@ -259,7 +259,7 @@ b.next(12) // { value:8, done:false } b.next(13) // { value:42, done:true } ``` -上面代码中,第二次运行`next`方法的时候不带参数,导致 y 的值等于`2 * undefined`(即`NaN`),除以 3 以后还是`NaN`,因此返回对象的`value`属性也等于`NaN`。第三次运行`Next`方法的时候不带参数,所以`z`等于`undefined`,返回对象的`value`属性等于`5 + NaN + undefined`,即`NaN`。 +上面代码中,第二次运行`next`方法的时候不带参数,导致 y 的值等于`2 * undefined`(即`NaN`),除以 3 以后还是`NaN`,因此返回对象的`value`属性也等于`NaN`。第三次运行`next`方法的时候不带参数,所以`z`等于`undefined`,返回对象的`value`属性等于`5 + NaN + undefined`,即`NaN`。 如果向`next`方法提供参数,返回结果就完全不一样了。上面代码第一次调用`b`的`next`方法时,返回`x+1`的值`6`;第二次调用`next`方法,将上一次`yield`表达式的值设为`12`,因此`y`等于`24`,返回`y / 3`的值`8`;第三次调用`next`方法,将上一次`yield`表达式的值设为`13`,因此`z`等于`13`,这时`x`等于`5`,`y`等于`24`,所以`return`语句的值等于`42`。 From 17acb4f3f54487f62d3687ac6b08ab00c41af5c4 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 24 Jul 2024 20:57:35 +0800 Subject: [PATCH 28/38] docs(string-methods): add .toWellFormed() --- docs/string-methods.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/docs/string-methods.md b/docs/string-methods.md index cfb23fe..79520fc 100644 --- a/docs/string-methods.md +++ b/docs/string-methods.md @@ -451,3 +451,37 @@ str.at(-1) // "o" 该方法来自数组添加的`at()`方法,目前还是一个第三阶段的提案,可以参考《数组》一章的介绍。 +## 实例方法:toWellFormed() + +ES2024 引入了新的字符串方法`toWellFormed()`,用来处理 Unicode 的代理字符对问题(surrogates)。 + +JavaScript 语言内部使用 UTF-16 格式,表示每个字符。UTF-16 只有16位,只能表示码点在`U+0000`到`U+FFFF`之间的 Unicode 字符。对于码点大于`U+FFFF`的 Unicode 字符(即码点大于16位的字符,`U+10000`到`U+10FFFF`),解决办法是使用代理字符对,即用两个 UTF-16 字符组合表示。 + +具体来说,UTF-16 规定,`U+D800`至`U+DFFF`是空字符段,专门留给代理字符对使用。只要遇到这个范围内的码点,就知道它是代理字符对,本身没有意义,必须两个字符结合在一起解读。其中,前一个字符的范围规定为`0xD800`到`0xDBFF`之间,后一个字符的范围规定为`0xDC00`到`0xDFFF`之间。举例来说,码点`U+1D306`对应的字符为`𝌆`,它写成 UTF-16 就是`0xD834 0xDF06`。 + +但是,字符串里面可能会出现单个代理字符对,即`U+D800`至`U+DFFF`里面的字符,它没有配对的另一个字符,无法进行解读,导致出现各种状况。 + +`.toWellFormed()`就是为了解决这个问题,不改变原始字符串,返回一个新的字符串,将原始字符串里面的单个代理字符对,都替换为`U+FFFD`,从而可以在任何正常处理字符串的函数里面使用。 + +```javascript +"ab\uD800".toWellFormed() // 'ab�' +``` + +上面示例中,`\uD800`是单个的代理字符对,单独使用时没有意义。`toWellFormed()`将这个字符转为`\uFFFD`。 + +再看下面的例子,`encodeURI()`遇到单个的代理字符对,会报错。 + +```javascript +const illFormed = "https://example.com/search?q=\uD800"; + +encodeURI(illFormed) // 报错 +``` + +`toWellFormed()`将其转换格式后,再使用`encodeURI()`就不会报错了。 + +```javascript +const illFormed = "https://example.com/search?q=\uD800"; + +encodeURI(illFormed.toWellFormed()) // 正确 +``` + From f7ebafd9805ddf16a5b14831c177e633144691e6 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 24 Jul 2024 21:31:02 +0800 Subject: [PATCH 29/38] docs(regex): edit v flag --- docs/regex.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/regex.md b/docs/regex.md index 87c3410..02f2439 100644 --- a/docs/regex.md +++ b/docs/regex.md @@ -483,7 +483,7 @@ regexArrows.test('←↑→↓↔↕↖↗↘↙⇏⇐⇑⇒⇓⇔⇕⇖⇗⇘ ## v 修饰符:Unicode 属性类的运算 -有时,需要向某个 Unicode 属性类添加或减少字符,即需要对属性类进行运算。现在有一个[提案](https://github.com/tc39/proposal-regexp-v-flag),增加了 Unicode 属性类的运算功能。 +有时,需要向某个 Unicode 属性类添加或减少字符,即需要对属性类进行运算。[ES2024](https://github.com/tc39/proposal-regexp-v-flag) 增加了 Unicode 属性类的运算功能。 它提供两种形式的运算,一种是差集运算(A 集合减去 B 集合),另一种是交集运算。 @@ -516,6 +516,22 @@ regexArrows.test('←↑→↓↔↕↖↗↘↙⇏⇐⇑⇒⇓⇔⇕⇖⇗⇘ [\p{Emoji}--\p{ASCII}] ``` +看一个实际的例子,`0`属于十进制字符类。 + +```javascript +/[\p{Decimal_Number}]/u.test('0') // true +``` + +上面示例中,字符类是 Unicode 专用的,所以必须使用`u`修饰符。 + +如果把`0-9`从十进制字符类里面去掉,那么`0`就不属于这个类了。 + +```javascript +/[\p{Decimal_Number}--[0-9]]/v.test('0') // false +``` + +上面示例中,`v`修饰符只能用于 Unicode,所以可以省略`u`修饰符。 + ## 具名组匹配 ### 简介 From 1cdbb5c9ef5d323e93f8a49d4c08d64e5ebf9d63 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 24 Jul 2024 21:51:29 +0800 Subject: [PATCH 30/38] docs(proposals): edit pipe operator --- docs/proposals.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/proposals.md b/docs/proposals.md index cfa19bc..2626982 100644 --- a/docs/proposals.md +++ b/docs/proposals.md @@ -314,6 +314,18 @@ const userAge = userId |> await fetchUserById |> getAgeFromUser; const userAge = getAgeFromUser(await fetchUserById(userId)); ``` +管道运算符对多步骤的数据处理,非常有用。 + +```javascript +const numbers = [10, 20, 30, 40, 50]; + +const processedNumbers = numbers + |> (_ => _.map(n => n / 2)) // [5, 10, 15, 20, 25] + |> (_ => _.filter(n => n > 10)); // [15, 20, 25] +``` + +上面示例中,管道运算符可以清晰表达数据处理的每一步,增加代码的可读性。 + ## Math.signbit() JavaScript 内部使用64位浮点数(国际标准 IEEE 754)表示数值。IEEE 754 规定,64位浮点数的第一位是符号位,`0`表示正数,`1`表示负数。所以会有两种零,`+0`是符号位为`0`时的零,`-0`是符号位为`1`时的零。实际编程中,判断一个值是`+0`还是`-0`非常麻烦,因为它们是相等的。 From d40bf5540db931d7b1b14baec70433987e62be15 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 25 Jul 2024 14:42:35 +0800 Subject: [PATCH 31/38] docs(set): edit set operator methods --- docs/set-map.md | 156 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 138 insertions(+), 18 deletions(-) diff --git a/docs/set-map.md b/docs/set-map.md index c5fa699..4407477 100644 --- a/docs/set-map.md +++ b/docs/set-map.md @@ -21,7 +21,7 @@ for (let i of s) { 上面代码通过`add()`方法向 Set 结构加入成员,结果表明 Set 结构不会添加重复的值。 -`Set`函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。 +`Set()`函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。 ```javascript // 例一 @@ -88,6 +88,23 @@ set.size // 2 上面代码表示,由于两个空对象不相等,所以它们被视为两个值。 +`Array.from()`方法可以将 Set 结构转为数组。 + +```javascript +const items = new Set([1, 2, 3, 4, 5]); +const array = Array.from(items); +``` + +这就提供了去除数组重复成员的另一种方法。 + +```javascript +function dedupe(array) { + return Array.from(new Set(array)); +} + +dedupe([1, 1, 2, 3]) // [1, 2, 3] +``` + ### Set 实例的属性和方法 Set 结构的实例有以下属性。 @@ -142,23 +159,6 @@ if (properties.has(someName)) { } ``` -`Array.from()`方法可以将 Set 结构转为数组。 - -```javascript -const items = new Set([1, 2, 3, 4, 5]); -const array = Array.from(items); -``` - -这就提供了去除数组重复成员的另一种方法。 - -```javascript -function dedupe(array) { - return Array.from(new Set(array)); -} - -dedupe([1, 1, 2, 3]) // [1, 2, 3] -``` - ### 遍历操作 Set 结构的实例有四个遍历方法,可以用于遍历成员。 @@ -302,6 +302,122 @@ set = new Set(Array.from(set, val => val * 2)); 上面代码提供了两种方法,直接在遍历操作中改变原来的 Set 结构。 +### 集合运算 + +[ES2025](https://github.com/tc39/proposal-set-methods) 为 Set 结构添加了以下集合运算方法。 + +- Set.prototype.intersection(other):交集 +- Set.prototype.union(other):并集 +- Set.prototype.difference(other):差集 +- Set.prototype.symmetricDifference(other):对称差集 +- Set.prototype.isSubsetOf(other):判断是否为子集 +- Set.prototype.isSupersetOf(other):判断是否为超集 +- Set.prototype.isDisjointFrom(other):判断是否不相交 + +以上方法的参数都必须是 Set 结构,或者是一个类似于 Set 的结构(拥有`size`属性,以及`keys()`和`has()`方法。 + +`.union()`是并集运算,返回包含两个集合中存在的所有成员的集合。 + +```javascript +const frontEnd = new Set(["JavaScript", "HTML", "CSS"]); +const backEnd = new Set(["Python", "Java", "JavaScript"]); + +const all = frontEnd.union(backEnd); +// Set {"JavaScript", "HTML", "CSS", "Python", "Java"} +``` + +`.intersection()`是交集运算,返回同时包含在两个集合中的成员的集合。 + +```javascript +const frontEnd = new Set(["JavaScript", "HTML", "CSS"]); +const backEnd = new Set(["Python", "Java", "JavaScript"]); + +const frontAndBackEnd = frontEnd.intersection(backEnd); +// Set {"JavaScript"} +``` + +`.difference()`是差集运算,返回第一个集合中存在但第二个集合中不存在的所有成员的集合。 + +```javascript +const frontEnd = new Set(["JavaScript", "HTML", "CSS"]); +const backEnd = new Set(["Python", "Java", "JavaScript"]); + +const onlyFrontEnd = frontEnd.difference(backEnd); +// Set {"HTML", "CSS"} + +const onlyBackEnd = backEnd.difference(frontEnd); +// Set {"Python", "Java"} +``` + +`.symmetryDifference()`是对称差集,返回两个集合的所有独一无二成员的集合,即去除了重复的成员。 + +```javascript +const frontEnd = new Set(["JavaScript", "HTML", "CSS"]); +const backEnd = new Set(["Python", "Java", "JavaScript"]); + +const onlyFrontEnd = frontEnd.symmetricDifference(backEnd); +// Set {"HTML", "CSS", "Python", "Java"} + +const onlyBackEnd = backEnd.symmetricDifference(frontEnd); +// Set {"Python", "Java", "HTML", "CSS"} +``` + +注意,返回结果中的成员顺序,由添加到集合的顺序决定。 + +`.isSubsetOf()`返回一个布尔值,判断第一个集合是否为第二个集合的子集,即第一个集合的所有成员都是第二个集合的成员。 + +```javascript +const frontEnd = new Set(["JavaScript", "HTML", "CSS"]); +const declarative = new Set(["HTML", "CSS"]); + +declarative.isSubsetOf(frontEnd); +// true + +frontEndLanguages.isSubsetOf(declarativeLanguages); +// false +``` + +任何集合都是自身的子集。 + +```javascript +frontEnd.isSubsetOf(frontEnd); +// true +``` + +`isSupersetOf()`返回一个布尔值,表示第一个集合是否为第二个集合的超集,即第二个集合的所有成员都是第一个集合的成员。 + +```javascript +const frontEnd = new Set(["JavaScript", "HTML", "CSS"]); +const declarative = new Set(["HTML", "CSS"]); + +declarative.isSupersetOf(frontEnd); +// false + +frontEnd.isSupersetOf(declarative); +// true +``` + +任何集合都是自身的超集。 + +```javascript +frontEnd.isSupersetOf(frontEnd); +// true +``` + +`.isDisjointFrom()`判断两个集合是否不相交,即没有共同成员。 + +```javascript +const frontEnd = new Set(["JavaScript", "HTML", "CSS"]); +const interpreted = new Set(["JavaScript", "Ruby", "Python"]); +const compiled = new Set(["Java", "C++", "TypeScript"]); + +interpreted.isDisjointFrom(compiled); +// true + +frontEnd.isDisjointFrom(interpreted); +// false +``` + ## WeakSet ### 含义 @@ -1283,3 +1399,7 @@ class Thingy { 由于无法知道清理器何时会执行,所以最好避免使用它。另外,如果浏览器窗口关闭或者进程意外退出,清理器则不会运行。 +## 参考链接 + +- [Union, intersection, difference, and more are coming to JavaScript Sets](https://www.sonarsource.com/blog/union-intersection-difference-javascript-sets/) + From fe56aa1fab2a3e9709fcf2f072423eed8f3794a9 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 25 Jul 2024 17:06:22 +0800 Subject: [PATCH 32/38] docs(module): edit import.meta --- docs/module.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/module.md b/docs/module.md index 5d68da6..207c383 100644 --- a/docs/module.md +++ b/docs/module.md @@ -855,3 +855,14 @@ import.meta.scriptElement.dataset.foo // "abc" ``` +**(3)其他** + +Deno 现在还支持`import.meta.filename`和`import.meta.dirname`属性,对应 CommonJS 模块系统的`__filename`和`__dirname`属性。 + +- `import.meta.filename`:当前模块文件的绝对路径。 +- `import.meta.dirname`:当前模块文件的目录的绝对路径。 + +这两个属性都提供当前平台的正确的路径分隔符,比如 Linux 系统返回`/dev/my_module.ts`,Windows 系统返回`C:\dev\my_module.ts`。 + +本地模块可以使用这两个属性,远程模块也可以使用。 + From f45cb0bf1c0c3b86cc9b29209b4cb6497d6c2fea Mon Sep 17 00:00:00 2001 From: Linho Date: Tue, 24 Sep 2024 21:18:25 +0800 Subject: [PATCH 33/38] Fix Pangu --- docs/number.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/number.md b/docs/number.md index e9904c5..1b3cfbb 100644 --- a/docs/number.md +++ b/docs/number.md @@ -820,7 +820,7 @@ for (let i = 1; i <= 70; i++) { console.log(p); // 1.197857166996989e+100 ``` -现在支持大整数了,就可以算了,浏览器的开发者工具运行下面代码,就OK。 +现在支持大整数了,就可以算了,浏览器的开发者工具运行下面代码,就 OK。 ```javascript let p = 1n; From 01709c9bea8b9e6be5aa23c10646ac1bc6d45c98 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 14 Nov 2024 14:42:39 +0800 Subject: [PATCH 34/38] style: update theme version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 38605d9..97bde07 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,6 @@ "dependencies": { "gh-pages": "6.x", "loppo": "^0.6.24", - "loppo-theme-wangdoc": "^0.7.1" + "loppo-theme-wangdoc": "^0.7.3" } } From 65ea5552820be9eff30cb2035859e2e7fe8e7664 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 25 Dec 2024 09:55:48 +0800 Subject: [PATCH 35/38] docs(object): fixed typo --- docs/object.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/object.md b/docs/object.md index 4b52b89..5832a8f 100644 --- a/docs/object.md +++ b/docs/object.md @@ -783,7 +783,7 @@ actual.cause; // 'Error cause' 上面示例中,生成 Error 实例时,使用描述对象给出`cause`属性,写入报错的原因。然后,就可以从实例对象上读取这个属性。 -`casue`属性可以放置任意内容,不必一定是字符串。 +`cause`属性可以放置任意内容,不必一定是字符串。 ```javascript try { From 4a7fa896a3cddc25b89ae62b00f5e744e833ed57 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 31 Dec 2024 16:24:06 +0800 Subject: [PATCH 36/38] docs(string-methonds): fixed typo --- docs/string-methods.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/string-methods.md b/docs/string-methods.md index 79520fc..1d3e63a 100644 --- a/docs/string-methods.md +++ b/docs/string-methods.md @@ -421,7 +421,7 @@ String.prototype.replaceAll(searchValue, replacement) 上面例子中,`replaceAll()`的第二个参数是一个函数,该函数的返回值会替换掉所有`b`的匹配。 -这个替换函数可以接受多个参数。第一个参数是捕捉到的匹配内容,第二个参数捕捉到是组匹配(有多少个组匹配,就有多少个对应的参数)。此外,最后还可以添加两个参数,倒数第二个参数是捕捉到的内容在整个字符串中的位置,最后一个参数是原字符串。 +这个替换函数可以接受多个参数。第一个参数是捕捉到的匹配内容,第二个参数是捕捉到的组匹配(有多少个组匹配,就有多少个对应的参数)。此外,最后还可以添加两个参数,倒数第二个参数是捕捉到的内容在整个字符串中的位置,最后一个参数是原字符串。 ```javascript const str = '123abc456'; From c81a2de26a56c8b9b912e2713e756c43ff2ecfb8 Mon Sep 17 00:00:00 2001 From: zihua <63008995+zihua-1022@users.noreply.github.com> Date: Sat, 22 Feb 2025 19:50:26 +0800 Subject: [PATCH 37/38] Update promise.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit console.log的输出和展示结果不一致 --- docs/promise.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/promise.md b/docs/promise.md index ee6a7aa..758bb2e 100644 --- a/docs/promise.md +++ b/docs/promise.md @@ -79,7 +79,7 @@ let promise = new Promise(function(resolve, reject) { }); promise.then(function() { - console.log('resolved.'); + console.log('resolved'); }); console.log('Hi!'); From a7335cba534a73e0a4d4cb148edf8f400c393da9 Mon Sep 17 00:00:00 2001 From: Chuck Lau Date: Sun, 27 Apr 2025 13:52:02 +0800 Subject: [PATCH 38/38] docs: fix typo in reference.md --- docs/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference.md b/docs/reference.md index 909c21c..9c07274 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -184,7 +184,7 @@ ## 异步操作和 Async 函数 -- Luke Hoban, [Async Functions for ECMAScript](https://github.com/lukehoban/ecmascript-asyncawait): Async 函数的设计思想,与 Promise、Gernerator 函数的关系 +- Luke Hoban, [Async Functions for ECMAScript](https://github.com/lukehoban/ecmascript-asyncawait): Async 函数的设计思想,与 Promise、Generator 函数的关系 - Jafar Husain, [Asynchronous Generators for ES7](https://github.com/jhusain/asyncgenerator): Async 函数的深入讨论 - Nolan Lawson, [Taming the asynchronous beast with ES7](http://pouchdb.com/2015/03/05/taming-the-async-beast-with-es7.html): async 函数通俗的实例讲解 - Jafar Husain, [Async Generators](https://docs.google.com/file/d/0B4PVbLpUIdzoMDR5dWstRllXblU/view?sle=true): 对 async 与 Generator 混合使用的一些讨论