From 1b0b7b87e6585dc06cd453ac5572577470dab82b Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 22 May 2020 12:19:59 +0800 Subject: [PATCH 001/133] 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 002/133] 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 003/133] =?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 004/133] =?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 005/133] 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 006/133] 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 007/133] =?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 008/133] 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 009/133] 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 010/133] 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 011/133] 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 012/133] 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 013/133] =?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 014/133] 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 015/133] 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 016/133] 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 017/133] 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 018/133] 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 代码,主要有四种方法。 - `