From c4a5be064713e4385768b2f86bcd704571589883 Mon Sep 17 00:00:00 2001 From: smith latube Date: 2018年8月20日 21:10:56 +0800 Subject: [PATCH 001/322] 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: 2018年8月23日 12:26:31 +0800 Subject: [PATCH 002/322] 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: 2018年8月24日 15:20:42 +0800 Subject: [PATCH 003/322] 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: 2018年8月25日 18:14:12 +0800 Subject: [PATCH 004/322] 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: 2018年8月26日 17:36:31 +0800 Subject: [PATCH 005/322] 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: 2018年8月26日 19:34:21 +0800 Subject: [PATCH 006/322] 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: 2018年8月27日 18:46:19 +0800 Subject: [PATCH 007/322] 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: 2018年8月28日 13:36:33 +0800 Subject: [PATCH 008/322] 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: 2018年8月28日 15:18:48 +0800 Subject: [PATCH 009/322] 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: 2018年8月28日 15:25:36 +0800 Subject: [PATCH 010/322] 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: 2018年8月30日 00:11:39 +0800 Subject: [PATCH 011/322] 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: 2018年8月30日 12:40:44 +0800 Subject: [PATCH 012/322] 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/322] 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/322] 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/322] =?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: 2018年9月12日 12:32:26 +0800 Subject: [PATCH 016/322] 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: 2018年9月12日 12:59:17 +0800 Subject: [PATCH 017/322] 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: 2018年9月15日 15:15:08 +0800 Subject: [PATCH 018/322] 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: 2018年9月21日 16:35:17 +0800 Subject: [PATCH 019/322] 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: 2018年9月21日 16:45:09 +0800 Subject: [PATCH 020/322] 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: 2018年9月23日 20:56:53 +0800 Subject: [PATCH 021/322] 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: 2018年9月25日 12:28:30 +0800 Subject: [PATCH 022/322] 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: 2018年9月25日 12:35:24 +0800 Subject: [PATCH 023/322] 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: 2018年9月25日 12:52:34 +0800 Subject: [PATCH 024/322] 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: 2018年9月25日 18:22:27 +0800 Subject: [PATCH 025/322] 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: 2018年9月26日 11:02:29 +0800 Subject: [PATCH 026/322] 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: 2018年9月26日 16:54:32 +0800 Subject: [PATCH 027/322] 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: 2018年9月29日 10:42:56 +0800 Subject: [PATCH 028/322] 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/322] 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/322] 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/322] 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/322] 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/322] 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: 2018年10月10日 15:28:21 +0800 Subject: [PATCH 034/322] 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: 2018年10月12日 11:21:28 +0800 Subject: [PATCH 035/322] 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: 2018年10月14日 22:08:45 +0800 Subject: [PATCH 036/322] 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: 2018年10月19日 16:39:19 +0800 Subject: [PATCH 037/322] 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: 2018年10月20日 14:39:33 +0800 Subject: [PATCH 038/322] 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: 2018年10月23日 16:04:42 +0800 Subject: [PATCH 039/322] 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){ 如果页面包含``或`