From 136026aa0de9fd00e73e8b93516c2f4e88160687 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Mon, 16 Mar 2020 10:19:47 +0800 Subject: [PATCH 001/152] docs(dom/css): fix typo --- docs/dom/css.md | 2 +- docs/dom/mutationobserver.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/dom/css.md b/docs/dom/css.md index d6d01db..a29de76 100644 --- a/docs/dom/css.md +++ b/docs/dom/css.md @@ -820,7 +820,7 @@ mql.onchange = function(e) { } ``` -上面代码中,`change`事件发生后,存在两种可能。一种是显示宽度从700像素以上变为以下,另一种是从700像素以下变为以上,所以在监听函数内部要判断一下当前是哪一种情况。 +上面代码中,`change`事件发生后,存在两种可能。一种是显示宽度从600像素以上变为以下,另一种是从600像素以下变为以上,所以在监听函数内部要判断一下当前是哪一种情况。 ### MediaQueryList 接口的实例方法 diff --git a/docs/dom/mutationobserver.md b/docs/dom/mutationobserver.md index e44f9a1..139709b 100644 --- a/docs/dom/mutationobserver.md +++ b/docs/dom/mutationobserver.md @@ -60,7 +60,7 @@ observer.observe(article, options); - **attributes**:属性的变动。 - **characterData**:节点内容或节点文本的变动。 -想要观察哪一种变动类型,就在`option`对象中指定它的值为`true`。需要注意的是,必须同时指定`childList`、`attributes`和`characterData`中的一种或多种,若未均指定将报错。 +想要观察哪一种变动类型,就在`option`对象中指定它的值为`true`。需要注意的是,至少必须同时指定这三种观察的一种,若均未指定将报错。 除了变动类型,`options`对象还可以设定以下属性: From a975c0ca1e5fa1b54ce3f0c37ebefd785fe3f55d Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 17 Mar 2020 18:09:14 +0800 Subject: [PATCH 002/152] docs(oop/this): fix #165 --- docs/oop/this.md | 44 ++++++++++++++++++++++---------------------- docs/stdlib/array.md | 16 ++++++++-------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/docs/oop/this.md b/docs/oop/this.md index ca6158b..6668047 100644 --- a/docs/oop/this.md +++ b/docs/oop/this.md @@ -694,11 +694,11 @@ var f = function (){ $('#button').on('click', f); ``` -上面代码中,点击按钮以后,控制台将会显示`true`。由于`apply`方法(或者`call`方法)不仅绑定函数执行时所在的对象,还会立即执行函数,因此不得不把绑定语句写在一个函数体内。更简洁的写法是采用下面介绍的`bind`方法。 +上面代码中,点击按钮以后,控制台将会显示`true`。由于`apply()`方法(或者`call()`方法)不仅绑定函数执行时所在的对象,还会立即执行函数,因此不得不把绑定语句写在一个函数体内。更简洁的写法是采用下面介绍的`bind()`方法。 ### Function.prototype.bind() -`bind`方法用于将函数体内的`this`绑定到某个对象,然后返回一个新函数。 +`bind()`方法用于将函数体内的`this`绑定到某个对象,然后返回一个新函数。 ```javascript var d = new Date(); @@ -708,16 +708,16 @@ var print = d.getTime; print() // Uncaught TypeError: this is not a Date object. ``` -上面代码中,我们将`d.getTime`方法赋给变量`print`,然后调用`print`就报错了。这是因为`getTime`方法内部的`this`,绑定`Date`对象的实例,赋给变量`print`以后,内部的`this`已经不指向`Date`对象的实例了。 +上面代码中,我们将`d.getTime()`方法赋给变量`print`,然后调用`print()`就报错了。这是因为`getTime()`方法内部的`this`,绑定`Date`对象的实例,赋给变量`print`以后,内部的`this`已经不指向`Date`对象的实例了。 -`bind`方法可以解决这个问题。 +`bind()`方法可以解决这个问题。 ```javascript var print = d.getTime.bind(d); print() // 1481869925657 ``` -上面代码中,`bind`方法将`getTime`方法内部的`this`绑定到`d`对象,这时就可以安全地将这个方法赋值给其他变量了。 +上面代码中,`bind()`方法将`getTime()`方法内部的`this`绑定到`d`对象,这时就可以安全地将这个方法赋值给其他变量了。 `bind`方法的参数就是所要绑定`this`的对象,下面是一个更清晰的例子。 @@ -734,7 +734,7 @@ func(); counter.count // 1 ``` -上面代码中,`counter.inc`方法被赋值给变量`func`。这时必须用`bind`方法将`inc`内部的`this`,绑定到`counter`,否则就会出错。 +上面代码中,`counter.inc()`方法被赋值给变量`func`。这时必须用`bind()`方法将`inc()`内部的`this`,绑定到`counter`,否则就会出错。 `this`绑定到其他对象也是可以的。 @@ -754,9 +754,9 @@ func(); obj.count // 101 ``` -上面代码中,`bind`方法将`inc`方法内部的`this`,绑定到`obj`对象。结果调用`func`函数以后,递增的就是`obj`内部的`count`属性。 +上面代码中,`bind()`方法将`inc()`方法内部的`this`,绑定到`obj`对象。结果调用`func`函数以后,递增的就是`obj`内部的`count`属性。 -`bind`还可以接受更多的参数,将这些参数绑定原函数的参数。 +`bind()`还可以接受更多的参数,将这些参数绑定原函数的参数。 ```javascript var add = function (x, y) { @@ -772,9 +772,9 @@ var newAdd = add.bind(obj, 5); newAdd(5) // 20 ``` -上面代码中,`bind`方法除了绑定`this`对象,还将`add`函数的第一个参数`x`绑定成`5`,然后返回一个新函数`newAdd`,这个函数只要再接受一个参数`y`就能运行了。 +上面代码中,`bind()`方法除了绑定`this`对象,还将`add()`函数的第一个参数`x`绑定成`5`,然后返回一个新函数`newAdd()`,这个函数只要再接受一个参数`y`就能运行了。 -如果`bind`方法的第一个参数是`null`或`undefined`,等于将`this`绑定到全局对象,函数运行时`this`指向顶层对象(浏览器为`window`)。 +如果`bind()`方法的第一个参数是`null`或`undefined`,等于将`this`绑定到全局对象,函数运行时`this`指向顶层对象(浏览器为`window`)。 ```javascript function add(x, y) { @@ -785,19 +785,19 @@ var plus5 = add.bind(null, 5); plus5(10) // 15 ``` -上面代码中,函数`add`内部并没有`this`,使用`bind`方法的主要目的是绑定参数`x`,以后每次运行新函数`plus5`,就只需要提供另一个参数`y`就够了。而且因为`add`内部没有`this`,所以`bind`的第一个参数是`null`,不过这里如果是其他对象,也没有影响。 +上面代码中,函数`add()`内部并没有`this`,使用`bind()`方法的主要目的是绑定参数`x`,以后每次运行新函数`plus5()`,就只需要提供另一个参数`y`就够了。而且因为`add()`内部没有`this`,所以`bind()`的第一个参数是`null`,不过这里如果是其他对象,也没有影响。 -`bind`方法有一些使用注意点。 +`bind()`方法有一些使用注意点。 **(1)每一次返回一个新函数** -`bind`方法每运行一次,就返回一个新函数,这会产生一些问题。比如,监听事件的时候,不能写成下面这样。 +`bind()`方法每运行一次,就返回一个新函数,这会产生一些问题。比如,监听事件的时候,不能写成下面这样。 ```javascript element.addEventListener('click', o.m.bind(o)); ``` -上面代码中,`click`事件绑定`bind`方法生成的一个匿名函数。这样会导致无法取消绑定,所以,下面的代码是无效的。 +上面代码中,`click`事件绑定`bind()`方法生成的一个匿名函数。这样会导致无法取消绑定,所以下面的代码是无效的。 ```javascript element.removeEventListener('click', o.m.bind(o)); @@ -814,7 +814,7 @@ element.removeEventListener('click', listener); **(2)结合回调函数使用** -回调函数是 JavaScript 最常用的模式之一,但是一个常见的错误是,将包含`this`的方法直接当作回调函数。解决方法就是使用`bind`方法,将`counter.inc`绑定`counter`。 +回调函数是 JavaScript 最常用的模式之一,但是一个常见的错误是,将包含`this`的方法直接当作回调函数。解决方法就是使用`bind()`方法,将`counter.inc()`绑定`counter`。 ```javascript var counter = { @@ -833,7 +833,7 @@ callIt(counter.inc.bind(counter)); counter.count // 1 ``` -上面代码中,`callIt`方法会调用回调函数。这时如果直接把`counter.inc`传入,调用时`counter.inc`内部的`this`就会指向全局对象。使用`bind`方法将`counter.inc`绑定`counter`以后,就不会有这个问题,`this`总是指向`counter`。 +上面代码中,`callIt()`方法会调用回调函数。这时如果直接把`counter.inc`传入,调用时`counter.inc()`内部的`this`就会指向全局对象。使用`bind()`方法将`counter.inc`绑定`counter`以后,就不会有这个问题,`this`总是指向`counter`。 还有一种情况比较隐蔽,就是某些数组方法可以接受一个函数当作参数。这些函数内部的`this`指向,很可能也会出错。 @@ -852,7 +852,7 @@ obj.print() // 没有任何输出 ``` -上面代码中,`obj.print`内部`this.times`的`this`是指向`obj`的,这个没有问题。但是,`forEach`方法的回调函数内部的`this.name`却是指向全局对象,导致没有办法取到值。稍微改动一下,就可以看得更清楚。 +上面代码中,`obj.print`内部`this.times`的`this`是指向`obj`的,这个没有问题。但是,`forEach()`方法的回调函数内部的`this.name`却是指向全局对象,导致没有办法取到值。稍微改动一下,就可以看得更清楚。 ```javascript obj.print = function () { @@ -867,7 +867,7 @@ obj.print() // true ``` -解决这个问题,也是通过`bind`方法绑定`this`。 +解决这个问题,也是通过`bind()`方法绑定`this`。 ```javascript obj.print = function () { @@ -882,9 +882,9 @@ obj.print() // 张三 ``` -**(3)结合`call`方法使用** +**(3)结合`call()`方法使用** -利用`bind`方法,可以改写一些 JavaScript 原生方法的使用形式,以数组的`slice`方法为例。 +利用`bind()`方法,可以改写一些 JavaScript 原生方法的使用形式,以数组的`slice()`方法为例。 ```javascript [1, 2, 3].slice(0, 1) // [1] @@ -892,9 +892,9 @@ obj.print() Array.prototype.slice.call([1, 2, 3], 0, 1) // [1] ``` -上面的代码中,数组的`slice`方法从`[1, 2, 3]`里面,按照指定位置和长度切分出另一个数组。这样做的本质是在`[1, 2, 3]`上面调用`Array.prototype.slice`方法,因此可以用`call`方法表达这个过程,得到同样的结果。 +上面的代码中,数组的`slice`方法从`[1, 2, 3]`里面,按照指定的开始位置和结束位置,切分出另一个数组。这样做的本质是在`[1, 2, 3]`上面调用`Array.prototype.slice()`方法,因此可以用`call`方法表达这个过程,得到同样的结果。 -`call`方法实质上是调用`Function.prototype.call`方法,因此上面的表达式可以用`bind`方法改写。 +`call()`方法实质上是调用`Function.prototype.call()`方法,因此上面的表达式可以用`bind()`方法改写。 ```javascript var slice = Function.prototype.call.bind(Array.prototype.slice); diff --git a/docs/stdlib/array.md b/docs/stdlib/array.md index 97912f2..5c999da 100644 --- a/docs/stdlib/array.md +++ b/docs/stdlib/array.md @@ -1,4 +1,4 @@ -# Array 对象 + Array 对象 ## 构造函数 @@ -282,13 +282,13 @@ a // ["c", "b", "a"] ### slice() -`slice`方法用于提取目标数组的一部分,返回一个新数组,原数组不变。 +`slice()`方法用于提取目标数组的一部分,返回一个新数组,原数组不变。 ```javascript arr.slice(start, end); ``` -它的第一个参数为起始位置(从0开始),第二个参数为终止位置(但该位置的元素本身不包括在内)。如果省略第二个参数,则一直返回到原数组的最后一个成员。 +它的第一个参数为起始位置(从0开始,会包括在返回的新数组之中),第二个参数为终止位置(但该位置的元素本身不包括在内)。如果省略第二个参数,则一直返回到原数组的最后一个成员。 ```javascript var a = ['a', 'b', 'c']; @@ -300,9 +300,9 @@ a.slice(2, 6) // ["c"] a.slice() // ["a", "b", "c"] ``` -上面代码中,最后一个例子`slice`没有参数,实际上等于返回一个原数组的拷贝。 +上面代码中,最后一个例子`slice()`没有参数,实际上等于返回一个原数组的拷贝。 -如果`slice`方法的参数是负数,则表示倒数计算的位置。 +如果`slice()`方法的参数是负数,则表示倒数计算的位置。 ```javascript var a = ['a', 'b', 'c']; @@ -320,7 +320,7 @@ a.slice(4) // [] a.slice(2, 1) // [] ``` -`slice`方法的一个重要应用,是将类似数组的对象转为真正的数组。 +`slice()`方法的一个重要应用,是将类似数组的对象转为真正的数组。 ```javascript Array.prototype.slice.call({ 0: 'a', 1: 'b', length: 2 }) @@ -330,11 +330,11 @@ Array.prototype.slice.call(document.querySelectorAll("div")); Array.prototype.slice.call(arguments); ``` -上面代码的参数都不是数组,但是通过`call`方法,在它们上面调用`slice`方法,就可以把它们转为真正的数组。 +上面代码的参数都不是数组,但是通过`call`方法,在它们上面调用`slice()`方法,就可以把它们转为真正的数组。 ### splice() -`splice`方法用于删除原数组的一部分成员,并可以在删除的位置添加新的数组成员,返回值是被删除的元素。注意,该方法会改变原数组。 +`splice()`方法用于删除原数组的一部分成员,并可以在删除的位置添加新的数组成员,返回值是被删除的元素。注意,该方法会改变原数组。 ```javascript arr.splice(start, count, addElement1, addElement2, ...); From 2f728aa4e40a805bc1319b8322dc2eea46bb619b Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 17 Mar 2020 19:29:57 +0800 Subject: [PATCH 003/152] docs(DOM): fix #167 --- docs/dom/general.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/dom/general.md b/docs/dom/general.md index 0382a94..7e08332 100644 --- a/docs/dom/general.md +++ b/docs/dom/general.md @@ -17,7 +17,7 @@ DOM 的最小组成单位叫做节点(node)。文档的树形结构(DOM - `Document`:整个文档树的顶层节点 - `DocumentType`:`doctype`标签(比如``) - `Element`:网页的各种HTML标签(比如``、``等) -- `Attribute`:网页元素的属性(比如`class="right"`) +- `Attr`:网页元素的属性(比如`class="right"`) - `Text`:标签之间或标签包含的文本 - `Comment`:注释 - `DocumentFragment`:文档的片段 @@ -26,7 +26,7 @@ DOM 的最小组成单位叫做节点(node)。文档的树形结构(DOM ## 节点树 -一个文档的所有节点,按照所在的层级,可以抽象成一种树状结构。这种树状结构就是 DOM 树。它有一个顶层节点,下一层都是顶层节点的子节点,然后子节点又有自己的子节点,就这样层层衍生出一个金字塔结构,倒过来就像一棵树。 +一个文档的所有节点,按照所在的层级,可以抽象成一种树状结构。这种树状结构就是 DOM 树。它有一个顶层节点,下一层都是顶层节点的子节点,然后子节点又有自己的子节点,就这样层层衍生出一个金字塔结构,又像一棵树。 浏览器原生提供`document`节点,代表整个文档。 From 0f286ea45b6be28df51d65e6aedfa15c3889e20a Mon Sep 17 00:00:00 2001 From: xiaobeiqiaodaima <32065775+xiaobeiqiaodaima@users.noreply.github.com> Date: Tue, 17 Mar 2020 23:27:16 +0800 Subject: [PATCH 004/152] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E6=8F=90=E5=8D=87=E8=A1=A8=E8=BF=B0=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 同时采用`function`命令和赋值语句声明同一个函数。调用函数的位置如果在顶部,会采用声明语句,调用函数的位置在赋值语句后面,就会采用赋值语句的定义。 --- docs/types/function.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/types/function.md b/docs/types/function.md index 71df9bb..c87b266 100644 --- a/docs/types/function.md +++ b/docs/types/function.md @@ -186,7 +186,7 @@ f(); f = function () {}; ``` -上面代码第二行,调用`f`的时候,`f`只是被声明了,还没有被赋值,等于`undefined`,所以会报错。因此,如果同时采用`function`命令和赋值语句声明同一个函数,最后总是采用赋值语句的定义。 +上面代码第二行,调用`f`的时候,`f`只是被声明了,还没有被赋值,等于`undefined`,所以会报错。因此,如果同时采用`function`命令和赋值语句声明同一个函数,调用函数的位置如果在顶部,会采用声明语句,调用函数的位置在赋值语句后面,就会采用赋值语句的定义。 ```javascript var f = function () { From aa26f6db13a9bf72e0ec8f234d2f69129be2ada4 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 18 Mar 2020 13:21:22 +0800 Subject: [PATCH 005/152] =?UTF-8?q?docs(types/function):=20edit=20?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E6=8F=90=E5=8D=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/types/function.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/types/function.md b/docs/types/function.md index c87b266..cb028b4 100644 --- a/docs/types/function.md +++ b/docs/types/function.md @@ -186,7 +186,9 @@ f(); f = function () {}; ``` -上面代码第二行,调用`f`的时候,`f`只是被声明了,还没有被赋值,等于`undefined`,所以会报错。因此,如果同时采用`function`命令和赋值语句声明同一个函数,调用函数的位置如果在顶部,会采用声明语句,调用函数的位置在赋值语句后面,就会采用赋值语句的定义。 +上面代码第二行,调用`f`的时候,`f`只是被声明了,还没有被赋值,等于`undefined`,所以会报错。 + +注意,如果像下面例子那样,采用`function`命令和`var`赋值语句声明同一个函数,由于存在函数提升,最后会采用`var`赋值语句的定义。 ```javascript var f = function () { @@ -200,6 +202,8 @@ function f() { f() // 1 ``` +上面例子中,表面上后面声明的函数`f`,应该覆盖前面的`var`赋值语句,但是由于存在函数提升,实际上正好反过来。 + ## 函数的属性和方法 ### name 属性 From a4bd6ee0dbb064bc79d7b7b546bd8cc42cda1042 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 7 Apr 2020 01:15:40 +0800 Subject: [PATCH 006/152] docs(stdlib): edit math/Math.pow() --- docs/stdlib/math.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/stdlib/math.md b/docs/stdlib/math.md index de60029..a36cd38 100644 --- a/docs/stdlib/math.md +++ b/docs/stdlib/math.md @@ -37,7 +37,7 @@ Math.SQRT2 // 1.4142135623730951 - `Math.floor()`:向下取整 - `Math.max()`:最大值 - `Math.min()`:最小值 -- `Math.pow()`:指数运算 +- `Math.pow()`:幂运算 - `Math.sqrt()`:平方根 - `Math.log()`:自然对数 - `Math.exp()`:`e`的指数 @@ -121,7 +121,7 @@ Math.round(-1.6) // -2 ### Math.pow() -`Math.pow`方法返回以第一个参数为底数、第二个参数为幂的指数值。 +`Math.pow`方法返回以第一个参数为底数、第二个参数为指数的幂运算值。 ```javascript // 等同于 2 ** 2 From 65d72c0486ffc83f65619c90c7da9e94496955be Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 7 Apr 2020 01:31:21 +0800 Subject: [PATCH 007/152] docs(stdlib/string): fix typo --- docs/stdlib/string.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/stdlib/string.md b/docs/stdlib/string.md index 08feda3..f155546 100644 --- a/docs/stdlib/string.md +++ b/docs/stdlib/string.md @@ -110,7 +110,7 @@ s.charAt(s.length - 1) // "c" ### String.prototype.charCodeAt() -`charCodeAt`方法返回字符串指定位置的 Unicode 码点(十进制表示),相当于`String.fromCharCode()`的逆操作。 +`charCodeAt()`方法返回字符串指定位置的 Unicode 码点(十进制表示),相当于`String.fromCharCode()`的逆操作。 ```javascript 'abc'.charCodeAt(1) // 98 @@ -131,7 +131,7 @@ s.charAt(s.length - 1) // "c" 'abc'.charCodeAt(4) // NaN ``` -注意,`charCodeAt`方法返回的 Unicode 码点不会大于65536(0xFFFF),也就是说,只返回两个字节的字符的码点。如果遇到码点大于 65536 的字符(四个字节的字符),必需连续使用两次`charCodeAt`,不仅读入`charCodeAt(i)`,还要读入`charCodeAt(i+1)`,将两个值放在一起,才能得到准确的字符。 +注意,`charCodeAt`方法返回的 Unicode 码点不会大于65536(0xFFFF),也就是说,只返回两个字节的字符的码点。如果遇到码点大于 65536 的字符(四个字节的字符),必须连续使用两次`charCodeAt`,不仅读入`charCodeAt(i)`,还要读入`charCodeAt(i+1)`,将两个值放在一起,才能得到准确的字符。 ### String.prototype.concat() From 5075536146334f3cd6a3b9fd1179e2a6479fe212 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 14 Apr 2020 00:24:52 +0800 Subject: [PATCH 008/152] docs(stdlib): edit array --- docs/stdlib/array.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/stdlib/array.md b/docs/stdlib/array.md index 5c999da..f2d971f 100644 --- a/docs/stdlib/array.md +++ b/docs/stdlib/array.md @@ -10,9 +10,9 @@ arr.length // 2 arr // [ empty x 2 ] ``` -上面代码中,`Array`构造函数的参数`2`,表示生成一个两个成员的数组,每个位置都是空值。 +上面代码中,`Array()`构造函数的参数`2`,表示生成一个两个成员的数组,每个位置都是空值。 -如果没有使用`new`,运行结果也是一样的。 +如果没有使用`new`关键字,运行结果也是一样的。 ```javascript var arr = new Array(2); @@ -20,7 +20,9 @@ var arr = new Array(2); var arr = Array(2); ``` -`Array`构造函数有一个很大的缺陷,就是不同的参数,会导致它的行为不一致。 +考虑到语义性,以及与其他构造函数用户保持一致,建议总是加上`new`。 + +`Array()`构造函数有一个很大的缺陷,不同的参数会导致行为不一致。 ```javascript // 无参数时,返回一个空数组 @@ -44,7 +46,7 @@ new Array(1, 2) // [1, 2] new Array('a', 'b', 'c') // ['a', 'b', 'c'] ``` -可以看到,`Array`作为构造函数,行为很不一致。因此,不建议使用它生成新数组,直接使用数组字面量是更好的做法。 +可以看到,`Array()`作为构造函数,行为很不一致。因此,不建议使用它生成新数组,直接使用数组字面量是更好的做法。 ```javascript // bad @@ -54,7 +56,7 @@ var arr = new Array(1, 2); var arr = [1, 2]; ``` -注意,如果参数是一个正整数,返回数组的成员都是空位。虽然读取的时候返回`undefined`,但实际上该位置没有任何值。虽然可以取到`length`属性,但是取不到键名。 +注意,如果参数是一个正整数,返回数组的成员都是空位。虽然读取的时候返回`undefined`,但实际上该位置没有任何值。虽然这时可以读取到`length`属性,但是取不到键名。 ```javascript var a = new Array(3); @@ -70,7 +72,7 @@ b[0] // undefined 0 in b // true ``` -上面代码中,`a`是一个长度为3的空数组,`b`是一个三个成员都是`undefined`的数组。读取键值的时候,`a`和`b`都返回`undefined`,但是`a`的键位都是空的,`b`的键位是有值的。 +上面代码中,`a`是`Array()`生成的一个长度为3的空数组,`b`是一个三个成员都是`undefined`的数组,这两个数组是不一样的。读取键值的时候,`a`和`b`都返回`undefined`,但是`a`的键名(成员的序号)都是空的,`b`的键名是有值的。 ## 静态方法 From 24db3a8758e209e482d4e2080a4dcfce15841796 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 14 Apr 2020 00:27:21 +0800 Subject: [PATCH 009/152] refactor: update dependencies --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 66e3f26..8487f50 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "homepage": "https://github.com/wangdoc/javascript-tutorial", "dependencies": { "gh-pages": "latest", - "husky": "^3.0.8", + "husky": "latest", "loppo": "latest", "loppo-theme-wangdoc": "latest" } From 7d37676b8a9f2da8d71612953f46195cbdbc9714 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 14 Apr 2020 00:29:56 +0800 Subject: [PATCH 010/152] refactor: update travis-ci node.js version --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6304e69..0a1ded5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: -- '10' +- 'node' branches: only: From 2baaafd4f3de2fb459eb1a0a9c1db8f347f732eb Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 14 Apr 2020 00:33:21 +0800 Subject: [PATCH 011/152] refactor: add lopp server command --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 8487f50..c4b5ac2 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "build-and-commit": "npm run build && npm run commit", "commit": "gh-pages --dist dist --dest dist/javascript --branch master --add --repo git@github.com:wangdoc/website.git", "chapter": "loppo chapter", + "server": "loppo server", "test": "echo \"Error: no test specified\" && exit 1" }, "husky": { From 1dad034da3a3a72d12e20248057c4354e7f7d095 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 14 Apr 2020 16:02:11 +0800 Subject: [PATCH 012/152] docs(types): edit function --- docs/types/function.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/types/function.md b/docs/types/function.md index cb028b4..66265d9 100644 --- a/docs/types/function.md +++ b/docs/types/function.md @@ -260,7 +260,7 @@ f.length // 2 ### toString() -函数的`toString`方法返回一个字符串,内容是函数的源码。 +函数的`toString()`方法返回一个字符串,内容是函数的源码。 ```javascript function f() { @@ -284,7 +284,7 @@ Math.sqrt.toString() // "function sqrt() { [native code] }" ``` -上面代码中,`Math.sqrt`是 JavaScript 引擎提供的原生函数,`toString()`方法就返回原生代码的提示。 +上面代码中,`Math.sqrt()`是 JavaScript 引擎提供的原生函数,`toString()`方法就返回原生代码的提示。 函数内部的注释也可以返回。 @@ -550,7 +550,7 @@ f(obj); obj // [1, 2, 3] ``` -上面代码中,在函数`f`内部,参数对象`obj`被整个替换成另一个值。这时不会影响到原始值。这是因为,形式参数(`o`)的值实际是参数`obj`的地址,重新对`o`赋值导致`o`指向另一个地址,保存在原地址上的值当然不受影响。 +上面代码中,在函数`f()`内部,参数对象`obj`被整个替换成另一个值。这时不会影响到原始值。这是因为,形式参数(`o`)的值实际是参数`obj`的地址,重新对`o`赋值导致`o`指向另一个地址,保存在原地址上的值当然不受影响。 ### 同名参数 @@ -564,7 +564,7 @@ function f(a, a) { f(1, 2) // 2 ``` -上面代码中,函数`f`有两个参数,且参数名都是`a`。取值的时候,以后面的`a`为准,即使后面的`a`没有值或被省略,也是以其为准。 +上面代码中,函数`f()`有两个参数,且参数名都是`a`。取值的时候,以后面的`a`为准,即使后面的`a`没有值或被省略,也是以其为准。 ```javascript function f(a, a) { @@ -574,7 +574,7 @@ function f(a, a) { f(1) // undefined ``` -调用函数`f`的时候,没有提供第二个参数,`a`的取值就变成了`undefined`。这时,如果要获得第一个`a`的值,可以使用`arguments`对象。 +调用函数`f()`的时候,没有提供第二个参数,`a`的取值就变成了`undefined`。这时,如果要获得第一个`a`的值,可以使用`arguments`对象。 ```javascript function f(a, a) { @@ -617,7 +617,7 @@ var f = function(a, b) { f(1, 1) // 5 ``` -上面代码中,函数`f`调用时传入的参数,在函数内部被修改成`3`和`2`。 +上面代码中,函数`f()`调用时传入的参数,在函数内部被修改成`3`和`2`。 严格模式下,`arguments`对象与函数参数不具有联动关系。也就是说,修改`arguments`对象不会影响到实际的函数参数。 From 0ea89ff02667b75bce80888e674528b8782a01fb Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 14 Apr 2020 16:26:42 +0800 Subject: [PATCH 013/152] docs(dom): edit mutation observer --- docs/dom/mutationobserver.md | 10 +++++----- package.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/dom/mutationobserver.md b/docs/dom/mutationobserver.md index 139709b..12651c2 100644 --- a/docs/dom/mutationobserver.md +++ b/docs/dom/mutationobserver.md @@ -36,7 +36,7 @@ var observer = new MutationObserver(function (mutations, observer) { ### observe() -`observe`方法用来启动监听,它接受两个参数。 +`observe()`方法用来启动监听,它接受两个参数。 - 第一个参数:所要观察的 DOM 节点 - 第二个参数:一个配置对象,指定所要观察的特定变动 @@ -52,7 +52,7 @@ var options = { observer.observe(article, options); ``` -上面代码中,`observe`方法接受两个参数,第一个是所要观察的DOM元素是`article`,第二个是所要观察的变动类型(子节点变动和属性变动)。 +上面代码中,`observe()`方法接受两个参数,第一个是所要观察的DOM元素是`article`,第二个是所要观察的变动类型(子节点变动和属性变动)。 观察器所能观察的 DOM 变动类型(即上面代码的`options`对象),有以下几种。 @@ -81,7 +81,7 @@ mutationObserver.observe(document.documentElement, { }); ``` -对一个节点添加观察器,就像使用`addEventListener`方法一样,多次添加同一个观察器是无效的,回调函数依然只会触发一次。如果指定不同的`options`对象,以后面添加的那个为准,类似覆盖。 +对一个节点添加观察器,就像使用`addEventListener()`方法一样,多次添加同一个观察器是无效的,回调函数依然只会触发一次。如果指定不同的`options`对象,以后面添加的那个为准,类似覆盖。 下面的例子是观察新增的子节点。 @@ -100,13 +100,13 @@ observer.observe(document, { childList: true, subtree: true }); ### disconnect(),takeRecords() -`disconnect`方法用来停止观察。调用该方法后,DOM 再发生变动,也不会触发观察器。 +`disconnect()`方法用来停止观察。调用该方法后,DOM 再发生变动,也不会触发观察器。 ```javascript observer.disconnect(); ``` -`takeRecords`方法用来清除变动记录,即不再处理未处理的变动。该方法返回变动记录的数组。 +`takeRecords()`方法用来清除变动记录,即不再处理未处理的变动。该方法返回变动记录的数组。 ```javascript observer.takeRecords(); diff --git a/package.json b/package.json index c4b5ac2..cd2b54a 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,6 @@ "gh-pages": "latest", "husky": "latest", "loppo": "latest", - "loppo-theme-wangdoc": "latest" + "loppo-theme-wangdoc": "^0.4.0" } } From d6847629e63102868c003cfac1f47a341c4e3e05 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 15 Apr 2020 03:02:52 +0800 Subject: [PATCH 014/152] docs(dom): edit element --- docs/dom/element.md | 6 +++++- package.json | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/dom/element.md b/docs/dom/element.md index 7593f9e..82c276b 100644 --- a/docs/dom/element.md +++ b/docs/dom/element.md @@ -1,5 +1,7 @@ # Element 节点 +## 简介 + `Element`节点对象对应网页的 HTML 元素。每一个 HTML 元素,在 DOM 树上都会转化成一个`Element`节点对象(以下简称元素节点)。 元素节点的`nodeType`属性都是`1`。 @@ -10,7 +12,9 @@ p.nodeName // "P" p.nodeType // 1 ``` -`Element`对象继承了`Node`接口,因此`Node`的属性和方法在`Element`对象都存在。此外,不同的 HTML 元素对应的元素节点是不一样的,浏览器使用不同的构造函数,生成不同的元素节点,比如``元素的节点对象由`HTMLAnchorElement`构造函数生成,` +
+
``` From 91161ff51f6e2e4b307788f44111574ebd86706e Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 14 May 2020 17:14:08 +0800 Subject: [PATCH 019/152] docs(operator): edit bit operator --- docs/operators/bit.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/operators/bit.md b/docs/operators/bit.md index f02a028..edbb8b4 100644 --- a/docs/operators/bit.md +++ b/docs/operators/bit.md @@ -303,7 +303,7 @@ var FLAG_D = 8; // 1000 上面代码设置 A、B、C、D 四个开关,每个开关分别占有一个二进制位。 -然后,就可以用二进制与运算检验,当前设置是否打开了指定开关。 +然后,就可以用二进制与运算,检查当前设置是否打开了指定开关。 ```javascript var flags = 5; // 二进制的0101 @@ -331,6 +331,8 @@ var mask = FLAG_A | FLAG_B | FLAG_D; flags = flags | mask; ``` +上面代码中,计算后得到的`flags`变量,代表三个开关的二进制位都打开了。 + 二进制与运算可以将当前设置中凡是与开关设置不一样的项,全部关闭。 ```javascript From 1b0b7b87e6585dc06cd453ac5572577470dab82b Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 22 May 2020 12:19:59 +0800 Subject: [PATCH 020/152] docs(event): edit load / unload event --- docs/events/common.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/events/common.md b/docs/events/common.md index d6e731a..13bab7f 100644 --- a/docs/events/common.md +++ b/docs/events/common.md @@ -27,9 +27,9 @@ window.addEventListener('beforeunload', function (e) { }); ``` -注意,许多手机浏览器默认忽略这个事件,桌面浏览器也有办法忽略这个事件。所以,它可能根本不会生效,不能依赖它来阻止用户关闭窗口。另外,一旦使用了`beforeunload`事件,浏览器就不会缓存当前网页,使用“回退”按钮将重新向服务器请求网页。这是因为监听这个事件的目的,一般是修改初始状态,这时缓存初始页面就没意义了。 +注意,许多手机浏览器(比如 Safari)默认忽略这个事件,桌面浏览器也有办法忽略这个事件。所以,它可能根本不会生效,不能依赖它来阻止用户关闭浏览器窗口,最好不要使用这个事件。 -基本上,只有一种场合可以监听`unload`事件,其他情况都不应该监听:用户修改了表单,还没有保存就要离开。 +另外,一旦使用了`beforeunload`事件,浏览器就不会缓存当前网页,使用“回退”按钮将重新向服务器请求网页。这是因为监听这个事件的目的,一般是为了网页状态,这时缓存页面的初始状态就没意义了。 ### unload 事件 @@ -45,6 +45,8 @@ window.addEventListener('unload', function(event) { 手机上,浏览器或系统可能会直接丢弃网页,这时该事件根本不会发生。而且跟`beforeunload`事件一样,一旦使用了`unload`事件,浏览器就不会缓存当前网页,理由同上。因此,任何情况下都不应该依赖这个事件,指定网页卸载时要执行的代码,可以考虑完全不使用这个事件。 +该事件可以用`pagehide`代替。 + ### load 事件,error 事件 `load`事件在页面或某个资源加载成功时触发。注意,页面或资源从浏览器缓存加载,并不会触发`load`事件。 @@ -59,13 +61,15 @@ window.addEventListener('load', function(event) { 这三个事件实际上属于进度事件,不仅发生在`document`对象,还发生在各种外部资源上面。浏览网页就是一个加载各种资源的过程,图像(image)、样式表(style sheet)、脚本(script)、视频(video)、音频(audio)、Ajax请求(XMLHttpRequest)等等。这些资源和`document`对象、`window`对象、XMLHttpRequestUpload 对象,都会触发`load`事件和`error`事件。 +最后,页面的`load`事件也可以用`pageshow`事件代替。 + ## session 历史事件 ### pageshow 事件,pagehide 事件 默认情况下,浏览器会在当前会话(session)缓存页面,当用户点击“前进/后退”按钮时,浏览器就会从缓存中加载页面。 -pageshow 事件在页面加载时触发,包括第一次加载和从缓存加载两种情况。如果要指定页面每次加载(不管是不是从浏览器缓存)时都运行的代码,可以放在这个事件的监听函数。 +`pageshow`事件在页面加载时触发,包括第一次加载和从缓存加载两种情况。如果要指定页面每次加载(不管是不是从浏览器缓存)时都运行的代码,可以放在这个事件的监听函数。 第一次加载时,它的触发顺序排在`load`事件后面。从缓存加载时,`load`事件不会触发,因为网页在缓存中的样子通常是`load`事件的监听函数运行后的样子,所以不必重复执行。同理,如果是从缓存中加载页面,网页内初始化的 JavaScript 脚本(比如 DOMContentLoaded 事件的监听函数)也不会执行。 @@ -75,7 +79,7 @@ window.addEventListener('pageshow', function(event) { }); ``` -pageshow 事件有一个`persisted`属性,返回一个布尔值。页面第一次加载时,这个属性是`false`;当页面从缓存加载时,这个属性是`true`。 +`pageshow`事件有一个`persisted`属性,返回一个布尔值。页面第一次加载时,这个属性是`false`;当页面从缓存加载时,这个属性是`true`。 ```javascript window.addEventListener('pageshow', function(event){ From 9eb914d2ad23e8151002da92423a755661afd862 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Mon, 25 May 2020 17:27:25 +0800 Subject: [PATCH 021/152] docs(types): edit array --- docs/types/array.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/types/array.md b/docs/types/array.md index d2fde5b..6f9d054 100644 --- a/docs/types/array.md +++ b/docs/types/array.md @@ -124,7 +124,7 @@ arr.length // 1001 上面代码表示,数组的数字键不需要连续,`length`属性的值总是比最大的那个整数键大`1`。另外,这也表明数组是一种动态的数据结构,可以随时增减数组的成员。 -`length`属性是可写的。如果人为设置一个小于当前成员个数的值,该数组的成员会自动减少到`length`设置的值。 +`length`属性是可写的。如果人为设置一个小于当前成员个数的值,该数组的成员数量会自动减少到`length`设置的值。 ```javascript var arr = [ 'a', 'b', 'c' ]; From 48619c081d054eaeb6321d269ebc7306340151ee Mon Sep 17 00:00:00 2001 From: ruanyf Date: Mon, 25 May 2020 17:53:19 +0800 Subject: [PATCH 022/152] =?UTF-8?q?docs(operator):=20edit=20=E7=BB=93?= =?UTF-8?q?=E5=90=88=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/operators/priority.md | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/docs/operators/priority.md b/docs/operators/priority.md index 8b2a65a..d347f87 100644 --- a/docs/operators/priority.md +++ b/docs/operators/priority.md @@ -162,34 +162,56 @@ f() // 1 ### 左结合与右结合 -对于优先级别相同的运算符,大多数情况,计算顺序总是从左到右,这叫做运算符的“左结合”(left-to-right associativity),即从左边开始计算。 +对于优先级别相同的运算符,同时出现的时候,就会有计算顺序的问题。 + +```javascript +a OP b OP c +``` + +上面代码中,`OP`表示运算符。它可以有两种解释方式。 + +```javascript +// 方式一 +(a OP b) OP c + +// 方式二 +a OP (b OP c) +``` + +上面的两种方式,得到的计算结果往往是不一样的。方式一是将左侧两个运算数结合在一起,采用这种解释方式的运算符,称为“左结合”(left-to-right associativity)运算符;方式二是将右侧两个运算数结合在一起,这样的运算符称为“右结合”运算符(right-to-left associativity)。 + +JavaScript 语言的大多数运算符是“左结合”,请看下面加法运算符的例子。 ```javascript x + y + z + +// 引擎解释如下 +(x + y) + z ``` -上面代码先计算最左边的`x`与`y`的和,然后再计算与`z`的和。 +上面代码中,`x`与`y`结合在一起,它们的预算结果再与`z`进行运算。 -但是少数运算符的计算顺序是从右到左,即从右边开始计算,这叫做运算符的“右结合”(right-to-left associativity)。其中,最主要的是赋值运算符(`=`)和三元条件运算符(`?:`)。 +少数运算符是“右结合”,其中最主要的是赋值运算符(`=`)和三元条件运算符(`?:`)。 ```javascript w = x = y = z; q = a ? b : c ? d : e ? f : g; ``` -上面代码的运算结果,相当于下面的样子。 +上面代码的解释方式如下。 ```javascript w = (x = (y = z)); q = a ? b : (c ? d : (e ? f : g)); ``` -上面的两行代码,各有三个等号运算符和三个三元运算符,都是先计算最右边的那个运算符。 +上面的两行代码,都是右侧的运算数结合在一起。 -指数运算符(`**`)也是右结合的。 +另外,指数运算符(`**`)也是右结合。 ```javascript -// 相当于 2 ** (3 ** 2) 2 ** 3 ** 2 +// 相当于 2 ** (3 ** 2) // 512 ``` + From 0d10e3bef5f2b4d52749a73e361c4812bb37e709 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sun, 31 May 2020 11:26:31 +0800 Subject: [PATCH 023/152] =?UTF-8?q?docs(bom):=20edit=20=E5=90=8C=E6=BA=90?= =?UTF-8?q?=E6=94=BF=E7=AD=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/bom/cookie.md | 2 +- docs/bom/same-origin.md | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/bom/cookie.md b/docs/bom/cookie.md index a18ff85..9c7f53b 100644 --- a/docs/bom/cookie.md +++ b/docs/bom/cookie.md @@ -36,7 +36,7 @@ document.cookie // "id=foo;key=bar" 不同浏览器对 Cookie 数量和大小的限制,是不一样的。一般来说,单个域名设置的 Cookie 不应超过30个,每个 Cookie 的大小不能超过4KB。超过限制以后,Cookie 将被忽略,不会被设置。 -浏览器的同源政策规定,两个网址只要域名相同和端口相同,就可以共享 Cookie(参见《同源政策》一章)。注意,这里不要求协议相同。也就是说,`http://example.com`设置的 Cookie,可以被`https://example.com`读取。 +浏览器的同源政策规定,两个网址只要域名相同,就可以共享 Cookie(参见《同源政策》一章)。注意,这里不要求协议相同。也就是说,`http://example.com`设置的 Cookie,可以被`https://example.com`读取。 ## Cookie 与 HTTP 协议 diff --git a/docs/bom/same-origin.md b/docs/bom/same-origin.md index 23d6c56..553dc39 100644 --- a/docs/bom/same-origin.md +++ b/docs/bom/same-origin.md @@ -12,7 +12,7 @@ > - 协议相同 > - 域名相同 -> - 端口相同 +> - 端口相同(这点可以忽略,详见下文) 举例来说,`http://www.example.com/dir/page.html`这个网址,协议是`http://`,域名是`www.example.com`,端口是`80`(默认端口可以省略),它的同源情况如下。 @@ -22,11 +22,13 @@ - `http://www.example.com:81/dir/other.html`:不同源(端口不同) - `https://www.example.com/dir/page.html`:不同源(协议不同) +注意,标准规定端口不同的网址不是同源(比如8000端口和8001端口不是同源),但是浏览器没有遵守这条规定。实际上,同一个网域的不同端口,是可以互相读取 Cookie 的。 + ### 目的 同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。 -设想这样一种情况:A 网站是一家银行,用户登录以后,A 网站在用户的机器上设置了一个 Cookie,包含了一些隐私信息(比如存款总额)。用户离开 A 网站以后,又去访问 B 网站,如果没有同源限制,B 网站可以读取 A 网站的 Cookie,那么隐私信息就会泄漏。更可怕的是,Cookie 往往用来保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。因为浏览器同时还规定,提交表单不受同源政策的限制。 +设想这样一种情况:A 网站是一家银行,用户登录以后,A 网站在用户的机器上设置了一个 Cookie,包含了一些隐私信息。用户离开 A 网站以后,又去访问 B 网站,如果没有同源限制,B 网站可以读取 A 网站的 Cookie,那么隐私就泄漏了。更可怕的是,Cookie 往往用来保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。因为浏览器同时还规定,提交表单不受同源政策的限制。 由此可见,同源政策是必需的,否则 Cookie 可以共享,互联网就毫无安全可言了。 @@ -56,7 +58,7 @@ - window.focus() - window.postMessage() -上面的九个属性之中,只有`window.location`是可读写的,其他八个全部都是只读。而且,即使是`location`对象,非同源的情况下,也只允许调用`location.replace`方法和写入`location.href`属性。 +上面的九个属性之中,只有`window.location`是可读写的,其他八个全部都是只读。而且,即使是`location`对象,非同源的情况下,也只允许调用`location.replace()`方法和写入`location.href`属性。 虽然这些限制是必要的,但是有时很不方便,合理的用途也受到影响。下面介绍如何规避上面的限制。 From 7afc47774546232445ebb5f3713411e392d8ce21 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sun, 31 May 2020 11:28:39 +0800 Subject: [PATCH 024/152] refactor: update dependencies --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index cd7c434..b556c0d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -512,9 +512,9 @@ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" }, "gh-pages": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-2.2.0.tgz", - "integrity": "sha512-c+yPkNOPMFGNisYg9r4qvsMIjVYikJv7ImFOhPIVPt0+AcRUamZ7zkGRLHz7FKB0xrlZ+ddSOJsZv9XAFVXLmA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-3.0.0.tgz", + "integrity": "sha512-oaOfVcrSwnqoWUgZ6cmCDM6mUuWyOSG+SHjqxGBawN0F3SKaF5NwbeYDG+w2RNXO2HJ/5Iam4o7dP5NAtoHuwQ==", "requires": { "async": "^2.6.1", "commander": "^2.18.0", diff --git a/package.json b/package.json index 0ba3685..b5fc37f 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ }, "homepage": "https://github.com/wangdoc/javascript-tutorial", "dependencies": { - "gh-pages": "latest", + "gh-pages": "^3.0.0", "husky": "latest", "loppo": "latest", "loppo-theme-wangdoc": "^0.4.6" From 3f8e88a297b525e89aa635c7a392dc3fc99ef43d Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 12 Jun 2020 00:01:10 +0800 Subject: [PATCH 025/152] docs(stdlib/attribute): fix #175 --- docs/stdlib/attributes.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/stdlib/attributes.md b/docs/stdlib/attributes.md index 851ac0a..1440a67 100644 --- a/docs/stdlib/attributes.md +++ b/docs/stdlib/attributes.md @@ -445,7 +445,7 @@ obj.p2 // 2 除了直接定义以外,属性还可以用存取器(accessor)定义。其中,存值函数称为`setter`,使用属性描述对象的`set`属性;取值函数称为`getter`,使用属性描述对象的`get`属性。 -一旦对目标属性定义了存取器,那么存取的时候,都将执行对应的函数。利用这个功能,可以实现许多高级特性,比如某个属性禁止赋值。 +一旦对目标属性定义了存取器,那么存取的时候,都将执行对应的函数。利用这个功能,可以实现许多高级特性,比如定制属性的读取和赋值行为。 ```javascript var obj = Object.defineProperty({}, 'p', { @@ -466,6 +466,7 @@ obj.p = 123 // "setter: 123" JavaScript 还提供了存取器的另一种写法。 ```javascript +// 写法二 var obj = { get p() { return 'getter'; @@ -476,7 +477,7 @@ var obj = { }; ``` -上面的写法与定义属性描述对象是等价的,而且使用更广泛。 +上面两种写法,虽然属性`p`的读取和赋值行为是一样的,但是有一些细微的区别。第一种写法,属性`p`的`configurable`和`enumerable`都为`false`,从而导致属性`p`是不可遍历的;第二种写法,属性`p`的`configurable`和`enumerable`都为`true`,因此属性`p`是可遍历的。实际开发中,写法二更常用。 注意,取值函数`get`不能接受参数,存值函数`set`只能接受一个参数(即属性的值)。 From 4b98a2ca237dfb806005584c769eaeff534fbbd2 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 12 Jun 2020 15:39:13 +0800 Subject: [PATCH 026/152] =?UTF-8?q?docs(stdlib/regex):=20edit=20=E8=B4=AA?= =?UTF-8?q?=E5=A9=AA=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/stdlib/regexp.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/stdlib/regexp.md b/docs/stdlib/regexp.md index 0d41c43..4d7fecb 100644 --- a/docs/stdlib/regexp.md +++ b/docs/stdlib/regexp.md @@ -694,7 +694,7 @@ var html = "Hello\nworld!"; ### 贪婪模式 -上一小节的三个量词符,默认情况下都是最大可能匹配,即匹配直到下一个字符不满足匹配规则为止。这被称为贪婪模式。 +上一小节的三个量词符,默认情况下都是最大可能匹配,即匹配到下一个字符不满足匹配规则为止。这被称为贪婪模式。 ```javascript var s = 'aaa'; @@ -703,29 +703,31 @@ s.match(/a+/) // ["aaa"] 上面代码中,模式是`/a+/`,表示匹配1个`a`或多个`a`,那么到底会匹配几个`a`呢?因为默认是贪婪模式,会一直匹配到字符`a`不出现为止,所以匹配结果是3个`a`。 -如果想将贪婪模式改为非贪婪模式,可以在量词符后面加一个问号。 +除了贪婪模式,还有非贪婪模式,即最小可能匹配。只要一发现匹配,就返回结果,不要往下检查。如果想将贪婪模式改为非贪婪模式,可以在量词符后面加一个问号。 ```javascript var s = 'aaa'; s.match(/a+?/) // ["a"] ``` -上面代码中,模式结尾添加了一个问号`/a+?/`,这时就改为非贪婪模式,一旦条件满足,就不再往下匹配。 +上面例子中,模式结尾添加了一个问号`/a+?/`,这时就改为非贪婪模式,一旦条件满足,就不再往下匹配,`+?`表示只要发现一个`a`,就不再往下匹配了。 -除了非贪婪模式的加号,还有非贪婪模式的星号(`*`)和非贪婪模式的问号(`?`)。 +除了非贪婪模式的加号(`+?`),还有非贪婪模式的星号(`*?`)和非贪婪模式的问号(`??`)。 - `+?`:表示某个模式出现1次或多次,匹配时采用非贪婪模式。 - `*?`:表示某个模式出现0次或多次,匹配时采用非贪婪模式。 - `??`:表格某个模式出现0次或1次,匹配时采用非贪婪模式。 ```javascript -'abb'.match(/ab*b/) // ["abb"] -'abb'.match(/ab*?b/) // ["ab"] +'abb'.match(/ab*/) // ["abb"] +'abb'.match(/ab*?/) // ["a"] -'abb'.match(/ab?b/) // ["abb"] -'abb'.match(/ab??b/) // ["ab"] +'abb'.match(/ab?/) // ["ab"] +'abb'.match(/ab??/) // ["a"] ``` +上面例子中,`/ab*/`表示如果`a`后面有多个`b`,那么匹配尽可能多的`b`;`/ab*?/`表示匹配尽可能少的`b`,也就是0个`b`。 + ### 修饰符 修饰符(modifier)表示模式的附加规则,放在正则模式的最尾部。 From 7b4c045afadefaa4185e8b4df1f347410a9acd61 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 12 Jun 2020 18:17:56 +0800 Subject: [PATCH 027/152] docs(string): fixed slice() #176 --- docs/stdlib/string.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/stdlib/string.md b/docs/stdlib/string.md index f155546..63d21fa 100644 --- a/docs/stdlib/string.md +++ b/docs/stdlib/string.md @@ -166,7 +166,7 @@ one + two + three // "33" ### String.prototype.slice() -`slice`方法用于从原字符串取出子字符串并返回,不改变原字符串。它的第一个参数是子字符串的开始位置,第二个参数是子字符串的结束位置(不含该位置)。 +`slice()`方法用于从原字符串取出子字符串并返回,不改变原字符串。它的第一个参数是子字符串的开始位置,第二个参数是子字符串的结束位置(不含该位置)。 ```javascript 'JavaScript'.slice(0, 4) // "Java" @@ -186,7 +186,7 @@ one + two + three // "33" 'JavaScript'.slice(-2, -1) // "p" ``` -如果第一个参数大于第二个参数,`slice`方法返回一个空字符串。 +如果第一个参数大于第二个参数(正数情况下),`slice()`方法返回一个空字符串。 ```javascript 'JavaScript'.slice(2, 1) // "" From 2d95d1e9f9cf15f5c85dfc688a25b09b6ee5ff62 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Mon, 22 Jun 2020 01:12:10 +0800 Subject: [PATCH 028/152] docs(dom): edit document.getElementsByTagName --- docs/dom/document.md | 16 ++++++++-------- docs/dom/element.md | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/dom/document.md b/docs/dom/document.md index 8e08982..46da3e9 100644 --- a/docs/dom/document.md +++ b/docs/dom/document.md @@ -496,7 +496,7 @@ document.querySelectorAll('DIV, A, SCRIPT'); ### document.getElementsByTagName() -`document.getElementsByTagName`方法搜索 HTML 标签名,返回符合条件的元素。它的返回值是一个类似数组对象(`HTMLCollection`实例),可以实时反映 HTML 文档的变化。如果没有任何匹配的元素,就返回一个空集。 +`document.getElementsByTagName()`方法搜索 HTML 标签名,返回符合条件的元素。它的返回值是一个类似数组对象(`HTMLCollection`实例),可以实时反映 HTML 文档的变化。如果没有任何匹配的元素,就返回一个空集。 ```javascript var paras = document.getElementsByTagName('p'); @@ -505,7 +505,7 @@ paras instanceof HTMLCollection // true 上面代码返回当前文档的所有`p`元素节点。 -HTML 标签名是大小写不敏感的,因此`getElementsByTagName`方法也是大小写不敏感的。另外,返回结果中,各个成员的顺序就是它们在文档中出现的顺序。 +HTML 标签名是大小写不敏感的,因此`getElementsByTagName()`方法的参数也是大小写不敏感的。另外,返回结果中,各个成员的顺序就是它们在文档中出现的顺序。 如果传入`*`,就可以返回文档中所有 HTML 元素。 @@ -524,7 +524,7 @@ var spans = firstPara.getElementsByTagName('span'); ### document.getElementsByClassName() -`document.getElementsByClassName`方法返回一个类似数组的对象(`HTMLCollection`实例),包括了所有`class`名字符合指定条件的元素,元素的变化实时反映在返回结果中。 +`document.getElementsByClassName()`方法返回一个类似数组的对象(`HTMLCollection`实例),包括了所有`class`名字符合指定条件的元素,元素的变化实时反映在返回结果中。 ```javascript var elements = document.getElementsByClassName(names); @@ -542,7 +542,7 @@ var elements = document.getElementsByClassName('foo bar'); 注意,正常模式下,CSS 的`class`是大小写敏感的。(`quirks mode`下,大小写不敏感。) -与`getElementsByTagName`方法一样,`getElementsByClassName`方法不仅可以在`document`对象上调用,也可以在任何元素节点上调用。 +与`getElementsByTagName()`方法一样,`getElementsByClassName()`方法不仅可以在`document`对象上调用,也可以在任何元素节点上调用。 ```javascript // 非document对象上调用 @@ -551,7 +551,7 @@ var elements = rootElement.getElementsByClassName(names); ### document.getElementsByName() -`document.getElementsByName`方法用于选择拥有`name`属性的 HTML 元素(比如`
`、``、``、``、``和``等),返回一个类似数组的的对象(`NodeList`实例),因为`name`属性相同的元素可能不止一个。 +`document.getElementsByName()`方法用于选择拥有`name`属性的 HTML 元素(比如``、``、``、``、``和``等),返回一个类似数组的的对象(`NodeList`实例),因为`name`属性相同的元素可能不止一个。 ```javascript // 表单为 @@ -561,7 +561,7 @@ forms[0].tagName // "FORM" ### document.getElementById() -`document.getElementById`方法返回匹配指定`id`属性的元素节点。如果没有发现匹配的节点,则返回`null`。 +`document.getElementById()`方法返回匹配指定`id`属性的元素节点。如果没有发现匹配的节点,则返回`null`。 ```javascript var elem = document.getElementById('para1'); @@ -569,7 +569,7 @@ var elem = document.getElementById('para1'); 注意,该方法的参数是大小写敏感的。比如,如果某个节点的`id`属性是`main`,那么`document.getElementById('Main')`将返回`null`。 -`document.getElementById`方法与`document.querySelector`方法都能获取元素节点,不同之处是`document.querySelector`方法的参数使用 CSS 选择器语法,`document.getElementById`方法的参数是元素的`id`属性。 +`document.getElementById()`方法与`document.querySelector()`方法都能获取元素节点,不同之处是`document.querySelector()`方法的参数使用 CSS 选择器语法,`document.getElementById()`方法的参数是元素的`id`属性。 ```javascript document.getElementById('myElement') @@ -582,7 +582,7 @@ document.querySelector('#myElement') ### document.elementFromPoint(),document.elementsFromPoint() -`document.elementFromPoint`方法返回位于页面指定位置最上层的元素节点。 +`document.elementFromPoint()`方法返回位于页面指定位置最上层的元素节点。 ```javascript var element = document.elementFromPoint(50, 50); diff --git a/docs/dom/element.md b/docs/dom/element.md index 82c276b..b569f31 100644 --- a/docs/dom/element.md +++ b/docs/dom/element.md @@ -603,14 +603,14 @@ for (var i = 0; i< matches.length; i++) { ### Element.getElementsByTagName() -`Element.getElementsByTagName`方法返回一个`HTMLCollection`实例,成员是当前节点的所有匹配指定标签名的子元素节点。该方法与`document.getElementsByClassName`方法的用法类似,只是搜索范围不是整个文档,而是当前元素节点。 +`Element.getElementsByTagName()`方法返回一个`HTMLCollection`实例,成员是当前节点的所有匹配指定标签名的子元素节点。该方法与`document.getElementsByClassName()`方法的用法类似,只是搜索范围不是整个文档,而是当前元素节点。 ```javascript var table = document.getElementById('forecast-table'); var cells = table.getElementsByTagName('td'); ``` -注意,该方法的参数是大小写不敏感的。 +注意,该方法的参数是大小写不敏感的,因为 HTML 标签名也是大小写不敏感。 ### Element.closest() From 3d936cd2a6a204fc5fd79c6a6055021622d71ebe Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 24 Jun 2020 17:24:20 +0800 Subject: [PATCH 029/152] docs: edit README --- README.md | 7 +++++-- package-lock.json | 37 ++++++++++++++++++++++++++++++++++--- package.json | 2 +- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 521bf3a..7b47ff2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ -本教程全面介绍 JavaScript 核心语法,从最简单的讲起,循序渐进、由浅入深,力求清晰易懂。所有章节都带有大量的代码实例,便于理解和模仿,可以用到实际项目中,即学即用。 +本教程全面介绍 JavaScript 核心语法,覆盖了 ES5 和 DOM 规范的所有内容。 + +内容上从最简单的讲起,循序渐进、由浅入深,力求清晰易懂。所有章节都带有大量的代码实例,便于理解和模仿,可以用到实际项目中,即学即用。 + +本教程适合初学者当作 JavaScript 语言入门教程,学完后就可以承担实际的网页开发工作,也适合当作日常使用的参考手册。JavaScript 后续新增的 ES6 语法,请看[《ES6 标准入门教程》](https://wangdoc.com/es6/)。 -本教程适合初学者当作 JavaScript 语言入门教程,也适合当作日常使用的参考手册。 diff --git a/package-lock.json b/package-lock.json index b556c0d..896253b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -237,6 +237,11 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + }, "compare-versions": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", @@ -464,6 +469,16 @@ } } }, + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -512,14 +527,15 @@ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" }, "gh-pages": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-3.0.0.tgz", - "integrity": "sha512-oaOfVcrSwnqoWUgZ6cmCDM6mUuWyOSG+SHjqxGBawN0F3SKaF5NwbeYDG+w2RNXO2HJ/5Iam4o7dP5NAtoHuwQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-3.1.0.tgz", + "integrity": "sha512-3b1rly9kuf3/dXsT8+ZxP0UhNLOo1CItj+3e31yUVcaph/yDsJ9RzD7JOw5o5zpBTJVQLlJAASNkUfepi9fe2w==", "requires": { "async": "^2.6.1", "commander": "^2.18.0", "email-addresses": "^3.0.1", "filenamify-url": "^1.0.0", + "find-cache-dir": "^3.3.1", "fs-extra": "^8.1.0", "globby": "^6.1.0" } @@ -932,6 +948,21 @@ "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, "markdown-it": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", diff --git a/package.json b/package.json index b5fc37f..ecfb296 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ }, "homepage": "https://github.com/wangdoc/javascript-tutorial", "dependencies": { - "gh-pages": "^3.0.0", + "gh-pages": "^3.1.0", "husky": "latest", "loppo": "latest", "loppo-theme-wangdoc": "^0.4.6" From 16df62c9604b9c4aa98ac95a7c9a01bebcccefda Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 24 Jun 2020 17:29:48 +0800 Subject: [PATCH 030/152] docs: edit README --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7b47ff2..b3f09b2 100644 --- a/README.md +++ b/README.md @@ -2,5 +2,7 @@ 内容上从最简单的讲起,循序渐进、由浅入深,力求清晰易懂。所有章节都带有大量的代码实例,便于理解和模仿,可以用到实际项目中,即学即用。 -本教程适合初学者当作 JavaScript 语言入门教程,学完后就可以承担实际的网页开发工作,也适合当作日常使用的参考手册。JavaScript 后续新增的 ES6 语法,请看[《ES6 标准入门教程》](https://wangdoc.com/es6/)。 +本教程适合初学者当作 JavaScript 语言入门教程,学完后就可以承担实际的网页开发工作,也适合当作日常使用的参考手册。 + +JavaScript 后续新增的 ES6 语法,请看[《ES6 标准入门教程》](https://wangdoc.com/es6/)。 From db23e4c9c1921f43d57166db776d95537b227a44 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jul 2020 23:19:26 +0000 Subject: [PATCH 031/152] build(deps): bump lodash from 4.17.15 to 4.17.19 Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19) Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 896253b..bc1165e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -812,9 +812,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" }, "log-symbols": { "version": "3.0.0", From e793217e29835b2ec73303a9c41e30228b3d3e7f Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sun, 2 Aug 2020 16:23:14 +0800 Subject: [PATCH 032/152] =?UTF-8?q?docs(types/function):=20edit=20?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=AE=9A=E4=B9=89=E5=90=8E=E9=9D=A2=E7=9A=84?= =?UTF-8?q?=E5=9C=86=E6=8B=AC=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/types/function.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/types/function.md b/docs/types/function.md index 66265d9..70c41ee 100644 --- a/docs/types/function.md +++ b/docs/types/function.md @@ -790,7 +790,7 @@ p1.getAge() // 25 ### 立即调用的函数表达式(IIFE) -在 JavaScript 中,圆括号`()`是一种运算符,跟在函数名之后,表示调用该函数。比如,`print()`就表示调用`print`函数。 +根据 JavaScript 的语法,圆括号`()`跟在函数名之后,表示调用该函数。比如,`print()`就表示调用`print`函数。 有时,我们需要在定义函数之后,立即调用该函数。这时,你不能在函数的定义之后加上圆括号,这会产生语法错误。 @@ -809,7 +809,16 @@ function f() {} var f = function f() {} ``` -为了避免解析上的歧义,JavaScript 引擎规定,如果`function`关键字出现在行首,一律解释成语句。因此,JavaScript 引擎看到行首是`function`关键字之后,认为这一段都是函数的定义,不应该以圆括号结尾,所以就报错了。 +当作表达式时,函数可以定义后直接加圆括号调用。 + +```javascript +var f = function f(){ return 1}(); +f // 1 +``` + +上面的代码中,函数定义后直接加圆括号调用,没有报错。原因就是`function`作为表达式,引擎就把函数定义当作一个值。这种情况下,就不会报错 + +为了避免解析的歧义,JavaScript 规定,如果`function`关键字出现在行首,一律解释成语句。因此,引擎看到行首是`function`关键字之后,认为这一段都是函数的定义,不应该以圆括号结尾,所以就报错了。 解决方法就是不要让`function`出现在行首,让引擎将其理解成一个表达式。最简单的处理,就是将其放在一个圆括号里面。 From 7cb09b2ea9946635c3ac8a620e1d1aad327f83c2 Mon Sep 17 00:00:00 2001 From: Lean You <7764115+byog@users.noreply.github.com> Date: Tue, 4 Aug 2020 15:42:53 +0800 Subject: [PATCH 033/152] Update math.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 不全 Math.floor() 和 Math.ceil() 信息 --- docs/stdlib/math.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/stdlib/math.md b/docs/stdlib/math.md index a36cd38..a5e8947 100644 --- a/docs/stdlib/math.md +++ b/docs/stdlib/math.md @@ -66,14 +66,14 @@ Math.max() // -Infinity ### Math.floor(),Math.ceil() -`Math.floor`方法返回小于参数值的最大整数(地板值)。 +`Math.floor`方法返回小于或等于参数值的最大整数(地板值)。 ```javascript Math.floor(3.2) // 3 Math.floor(-3.2) // -4 ``` -`Math.ceil`方法返回大于参数值的最小整数(天花板值)。 +`Math.ceil`方法返回大于或等于参数值的最小整数(天花板值)。 ```javascript Math.ceil(3.2) // 4 From d0ae41cbc4435f9b3ffd885116760cbfe966e88b Mon Sep 17 00:00:00 2001 From: ruanyf Date: Mon, 24 Aug 2020 23:43:15 +0800 Subject: [PATCH 034/152] docs(stdlib/regex): fix typo --- docs/stdlib/regexp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stdlib/regexp.md b/docs/stdlib/regexp.md index 4d7fecb..8e306e0 100644 --- a/docs/stdlib/regexp.md +++ b/docs/stdlib/regexp.md @@ -485,7 +485,7 @@ str.split(separator, [limit]) 上面代码指的是,`a`和`b`之间有一个空格或者一个制表符。 -其他的元字符还包括`\`、`\*`、`+`、`?`、`()`、`[]`、`{}`等,将在下文解释。 +其他的元字符还包括`\`、`*`、`+`、`?`、`()`、`[]`、`{}`等,将在下文解释。 ### 转义符 From a2aed617b96b8c5b75ab319a15bd327564687dd1 Mon Sep 17 00:00:00 2001 From: Lean You <7764115+byog@users.noreply.github.com> Date: Wed, 26 Aug 2020 16:51:55 +0800 Subject: [PATCH 035/152] fix: typo --- docs/events/drag.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/events/drag.md b/docs/events/drag.md index d082d4d..94ba613 100644 --- a/docs/events/drag.md +++ b/docs/events/drag.md @@ -452,7 +452,7 @@ event.dataTransfer.clearData('text/uri-list'); 拖动过程中(`dragstart`事件触发后),浏览器会显示一张图片跟随鼠标一起移动,表示被拖动的节点。这张图片是自动创造的,通常显示为被拖动节点的外观,不需要自己动手设置。 -`DataTransfer.setDragImage()`方法可以自定义这张图片。它接受三个参数。第一个是``节点或者``节点,如果省略或为`null`,则使用被拖动的节点的外观;第二个和第三个参数为鼠标相对于该图片左上角的横坐标和右坐标。 +`DataTransfer.setDragImage()`方法可以自定义这张图片。它接受三个参数。第一个是``节点或者``节点,如果省略或为`null`,则使用被拖动的节点的外观;第二个和第三个参数为鼠标相对于该图片左上角的横坐标和纵坐标。 下面是一个例子。 From 9ab17c05c08b336d92de53f58380c78dacc051c0 Mon Sep 17 00:00:00 2001 From: Lean You <7764115+byog@users.noreply.github.com> Date: Thu, 27 Aug 2020 23:39:32 +0800 Subject: [PATCH 036/152] Update engine.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 参考 MDN 上的介绍和自己的理解 --- docs/bom/engine.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/bom/engine.md b/docs/bom/engine.md index b42197c..006a43d 100644 --- a/docs/bom/engine.md +++ b/docs/bom/engine.md @@ -372,13 +372,13 @@ foo.style.marginTop = '30px'; - 使用`documentFragment`操作 DOM - 动画使用`absolute`定位或`fixed`定位,这样可以减少对其他元素的影响。 - 只在必要时才显示隐藏元素。 -- 使用`window.requestAnimationFrame()`,因为它可以把代码推迟到下一次重流时执行,而不是立即要求页面重流。 +- 使用`window.requestAnimationFrame()`,因为它可以把代码推迟到下一次重绘之前执行,而不是立即要求页面重绘。 - 使用虚拟 DOM(virtual DOM)库。 下面是一个`window.requestAnimationFrame()`对比效果的例子。 ```javascript -// 重绘代价高 +// 重流代价高 function doubleHeight(element) { var currentHeight = element.clientHeight; element.style.height = (currentHeight * 2) + 'px'; From 913da4be3964b0111996d6ef18d401d7783a9835 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sat, 29 Aug 2020 13:08:29 +0800 Subject: [PATCH 037/152] docs: edit bom/engine & event/drag --- docs/bom/engine.md | 4 ++-- docs/events/drag.md | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/bom/engine.md b/docs/bom/engine.md index 006a43d..86e7f53 100644 --- a/docs/bom/engine.md +++ b/docs/bom/engine.md @@ -6,7 +6,7 @@ JavaScript 是浏览器的内置脚本语言。也就是说,浏览器内置了 ## 代码嵌入网页的方法 -网页中嵌入 JavaScript 代码,主要有三种方法。 +网页中嵌入 JavaScript 代码,主要有四种方法。 - `