From c4a5be064713e4385768b2f86bcd704571589883 Mon Sep 17 00:00:00 2001 From: smith latube Date: Mon, 20 Aug 2018 21:10:56 +0800 Subject: [PATCH 001/321] format the code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更具层次感 --- docs/stdlib/boolean.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/stdlib/boolean.md b/docs/stdlib/boolean.md index 1eb39ff..f630824 100644 --- a/docs/stdlib/boolean.md +++ b/docs/stdlib/boolean.md @@ -56,6 +56,7 @@ Boolean(/foo/) // true !!0 // false !!'' // false !!NaN // false + !!1 // true !!'false' // true !![] // true From cd31344eb27e5abf463ac1715bbc6e9e18d4d086 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 23 Aug 2018 12:26:31 +0800 Subject: [PATCH 002/321] docs(stdlib): edit json #30 --- docs/stdlib/json.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stdlib/json.md b/docs/stdlib/json.md index bb7001a..7afc511 100644 --- a/docs/stdlib/json.md +++ b/docs/stdlib/json.md @@ -121,7 +121,7 @@ JSON.stringify(arr) // "[null,null]" JSON.stringify(/foo/) // "{}" ``` -`JSON.stringify`方法会忽略对象的不可遍历属性。 +`JSON.stringify`方法会忽略对象的不可遍历的属性。 ```javascript var obj = {}; From 12a01014154f5d37c8baf0035fbd5ccbba2f4a6a Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 24 Aug 2018 15:20:42 +0800 Subject: [PATCH 003/321] docs(basic): fix grammar --- docs/basic/grammar.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/basic/grammar.md b/docs/basic/grammar.md index 52e329e..4694c48 100644 --- a/docs/basic/grammar.md +++ b/docs/basic/grammar.md @@ -425,6 +425,7 @@ var x = 1; switch (x) { case true: console.log('x 发生类型转换'); + break; default: console.log('x 没有发生类型转换'); } @@ -435,7 +436,7 @@ switch (x) { ### 三元运算符 ?: -JavaScript还有一个三元运算符(即该运算符需要三个运算子)`?:`,也可以用于逻辑判断。 +JavaScript 还有一个三元运算符(即该运算符需要三个运算子)`?:`,也可以用于逻辑判断。 ```javascript (条件) ? 表达式1 : 表达式2 From cd5b10f8f73a106e411e7c2cf6028f62e326d556 Mon Sep 17 00:00:00 2001 From: GJ Wang Date: Sat, 25 Aug 2018 18:14:12 +0800 Subject: [PATCH 004/321] docs: fix blank --- docs/basic/grammar.md | 4 ++-- docs/basic/history.md | 8 ++++---- docs/bom/engine.md | 2 +- docs/dom/document.md | 2 +- docs/oop/strict.md | 2 +- docs/types/function.md | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/basic/grammar.md b/docs/basic/grammar.md index 4694c48..62c89fb 100644 --- a/docs/basic/grammar.md +++ b/docs/basic/grammar.md @@ -20,7 +20,7 @@ var a = 1 + 3; var a = 1 + 3 ; var b = 'abc'; ``` -分号前面可以没有任何内容,JavaScript引擎将其视为空语句。 +分号前面可以没有任何内容,JavaScript 引擎将其视为空语句。 ```javascript ;;; @@ -177,7 +177,7 @@ a+b // 标识符不能包含加号 var 临时变量 = 1; ``` -> JavaScript有一些保留字,不能用作标识符:arguments、break、case、catch、class、const、continue、debugger、default、delete、do、else、enum、eval、export、extends、false、finally、for、function、if、implements、import、in、instanceof、interface、let、new、null、package、private、protected、public、return、static、super、switch、this、throw、true、try、typeof、var、void、while、with、yield。 +> JavaScript 有一些保留字,不能用作标识符:arguments、break、case、catch、class、const、continue、debugger、default、delete、do、else、enum、eval、export、extends、false、finally、for、function、if、implements、import、in、instanceof、interface、let、new、null、package、private、protected、public、return、static、super、switch、this、throw、true、try、typeof、var、void、while、with、yield。 ## 注释 diff --git a/docs/basic/history.md b/docs/basic/history.md index 4f782cd..552a69f 100644 --- a/docs/basic/history.md +++ b/docs/basic/history.md @@ -51,7 +51,7 @@ JavaScript 语言的函数是一种独立的数据类型,以及采用基于原 ## JavaScript 与 ECMAScript 的关系 -1996年8月,微软模仿 JavaScript 开发了一种相近的语言,取名为JScript(JavaScript是Netscape的注册商标,微软不能用),首先内置于IE 3.0。Netscape 公司面临丧失浏览器脚本语言的主导权的局面。 +1996年8月,微软模仿 JavaScript 开发了一种相近的语言,取名为JScript(JavaScript 是Netscape的注册商标,微软不能用),首先内置于IE 3.0。Netscape 公司面临丧失浏览器脚本语言的主导权的局面。 1996年11月,Netscape 公司决定将 JavaScript 提交给国际标准化组织 ECMA(European Computer Manufacturers Association),希望 JavaScript 能够成为国际标准,以此抵抗微软。ECMA 的39号技术委员会(Technical Committee 39)负责制定和审核这个标准,成员由业内的大公司派出的工程师组成,目前共25个人。该委员会定期开会,所有的邮件讨论和会议记录,都是公开的。 @@ -61,7 +61,7 @@ ECMAScript 只用来标准化 JavaScript 这种语言的基本语法结构,与 ECMA-262 标准后来也被另一个国际标准化组织 ISO(International Organization for Standardization)批准,标准号是 ISO-16262。 -## JavaScript的版本 +## JavaScript 的版本 1997年7月,ECMAScript 1.0发布。 @@ -131,7 +131,7 @@ JavaScript 伴随着互联网的发展一起发展。互联网周边技术的快 2009年,Node.js 项目诞生,创始人为 Ryan Dahl,它标志着 JavaScript 可以用于服务器端编程,从此网站的前端和后端可以使用同一种语言开发。并且,Node.js 可以承受很大的并发流量,使得开发某些互联网大规模的实时应用变得容易。 -2009年,Jeremy Ashkenas 发布了 CoffeeScript 的最初版本。CoffeeScript 可以被转换为 JavaScript 运行,但是语法要比 JavaScript简洁。这开启了其他语言转为 JavaScript 的风潮。 +2009年,Jeremy Ashkenas 发布了 CoffeeScript 的最初版本。CoffeeScript 可以被转换为 JavaScript 运行,但是语法要比 JavaScript 简洁。这开启了其他语言转为 JavaScript 的风潮。 2009年,PhoneGap 项目诞生,它将 HTML5 和 JavaScript 引入移动设备的应用程序开发,主要针对 iOS 和 Android 平台,使得 JavaScript 可以用于跨平台的应用程序开发。 @@ -169,7 +169,7 @@ JavaScript 伴随着互联网的发展一起发展。互联网周边技术的快 2015年5月,Google 公司的 Polymer 框架发布1.0版。该项目的目标是生产环境可以使用 WebComponent 组件,如果能够达到目标,Web 开发将进入一个全新的以组件为开发基础的阶段。 -2015年6月,ECMA 标准化组织正式批准了 ECMAScript 6 语言标准,定名为《ECMAScript 2015 标准》。JavaScript语言正式进入了下一个阶段,成为一种企业级的、开发大规模应用的语言。这个标准从提出到批准,历时10年,而 JavaScript 语言从诞生至今也已经20年了。 +2015年6月,ECMA 标准化组织正式批准了 ECMAScript 6 语言标准,定名为《ECMAScript 2015 标准》。JavaScript 语言正式进入了下一个阶段,成为一种企业级的、开发大规模应用的语言。这个标准从提出到批准,历时10年,而 JavaScript 语言从诞生至今也已经20年了。 2015年6月,Mozilla 在 asm.js 的基础上发布 WebAssembly 项目。这是一种 JavaScript 引擎的中间码格式,全部都是二进制,类似于 Java 的字节码,有利于移动设备加载 JavaScript 脚本,执行速度提高了 20+ 倍。这意味着将来的软件,会发布 JavaScript 二进制包。 diff --git a/docs/bom/engine.md b/docs/bom/engine.md index 5d17cf5..b0acb7e 100644 --- a/docs/bom/engine.md +++ b/docs/bom/engine.md @@ -417,7 +417,7 @@ JavaScript 是一种解释型语言,也就是说,它不需要编译,由解 逐行解释将字节码转为机器码,是很低效的。为了提高运行速度,现代浏览器改为采用“即时编译”(Just In Time compiler,缩写JIT),即字节码只在运行时编译,用到哪一行就编译哪一行,并且把编译结果缓存(inline cache)。通常,一个程序被经常用到的,只是其中一小部分代码,有了缓存的编译结果,整个程序的运行速度就会显著提升。 -字节码不能直接运行,而是运行在一个虚拟机(Virtual Machine)之上,一般也把虚拟机称为 JavaScript 引擎。并非所有的 JavaScript 虚拟机运行时都有字节码,有的 JavaScript 虚拟机基于源码,即只要有可能,就通过JIT(just in time)编译器直接把源码编译成机器码运行,省略字节码步骤。这一点与其他采用虚拟机(比如 Java)的语言不尽相同。这样做的目的,是为了尽可能地优化代码、提高性能。下面是目前最常见的一些JavaScript虚拟机: +字节码不能直接运行,而是运行在一个虚拟机(Virtual Machine)之上,一般也把虚拟机称为 JavaScript 引擎。并非所有的 JavaScript 虚拟机运行时都有字节码,有的 JavaScript 虚拟机基于源码,即只要有可能,就通过JIT(just in time)编译器直接把源码编译成机器码运行,省略字节码步骤。这一点与其他采用虚拟机(比如 Java)的语言不尽相同。这样做的目的,是为了尽可能地优化代码、提高性能。下面是目前最常见的一些 JavaScript 虚拟机: - [Chakra](http://en.wikipedia.org/wiki/Chakra_(JScript_engine\))(Microsoft Internet Explorer) - [Nitro/JavaScript Core](http://en.wikipedia.org/wiki/WebKit#JavaScriptCore) (Safari) diff --git a/docs/dom/document.md b/docs/dom/document.md index 577eca1..6099d0e 100644 --- a/docs/dom/document.md +++ b/docs/dom/document.md @@ -417,7 +417,7 @@ hello 在浏览器打开上面网页,将会显示`hello world`。 -`document.write`是JavaScript语言标准化之前就存在的方法,现在完全有更符合标准的方法向文档写入内容(比如对`innerHTML`属性赋值)。所以,除了某些特殊情况,应该尽量避免使用`document.write`这个方法。 +`document.write`是 JavaScript 语言标准化之前就存在的方法,现在完全有更符合标准的方法向文档写入内容(比如对`innerHTML`属性赋值)。所以,除了某些特殊情况,应该尽量避免使用`document.write`这个方法。 `document.writeln`方法与`write`方法完全一致,除了会在输出内容的尾部添加换行符。 diff --git a/docs/oop/strict.md b/docs/oop/strict.md index 36655eb..3dffbe6 100644 --- a/docs/oop/strict.md +++ b/docs/oop/strict.md @@ -406,7 +406,7 @@ f(1); // 严格模式为[2, 1] ## 向下一个版本的 JavaScript 过渡 -JavaScript语言的下一个版本是 ECMAScript 6,为了平稳过渡,严格模式引入了一些 ES6 语法。 +JavaScript 语言的下一个版本是 ECMAScript 6,为了平稳过渡,严格模式引入了一些 ES6 语法。 ### 非函数代码块不得声明函数 diff --git a/docs/types/function.md b/docs/types/function.md index 071c31b..063c429 100644 --- a/docs/types/function.md +++ b/docs/types/function.md @@ -796,7 +796,7 @@ function f() {} var f = function f() {} ``` -为了避免解析上的歧义,JavaScript 引擎规定,如果`function`关键字出现在行首,一律解释成语句。因此,JavaScript引擎看到行首是`function`关键字之后,认为这一段都是函数的定义,不应该以圆括号结尾,所以就报错了。 +为了避免解析上的歧义,JavaScript 引擎规定,如果`function`关键字出现在行首,一律解释成语句。因此,JavaScript 引擎看到行首是`function`关键字之后,认为这一段都是函数的定义,不应该以圆括号结尾,所以就报错了。 解决方法就是不要让`function`出现在行首,让引擎将其理解成一个表达式。最简单的处理,就是将其放在一个圆括号里面。 From fa08be382637b3f2b1050ed9ac5dea5ab2491c0c Mon Sep 17 00:00:00 2001 From: GJ Wang Date: Sun, 26 Aug 2018 17:36:31 +0800 Subject: [PATCH 005/321] docs(stdlib): fix math --- docs/stdlib/math.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/stdlib/math.md b/docs/stdlib/math.md index 579a8d1..8e77265 100644 --- a/docs/stdlib/math.md +++ b/docs/stdlib/math.md @@ -11,7 +11,7 @@ - `Math.LN10`:10 的自然对数。 - `Math.LOG2E`:以 2 为底的`e`的对数。 - `Math.LOG10E`:以 10 为底的`e`的对数。 -- `Math.PI`:常数 Pi。 +- `Math.PI`:常数`π`。 - `Math.SQRT1_2`:0.5 的平方根。 - `Math.SQRT2`:2 的平方根。 @@ -40,7 +40,7 @@ Math.SQRT2 // 1.4142135623730951 - `Math.pow()`:指数运算 - `Math.sqrt()`:平方根 - `Math.log()`:自然对数 -- `Math.exp()`:e的指数 +- `Math.exp()`:`e`的指数 - `Math.round()`:四舍五入 - `Math.random()`:随机数 @@ -208,7 +208,7 @@ function random_str(length) { ALPHABET += 'abcdefghijklmnopqrstuvwxyz'; ALPHABET += '0123456789-_'; var str = ''; - for (var i=0; i < length; ++i) { + for (var i = 0; i < length; ++i) { var rand = Math.floor(Math.random() * ALPHABET.length); str += ALPHABET.substring(rand, rand + 1); } From 2c9fb41b8189a0c83fa5ac70910ee009599f0a87 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sun, 26 Aug 2018 19:34:21 +0800 Subject: [PATCH 006/321] docs(types): edit number --- docs/types/number.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/types/number.md b/docs/types/number.md index 3b52ef1..be3c3f4 100644 --- a/docs/types/number.md +++ b/docs/types/number.md @@ -43,7 +43,7 @@ JavaScript 内部,所有数字都是以64位浮点数形式储存,即使整 上面公式是正常情况下(指数部分在0到2047之间),一个数在 JavaScript 内部实际的表示形式。 -精度最多只能到53个二进制位,这意味着,绝对值小于等于2的53次方的整数,即-253到253,都可以精确表示。 +精度最多只能到53个二进制位,这意味着,绝对值小于2的53次方的整数,即-253到253,都可以精确表示。 ```javascript Math.pow(2, 53) @@ -309,7 +309,7 @@ Infinity === -Infinity // false 上面代码中,非零正数除以`-0`,会得到`-Infinity`,负数除以`-0`,会得到`Infinity`。 -由于数值正向溢出(overflow)、负向溢出(underflow)和被`0`除,JavaScript 都不报错,而是返回`Infinity`,所以单纯的数学运算几乎没有可能抛出错误。 +由于数值正向溢出(overflow)、负向溢出(underflow)和被`0`除,JavaScript 都不报错,所以单纯的数学运算几乎没有可能抛出错误。 `Infinity`大于一切数值(除了`NaN`),`-Infinity`小于一切数值(除了`NaN`)。 From 884edf555ac5d513cf01393862be6bfc7babb11f Mon Sep 17 00:00:00 2001 From: GJ Wang Date: Mon, 27 Aug 2018 18:46:19 +0800 Subject: [PATCH 007/321] docs(stdlib): edit date --- docs/stdlib/date.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/stdlib/date.md b/docs/stdlib/date.md index c34bd99..5dad6f7 100644 --- a/docs/stdlib/date.md +++ b/docs/stdlib/date.md @@ -327,6 +327,18 @@ d.toLocaleTimeString() // 英文版浏览器为"12:00:00 AM" ``` +**(9)Date.prototype.toLocaleString()** + +`toLocaleString`方法返回一个字符串,代表时间的当地写法。 + +```javascript +var d = new Date(2013, 0, 1); + +d.toLocaleString() +// 中文版浏览器为"2013年1月1日 上午12:00:00" +// 英文版浏览器为"1/1/2013 12:00:00 AM" +``` + ### get 类方法 `Date`对象提供了一系列`get*`方法,用来获取实例对象某个方面的值。 From 2c1f76e4cf717f902aab34bc43cd19088216aaa5 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 28 Aug 2018 13:36:33 +0800 Subject: [PATCH 008/321] docs(types): edit function & bit --- docs/operators/bit.md | 2 +- docs/types/function.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/operators/bit.md b/docs/operators/bit.md index de5e111..c1266b0 100644 --- a/docs/operators/bit.md +++ b/docs/operators/bit.md @@ -41,7 +41,7 @@ toInt32(Math.pow(2, 32) + 1) // 1 toInt32(Math.pow(2, 32) - 1) // -1 ``` -上面代码中,`toInt32`可以将小数转为整数。对于一般的整数,返回值不会有任何变化。对于大于2的32次方的整数,大于32位的数位都会被舍去。 +上面代码中,`toInt32`可以将小数转为整数。对于一般的整数,返回值不会有任何变化。对于大于或等于2的32次方的整数,大于32位的数位都会被舍去。 ## 二进制或运算符 diff --git a/docs/types/function.md b/docs/types/function.md index 063c429..e1d9973 100644 --- a/docs/types/function.md +++ b/docs/types/function.md @@ -77,7 +77,7 @@ function add(x, y) { ```javascript var foo = new Function( - 'return "hello world"' + 'return "hello world";' ); // 等同于 From f97074a972e5a3d682f86937d0ff979c9f57bc27 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 28 Aug 2018 15:18:48 +0800 Subject: [PATCH 009/321] docs(stdlib): edit date --- docs/stdlib/date.md | 79 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 66 insertions(+), 13 deletions(-) diff --git a/docs/stdlib/date.md b/docs/stdlib/date.md index 5dad6f7..a897c07 100644 --- a/docs/stdlib/date.md +++ b/docs/stdlib/date.md @@ -303,40 +303,93 @@ var d = new Date(2013, 0, 1); d.toTimeString() // "00:00:00 GMT+0800 (CST)" ``` -**(7)Date.prototype.toLocaleDateString()** +**(7)本地时间** -`toLocaleDateString`方法返回一个字符串,代表日期的当地写法(不含小时、分和秒)。 +以下三种方法,可以将 Date 实例转为表示本地时间的字符串。 + +- Date.prototype.toLocaleString():完整的本地时间。 +- Date.prototype.toLocaleDateString():本地日期(不含小时、分和秒)。 +- Date.prototype.toLocaleTimeString():本地时间(不含年月日)。 + +下面是用法实例。 ```javascript var d = new Date(2013, 0, 1); +d.toLocaleString() +// 中文版浏览器为"2013年1月1日 上午12:00:00" +// 英文版浏览器为"1/1/2013 12:00:00 AM" + d.toLocaleDateString() // 中文版浏览器为"2013年1月1日" // 英文版浏览器为"1/1/2013" + +d.toLocaleTimeString() +// 中文版浏览器为"上午12:00:00" +// 英文版浏览器为"12:00:00 AM" ``` -**(8)Date.prototype.toLocaleTimeString()** +这三个方法都有两个可选的参数。 + +```javascript +dateObj.toLocaleString([locales[, options]]) +dateObj.toLocaleDateString([locales[, options]]) +dateObj.toLocaleTimeString([locales[, options]]) +``` -`toLocaleTimeString`方法返回一个字符串,代表时间的当地写法(不含年月日)。 +这两个参数中,`locales`是一个指定所用语言的字符串,`options`是一个配置对象。下面是`locales`的例子。 ```javascript var d = new Date(2013, 0, 1); -d.toLocaleTimeString() -// 中文版浏览器为"上午12:00:00" -// 英文版浏览器为"12:00:00 AM" -``` +d.toLocaleString('en-US') // "1/1/2013, 12:00:00 AM" +d.toLocaleString('zh-CN') // "2013/1/1 上午12:00:00" -**(9)Date.prototype.toLocaleString()** +d.toLocaleDateString('en-US') // "1/1/2013" +d.toLocaleDateString('zh-CN') // "2013/1/1" -`toLocaleString`方法返回一个字符串,代表时间的当地写法。 +d.toLocaleTimeString('en-US') // "12:00:00 AM" +d.toLocaleTimeString('zh-CN') // "上午12:00:00" +``` + +下面是`options`的例子。 ```javascript var d = new Date(2013, 0, 1); -d.toLocaleString() -// 中文版浏览器为"2013年1月1日 上午12:00:00" -// 英文版浏览器为"1/1/2013 12:00:00 AM" +// 时间格式 +// 下面的设置是,星期和月份为完整文字,年份和日期为数字 +d.toLocaleDateString('en-US', { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric' +}) +// "Tuesday, January 1, 2013" + +// 指定时区 +d.toLocaleTimeString('en-US', { + timeZone: 'UTC', + timeZoneName: 'short' +}) +// "4:00:00 PM UTC" + +d.toLocaleTimeString('en-US', { + timeZone: 'Asia/Shanghai', + timeZoneName: 'long' +}) +// "12:00:00 AM China Standard Time" + +// 小时周期为12还是24 +d.toLocaleTimeString('en-US', { + hour12: false +}) +// "00:00:00" + +d.toLocaleTimeString('en-US', { + hour12: true +}) +// "12:00:00 AM" ``` ### get 类方法 From 61f810d0761331967df4c25a3abf1e759e6e8e72 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 28 Aug 2018 15:25:36 +0800 Subject: [PATCH 010/321] docs(stdlib): edit date --- docs/stdlib/date.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/stdlib/date.md b/docs/stdlib/date.md index a897c07..b90dd8a 100644 --- a/docs/stdlib/date.md +++ b/docs/stdlib/date.md @@ -307,9 +307,9 @@ d.toTimeString() // "00:00:00 GMT+0800 (CST)" 以下三种方法,可以将 Date 实例转为表示本地时间的字符串。 -- Date.prototype.toLocaleString():完整的本地时间。 -- Date.prototype.toLocaleDateString():本地日期(不含小时、分和秒)。 -- Date.prototype.toLocaleTimeString():本地时间(不含年月日)。 +- `Date.prototype.toLocaleString()`:完整的本地时间。 +- `Date.prototype.toLocaleDateString()`:本地日期(不含小时、分和秒)。 +- `Date.prototype.toLocaleTimeString()`:本地时间(不含年月日)。 下面是用法实例。 From 648eb30c61381b8a89c698ffca8f695a2d62ccd3 Mon Sep 17 00:00:00 2001 From: GJ Wang Date: Thu, 30 Aug 2018 00:11:39 +0800 Subject: [PATCH 011/321] docs:fix blank --- docs/basic/history.md | 2 +- docs/bom/cors.md | 2 +- docs/bom/engine.md | 6 +++--- docs/bom/indexeddb.md | 2 +- docs/bom/window.md | 2 +- docs/bom/xmlhttprequest.md | 2 +- docs/features/console.md | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/basic/history.md b/docs/basic/history.md index 552a69f..97dd32b 100644 --- a/docs/basic/history.md +++ b/docs/basic/history.md @@ -51,7 +51,7 @@ JavaScript 语言的函数是一种独立的数据类型,以及采用基于原 ## JavaScript 与 ECMAScript 的关系 -1996年8月,微软模仿 JavaScript 开发了一种相近的语言,取名为JScript(JavaScript 是Netscape的注册商标,微软不能用),首先内置于IE 3.0。Netscape 公司面临丧失浏览器脚本语言的主导权的局面。 +1996年8月,微软模仿 JavaScript 开发了一种相近的语言,取名为JScript(JavaScript 是 Netscape 的注册商标,微软不能用),首先内置于IE 3.0。Netscape 公司面临丧失浏览器脚本语言的主导权的局面。 1996年11月,Netscape 公司决定将 JavaScript 提交给国际标准化组织 ECMA(European Computer Manufacturers Association),希望 JavaScript 能够成为国际标准,以此抵抗微软。ECMA 的39号技术委员会(Technical Committee 39)负责制定和审核这个标准,成员由业内的大公司派出的工程师组成,目前共25个人。该委员会定期开会,所有的邮件讨论和会议记录,都是公开的。 diff --git a/docs/bom/cors.md b/docs/bom/cors.md index fd4c976..c990257 100644 --- a/docs/bom/cors.md +++ b/docs/bom/cors.md @@ -1,6 +1,6 @@ # CORS 通信 -CORS 是一个 W3C 标准,全称是“跨域资源共享”(Cross-origin resource sharing)。它允许浏览器向跨域的服务器,发出`XMLHttpRequest`请求,从而克服了AJAX只能同源使用的限制。 +CORS 是一个 W3C 标准,全称是“跨域资源共享”(Cross-origin resource sharing)。它允许浏览器向跨域的服务器,发出`XMLHttpRequest`请求,从而克服了 AJAX 只能同源使用的限制。 ## 简介 diff --git a/docs/bom/engine.md b/docs/bom/engine.md index b0acb7e..9b29f62 100644 --- a/docs/bom/engine.md +++ b/docs/bom/engine.md @@ -373,7 +373,7 @@ foo.style.marginTop = '30px'; - 动画使用`absolute`定位或`fixed`定位,这样可以减少对其他元素的影响。 - 只在必要时才显示隐藏元素。 - 使用`window.requestAnimationFrame()`,因为它可以把代码推迟到下一次重流时执行,而不是立即要求页面重流。 -- 使用虚拟DOM(virtual DOM)库。 +- 使用虚拟 DOM(virtual DOM)库。 下面是一个`window.requestAnimationFrame()`对比效果的例子。 @@ -415,9 +415,9 @@ JavaScript 是一种解释型语言,也就是说,它不需要编译,由解 3. 使用“翻译器”(translator),将代码转为字节码(bytecode)。 4. 使用“字节码解释器”(bytecode interpreter),将字节码转为机器码。 -逐行解释将字节码转为机器码,是很低效的。为了提高运行速度,现代浏览器改为采用“即时编译”(Just In Time compiler,缩写JIT),即字节码只在运行时编译,用到哪一行就编译哪一行,并且把编译结果缓存(inline cache)。通常,一个程序被经常用到的,只是其中一小部分代码,有了缓存的编译结果,整个程序的运行速度就会显著提升。 +逐行解释将字节码转为机器码,是很低效的。为了提高运行速度,现代浏览器改为采用“即时编译”(Just In Time compiler,缩写 JIT),即字节码只在运行时编译,用到哪一行就编译哪一行,并且把编译结果缓存(inline cache)。通常,一个程序被经常用到的,只是其中一小部分代码,有了缓存的编译结果,整个程序的运行速度就会显著提升。 -字节码不能直接运行,而是运行在一个虚拟机(Virtual Machine)之上,一般也把虚拟机称为 JavaScript 引擎。并非所有的 JavaScript 虚拟机运行时都有字节码,有的 JavaScript 虚拟机基于源码,即只要有可能,就通过JIT(just in time)编译器直接把源码编译成机器码运行,省略字节码步骤。这一点与其他采用虚拟机(比如 Java)的语言不尽相同。这样做的目的,是为了尽可能地优化代码、提高性能。下面是目前最常见的一些 JavaScript 虚拟机: +字节码不能直接运行,而是运行在一个虚拟机(Virtual Machine)之上,一般也把虚拟机称为 JavaScript 引擎。并非所有的 JavaScript 虚拟机运行时都有字节码,有的 JavaScript 虚拟机基于源码,即只要有可能,就通过 JIT(just in time)编译器直接把源码编译成机器码运行,省略字节码步骤。这一点与其他采用虚拟机(比如 Java)的语言不尽相同。这样做的目的,是为了尽可能地优化代码、提高性能。下面是目前最常见的一些 JavaScript 虚拟机: - [Chakra](http://en.wikipedia.org/wiki/Chakra_(JScript_engine\))(Microsoft Internet Explorer) - [Nitro/JavaScript Core](http://en.wikipedia.org/wiki/WebKit#JavaScriptCore) (Safari) diff --git a/docs/bom/indexeddb.md b/docs/bom/indexeddb.md index 752f4f2..fd010a1 100644 --- a/docs/bom/indexeddb.md +++ b/docs/bom/indexeddb.md @@ -467,7 +467,7 @@ IDBDatabase 对象有以下属性。 - `IDBDatabase.onerror`:指定 error 事件(访问数据库失败)的监听函数。 - `IDBDatabase.onversionchange`:数据库版本变化时触发(发生`upgradeneeded`事件,或调用`indexedDB.deleteDatabase()`)。 -下面是`objectStoreNames`属性的例子。该属性返回一个DOMStringList 对象,包含了当前数据库所有对象仓库的名称(即表名),可以使用 DOMStringList 对象的`contains`方法,检查数据库是否包含某个对象仓库。 +下面是`objectStoreNames`属性的例子。该属性返回一个 DOMStringList 对象,包含了当前数据库所有对象仓库的名称(即表名),可以使用 DOMStringList 对象的`contains`方法,检查数据库是否包含某个对象仓库。 ```javascript if (!db.objectStoreNames.contains('firstOS')) { diff --git a/docs/bom/window.md b/docs/bom/window.md index 9da5449..33163b5 100644 --- a/docs/bom/window.md +++ b/docs/bom/window.md @@ -220,7 +220,7 @@ window.alert('Hello World'); 用户只有点击“确定”按钮,对话框才会消失。对话框弹出期间,浏览器窗口处于冻结状态,如果不点“确定”按钮,用户什么也干不了。 -`window.alert()`方法的参数只能是字符串,没法使用CSS样式,但是可以用`\n`指定换行。 +`window.alert()`方法的参数只能是字符串,没法使用 CSS 样式,但是可以用`\n`指定换行。 ```javascript alert('本条提示\n分成两行'); diff --git a/docs/bom/xmlhttprequest.md b/docs/bom/xmlhttprequest.md index 7e2f1ff..83c4ed0 100644 --- a/docs/bom/xmlhttprequest.md +++ b/docs/bom/xmlhttprequest.md @@ -345,7 +345,7 @@ xhr.onerror = function() { `XMLHttpRequest.withCredentials`属性是一个布尔值,表示跨域请求时,用户信息(比如 Cookie 和认证的 HTTP 头信息)是否会包含在请求之中,默认为`false`,即向`example.com`发出跨域请求时,不会发送`example.com`设置在本机上的 Cookie(如果有的话)。 -如果需要跨域 AJAX 请求发送Cookie,需要`withCredentials`属性设为`true`。注意,同源的请求不需要设置这个属性。 +如果需要跨域 AJAX 请求发送 Cookie,需要`withCredentials`属性设为`true`。注意,同源的请求不需要设置这个属性。 ```javascript var xhr = new XMLHttpRequest(); diff --git a/docs/features/console.md b/docs/features/console.md index 8367112..a264650 100644 --- a/docs/features/console.md +++ b/docs/features/console.md @@ -83,7 +83,7 @@ console.log('%d %s balloons', number, color); 上面代码中,第二个参数是数值,对应的占位符是`%d`,第三个参数是字符串,对应的占位符是`%s`。 -使用`%c`占位符时,对应的参数必须是 CSS 代码,用来对输出内容进行CSS渲染。 +使用`%c`占位符时,对应的参数必须是 CSS 代码,用来对输出内容进行 CSS 渲染。 ```javascript console.log( From 3290cda086393ce6c1aeae3df8fa27e8ada8c9b1 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 30 Aug 2018 12:40:44 +0800 Subject: [PATCH 012/321] docs(operators): edit priority --- docs/features/error.md | 4 ++-- docs/operators/arithmetic.md | 10 ++++++++++ docs/operators/boolean.md | 14 ++++++++++---- docs/operators/priority.md | 9 +++++++++ 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/docs/features/error.md b/docs/features/error.md index 8a7aa40..eb9711e 100644 --- a/docs/features/error.md +++ b/docs/features/error.md @@ -170,13 +170,13 @@ new UserError('这是自定义的错误!'); `throw`语句的作用是手动中断程序执行,抛出一个错误。 ```javascript -if (x < 0) { +if (x <= 0) { throw new Error('x 必须为正数'); } // Uncaught ReferenceError: x is not defined ``` -上面代码中,如果变量`x`小于`0`,就手动抛出一个错误,告诉用户`x`的值不正确,整个程序就会在这里中断执行。可以看到,`throw`抛出的错误就是它的参数,这里是一个`Error`实例。 +上面代码中,如果变量`x`小于等于`0`,就手动抛出一个错误,告诉用户`x`的值不正确,整个程序就会在这里中断执行。可以看到,`throw`抛出的错误就是它的参数,这里是一个`Error`实例。 `throw`也可以抛出自定义错误。 diff --git a/docs/operators/arithmetic.md b/docs/operators/arithmetic.md index 7193c34..fa33562 100644 --- a/docs/operators/arithmetic.md +++ b/docs/operators/arithmetic.md @@ -242,6 +242,16 @@ var x = 1; 2 ** 4 // 16 ``` +注意,指数运算符是右结合,而不是左结合。即多个指数运算符连用时,先进行最右边的计算。 + +```javascript +// 相当于 2 ** (3 ** 2) +2 ** 3 ** 2 +// 512 +``` + +上面代码中,由于指数运算符是右结合,所以先计算第二个指数运算符,而不是第一个。 + ## 赋值运算符 赋值运算符(Assignment Operators)用于给变量赋值。 diff --git a/docs/operators/boolean.md b/docs/operators/boolean.md index 63155d9..1a201b5 100644 --- a/docs/operators/boolean.md +++ b/docs/operators/boolean.md @@ -86,14 +86,17 @@ i && doSomething(); 上面代码的两种写法是等价的,但是后一种不容易看出目的,也不容易除错,建议谨慎使用。 -且运算符可以多个连用,这时返回第一个布尔值为`false`的表达式的值。 +且运算符可以多个连用,这时返回第一个布尔值为`false`的表达式的值。如果所有表达式的布尔值都为`true`,则返回最后一个表达式的值。 ```javascript true && 'foo' && '' && 4 && 'foo' && true // '' + +1 && 2 && 3 +// 3 ``` -上面代码中,第一个布尔值为`false`的表达式为第三个表达式,所以得到一个空字符串。 +上面代码中,例一里面,第一个布尔值为`false`的表达式为第三个表达式,所以得到一个空字符串。例二里面,所有表达式的布尔值都是`true`,所有返回最后一个表达式的值`3`。 ## 或运算符(||) @@ -116,14 +119,17 @@ x // 1 上面代码中,且运算符的第一个运算子为`true`,所以直接返回`true`,不再运行第二个运算子。所以,`x`的值没有改变。这种只通过第一个表达式的值,控制是否运行第二个表达式的机制,就称为“短路”(short-cut)。 -或运算符可以多个连用,这时返回第一个布尔值为`true`的表达式的值。 +或运算符可以多个连用,这时返回第一个布尔值为`true`的表达式的值。如果所有表达式都为`false`,则返回最后一个表达式的值。 ```javascript false || 0 || '' || 4 || 'foo' || true // 4 + +false || 0 || '' +// '' ``` -上面代码中第一个布尔值为`true`的表达式是第四个表达式,所以得到数值4。 +上面代码中,例一里面,第一个布尔值为`true`的表达式是第四个表达式,所以得到数值4。例二里面,所有表达式的布尔值都为`false`,所以返回最后一个表达式的值。 或运算符常用于为一个变量设置默认值。 diff --git a/docs/operators/priority.md b/docs/operators/priority.md index e3657d0..34e0288 100644 --- a/docs/operators/priority.md +++ b/docs/operators/priority.md @@ -185,3 +185,12 @@ q = a ? b : (c ? d : (e ? f : g)); ``` 上面的两行代码,各有三个等号运算符和三个三元运算符,都是先计算最右边的那个运算符。 + +指数运算符(`**`)也是右结合的。 + +```javascript +// 相当于 2 ** (3 ** 2) +2 ** 3 ** 2 +// 512 +``` + From 02c10749c00ea06cc6d5619f1229ff34749e1a96 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sat, 1 Sep 2018 11:43:40 +0800 Subject: [PATCH 013/321] docs(features): edit console --- docs/features/console.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/features/console.md b/docs/features/console.md index a264650..2e1ffc8 100644 --- a/docs/features/console.md +++ b/docs/features/console.md @@ -288,7 +288,7 @@ console.assert(false, '判断条件不成立') // 相当于 try { - if (false) { + if (!false) { throw new Error('判断条件不成立'); } } catch(e) { @@ -333,8 +333,8 @@ console.log('一级分组的内容'); console.group('二级分组'); console.log('二级分组的内容'); -console.groupEnd(); // 一级分组结束 console.groupEnd(); // 二级分组结束 +console.groupEnd(); // 一级分组结束 ``` 上面代码会将“二级分组”显示在“一级分组”内部,并且“一级分组”和“二级分组”前面都有一个折叠符号,可以用来折叠本级的内容。 From e70963eec563d0c2dd449142f549ad6952e52fec Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 4 Sep 2018 16:09:26 +0800 Subject: [PATCH 014/321] docs(operator): fix equality operator --- docs/operators/comparison.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/operators/comparison.md b/docs/operators/comparison.md index 17d7ad1..828a06f 100644 --- a/docs/operators/comparison.md +++ b/docs/operators/comparison.md @@ -227,7 +227,7 @@ v1 === v2 // true 1 === 1.0 ``` -比较不同类型的数据时,相等运算符会先将数据进行类型转换,然后再用严格相等运算符比较。类型转换规则如下。 +比较不同类型的数据时,相等运算符会先将数据进行类型转换,然后再用严格相等运算符比较。下面分成四种情况,讨论不同类型的值互相比较的规则。 **(1)原始类型值** @@ -273,17 +273,24 @@ v1 === v2 // true 对象(这里指广义的对象,包括数组和函数)与原始类型的值比较时,对象转换成原始类型的值,再进行比较。 ```javascript +// 对象与数值比较时,对象转为数值 [1] == 1 // true // 等同于 Number([1]) == 1 +// 对象与字符串比较时,对象转为字符串 [1] == '1' // true -// 等同于 Number([1]) == Number('1') +// 等同于 String([1]) == '1' +[1, 2] == '1,2' // true +// 等同于 String([1, 2]) == '1,2' +// 对象与布尔值比较时,两边都转为数值 [1] == true // true // 等同于 Number([1]) == Number(true) +[2] == true // false +// 等同于 Number([2]) == Number(true) ``` -上面代码中,数组`[1]`与数值进行比较,会先转成数值,再进行比较;与字符串进行比较,会先转成数值,再与字符串进行比较,然后字符串也会转成数值;与布尔值进行比较,两个运算子都会先转成数值,然后再进行比较。 +上面代码中,数组`[1]`与数值进行比较,会先转成数值,再进行比较;与字符串进行比较,会先转成字符串,再进行比较;与布尔值进行比较,对象和布尔值都会先转成数值,再进行比较。 **(3)undefined 和 null** From ddf44bb2ae0f36ceca398a96e54244a0d9a6f60a Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sat, 8 Sep 2018 22:17:39 +0800 Subject: [PATCH 015/321] =?UTF-8?q?docs(object):=20edit=20=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E6=8F=8F=E8=BF=B0=E5=AF=B9=E8=B1=A1=20#41?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/basic/grammar.md | 2 +- docs/stdlib/attributes.md | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/basic/grammar.md b/docs/basic/grammar.md index 62c89fb..3dd6d07 100644 --- a/docs/basic/grammar.md +++ b/docs/basic/grammar.md @@ -58,7 +58,7 @@ var a; a = 1; ``` -如果只是声明变量而没有赋值,则该变量的值是`undefined`。`undefined`是一个 JavaScript 关键字,表示“无定义”。 +如果只是声明变量而没有赋值,则该变量的值是`undefined`。`undefined`是一个特殊的值,表示“无定义”。 ```javascript var a; diff --git a/docs/stdlib/attributes.md b/docs/stdlib/attributes.md index 6eea5ba..b85182d 100644 --- a/docs/stdlib/attributes.md +++ b/docs/stdlib/attributes.md @@ -45,7 +45,7 @@ JavaScript 提供了一个内部数据结构,用来描述对象的属性,控 ## Object.getOwnPropertyDescriptor() -`Object.getOwnPropertyDescriptor`方法可以获取属性描述对象。它的第一个参数是一个对象,第二个参数是一个字符串,对应该对象的某个属性名。 +`Object.getOwnPropertyDescriptor()`方法可以获取属性描述对象。它的第一个参数是目标对象,第二个参数是一个字符串,对应目标对象的某个属性名。 ```javascript var obj = { p: 'a' }; @@ -58,9 +58,9 @@ Object.getOwnPropertyDescriptor(obj, 'p') // } ``` -上面代码中,`Object.getOwnPropertyDescriptor`方法获取`obj.p`的属性描述对象。 +上面代码中,`Object.getOwnPropertyDescriptor()`方法获取`obj.p`的属性描述对象。 -注意,`Object.getOwnPropertyDescriptor`方法只能用于对象自身的属性,不能用于继承的属性。 +注意,`Object.getOwnPropertyDescriptor()`方法只能用于对象自身的属性,不能用于继承的属性。 ```javascript var obj = { p: 'a' }; @@ -69,7 +69,7 @@ Object.getOwnPropertyDescriptor(obj, 'toString') // undefined ``` -上面代码中,`toString`是`Obj`对象继承的属性,`Object.getOwnPropertyDescriptor`无法获取。 +上面代码中,`toString`是`obj`对象继承的属性,`Object.getOwnPropertyDescriptor()`无法获取。 ## Object.getOwnPropertyNames() @@ -108,7 +108,7 @@ Object.getOwnPropertyNames(Object.prototype) ## Object.defineProperty(),Object.defineProperties() -`Object.defineProperty`方法允许通过属性描述对象,定义或修改一个属性,然后返回修改后的对象,它的用法如下。 +`Object.defineProperty()`方法允许通过属性描述对象,定义或修改一个属性,然后返回修改后的对象,它的用法如下。 ```javascript Object.defineProperty(object, propertyName, attributesObject) @@ -116,9 +116,9 @@ Object.defineProperty(object, propertyName, attributesObject) `Object.defineProperty`方法接受三个参数,依次如下。 -- 属性所在的对象 -- 属性名(它应该是一个字符串) -- 属性描述对象 +- object:属性所在的对象 +- propertyName:字符串,表示属性名 +- attributesObject:属性描述对象 举例来说,定义`obj.p`可以写成下面这样。 @@ -136,11 +136,11 @@ obj.p = 246; obj.p // 123 ``` -上面代码中,`Object.defineProperty`方法定义了`obj.p`属性。由于属性描述对象的`writable`属性为`false`,所以`obj.p`属性不可写。注意,这里的`Object.defineProperty`方法的第一个参数是`{}`(一个新建的空对象),`p`属性直接定义在这个空对象上面,然后返回这个对象,这是`Object.defineProperty`的常见写法。 +上面代码中,`Object.defineProperty()`方法定义了`obj.p`属性。由于属性描述对象的`writable`属性为`false`,所以`obj.p`属性不可写。注意,这里的`Object.defineProperty`方法的第一个参数是`{}`(一个新建的空对象),`p`属性直接定义在这个空对象上面,然后返回这个对象,这是`Object.defineProperty()`的常见用法。 -如果属性已经存在,`Object.defineProperty`方法相当于更新该属性的属性描述对象。 +如果属性已经存在,`Object.defineProperty()`方法相当于更新该属性的属性描述对象。 -如果一次性定义或修改多个属性,可以使用`Object.defineProperties`方法。 +如果一次性定义或修改多个属性,可以使用`Object.defineProperties()`方法。 ```javascript var obj = Object.defineProperties({}, { @@ -157,7 +157,7 @@ obj.p2 // "abc" obj.p3 // "123abc" ``` -上面代码中,`Object.defineProperties`同时定义了`obj`对象的三个属性。其中,`p3`属性定义了取值函数`get`,即每次读取该属性,都会调用这个取值函数。 +上面代码中,`Object.defineProperties()`同时定义了`obj`对象的三个属性。其中,`p3`属性定义了取值函数`get`,即每次读取该属性,都会调用这个取值函数。 注意,一旦定义了取值函数`get`(或存值函数`set`),就不能将`writable`属性设为`true`,或者同时定义`value`属性,否则会报错。 @@ -181,7 +181,7 @@ Object.defineProperty(obj, 'p', { 上面代码中,同时定义了`get`属性和`value`属性,以及将`writable`属性设为`true`,就会报错。 -`Object.defineProperty()`和`Object.defineProperties()`的第三个参数,是一个属性对象。它的`writable`、`configurable`、`enumerable`这三个属性的默认值都为`false`。 +`Object.defineProperty()`和`Object.defineProperties()`参数里面的属性描述对象,`writable`、`configurable`、`enumerable`这三个属性的默认值都为`false`。 ```javascript var obj = {}; @@ -195,11 +195,11 @@ Object.getOwnPropertyDescriptor(obj, 'foo') // } ``` -上面代码中,定义`obj.p`时用了一个空的属性描述对象,就可以看到各个元属性的默认值。 +上面代码中,定义`obj.foo`时用了一个空的属性描述对象,就可以看到各个元属性的默认值。 ## Object.prototype.propertyIsEnumerable() -实例对象的`propertyIsEnumerable`方法返回一个布尔值,用来判断某个属性是否可遍历。 +实例对象的`propertyIsEnumerable()`方法返回一个布尔值,用来判断某个属性是否可遍历。注意,这个方法只能用于判断对象自身的属性,对于继承的属性一律返回`false`。 ```javascript var obj = {}; @@ -209,7 +209,7 @@ obj.propertyIsEnumerable('p') // true obj.propertyIsEnumerable('toString') // false ``` -上面代码中,`obj.p`是可遍历的,而继承自原型对象的`obj.toString`属性是不可遍历的。 +上面代码中,`obj.p`是可遍历的,而`obj.toString`是继承的属性。 ## 元属性 From 9af612278fefe062c09741720ed9dac00d5f9379 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 12 Sep 2018 12:32:26 +0800 Subject: [PATCH 016/321] docs(stdlib): edit regex --- docs/stdlib/regexp.md | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/docs/stdlib/regexp.md b/docs/stdlib/regexp.md index 87e029d..7c589ae 100644 --- a/docs/stdlib/regexp.md +++ b/docs/stdlib/regexp.md @@ -306,11 +306,11 @@ str.replace(/^\s+|\s+$/g, '') `replace`方法的第二个参数可以使用美元符号`$`,用来指代所替换的内容。 -- $&:匹配的子字符串。 -- $\`:匹配结果前面的文本。 -- $':匹配结果后面的文本。 -- $n:匹配成功的第`n`组内容,`n`是从1开始的自然数。 -- $$:指代美元符号`$`。 +- `$&`:匹配的子字符串。 +- `$\``:匹配结果前面的文本。 +- `$'`:匹配结果后面的文本。 +- `$n`:匹配成功的第`n`组内容,`n`是从1开始的自然数。 +- `$$`:指代美元符号`$`。 ```javascript 'hello world'.replace(/(\w+)\s(\w+)/, '$2 $1') @@ -707,10 +707,19 @@ s.match(/a+?/) // ["a"] 上面代码中,模式结尾添加了一个问号`/a+?/`,这时就改为非贪婪模式,一旦条件满足,就不再往下匹配。 -除了非贪婪模式的加号,还有非贪婪模式的星号(`*`)。 +除了非贪婪模式的加号,还有非贪婪模式的星号(`*`)和非贪婪模式的问号(`?`)。 -- `*?`:表示某个模式出现0次或多次,匹配时采用非贪婪模式。 - `+?`:表示某个模式出现1次或多次,匹配时采用非贪婪模式。 +- `*?`:表示某个模式出现0次或多次,匹配时采用非贪婪模式。 +- `??`:表格某个模式出现0次或1次,匹配时采用非贪婪模式。 + +```javascript +'abb'.match(/ab*b/) // ["abb"] +'abb'.match(/ab*?b/) // ["ab"] + +'abb'.match(/ab?b/) // ["abb"] +'abb'.match(/ab??b/) // ["ab"] +``` ### 修饰符 From 882b13014c7baa9b142a5d4476466d85c8b80291 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 12 Sep 2018 12:59:17 +0800 Subject: [PATCH 017/321] docs(stdlib): edit regex --- 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 7c589ae..eb259bf 100644 --- a/docs/stdlib/regexp.md +++ b/docs/stdlib/regexp.md @@ -307,7 +307,7 @@ str.replace(/^\s+|\s+$/g, '') `replace`方法的第二个参数可以使用美元符号`$`,用来指代所替换的内容。 - `$&`:匹配的子字符串。 -- `$\``:匹配结果前面的文本。 +- `` $` ``:匹配结果前面的文本。 - `$'`:匹配结果后面的文本。 - `$n`:匹配成功的第`n`组内容,`n`是从1开始的自然数。 - `$$`:指代美元符号`$`。 From ca22c107e7355aa287bc1651c9c40e1cff1ab569 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sat, 15 Sep 2018 15:15:08 +0800 Subject: [PATCH 018/321] docs(types): fix boolean #45 --- docs/types/null-undefined-boolean.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/types/null-undefined-boolean.md b/docs/types/null-undefined-boolean.md index e7854ce..9a76679 100644 --- a/docs/types/null-undefined-boolean.md +++ b/docs/types/null-undefined-boolean.md @@ -87,7 +87,6 @@ f() // undefined 下列运算符会返回布尔值: -- 两元逻辑运算符: `&&` (And),`||` (Or) - 前置逻辑运算符: `!` (Not) - 相等运算符:`===`,`!==`,`==`,`!=` - 比较运算符:`>`,`>=`,`<`,`<=` From cf7c15d29093bf9a070414ed38dc74c9ecaf1ccc Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 21 Sep 2018 16:35:17 +0800 Subject: [PATCH 019/321] docs(event): fix form --- docs/events/form.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/events/form.md b/docs/events/form.md index 5a5266b..e724f8f 100644 --- a/docs/events/form.md +++ b/docs/events/form.md @@ -139,7 +139,7 @@ function myFunction(e) { - 手动插入文本:`insertText` - 粘贴插入文本:`insertFromPaste` - 向后删除:`deleteContentBackward` -- 向前删除:`deleteContentBackward` +- 向前删除:`deleteContentForward` **(3)InputEvent.dataTransfer** From d2364276df8b22dd0b01659d0c18bb5cb07169f1 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 21 Sep 2018 16:45:09 +0800 Subject: [PATCH 020/321] docs(stdlib): fix regex --- docs/stdlib/regexp.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/stdlib/regexp.md b/docs/stdlib/regexp.md index eb259bf..d3ad8b7 100644 --- a/docs/stdlib/regexp.md +++ b/docs/stdlib/regexp.md @@ -100,9 +100,12 @@ var s = '_x_x'; r.lastIndex = 4; r.test(s) // false + +r.lastIndex // 0 +r.test(s) ``` -上面代码指定从字符串的第五个位置开始搜索,这个位置是没有字符的,所以返回`false`。 +上面代码指定从字符串的第五个位置开始搜索,这个位置为空,所以返回`false`。同时,`lastIndex`属性重置为`0`,所以第二次执行`r.test(s)`会返回`true`。 注意,带有`g`修饰符时,正则表达式内部会记住上一次的`lastIndex`属性,这时不应该更换所要匹配的字符串,否则会有一些难以察觉的错误。 From 6c170a2d158c86f133f6d80c1c120546c298320d Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sun, 23 Sep 2018 20:56:53 +0800 Subject: [PATCH 021/321] docs(bom): edit Web Worker --- docs/bom/webworker.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/bom/webworker.md b/docs/bom/webworker.md index 3b8f11f..1c7d8f4 100644 --- a/docs/bom/webworker.md +++ b/docs/bom/webworker.md @@ -18,15 +18,19 @@ Web Worker 有以下几个使用注意点。 Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用`document`、`window`、`parent`这些对象。但是,Worker 线程可以`navigator`对象和`location`对象。 -(3)**通信联系** +(3)**全局对象限制** + +Worker 的全局对象`WorkerGlobalScope`,不同于网页的全局对象`Window`,很多接口拿不到。比如,理论上 Worker 线程不能使用`console.log`,因为标准里面没有提到 Worker 的全局对象存在`console`接口,只定义了`Navigator`接口和`Location`接口。不过,浏览器实际上支持 Worker 线程使用`console.log`,保险的做法还是不使用这个方法。 + +(4)**通信联系** Worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成。 -(4)**脚本限制** +(5)**脚本限制** Worker 线程不能执行`alert()`方法和`confirm()`方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。 -(5)**文件限制** +(6)**文件限制** Worker 线程无法读取本地文件,即不能打开本机的文件系统(`file://`),它所加载的脚本,必须来自网络。 @@ -55,8 +59,7 @@ worker.postMessage({method: 'echo', args: ['Work']}); ```javascript worker.onmessage = function (event) { - console.log('Received message ' + event.data); - doSomething(); + doSomething(event.data); } function doSomething() { From e6dc271f0ddd54f83316bd24820b373e5088ca28 Mon Sep 17 00:00:00 2001 From: magical-l Date: Tue, 25 Sep 2018 12:28:30 +0800 Subject: [PATCH 022/321] Update prototype.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 字符串里多了个冒号 --- docs/oop/prototype.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/oop/prototype.md b/docs/oop/prototype.md index 7ed4a74..c91cc30 100644 --- a/docs/oop/prototype.md +++ b/docs/oop/prototype.md @@ -443,7 +443,7 @@ Object.assign(S.prototype, M2.prototype); S.prototype.constructor = S; var s = new S(); -s.hello // 'hello:' +s.hello // 'hello' s.world // 'world' ``` From 14215dff1a58cd87ff0c7999a593e9963d711c10 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 25 Sep 2018 12:35:24 +0800 Subject: [PATCH 023/321] docs(oop): fix prototype #48 --- docs/oop/prototype.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/oop/prototype.md b/docs/oop/prototype.md index 7ed4a74..9c20673 100644 --- a/docs/oop/prototype.md +++ b/docs/oop/prototype.md @@ -2,7 +2,9 @@ 面向对象编程很重要的一个方面,就是对象的继承。A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法。这对于代码的复用是非常有用的。 -大部分面向对象的编程语言,都是通过“类”(class)来实现对象的继承。JavaScript 语言的继承则是通过“原型对象”(prototype)。 +大部分面向对象的编程语言,都是通过“类”(class)实现对象的继承。传统上,JavaScript 语言的继承不通过 class,而是通过“原型对象”(prototype)实现,本章介绍 JavaScript 的原型链继承。 + +ES6 引入了 class 语法,基于 class 的继承不在这个教程介绍,请参阅《ES6 标准语法入门》一书的相关章节。 ## 原型对象概述 @@ -451,14 +453,10 @@ s.world // 'world' ## 模块 -随着网站逐渐变成"互联网应用程序",嵌入网页的 JavaScript 代码越来越庞大,越来越复杂。网页越来越像桌面程序,需要一个团队分工协作、进度管理、单元测试等等……开发者必须使用软件工程的方法,管理网页的业务逻辑。 +随着网站逐渐变成“互联网应用程序”,嵌入网页的 JavaScript 代码越来越庞大,越来越复杂。网页越来越像桌面程序,需要一个团队分工协作、进度管理、单元测试等等……开发者必须使用软件工程的方法,管理网页的业务逻辑。 JavaScript 模块化编程,已经成为一个迫切的需求。理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块。 - -:"污染"了全局变量,无法保证不与其他模块发生变量名冲突,而且模块成员之间看不出直接关系。 - -为了解决上面的缺点,可以 但是,JavaScript 不是一种模块化编程语言,ES6 才开始支持“类”和“模块”。下面介绍传统的做法,如何利用对象实现模块的效果。 ### 基本的实现方法 From a54ff9b92bd737fbd7b7678dffec3a022914bb3d Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 25 Sep 2018 12:52:34 +0800 Subject: [PATCH 024/321] docs(oop): fix oop/prototype --- docs/oop/prototype.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/oop/prototype.md b/docs/oop/prototype.md index 140240f..ffc7b8d 100644 --- a/docs/oop/prototype.md +++ b/docs/oop/prototype.md @@ -4,7 +4,7 @@ 大部分面向对象的编程语言,都是通过“类”(class)实现对象的继承。传统上,JavaScript 语言的继承不通过 class,而是通过“原型对象”(prototype)实现,本章介绍 JavaScript 的原型链继承。 -ES6 引入了 class 语法,基于 class 的继承不在这个教程介绍,请参阅《ES6 标准语法入门》一书的相关章节。 +ES6 引入了 class 语法,基于 class 的继承不在这个教程介绍,请参阅《ES6 标准入门》一书的相关章节。 ## 原型对象概述 From d953738c1d781f3569da9e11c7b6c3ed6c03980f Mon Sep 17 00:00:00 2001 From: magical-l Date: Tue, 25 Sep 2018 18:22:27 +0800 Subject: [PATCH 025/321] Update window.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 也许改正了错误的语序。要取决于原作者本来想表达的意思。 --- docs/bom/window.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/bom/window.md b/docs/bom/window.md index 33163b5..9f66a0e 100644 --- a/docs/bom/window.md +++ b/docs/bom/window.md @@ -344,7 +344,7 @@ var windowB = window.open('windowB.html', 'WindowB'); windowB.window.name // "WindowB" ``` -注意,如果新窗口和父窗口不是同源的(即不在同一个域),它们彼此不能窗口对象获取对方的内部属性。 +注意,如果新窗口和父窗口不是同源的(即不在同一个域),它们彼此不能获取对方窗口对象的内部属性。 下面是另一个例子。 From 059323e64a4588e93a4d755bcad414c6d0a94227 Mon Sep 17 00:00:00 2001 From: magical-l Date: Wed, 26 Sep 2018 11:02:29 +0800 Subject: [PATCH 026/321] Update webworker.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 补漏词;优化文案。 --- docs/bom/webworker.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/bom/webworker.md b/docs/bom/webworker.md index 1c7d8f4..d4e7d60 100644 --- a/docs/bom/webworker.md +++ b/docs/bom/webworker.md @@ -4,7 +4,7 @@ JavaScript 语言采用的是单线程模型,也就是说,所有任务只能在一个线程上完成,一次只能做一件事。前面的任务没做完,后面的任务只能等着。随着电脑计算能力的增强,尤其是多核 CPU 的出现,单线程带来很大的不便,无法充分发挥计算机的计算能力。 -Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢。 +Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务可以交由 Worker 线程执行,主线程(通常负责 UI 交互)能够保持流畅,不会被阻塞或拖慢。 Worker 线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断。这样有利于随时响应主线程的通信。但是,这也造成了 Worker 比较耗费资源,不应该过度使用,而且一旦使用完毕,就应该关闭。 @@ -16,7 +16,7 @@ Web Worker 有以下几个使用注意点。 (2)**DOM 限制** -Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用`document`、`window`、`parent`这些对象。但是,Worker 线程可以`navigator`对象和`location`对象。 +Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用`document`、`window`、`parent`这些对象。但是,Worker 线程可以使用`navigator`对象和`location`对象。 (3)**全局对象限制** From 472248dbeb90e603839a06eec980fd0c97543e8e Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 26 Sep 2018 16:54:32 +0800 Subject: [PATCH 027/321] docs(bom): fix location #52 --- docs/bom/location.md | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/docs/bom/location.md b/docs/bom/location.md index 4f782da..78698a7 100644 --- a/docs/bom/location.md +++ b/docs/bom/location.md @@ -10,17 +10,17 @@ URL 是互联网的基础设施之一。浏览器提供了一些原生对象, `Location`对象提供以下属性。 -- Location.href:整个 URL。 -- Location.protocol:当前 URL 的协议,包括冒号(`:`)。 -- Location.host:主机,包括冒号(`:`)和端口(默认的80端口和443端口会省略)。 -- Location.hostname:主机名,不包括端口。 -- Location.port:端口号。 -- Location.pathname:URL 的路径部分,从根路径`/`开始。 -- Location.search:查询字符串部分,从问号`?`开始。 -- Location.hash:片段字符串部分,从`#`开始。 -- Location.username:域名前面的用户名。 -- Location.password:域名前面的密码。 -- Location.origin:URL 的协议、主机名和端口。 +- `Location.href`:整个 URL。 +- `Location.protocol`:当前 URL 的协议,包括冒号(`:`)。 +- `Location.host`:主机,包括冒号(`:`)和端口(默认的80端口和443端口会省略)。 +- `Location.hostname`:主机名,不包括端口。 +- `Location.port`:端口号。 +- `Location.pathname`:URL 的路径部分,从根路径`/`开始。 +- `Location.search`:查询字符串部分,从问号`?`开始。 +- `Location.hash`:片段字符串部分,从`#`开始。 +- `Location.username`:域名前面的用户名。 +- `Location.password`:域名前面的密码。 +- `Location.origin`:URL 的协议、主机名和端口。 ```javascript // 当前网址为 @@ -115,12 +115,14 @@ window.location.reload(true); ## URL 的编码和解码 -网页的 URL 只能包含合法的字符,这可以分成两类。 +网页的 URL 只能包含合法的字符。合法字符分成两类。 -- URL 元字符:分号(`;`),逗号(','),斜杠(`/`),问号(`?`),冒号(`:`),at(`@`),`&`,等号(`=`),加号(`+`),美元符号(`$`),井号(`#`) -- 语义字符:`a-z`,`A-Z`,`0-9`,连词号(`-`),下划线(`_`),点(`.`),感叹号(`!`),波浪线(`~`),星号(`*`),单引号(`\``),圆括号(`()`) +- URL 元字符:分号(`;`),逗号(`,`),斜杠(`/`),问号(`?`),冒号(`:`),at(`@`),`&`,等号(`=`),加号(`+`),美元符号(`$`),井号(`#`) +- 语义字符:`a-z`,`A-Z`,`0-9`,连词号(`-`),下划线(`_`),点(`.`),感叹号(`!`),波浪线(`~`),星号(`*`),单引号(`'`),圆括号(`()`) -除了以上字符,其他字符出现在 URL 之中都必须转义,规则是根据操作系统的默认编码,将每个字节转为百分号(`%`)加上两个大写的十六进制字母。比如,UTF-8 的操作系统上,`http://www.example.com/q=春节`这个 URL 之中,汉字“春节”不是 URL 的合法字符,所以被浏览器自动转成`http://www.example.com/q=%E6%98%A5%E8%8A%82`。其中,“春”转成了`%E6%98%A5`,“节”转成了“%E8%8A%82”。这是因为“春”和”节“的 UTF-8 编码分别是`E6 98 A5`和`E8 8A 82`,将每个字节前面加上百分号,就构成了 URL 编码。 +除了以上字符,其他字符出现在 URL 之中都必须转义,规则是根据操作系统的默认编码,将每个字节转为百分号(`%`)加上两个大写的十六进制字母。 + +比如,UTF-8 的操作系统上,`http://www.example.com/q=春节`这个 URL 之中,汉字“春节”不是 URL 的合法字符,所以被浏览器自动转成`http://www.example.com/q=%E6%98%A5%E8%8A%82`。其中,“春”转成了`%E6%98%A5`,“节”转成了`%E8%8A%82`。这是因为“春”和”节“的 UTF-8 编码分别是`E6 98 A5`和`E8 8A 82`,将每个字节前面加上百分号,就构成了 URL 编码。 JavaScript 提供四个 URL 的编码/解码方法。 From 55b4ec65574391da14844309a7e667b026c12f0e Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sat, 29 Sep 2018 10:42:56 +0800 Subject: [PATCH 028/321] docs(stdlib): fix array --- docs/stdlib/array.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/stdlib/array.md b/docs/stdlib/array.md index e267830..e4ef47a 100644 --- a/docs/stdlib/array.md +++ b/docs/stdlib/array.md @@ -774,11 +774,13 @@ users .filter(function (email) { return /^t/.test(email); }) -.forEach(console.log); +.forEach(function (email) { + console.log(email); +}); // "tom@example.com" ``` -上面代码中,先产生一个所有 Email 地址组成的数组,然后再过滤出以`t`开头的 Email 地址。 +上面代码中,先产生一个所有 Email 地址组成的数组,然后再过滤出以`t`开头的 Email 地址,最后将它打印出来。 ## 参考链接 From 2debcf742cd0f346f328cdbbef903809266d98d4 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 4 Oct 2018 11:17:39 +0800 Subject: [PATCH 029/321] docs(bom): edit cors/withCredentials --- docs/bom/cors.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/bom/cors.md b/docs/bom/cors.md index c990257..aa41f83 100644 --- a/docs/bom/cors.md +++ b/docs/bom/cors.md @@ -78,28 +78,28 @@ Content-Type: text/html; charset=utf-8 ### withCredentials 属性 -上面说到,CORS 请求默认不包含 Cookie 信息(以及 HTTP 认证信息等)。如果需要包含 Cookie 信息,一方面要服务器同意,指定`Access-Control-Allow-Credentials`字段。 +上面说到,CORS 请求默认不包含 Cookie 信息(以及 HTTP 认证信息等),这是为了降低 CSRF 攻击的风险。但是某些场合,服务器可能需要拿到 Cookie,这时需要服务器显式指定`Access-Control-Allow-Credentials`字段,告诉浏览器可以发送 Cookie。 ```http Access-Control-Allow-Credentials: true ``` -另一方面,开发者必须在 AJAX 请求中打开`withCredentials`属性。 +同时,开发者必须在 AJAX 请求中打开`withCredentials`属性。 ```javascript var xhr = new XMLHttpRequest(); xhr.withCredentials = true; ``` -否则,即使服务器同意发送 Cookie,浏览器也不会发送。或者,服务器要求设置 Cookie,浏览器也不会处理。 +否则,即使服务器要求发送 Cookie,浏览器也不会发送。或者,服务器要求设置 Cookie,浏览器也不会处理。 -但是,如果省略`withCredentials`设置,有的浏览器还是会一起发送 Cookie。这时,可以显式关闭`withCredentials`。 +但是,有的浏览器默认将`withCredentials`属性设为`true`。这导致如果省略`withCredentials`设置,这些浏览器可能还是会一起发送 Cookie。这时,可以显式关闭`withCredentials`。 ```javascript xhr.withCredentials = false; ``` -需要注意的是,如果要发送 Cookie,`Access-Control-Allow-Origin`就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie 依然遵循同源政策,只有用服务器域名设置的 Cookie 才会上传,其他域名的 Cookie 并不会上传,且(跨域)原网页代码中的`document.cookie`也无法读取服务器域名下的 Cookie。 +需要注意的是,如果服务器要求浏览器发送 Cookie,`Access-Control-Allow-Origin`就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie 依然遵循同源政策,只有用服务器域名设置的 Cookie 才会上传,其他域名的 Cookie 并不会上传,且(跨域)原网页代码中的`document.cookie`也无法读取服务器域名下的 Cookie。 ## 非简单请求 @@ -247,7 +247,7 @@ CORS 与 JSONP 的使用目的相同,但是比 JSONP 更强大。JSONP 只支 ## 参考链接 -- Monsur Hossain, [Using CORS](http://www.html5rocks.com/en/tutorials/cors/) -- MDN, [HTTP access control (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS) -- Ryan Miller, [CORS](https://frontendian.co/cors) - +- [Using CORS](http://www.html5rocks.com/en/tutorials/cors/), Monsur Hossain +- [HTTP access control (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS), MDN +- [CORS](https://frontendian.co/cors), Ryan Miller +- [Do You Really Know CORS?](http://performantcode.com/web/do-you-really-know-cors), Grzegorz Mirek From 3f39bd7eabba584dfb6eaaeb07e71587693965b5 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 4 Oct 2018 19:31:22 +0800 Subject: [PATCH 030/321] docs(bom): edit window --- docs/async/timer.md | 2 + docs/bom/window.md | 85 +++++++++++++++++++++++++++++++++++++++++++ docs/events/common.md | 2 + 3 files changed, 89 insertions(+) diff --git a/docs/async/timer.md b/docs/async/timer.md index a339f8d..89b6421 100644 --- a/docs/async/timer.md +++ b/docs/async/timer.md @@ -288,6 +288,8 @@ console.log(2); 总之,`setTimeout(f, 0)`这种写法的目的是,尽可能早地执行`f`,但是并不能保证立刻就执行`f`。 +实际上,`setTimeout(f, 0)`不会真的在0毫秒之后运行,不同的浏览器有不同的实现。以 Edge 浏览器为例,会等到4毫秒之后运行。如果电脑正在使用电池供电,会等到16毫秒之后运行;如果网页不在当前 Tab 页,会推迟到1000毫秒(1秒)之后运行。这样是为了节省系统资源。 + ### 应用 `setTimeout(f, 0)`有几个非常重要的用途。它的一大应用是,可以调整事件的发生顺序。比如,网页开发中,某个事件先发生在子元素,然后冒泡到父元素,即子元素的事件回调函数,会早于父元素的事件回调函数触发。如果,想让父元素的事件回调函数先发生,就要用到`setTimeout(f, 0)`。 diff --git a/docs/bom/window.md b/docs/bom/window.md index 9f66a0e..c813fc3 100644 --- a/docs/bom/window.md +++ b/docs/bom/window.md @@ -529,6 +529,91 @@ var selectedText = selObj.toString(); `window.matchMedia()`方法用来检查 CSS 的`mediaQuery`语句,详见《CSS 操作》一章。 +### window.requestAnimationFrame() + +`window.requestAnimationFrame()`方法跟`setTimeout`类似,都是推迟某个函数的执行。不同之处在于,`setTimeout`必须指定推迟的时间,`window.requestAnimationFrame()`则是推迟到浏览器下一次重流时执行,即在下一次重绘之前执行。重绘通常是 16ms 执行一次,不过浏览器会自动调节这个速率,比如网页切换到后台 Tab 页时,`requestAnimationFrame()`会暂停执行。 + +如果某个函数会改变网页的布局,一般就放在`window.requestAnimationFrame()`里面执行,这样可以节省系统资源,使得网页效果更加平滑。因为慢速设备会用较慢的速率重流和重绘,而速度更快的设备会有更快的速率。 + +该方法接受一个回调函数作为参数。 + +```javascript +window.requestAnimationFrame(callback) +``` + +上面代码中,`callback`是一个回调函数。`callback`执行时,它的参数就是系统传入的一个高精度时间戳(`performance.now()`的返回值),单位是毫秒,表示距离网页加载的时间。 + +`window.requestAnimationFrame()`的返回值是一个整数,这个整数可以传入`window.cancelAnimationFrame()`,用来取消回调函数的执行。 + +下面是一个`window.requestAnimationFrame()`执行网页动画的例子。 + +```javascript +var element = document.getElementById('animate'); +element.style.position = 'absolute'; + +var start = null; + +function step(timestamp) { + if (!start) start = timestamp; + var progress = timestamp - start; + // 元素不断向左移,最大不超过200像素 + element.style.left = Math.min(progress / 10, 200) + 'px'; + // 如果距离第一次执行不超过 2000 毫秒, + // 就继续执行动画 + if (progress < 2000) { + window.requestAnimationFrame(step); + } +} + +window.requestAnimationFrame(step); +``` + +上面代码定义了一个网页动画,持续时间是2秒,会让元素向右移动。 + +### window.requestIdleCallback() + +`window.requestIdleCallback()`跟`setTimeout`类似,也是将某个函数推迟执行,但是它保证将回调函数推迟到系统资源空闲时执行。也就是说,如果某个任务不是很关键,就可以使用`window.requestIdleCallback()`将其推迟执行,以保证网页性能。 + +它跟`window.requestAnimationFrame()`的区别在于,后者指定回调函数在下一次浏览器重排时执行,问题在于下一次重排时,系统资源未必空闲,不一定能保证在16毫秒之内完成;`window.requestIdleCallback()`可以保证回调函数在系统资源空闲时执行。 + +该方法接受一个回调函数和一个配置对象作为参数。配置对象可以指定一个推迟执行的最长时间,如果过了这个时间,回调函数不管系统资源有无空虚,都会执行。 + +```javascript +window.requestIdleCallback(callback[, options]) +``` + +`callback`参数是一个回调函数。该回调函数执行时,系统会传入一个`IdleDeadline`对象作为参数。`IdleDeadline`对象有一个`didTimeout`属性(布尔值,表示是否为超时调用)和一个`timeRemaining()`方法(返回该空闲时段剩余的毫秒数)。 + +`options`参数是一个配置对象,目前只有`timeout`一个属性,用来指定回调函数推迟执行的最大毫秒数。该参数可选。 + +`window.requestAnimationFrame()`方法返回一个整数。该整数可以传入`window.cancelIdleCallback()`取消回调函数。 + +下面是一个例子。 + +```javascript +requestIdleCallback(myNonEssentialWork); + +function myNonEssentialWork(deadline) { + while (deadline.timeRemaining() > 0) { + doWorkIfNeeded(); + } +} +``` + +上面代码中,`requestIdleCallback()`用来执行非关键任务`myNonEssentialWork`。该任务先确认本次空闲时段有剩余时间,然后才真正开始执行任务。 + +下面是指定`timeout`的例子。 + +```javascript +requestIdleCallback(processPendingAnalyticsEvents, { timeout: 2000 }); +``` + +上面代码指定,`processPendingAnalyticsEvents`必须在未来2秒之内执行。 + +如果由于超时导致回调函数执行,则`deadline.timeRemaining()`返回`0`,`deadline.didTimeout`返回`true`。 + +如果多次执行`window.requestAnimationFrame()`,指定多个回调函数,那么这些回调函数将排成一个队列,按照先进先出的顺序执行。 + ## 事件 `window`对象可以接收以下事件。 diff --git a/docs/events/common.md b/docs/events/common.md index 3f67ec8..804ad06 100644 --- a/docs/events/common.md +++ b/docs/events/common.md @@ -259,6 +259,8 @@ window.addEventListener('scroll', throttle(callback, 1000)); window.addEventListener('scroll', _.throttle(callback, 1000)); ``` +本书前面介绍过`debounce`的概念,`throttle`与它区别在于,`throttle`是“节流”,确保一段时间内只执行一次,而`debounce`是“防抖”,要连续操作结束后再执行。以网页滚动为例,`debounce`要等到用户停止滚动后才执行,`throttle`则是如果用户一直在滚动网页,那么在滚动过程中还是会执行。 + ### resize 事件 `resize`事件在改变浏览器窗口大小时触发,主要发生在`window`对象上面。 From 2b0815e401188c003e0a161f4b358523bec50f36 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sun, 7 Oct 2018 21:59:41 +0800 Subject: [PATCH 031/321] docs(operator): fix typo #55 --- docs/operators/comparison.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operators/comparison.md b/docs/operators/comparison.md index 828a06f..9699670 100644 --- a/docs/operators/comparison.md +++ b/docs/operators/comparison.md @@ -52,7 +52,7 @@ JavaScript 引擎内部首先比较首字符的 Unicode 码点。如果相等, ## 非相等运算符:非字符串的比较 -如果两个运算子都不是字符串,分成以下三种情况。 +如果两个运算子都不是字符串,分成以下两种情况。 **(1)原始类型值** From 864ad8edc6fd034b9a5c8a833cd08ffb7f0ba0ba Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sun, 7 Oct 2018 22:53:52 +0800 Subject: [PATCH 032/321] docs: edit README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 193c114..55703f1 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -本教程全面介绍 JavaScript 核心语法,从最简单的开始讲起,循序渐进、由浅入深,力求清晰易懂。所有章节都带有大量的代码实例,便于理解和模仿,可以用到实际项目中,即学即用。 +本教程全面介绍 JavaScript 核心语法,从最简单的讲起,循序渐进、由浅入深,力求清晰易懂。所有章节都带有大量的代码实例,便于理解和模仿,可以用到实际项目中,即学即用。 本教程适合初学者当作 JavaScript 语言的入门教程,也适合当作日常使用的参考手册。 From 44f6a5167dcc03e6fc4ed18a363704d5930bfe83 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Mon, 8 Oct 2018 20:56:29 +0800 Subject: [PATCH 033/321] docs(async): fix promise typo #57 --- docs/async/promise.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/async/promise.md b/docs/async/promise.md index fe69b28..f909c7d 100644 --- a/docs/async/promise.md +++ b/docs/async/promise.md @@ -114,7 +114,7 @@ timeout(100) Promise 实例的`then`方法,用来添加回调函数。 -`then`方法可以接受两个回调函数,第一个是异步操作成功时(变为`fulfilled`状态)时的回调函数,第二个是异步操作失败(变为`rejected`)时的回调函数(该参数可以省略)。一旦状态改变,就调用相应的回调函数。 +`then`方法可以接受两个回调函数,第一个是异步操作成功时(变为`fulfilled`状态)的回调函数,第二个是异步操作失败(变为`rejected`)时的回调函数(该参数可以省略)。一旦状态改变,就调用相应的回调函数。 ```javascript var p1 = new Promise(function (resolve, reject) { From 5cd2003208c14bb0cef436637d5b5743177689fe Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 10 Oct 2018 15:28:21 +0800 Subject: [PATCH 034/321] docs(bom): edit window/requestAnimationFrame --- docs/bom/window.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/bom/window.md b/docs/bom/window.md index c813fc3..e87131b 100644 --- a/docs/bom/window.md +++ b/docs/bom/window.md @@ -531,7 +531,7 @@ var selectedText = selObj.toString(); ### window.requestAnimationFrame() -`window.requestAnimationFrame()`方法跟`setTimeout`类似,都是推迟某个函数的执行。不同之处在于,`setTimeout`必须指定推迟的时间,`window.requestAnimationFrame()`则是推迟到浏览器下一次重流时执行,即在下一次重绘之前执行。重绘通常是 16ms 执行一次,不过浏览器会自动调节这个速率,比如网页切换到后台 Tab 页时,`requestAnimationFrame()`会暂停执行。 +`window.requestAnimationFrame()`方法跟`setTimeout`类似,都是推迟某个函数的执行。不同之处在于,`setTimeout`必须指定推迟的时间,`window.requestAnimationFrame()`则是推迟到浏览器下一次重流时执行,执行完才会进行下一次重绘。重绘通常是 16ms 执行一次,不过浏览器会自动调节这个速率,比如网页切换到后台 Tab 页时,`requestAnimationFrame()`会暂停执行。 如果某个函数会改变网页的布局,一般就放在`window.requestAnimationFrame()`里面执行,这样可以节省系统资源,使得网页效果更加平滑。因为慢速设备会用较慢的速率重流和重绘,而速度更快的设备会有更快的速率。 @@ -586,7 +586,7 @@ window.requestIdleCallback(callback[, options]) `options`参数是一个配置对象,目前只有`timeout`一个属性,用来指定回调函数推迟执行的最大毫秒数。该参数可选。 -`window.requestAnimationFrame()`方法返回一个整数。该整数可以传入`window.cancelIdleCallback()`取消回调函数。 +`window.requestIdelCallback()`方法返回一个整数。该整数可以传入`window.cancelIdleCallback()`取消回调函数。 下面是一个例子。 @@ -612,7 +612,7 @@ requestIdleCallback(processPendingAnalyticsEvents, { timeout: 2000 }); 如果由于超时导致回调函数执行,则`deadline.timeRemaining()`返回`0`,`deadline.didTimeout`返回`true`。 -如果多次执行`window.requestAnimationFrame()`,指定多个回调函数,那么这些回调函数将排成一个队列,按照先进先出的顺序执行。 +如果多次执行`window.requestIdelCallback()`,指定多个回调函数,那么这些回调函数将排成一个队列,按照先进先出的顺序执行。 ## 事件 From 9f0f31707daaeb4fbb736ee838c169272dd8fed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=8C=E4=B9=85?= Date: Fri, 12 Oct 2018 11:21:28 +0800 Subject: [PATCH 035/321] typo rt --- docs/elements/video.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/elements/video.md b/docs/elements/video.md index 799e679..879fdb3 100644 --- a/docs/elements/video.md +++ b/docs/elements/video.md @@ -35,7 +35,7 @@ - HTMLMediaElement.audioTracks:返回一个类似数组的对象,表示媒体文件包含的音轨。 - HTMLMediaElement.autoplay:布尔值,表示媒体文件是否自动播放,对应 HTML 属性`autoplay`。 - HTMLMediaElement.buffered:返回一个 TimeRanges 对象,表示浏览器缓冲的内容。该对象的`length`属性返回缓存里面有多少段内容,`start(rangeId)`方法返回指定的某段内容(从0开始)开始的时间点,`end()`返回指定的某段内容结束的时间点。该属性只读。 -- HTMLMediaElement.controls:布尔值,表示是否显示媒体文件的控制栏,对应 HTML 属性`autoplay`。 +- HTMLMediaElement.controls:布尔值,表示是否显示媒体文件的控制栏,对应 HTML 属性`controls`。 - HTMLMediaElement.controlsList:返回一个类似数组的对象,表示是否显示控制栏的某些控件。该对象包含三个可能的值:`nodownload`、`nofullscreen`和`noremoteplayback`。该属性只读。 - HTMLMediaElement.crossOrigin:字符串,表示跨域请求时是否附带用户信息(比如 Cookie),对应 HTML 属性`crossorigin`。该属性只有两个可能的值:`anonymous`和`use-credentials`。 - HTMLMediaElement.currentSrc:字符串,表示当前正在播放的媒体文件的绝对路径。该属性只读。 From 9b78af10405c1651ae5813186c3766c3d26b297f Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sun, 14 Oct 2018 22:08:45 +0800 Subject: [PATCH 036/321] docs(bom): edit ArrayBuffer --- docs/bom/arraybuffer.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/bom/arraybuffer.md b/docs/bom/arraybuffer.md index acd35ac..a93cac2 100644 --- a/docs/bom/arraybuffer.md +++ b/docs/bom/arraybuffer.md @@ -2,7 +2,7 @@ ## ArrayBuffer 对象 -ArrayBuffer 对象表示一段二进制数据,用来模拟内存里面的数据。通过这个对象,JavaScript 可以读写二进制数据。 +ArrayBuffer 对象表示一段二进制数据,用来模拟内存里面的数据。通过这个对象,JavaScript 可以读写二进制数据。这个对象可以看作内存数据的表达。 这个对象是 ES6 才写入标准的,普通的网页编程用不到它,为了教程体系的完整,下面只提供一个简略的介绍,详细介绍请看《ES6 标准入门》里面的章节。 @@ -33,7 +33,7 @@ var buf2 = buf1.slice(0); ## Blob 对象 -Blob 对象表示一个二进制文件的数据内容,比如一个图片文件的内容就可以通过 Blob 对象读写。它通常用来读写文件。 +Blob 对象表示一个二进制文件的数据内容,比如一个图片文件的内容就可以通过 Blob 对象读写。它通常用来读写文件。它与 ArrayBuffer 的区别在于,它用于操作二进制文件,而 ArrayBuffer 用于操作内存。 浏览器原生提供`Blob()`构造函数,用来生成实例对象。 From ae88ca9875c8838ee04bbf5d26f37e716d771035 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 19 Oct 2018 16:39:19 +0800 Subject: [PATCH 037/321] docs(bom): fix arrayBuffer #61 --- docs/bom/arraybuffer.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/bom/arraybuffer.md b/docs/bom/arraybuffer.md index a93cac2..f1116e1 100644 --- a/docs/bom/arraybuffer.md +++ b/docs/bom/arraybuffer.md @@ -14,12 +14,11 @@ var buffer = new ArrayBuffer(8); 上面代码中,实例对象`buffer`占用8个字节。 -ArrayBuffer 对象有实例属性`length`和`byteLength`,都表示当前实例占用的内存长度(单位字节)。 +ArrayBuffer 对象有实例属性`byteLength`,表示当前实例占用的内存长度(单位字节)。 ```javascript var buffer = new ArrayBuffer(8); -buffer.length // 8 -buffer.length // 8 +buffer.byteLength // 8 ``` ArrayBuffer 对象有实例方法`slice()`,用来复制一部分内存。它接受两个整数参数,分别表示复制的开始位置(从0开始)和结束位置(复制时不包括结束位置),如果省略第二个参数,则表示一直复制到结束。 From f4982f934e209cc5c5b7b46eba9ccf257e81dbb1 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sat, 20 Oct 2018 14:39:33 +0800 Subject: [PATCH 038/321] docs(dom): fix node/nodeValue #62 --- docs/dom/node.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/dom/node.md b/docs/dom/node.md index 6ed7d65..bffcb0d 100644 --- a/docs/dom/node.md +++ b/docs/dom/node.md @@ -68,7 +68,7 @@ div.nodeName // "DIV" `nodeValue`属性返回一个字符串,表示当前节点本身的文本值,该属性可读写。 -只有文本节点(text)和注释节点(comment)有文本值,因此这两类节点的`nodeValue`可以返回结果,其他类型的节点一律返回`null`。同样的,也只有这两类节点可以设置`nodeValue`属性的值,其他类型的节点设置无效。 +只有文本节点(text)、注释节点(comment)和属性节点(attr)有文本值,因此这三类节点的`nodeValue`可以返回结果,其他类型的节点一律返回`null`。同样的,也只有这三类节点可以设置`nodeValue`属性的值,其他类型的节点设置无效。 ```javascript // HTML 代码如下 @@ -102,7 +102,7 @@ document.getElementById('foo').textContent = '

GoodBye!

'; 上面代码在插入文本时,会将`

`标签解释为文本,而不会当作标签处理。 -对于文本节点(text)和注释节点(comment),`textContent`属性的值与`nodeValue`属性相同。对于其他类型的节点,该属性会将每个子节点的内容连接在一起返回,但是不包括注释节点。如果一个节点没有子节点,则返回空字符串。 +对于文本节点(text)、注释节点(comment)和属性节点(attr),`textContent`属性的值与`nodeValue`属性相同。对于其他类型的节点,该属性会将每个子节点(不包括注释节点)的内容连接在一起返回。如果一个节点没有子节点,则返回空字符串。 文档节点(document)和文档类型节点(doctype)的`textContent`属性为`null`。如果要读取整个文档的内容,可以使用`document.documentElement.textContent`。 From 0a9f7d0713f4524e99216f281d730d75d948576c Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 23 Oct 2018 16:04:42 +0800 Subject: [PATCH 039/321] docs: edit events/common --- docs/events/common.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/events/common.md b/docs/events/common.md index 804ad06..94cf8fe 100644 --- a/docs/events/common.md +++ b/docs/events/common.md @@ -9,7 +9,7 @@ 如果该事件对象的`returnValue`属性是一个非空字符串,那么浏览器就会弹出一个对话框,询问用户是否要卸载该资源。但是,用户指定的字符串可能无法显示,浏览器会展示预定义的字符串。如果用户点击“取消”按钮,资源就不会卸载。 ```javascript -window.addEventListener('beforeunload', function(event) { +window.addEventListener('beforeunload', function (event) { event.returnValue = '你确定离开吗?'; }); ``` @@ -19,7 +19,7 @@ window.addEventListener('beforeunload', function(event) { 浏览器对这个事件的行为很不一致,有的浏览器调用`event.preventDefault()`,也会弹出对话框。IE 浏览器需要显式返回一个非空的字符串,才会弹出对话框。而且,大多数浏览器在对话框中不显示指定文本,只显示默认文本。因此,可以采用下面的写法,取得最大的兼容性。 ```javascript -window.addEventListener('beforeunload', function(e) { +window.addEventListener('beforeunload', function (e) { var confirmationMessage = '确认关闭窗口?'; e.returnValue = confirmationMessage; @@ -27,9 +27,9 @@ window.addEventListener('beforeunload', function(e) { }); ``` -注意,许多手机浏览器默认忽略这个事件,桌面浏览器也有办法忽略这个事件。所以,它可能根本不会生效,不能依赖它来阻止用户关闭窗口。 +注意,许多手机浏览器默认忽略这个事件,桌面浏览器也有办法忽略这个事件。所以,它可能根本不会生效,不能依赖它来阻止用户关闭窗口。另外,一旦使用了`beforeunload`事件,浏览器就不会缓存当前网页。因为执行了这个事件以后,缓存页面就没意义了。 -另外,一旦使用了`beforeunload`事件,浏览器就不会缓存当前网页。因为执行了这个事件以后,缓存页面就没意义了。 +基本上,只有一种场合可以监听`unload`事件,其他情况都不应该监听:用户修改了表单,还没有保存就要离开。 ### unload 事件 @@ -43,7 +43,7 @@ window.addEventListener('unload', function(event) { }); ``` -跟`beforeunload`事件一样,一旦使用了`unload`事件,浏览器就不会缓存当前网页,理由同上。 +手机上,浏览器或系统可能会直接丢弃网页,这时该事件根本不会发生。而且跟`beforeunload`事件一样,一旦使用了`unload`事件,浏览器就不会缓存当前网页,理由同上。因此,任何情况下都不应该依赖这个事件,指定网页卸载时要执行的代码,可以考虑完全不使用这个事件。 ### load 事件,error 事件 @@ -91,6 +91,8 @@ window.addEventListener('pageshow', function(event){ 如果页面包含``或`` | 发送 Cookie | 不发送 | +| AJAX | `$.get("...")` | 发送 Cookie | 不发送 | +| Image | `` | 发送 Cookie | 不发送 | + +设置了`Strict`或`Lax`以后,基本就杜绝了 CSRF 攻击。当然,前提是用户浏览器支持 SameSite 属性。 + +**(3)None** + +Chrome 计划将`Lax`变为默认设置。这时,网站可以选择显式关闭`SameSite`属性,将其设为`None`。不过,前提是必须同时设置`Secure`属性(Cookie 只能通过 HTTPS 协议发送),否则无效。 + +下面的设置无效。 + +```text +Set-Cookie: widget_session=abc123; SameSite=None +``` + +下面的设置有效。 + +```text +Set-Cookie: widget_session=abc123; SameSite=None; Secure +``` + ## document.cookie `document.cookie`属性用于读写当前网页的 Cookie。 @@ -259,3 +346,8 @@ document.cookie = 'fontSize=;expires=Thu, 01-Jan-1970 00:00:01 GMT'; ## 参考链接 - [HTTP cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies), by MDN +- [Using the Same-Site Cookie Attribute to Prevent CSRF Attacks](https://www.netsparker.com/blog/web-security/same-site-cookie-attribute-prevent-cross-site-request-forgery/) +- [SameSite cookies explained](https://web.dev/samesite-cookies-explained) +- [Tough Cookies](https://scotthelme.co.uk/tough-cookies/), Scott Helme +- [Cross-Site Request Forgery is dead!](https://scotthelme.co.uk/csrf-is-dead/), Scott Helme + From ecef95529e3720f1f951d691160ebd104a7652e2 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 10 Sep 2019 15:36:58 +0800 Subject: [PATCH 147/321] docs(dom): edit CSS --- docs/dom/css.md | 9 +++++++-- package.json | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/dom/css.md b/docs/dom/css.md index eaa28cd..d6d01db 100644 --- a/docs/dom/css.md +++ b/docs/dom/css.md @@ -1,10 +1,10 @@ # CSS 操作 -CSS 与 JavaScript 是两个有着明确分工的领域,前者负责页面的视觉效果,后者负责与用户的行为互动。但是,它们毕竟同属网页开发的前端,因此不可避免有着交叉和互相配合。本节介绍如何通过 JavaScript 操作 CSS。 +CSS 与 JavaScript 是两个有着明确分工的领域,前者负责页面的视觉效果,后者负责与用户的行为互动。但是,它们毕竟同属网页开发的前端,因此不可避免有着交叉和互相配合。本章介绍如何通过 JavaScript 操作 CSS。 ## HTML 元素的 style 属性 -操作 CSS 样式最简单的方法,就是使用网页元素节点的`getAttribute`方法、`setAttribute`方法和`removeAttribute`方法,直接读写或删除网页元素的`style`属性。 +操作 CSS 样式最简单的方法,就是使用网页元素节点的`getAttribute()`方法、`setAttribute()`方法和`removeAttribute()`方法,直接读写或删除网页元素的`style`属性。 ```javascript div.setAttribute( @@ -756,6 +756,8 @@ var mdl = window.matchMedia('(min-width: 400px)'); mdl instanceof MediaQueryList // true ``` +上面代码中,变量`mdl`就是 mediaQueryList 的实例。 + 注意,如果参数不是有效的`MediaQuery`条件语句,`window.matchMedia`不会报错,依然返回一个 MediaQueryList 实例。 ```javascript @@ -841,3 +843,6 @@ function mqCallback(e) { } } ``` + +注意,`MediaQueryList.removeListener()`方法不能撤销`MediaQueryList.onchange`属性指定的监听函数。 + diff --git a/package.json b/package.json index 7328981..a7eeda3 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "homepage": "https://github.com/wangdoc/javascript-tutorial", "dependencies": { "gh-pages": "latest", - "husky": "3.x", + "husky": "^3.0.5", "loppo": "latest", "loppo-theme-wangdoc": "latest" } From ad6049aa962adedb2442dc4cd9eba8bd87753b5a Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 12 Sep 2019 17:05:06 +0800 Subject: [PATCH 148/321] docs(dom): edit mutationobserver --- docs/dom/mutationobserver.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dom/mutationobserver.md b/docs/dom/mutationobserver.md index c638f15..e44f9a1 100644 --- a/docs/dom/mutationobserver.md +++ b/docs/dom/mutationobserver.md @@ -81,7 +81,7 @@ mutationObserver.observe(document.documentElement, { }); ``` -对一个节点添加观察器,就像使用`addEventListener`方法一样,多次添加同一个观察器是无效的,回调函数依然只会触发一次。但是,如果指定不同的`options`对象,就会被当作两个不同的观察器。 +对一个节点添加观察器,就像使用`addEventListener`方法一样,多次添加同一个观察器是无效的,回调函数依然只会触发一次。如果指定不同的`options`对象,以后面添加的那个为准,类似覆盖。 下面的例子是观察新增的子节点。 From 11d71b0b11d2b4b699abbf13758ed5ff46c17161 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 12 Sep 2019 17:08:19 +0800 Subject: [PATCH 149/321] docs(bom): edit form --- docs/bom/form.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/bom/form.md b/docs/bom/form.md index 855724a..6773acd 100644 --- a/docs/bom/form.md +++ b/docs/bom/form.md @@ -42,7 +42,7 @@ Content-Length: 74 user_name=张三&user_passwd=123&submit_button=提交 ``` -注意,实际提交的时候,只要键值不是 URL 的合法字符(比如汉字“张三”和“确定”),浏览器会自动对其进行编码。 +注意,实际提交的时候,只要键值不是 URL 的合法字符(比如汉字“张三”和“提交”),浏览器会自动对其进行编码。 点击`submit`控件,就可以提交表单。 From dcd00fe32b3c4626809baf300888c12c383cba53 Mon Sep 17 00:00:00 2001 From: Vincent Hy Date: Tue, 17 Sep 2019 16:01:37 +0800 Subject: [PATCH 150/321] =?UTF-8?q?=E6=9B=B4=E6=AD=A3=20'instanceOf'=20?= =?UTF-8?q?=E6=8B=BC=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/oop/prototype.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/oop/prototype.md b/docs/oop/prototype.md index e463e57..f01c701 100644 --- a/docs/oop/prototype.md +++ b/docs/oop/prototype.md @@ -323,7 +323,7 @@ s instanceof String // false 上面代码中,字符串不是`String`对象的实例(因为字符串不是对象),所以返回`false`。 -此外,对于`undefined`和`null`,`instanceOf`运算符总是返回`false`。 +此外,对于`undefined`和`null`,`instanceof`运算符总是返回`false`。 ```javascript undefined instanceof Object // false From 727c26c72b49cba68d353a8fdd14354e93b325e1 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Mon, 30 Sep 2019 17:25:14 +0800 Subject: [PATCH 151/321] docs(bom): edit form --- docs/bom/form.md | 73 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/docs/bom/form.md b/docs/bom/form.md index 6773acd..c4bb42b 100644 --- a/docs/bom/form.md +++ b/docs/bom/form.md @@ -214,6 +214,16 @@ for (var pair of formData) { 如果一个控件通过验证,它就会匹配`:valid`的 CSS 伪类,浏览器会继续进行表单提交的流程。如果没有通过验证,该控件就会匹配`:invalid`的 CSS 伪类,浏览器会终止表单提交,并显示一个错误信息。 +```css +input:invalid { + border-color: red; +} +input, +input:valid { + border-color: #ccc; +} +``` + ### checkValidity() 除了提交表单的时候,浏览器自动校验表单,还可以手动触发表单的校验。表单元素和表单控件都有`checkValidity()`方法,用于手动触发校验。 @@ -279,7 +289,33 @@ if (!myInput.checkValidity()) { 控件元素的`setCustomValidity()`方法用来定制校验失败时的报错信息。它接受一个字符串作为参数,该字符串就是定制的报错信息。如果参数为空字符串,则上次设置的报错信息被清除。 -如果调用这个方法,并且参数不为空字符串,浏览器就会认为控件没有通过校验,就会立刻显示该方法设置的报错信息。 +这个方法可以替换浏览器内置的表单验证报错信息,参数就是要显示的报错信息。 + +```html +

+ + +
+``` + +上面的表单输入框,要求只能输入小写字母,且不得超过15个字符。如果输入不符合要求(比如输入“ABC”),提交表单的时候,Chrome 浏览器会弹出报错信息“Please match the requested format.”,禁止表单提交。下面使用`setCustomValidity()`方法替换掉报错信息。 + +```javascript +var input = document.getElementById('username'); +input.oninvalid = function (event) { + event.target.setCustomValidity( + '用户名必须是小写字母,不能为空,最长不超过15个字符' + ); +} +``` + +上面代码中,`setCustomValidity()`方法是在`invalid`事件的监听函数里面调用。该方法也可以直接调用,这时如果参数不为空字符串,浏览器就会认为该控件没有通过校验,就会立刻显示该方法设置的报错信息。 ```javascript /* HTML 代码如下 @@ -345,6 +381,37 @@ if (document.getElementById('myInput').validity.rangeOverflow) { document.getElementById('prompt').innerHTML = txt; ``` +如果想禁止浏览器弹出表单验证的报错信息,可以监听`invalid`事件。 + +```javascript +var input = document.getElementById('username'); +var form = document.getElementById('form'); + +var elem = document.createElement('div'); +elem.id = 'notify'; +elem.style.display = 'none'; +form.appendChild(elem); + +input.addEventListener('invalid', function (event) { + event.preventDefault(); + if (!event.target.validity.valid) { + elem.textContent = '用户名必须是小写字母'; + elem.className = 'error'; + elem.style.display = 'block'; + input.className = 'invalid animated shake'; + } +}); + +input.addEventListener('input', function(event){ + if ( 'block' === elem.style.display ) { + input.className = ''; + elem.style.display = 'none'; + } +}); +``` + +上面代码中,一旦发生`invalid`事件(表单验证失败),`event.preventDefault()`用来禁止浏览器弹出默认的验证失败提示,然后设置定制的报错提示框。 + ### 表单的 novalidate 属性 表单元素的 HTML 属性`novalidate`,可以关闭浏览器的自动校验。 @@ -553,3 +620,7 @@ xhr.open('POST', 'myserver/uploads'); xhr.setRequestHeader('Content-Type', file.type); xhr.send(file); ``` + +## 参考链接 + +- [HTML5 Form Validation With the “pattern” Attribute](https://webdesign.tutsplus.com/tutorials/html5-form-validation-with-the-pattern-attribute--cms-25145), Thoriq Firdaus From 486addf67169806ce731003a112183c29082d323 Mon Sep 17 00:00:00 2001 From: harriet247 <50596251+harriet247@users.noreply.github.com> Date: Thu, 3 Oct 2019 10:45:40 -0700 Subject: [PATCH 152/321] Update arraybuffer.md --- docs/bom/arraybuffer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/bom/arraybuffer.md b/docs/bom/arraybuffer.md index fea14b8..1ad0e2b 100644 --- a/docs/bom/arraybuffer.md +++ b/docs/bom/arraybuffer.md @@ -73,7 +73,7 @@ myBlob.type // "text/html" `Blob`具有一个实例方法`slice`,用来拷贝原来的数据,返回的也是一个`Blob`实例。 ```javascript -myBlob.slice(start,end, contentType) +myBlob.slice(start, end, contentType) ``` `slice`方法有三个参数,都是可选的。它们依次是起始的字节位置(默认为0)、结束的字节位置(默认为`size`属性的值,该位置本身将不包含在拷贝的数据之中)、新实例的数据类型(默认为空字符串)。 From cbf8fcf2b7d2bdc99d11a80d22cd4fd96111b859 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sun, 6 Oct 2019 10:12:56 +0800 Subject: [PATCH 153/321] docs(stdlib): edit array/sort --- docs/stdlib/array.md | 14 +++++++++++++- package.json | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/stdlib/array.md b/docs/stdlib/array.md index b8736d4..97912f2 100644 --- a/docs/stdlib/array.md +++ b/docs/stdlib/array.md @@ -402,7 +402,7 @@ a // [1, 2] // [10111, 1101, 111] ``` -上面代码的最后两个例子,需要特殊注意。`sort`方法不是按照大小排序,而是按照字典顺序。也就是说,数值会被先转成字符串,再按照字典顺序进行比较,所以`101`排在`11`的前面。 +上面代码的最后两个例子,需要特殊注意。`sort()`方法不是按照大小排序,而是按照字典顺序。也就是说,数值会被先转成字符串,再按照字典顺序进行比较,所以`101`排在`11`的前面。 如果想让`sort`方法按照自定义方式排序,可以传入一个函数作为参数。 @@ -430,6 +430,18 @@ a // [1, 2] // ] ``` +注意,自定义的排序函数应该返回数值,否则不同的浏览器可能有不同的实现,不能保证结果都一致。 + +```javascript +// bad +[1, 4, 2, 6, 0, 6, 2, 6].sort((a, b) => a > b) + +// good +[1, 4, 2, 6, 0, 6, 2, 6].sort((a, b) => a - b) +``` + +上面代码中,前一种排序算法返回的是布尔值,这是不推荐使用的。后一种是数值,才是更好的写法。 + ### map() `map`方法将数组的所有成员依次传入参数函数,然后把每一次的执行结果组成一个新数组返回。 diff --git a/package.json b/package.json index a7eeda3..bceaca7 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.5", + "husky": "^3.0.7", "loppo": "latest", "loppo-theme-wangdoc": "latest" } From ae4e9cfb4b77f85a0d38234b1e3d7c0417f74fa1 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sun, 6 Oct 2019 10:18:22 +0800 Subject: [PATCH 154/321] docs(stdlib): edit array/sort --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bceaca7..66e3f26 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.7", + "husky": "^3.0.8", "loppo": "latest", "loppo-theme-wangdoc": "latest" } From b8523bcffed334a1acbdbb7b9c14b5663a50d980 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Mon, 7 Oct 2019 00:05:25 +0800 Subject: [PATCH 155/321] docs(stdlib): edit Number/toLocalString() --- docs/stdlib/number.md | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/docs/stdlib/number.md b/docs/stdlib/number.md index d585fff..dc5dcbc 100644 --- a/docs/stdlib/number.md +++ b/docs/stdlib/number.md @@ -144,7 +144,7 @@ Number.MIN_SAFE_INTEGER // -9007199254740991 ### Number.prototype.toPrecision() -`toPrecision`方法用于将一个数转为指定位数的有效数字。 +`Number.prototype.toPrecision()`方法用于将一个数转为指定位数的有效数字。 ```javascript (12.34).toPrecision(1) // "1e+1" @@ -154,9 +154,9 @@ Number.MIN_SAFE_INTEGER // -9007199254740991 (12.34).toPrecision(5) // "12.340" ``` -`toPrecision`方法的参数为有效数字的位数,范围是1到21,超出这个范围会抛出 RangeError 错误。 +该方法的参数为有效数字的位数,范围是1到21,超出这个范围会抛出 RangeError 错误。 -`toPrecision`方法用于四舍五入时不太可靠,跟浮点数不是精确储存有关。 +该方法用于四舍五入时不太可靠,跟浮点数不是精确储存有关。 ```javascript (12.35).toPrecision(3) // "12.3" @@ -165,6 +165,41 @@ Number.MIN_SAFE_INTEGER // -9007199254740991 (12.45).toPrecision(3) // "12.4" ``` +### Number.prototype.toLocaleString() + +`Number.prototype.toLocaleString()`方法接受一个地区码作为参数,返回一个字符串,表示当前数字在该地区的当地书写形式。 + +```javascript +(123).toLocaleString('zh-Hans-CN-u-nu-hanidec') +// "一二三" +``` + +该方法还可以接受第二个参数配置对象,用来定制指定用途的返回字符串。该对象的`style`属性指定输出样式,默认值是`decimal`,表示输出十进制形式。如果值为`percent`,表示输出百分数。 + +```javascript +(123).toLocaleString('zh-Hans-CN', { style: 'persent' }) +// "12,300%" +``` + +如果`style`属性的值为`currency`,则可以搭配`currency`属性,输出指定格式的货币字符串形式。 + +```javascript +(123).toLocaleString('zh-Hans-CN', { style: 'currency', currency: 'CNY' }) +// "¥123.00" + +(123).toLocaleString('de-DE', { style: 'currency', currency: 'EUR' }) +// "123,00 €" + +(123).toLocaleString('en-US', { style: 'currency', currency: 'USD' }) +// "$123.00" +``` + +如果`Number.prototype.toLocaleString()`省略了参数,则由浏览器自行决定如何处理,通常会使用操作系统的地区设定。注意,该方法如果使用浏览器不认识的地区码,会抛出一个错误。 + +```javascript +(123).toLocaleString('123') // 出错 +``` + ## 自定义方法 与其他对象一样,`Number.prototype`对象上面可以自定义方法,被`Number`的实例继承。 From 23e3bcb59f4279f7b756cb76bd1bffcb0aba8fff Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 31 Oct 2019 00:03:34 +0800 Subject: [PATCH 156/321] docs(bom): fix #154 --- docs/bom/location.md | 54 +++++++++++++------------------------------- 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/docs/bom/location.md b/docs/bom/location.md index 3cec254..4ea667e 100644 --- a/docs/bom/location.md +++ b/docs/bom/location.md @@ -171,27 +171,13 @@ decodeURIComponent('%E6%98%A5%E8%8A%82') // "春节" ``` -## URL 对象 +## URL 接口 -`URL`对象是浏览器的原生对象,可以用来构造、解析和编码 URL。一般情况下,通过`window.URL`可以拿到这个对象。 - -``元素和``元素都部署了这个接口。这就是说,它们的 DOM 节点对象可以使用 URL 的实例属性和方法。 - -```javascript -var a = document.createElement('a'); -a.href = 'http://example.com/?foo=1'; - -a.hostname // "example.com" -a.search // "?foo=1" -``` - -上面代码中,`a`是``元素的 DOM 节点对象。可以在这个对象上使用 URL 的实例属性,比如`hostname`和`search`。 +`URL`接口是一个构造函数,浏览器原生提供,可以用来构造、解析和编码 URL。一般情况下,通过`window.URL`可以拿到这个构造函数。 ### 构造函数 -`URL`对象本身是一个构造函数,可以生成 URL 实例。 - -它接受一个表示 URL 的字符串作为参数。如果参数不是合法的 URL,会报错。 +`URL`作为构造函数,可以生成 URL 实例。它接受一个表示 URL 的字符串作为参数。如果参数不是合法的 URL,会报错。 ```javascript var url = new URL('http://www.example.com/index.html'); @@ -283,7 +269,7 @@ url.href // "http://example.com/index2.html#part2" **(1)URL.createObjectURL()** -`URL.createObjectURL`方法用来为上传/下载的文件、流媒体文件生成一个 URL 字符串。这个字符串代表了`File`对象或`Blob`对象的 URL。 +`URL.createObjectURL()`方法用来为上传/下载的文件、流媒体文件生成一个 URL 字符串。这个字符串代表了`File`对象或`Blob`对象的 URL。 ```javascript // HTML 代码如下 @@ -306,7 +292,7 @@ function handleFiles(files) { } ``` -上面代码中,`URL.createObjectURL`方法用来为上传的文件生成一个 URL 字符串,作为``元素的图片来源。 +上面代码中,`URL.createObjectURL()`方法用来为上传的文件生成一个 URL 字符串,作为``元素的图片来源。 该方法生成的 URL 就像下面的样子。 @@ -314,11 +300,11 @@ function handleFiles(files) { blob:http://localhost/c745ef73-ece9-46da-8f66-ebes574789b1 ``` -注意,每次使用`URL.createObjectURL`方法,都会在内存里面生成一个 URL 实例。如果不再需要该方法生成的 URL 字符串,为了节省内存,可以使用`URL.revokeObjectURL()`方法释放这个实例。 +注意,每次使用`URL.createObjectURL()`方法,都会在内存里面生成一个 URL 实例。如果不再需要该方法生成的 URL 字符串,为了节省内存,可以使用`URL.revokeObjectURL()`方法释放这个实例。 **(2)URL.revokeObjectURL()** -`URL.revokeObjectURL`方法用来释放`URL.createObjectURL`方法生成的 URL 实例。它的参数就是`URL.createObjectURL`方法返回的 URL 字符串。 +`URL.revokeObjectURL()`方法用来释放`URL.createObjectURL()`方法生成的 URL 实例。它的参数就是`URL.createObjectURL()`方法返回的 URL 字符串。 下面为上一段的示例加上`URL.revokeObjectURL()`。 @@ -337,7 +323,7 @@ function handleFiles(files) { } ``` -上面代码中,一旦图片加载成功以后,为本地文件生成的 URL 字符串就没用了,于是可以在`img.onload`回调函数里面,通过`URL.revokeObjectURL`方法卸载这个 URL 实例。 +上面代码中,一旦图片加载成功以后,为本地文件生成的 URL 字符串就没用了,于是可以在`img.onload`回调函数里面,通过`URL.revokeObjectURL()`方法卸载这个 URL 实例。 ## URLSearchParams 对象 @@ -390,14 +376,6 @@ var foo = url.searchParams.get('foo') || 'somedefault'; 上面代码中,URL 实例的`searchParams`属性就是一个`URLSearchParams`实例,所以可以使用`URLSearchParams`接口的`get`方法。 -DOM 的`a`元素节点的`searchParams`属性,就是一个`URLSearchParams`实例。 - -```javascript -var a = document.createElement('a'); -a.href = 'https://example.com?filter=api'; -a.searchParams.get('filter') // "api" -``` - `URLSearchParams`实例有遍历器接口,可以用`for...of`循环遍历(详见《ES6 标准入门》的《Iterator》一章)。 ```javascript @@ -434,7 +412,7 @@ window.location.href = location.pathname + '?' + params; ### URLSearchParams.append() -`append`方法用来追加一个查询参数。它接受两个参数,第一个为键名,第二个为键值,没有返回值。 +`append()`方法用来追加一个查询参数。它接受两个参数,第一个为键名,第二个为键值,没有返回值。 ```javascript var params = new URLSearchParams({'foo': 1 , 'bar': 2}); @@ -442,7 +420,7 @@ params.append('baz', 3); params.toString() // "foo=1&bar=2&baz=3" ``` -`append`方法不会识别是否键名已经存在。 +`append()`方法不会识别是否键名已经存在。 ```javascript var params = new URLSearchParams({'foo': 1 , 'bar': 2}); @@ -454,7 +432,7 @@ params.toString() // "foo=1&bar=2&foo=3" ### URLSearchParams.delete() -`delete`方法用来删除指定的查询参数。它接受键名作为参数。 +`delete()`方法用来删除指定的查询参数。它接受键名作为参数。 ```javascript var params = new URLSearchParams({'foo': 1 , 'bar': 2}); @@ -464,7 +442,7 @@ params.toString() // "foo=1" ### URLSearchParams.has() -`has`方法返回一个布尔值,表示查询字符串是否包含指定的键名。 +`has()`方法返回一个布尔值,表示查询字符串是否包含指定的键名。 ```javascript var params = new URLSearchParams({'foo': 1 , 'bar': 2}); @@ -474,7 +452,7 @@ params.has('baz') // false ### URLSearchParams.set() -`set`方法用来设置查询字符串的键值。 +`set()`方法用来设置查询字符串的键值。 它接受两个参数,第一个是键名,第二个是键值。如果是已经存在的键,键值会被改写,否则会被追加。 @@ -509,7 +487,7 @@ window.history.replaceState({}, '', location.pathname + `?` + params); ### URLSearchParams.get(),URLSearchParams.getAll() -`get`方法用来读取查询字符串里面的指定键。它接受键名作为参数。 +`get()`方法用来读取查询字符串里面的指定键。它接受键名作为参数。 ```javascript var params = new URLSearchParams('?foo=1'); @@ -528,7 +506,7 @@ params.get('foo') // "3" 上面代码中,查询字符串有三个`foo`键,`get`方法返回最前面的键值`3`。 -`getAll`方法返回一个数组,成员是指定键的所有键值。它接受键名作为参数。 +`getAll()`方法返回一个数组,成员是指定键的所有键值。它接受键名作为参数。 ```javascript var params = new URLSearchParams('?foo=1&foo=2'); @@ -539,7 +517,7 @@ params.getAll('foo') // ["1", "2"] ### URLSearchParams.sort() -`sort`方法对查询字符串里面的键进行排序,规则是按照 Unicode 码点从小到大排列。 +`sort()`方法对查询字符串里面的键进行排序,规则是按照 Unicode 码点从小到大排列。 该方法没有返回值,或者说返回值是`undefined`。 From ff74e42925763ae85fb1f6ea509fc69849357c8f Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 31 Oct 2019 00:16:01 +0800 Subject: [PATCH 157/321] refactor: upgrade node.js --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ead9a81..6304e69 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: -- '8' +- '10' branches: only: From 786148c7b0363871eafc1327001623dfa4eaaf1b Mon Sep 17 00:00:00 2001 From: ruanyf Date: Mon, 4 Nov 2019 18:44:07 +0800 Subject: [PATCH 158/321] docs: fix #155 --- docs/stdlib/number.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stdlib/number.md b/docs/stdlib/number.md index dc5dcbc..e0c2158 100644 --- a/docs/stdlib/number.md +++ b/docs/stdlib/number.md @@ -177,7 +177,7 @@ Number.MIN_SAFE_INTEGER // -9007199254740991 该方法还可以接受第二个参数配置对象,用来定制指定用途的返回字符串。该对象的`style`属性指定输出样式,默认值是`decimal`,表示输出十进制形式。如果值为`percent`,表示输出百分数。 ```javascript -(123).toLocaleString('zh-Hans-CN', { style: 'persent' }) +(123).toLocaleString('zh-Hans-CN', { style: 'percent' }) // "12,300%" ``` From 19d0628816dd19f6395e1f762c988d1ee1a85780 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 12 Nov 2019 05:38:48 +0800 Subject: [PATCH 159/321] docs(stdlib): fix Date.setDate --- docs/stdlib/date.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/stdlib/date.md b/docs/stdlib/date.md index 357913c..503c3b1 100644 --- a/docs/stdlib/date.md +++ b/docs/stdlib/date.md @@ -480,7 +480,7 @@ d.setDate(9) // 1357660800000 d // Wed Jan 09 2013 00:00:00 GMT+0800 (CST) ``` -`set*`方法的参数都会自动折算。以`setDate`为例,如果参数超过当月的最大天数,则向下一个月顺延,如果参数是负数,表示从上个月的最后一天开始减去的天数。 +`set*`方法的参数都会自动折算。以`setDate()`为例,如果参数超过当月的最大天数,则向下一个月顺延,如果参数是负数,表示从上个月的最后一天开始减去的天数。 ```javascript var d1 = new Date('January 6, 2013'); @@ -490,10 +490,12 @@ d1 // Fri Feb 01 2013 00:00:00 GMT+0800 (CST) var d2 = new Date ('January 6, 2013'); -d.setDate(-1) // 1356796800000 -d // Sun Dec 30 2012 00:00:00 GMT+0800 (CST) +d2.setDate(-1) // 1356796800000 +d2 // Sun Dec 30 2012 00:00:00 GMT+0800 (CST) ``` +上面代码中,`d1.setDate(32)`将日期设为1月份的32号,因为1月份只有31号,所以自动折算为2月1日。`d2.setDate(-1)`表示设为上个月的倒数第二天,即12月30日。 + `set`类方法和`get`类方法,可以结合使用,得到相对时间。 ```javascript From d3e17b1373c3fbb4f3ff6a5eef61532755e081f8 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 15 Nov 2019 01:12:31 +0800 Subject: [PATCH 160/321] docs(bom): edit window --- docs/bom/window.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/bom/window.md b/docs/bom/window.md index 4b75320..f5eea3b 100644 --- a/docs/bom/window.md +++ b/docs/bom/window.md @@ -416,7 +416,7 @@ window.moveTo(100, 200) 上面代码将窗口移动到屏幕`(100, 200)`的位置。 -`window.moveBy`方法将窗口移动到一个相对位置。它接受两个参数,分布是窗口左上角向右移动的水平距离和向下移动的垂直距离,单位为像素。 +`window.moveBy()`方法将窗口移动到一个相对位置。它接受两个参数,分别是窗口左上角向右移动的水平距离和向下移动的垂直距离,单位为像素。 ```javascript window.moveBy(25, 50) @@ -424,7 +424,7 @@ window.moveBy(25, 50) 上面代码将窗口向右移动25像素、向下移动50像素。 -为了防止有人滥用这两个方法,随意移动用户的窗口,目前只有一种情况,浏览器允许用脚本移动窗口:该窗口是用`window.open`方法新建的,并且它所在的 Tab 页是当前窗口里面唯一的。除此以外的情况,使用上面两个方法都是无效的。 +为了防止有人滥用这两个方法,随意移动用户的窗口,目前只有一种情况,浏览器允许用脚本移动窗口:该窗口是用`window.open()`方法新建的,并且窗口里只有它一个 Tab 页。除此以外的情况,使用上面两个方法都是无效的。 ### window.resizeTo(),window.resizeBy() From 4e1e7ddeb86a5d942e0fed698f62673af7c1ba8c Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 22 Nov 2019 18:56:54 +0800 Subject: [PATCH 161/321] docs: fix #157 --- docs/dom/document.md | 2 +- docs/dom/parentnode.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/dom/document.md b/docs/dom/document.md index 7f4b8ed..4a5315c 100644 --- a/docs/dom/document.md +++ b/docs/dom/document.md @@ -11,7 +11,7 @@ - Ajax 操作返回的文档,使用`XMLHttpRequest`对象的`responseXML`属性。 - 内部节点的`ownerDocument`属性。 -`document`对象继承了`EventTarget`接口、`Node`接口、`ParentNode`接口。这意味着,这些接口的方法都可以在`document`对象上调用。除此之外,`document`对象还有很多自己的属性和方法。 +`document`对象继承了`EventTarget`接口和`Node`接口,并且混入(mixin)了`ParentNode`接口。这意味着,这些接口的方法都可以在`document`对象上调用。除此之外,`document`对象还有很多自己的属性和方法。 ## 属性 diff --git a/docs/dom/parentnode.md b/docs/dom/parentnode.md index f440ff1..1aa2d0c 100644 --- a/docs/dom/parentnode.md +++ b/docs/dom/parentnode.md @@ -1,10 +1,10 @@ # ParentNode 接口,ChildNode 接口 -节点对象除了继承 Node 接口以外,还会继承其他接口。`ParentNode`接口表示当前节点是一个父节点,提供一些处理子节点的方法。`ChildNode`接口表示当前节点是一个子节点,提供一些相关方法。 +节点对象除了继承 Node 接口以外,还拥有其他接口。`ParentNode`接口表示当前节点是一个父节点,提供一些处理子节点的方法。`ChildNode`接口表示当前节点是一个子节点,提供一些相关方法。 ## ParentNode 接口 -如果当前节点是父节点,就会继承`ParentNode`接口。由于只有元素节点(element)、文档节点(document)和文档片段节点(documentFragment)拥有子节点,因此只有这三类节点会继承`ParentNode`接口。 +如果当前节点是父节点,就会混入了(mixin)`ParentNode`接口。由于只有元素节点(element)、文档节点(document)和文档片段节点(documentFragment)拥有子节点,因此只有这三类节点会拥有`ParentNode`接口。 ### ParentNode.children @@ -84,7 +84,7 @@ parent.append('Hello', p); ## ChildNode 接口 -如果一个节点有父节点,那么该节点就继承了`ChildNode`接口。 +如果一个节点有父节点,那么该节点就拥有了`ChildNode`接口。 ### ChildNode.remove() From 7f65d8b0e5873eead0d4ea91848c4b81a7c5d15e Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 28 Nov 2019 17:26:39 +0800 Subject: [PATCH 162/321] docs: fix #158 --- docs/features/error.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/error.md b/docs/features/error.md index c0b8ebb..17c33cd 100644 --- a/docs/features/error.md +++ b/docs/features/error.md @@ -406,7 +406,7 @@ result 上面代码中,`catch`代码块结束执行之前,会先执行`finally`代码块。 -`catch`代码块之中,触发转入`finally`代码快的标志,不仅有`return`语句,还有`throw`语句。 +`catch`代码块之中,触发转入`finally`代码块的标志,不仅有`return`语句,还有`throw`语句。 ```javascript function f() { From 173611cb7b46fd4a355e765566621355e594485e Mon Sep 17 00:00:00 2001 From: atimidguy <49008464+atimidguy@users.noreply.github.com> Date: Tue, 24 Dec 2019 12:16:23 +0800 Subject: [PATCH 163/321] fixed 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 3ba5f86..b253cbb 100644 --- a/docs/stdlib/regexp.md +++ b/docs/stdlib/regexp.md @@ -298,7 +298,7 @@ str.replace(search, replacement) 'aaa'.replace(/a/g, 'b') // "bbb" ``` -上面代码中,最后一个正则表达式使用了`g`修饰符,导致所有的`b`都被替换掉了。 +上面代码中,最后一个正则表达式使用了`g`修饰符,导致所有的`a`都被替换掉了。 `replace`方法的一个应用,就是消除字符串首尾两端的空格。 From 5312a09ac73b5db5464756959b9bc118a5b658bd Mon Sep 17 00:00:00 2001 From: Jacty Date: Tue, 7 Jan 2020 02:22:23 +0800 Subject: [PATCH 164/321] typo fixed a typo --- docs/stdlib/wrapper.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stdlib/wrapper.md b/docs/stdlib/wrapper.md index 7c3367b..7e89bf3 100644 --- a/docs/stdlib/wrapper.md +++ b/docs/stdlib/wrapper.md @@ -124,5 +124,5 @@ Number.prototype.double = function () { (123).double() // 246 ``` -上面代码在`String`和`Number`这两个对象的原型上面,分别自定义了一个方法,从而可以在所有实例对象上调用。注意,最后一张的`123`外面必须要加上圆括号,否则后面的点运算符(`.`)会被解释成小数点。 +上面代码在`String`和`Number`这两个对象的原型上面,分别自定义了一个方法,从而可以在所有实例对象上调用。注意,最后一行的`123`外面必须要加上圆括号,否则后面的点运算符(`.`)会被解释成小数点。 From f71489d048ec352c95e5be304ce7c3616e4bf8df Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 13 Feb 2020 13:55:20 +0800 Subject: [PATCH 165/321] docs(stdlib): edit regexp/exec() --- docs/stdlib/regexp.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/stdlib/regexp.md b/docs/stdlib/regexp.md index b253cbb..0d41c43 100644 --- a/docs/stdlib/regexp.md +++ b/docs/stdlib/regexp.md @@ -137,7 +137,7 @@ new RegExp('').test('abc') ### RegExp.prototype.exec() -正则实例对象的`exec`方法,用来返回匹配结果。如果发现匹配,就返回一个数组,成员是匹配成功的子字符串,否则返回`null`。 +正则实例对象的`exec()`方法,用来返回匹配结果。如果发现匹配,就返回一个数组,成员是匹配成功的子字符串,否则返回`null`。 ```javascript var s = '_x_x'; @@ -159,12 +159,12 @@ var r = /_(x)/; r.exec(s) // ["_x", "x"] ``` -上面代码的`exec`方法,返回一个数组。第一个成员是整个匹配的结果,第二个成员是圆括号匹配的结果。 +上面代码的`exec()`方法,返回一个数组。第一个成员是整个匹配的结果,第二个成员是圆括号匹配的结果。 -`exec`方法的返回数组还包含以下两个属性: +`exec()`方法的返回数组还包含以下两个属性: - `input`:整个原字符串。 -- `index`:整个模式匹配成功的开始位置(从0开始计数)。 +- `index`:模式匹配成功的开始位置(从0开始计数)。 ```javascript var r = /a(b+)a/; @@ -178,7 +178,7 @@ arr.input // "_abbba_aba_" 上面代码中的`index`属性等于1,是因为从原字符串的第二个位置开始匹配成功。 -如果正则表达式加上`g`修饰符,则可以使用多次`exec`方法,下一次搜索的位置从上一次匹配成功结束的位置开始。 +如果正则表达式加上`g`修饰符,则可以使用多次`exec()`方法,下一次搜索的位置从上一次匹配成功结束的位置开始。 ```javascript var reg = /a/g; @@ -204,7 +204,7 @@ r4 // null reg.lastIndex // 0 ``` -上面代码连续用了四次`exec`方法,前三次都是从上一次匹配结束的位置向后匹配。当第三次匹配结束以后,整个字符串已经到达尾部,匹配结果返回`null`,正则实例对象的`lastIndex`属性也重置为`0`,意味着第四次匹配将从头开始。 +上面代码连续用了四次`exec()`方法,前三次都是从上一次匹配结束的位置向后匹配。当第三次匹配结束以后,整个字符串已经到达尾部,匹配结果返回`null`,正则实例对象的`lastIndex`属性也重置为`0`,意味着第四次匹配将从头开始。 利用`g`修饰符允许多次匹配的特点,可以用一个循环完成全部匹配。 @@ -222,7 +222,7 @@ while(true) { // #8:a ``` -上面代码中,只要`exec`方法不返回`null`,就会一直循环下去,每次输出匹配的位置和匹配的文本。 +上面代码中,只要`exec()`方法不返回`null`,就会一直循环下去,每次输出匹配的位置和匹配的文本。 正则实例对象的`lastIndex`属性不仅可读,还可写。设置了`g`修饰符的时候,只要手动设置了`lastIndex`的值,就会从指定位置开始匹配。 From 23b342aad96e264d5f35a5191783f7741b980589 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 21 Feb 2020 19:01:49 +0800 Subject: [PATCH 166/321] docs(dom): add document.currentScript --- docs/dom/document.md | 14 ++++++++++++++ docs/stdlib/date.md | 27 +++++++++++++++++++++------ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/docs/dom/document.md b/docs/dom/document.md index 4a5315c..8e08982 100644 --- a/docs/dom/document.md +++ b/docs/dom/document.md @@ -327,6 +327,20 @@ var editor = document.getElementById('editor'); editor.contentDocument.designMode = 'on'; ``` +### document.currentScript + +`document.currentScript`属性只用在` +``` + +上面代码中,`document.currentScript`就是`