From 69f0108faa056017aa838ca552be75cf69b9379c Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Sat, 28 May 2022 20:39:18 +0800 Subject: [PATCH] AutoCorrect files/zh-cn/web/javascript/reference/{s,t}* --- .../statements/async_function/index.html | 66 +++++++------- .../reference/statements/block/index.html | 12 +-- .../reference/statements/break/index.html | 6 +- .../reference/statements/class/index.html | 2 +- .../reference/statements/const/index.html | 4 +- .../reference/statements/continue/index.html | 2 +- .../reference/statements/debugger/index.html | 4 +- .../reference/statements/export/index.html | 8 +- .../statements/for-await...of/index.html | 8 +- .../reference/statements/for...in/index.html | 8 +- .../reference/statements/for...of/index.html | 4 +- .../reference/statements/for/index.html | 2 +- .../reference/statements/function/index.html | 36 ++++---- .../statements/function_star_/index.html | 26 +++--- .../reference/statements/if...else/index.html | 6 +- .../statements/import.meta/index.html | 20 ++--- .../reference/statements/import/index.html | 4 +- .../reference/statements/index.html | 6 +- .../reference/statements/label/index.html | 2 +- .../reference/statements/let/index.md | 8 +- .../reference/statements/return/index.html | 4 +- .../reference/statements/throw/index.html | 10 +-- .../statements/try...catch/index.html | 10 +-- .../reference/statements/var/index.md | 6 +- .../reference/statements/with/index.html | 16 ++-- .../reference/strict_mode/index.html | 88 +++++++++---------- .../transitioning_to_strict_mode/index.html | 42 ++++----- .../reference/template_literals/index.html | 20 ++--- 28 files changed, 215 insertions(+), 215 deletions(-) diff --git a/files/zh-cn/web/javascript/reference/statements/async_function/index.html b/files/zh-cn/web/javascript/reference/statements/async_function/index.html index 5088f771301a8e..0f739efeeff7ef 100644 --- a/files/zh-cn/web/javascript/reference/statements/async_function/index.html +++ b/files/zh-cn/web/javascript/reference/statements/async_function/index.html @@ -1,5 +1,5 @@ --- -title: async函数 +title: async 函数 slug: Web/JavaScript/Reference/Statements/async_function tags: - JavaScript @@ -11,10 +11,10 @@ ---
{{jsSidebar("Statements")}}
-

async函数是使用async关键字声明的函数。 async函数是{{jsxref("Global_Objects/AsyncFunction","AsyncFunction")}}构造函数的实例, 并且其中允许使用await关键字。asyncawait关键字让我们可以用一种更简洁的方式写出基于{{jsxref("Promise")}}的异步行为,而无需刻意地链式调用promise

+

async 函数是使用async关键字声明的函数。 async 函数是{{jsxref("Global_Objects/AsyncFunction","AsyncFunction")}}构造函数的实例, 并且其中允许使用await关键字。asyncawait关键字让我们可以用一种更简洁的方式写出基于{{jsxref("Promise")}}的异步行为,而无需刻意地链式调用promise

-

async函数还可以被{{jsxref("Operators/async_function", "作为表达式", "", 1)}}来定义。

+

async 函数还可以被{{jsxref("Operators/async_function", "作为表达式", "", 1)}}来定义。

{{EmbedInteractiveExample("pages/js/statement-async.html", "taller")}}
@@ -38,37 +38,37 @@

参数

返回值

-

一个{{jsxref("Promise")}},这个promise要么会通过一个由async函数返回的值被解决,要么会通过一个从async函数中抛出的(或其中没有被捕获到的)异常被拒绝。

+

一个{{jsxref("Promise")}},这个 promise 要么会通过一个由 async 函数返回的值被解决,要么会通过一个从 async 函数中抛出的(或其中没有被捕获到的)异常被拒绝。

描述

-

async函数可能包含0个或者多个{{jsxref("Operators/await", "await")}}表达式。await表达式会暂停整个async函数的执行进程并出让其控制权,只有当其等待的基于promise的异步操作被兑现或被拒绝之后才会恢复进程。promise的解决值会被当作该await表达式的返回值。使用async / await关键字就可以在异步代码中使用普通的try / catch代码块。

+

async 函数可能包含 0 个或者多个{{jsxref("Operators/await", "await")}}表达式。await 表达式会暂停整个 async 函数的执行进程并出让其控制权,只有当其等待的基于 promise 的异步操作被兑现或被拒绝之后才会恢复进程。promise 的解决值会被当作该 await 表达式的返回值。使用async / await关键字就可以在异步代码中使用普通的try / catch代码块。

-

备注:await关键字只在async函数内有效。如果你在async函数体之外使用它,就会抛出语法错误 {{jsxref("SyntaxError")}} 。

+

备注:await关键字只在 async 函数内有效。如果你在 async 函数体之外使用它,就会抛出语法错误 {{jsxref("SyntaxError")}} 。

-

备注:async/await的目的为了简化使用基于promise的API时所需的语法。async/await的行为就好像搭配使用了生成器和promise。

+

备注:async/await的目的为了简化使用基于 promise 的 API 时所需的语法。async/await的行为就好像搭配使用了生成器和 promise。

-

async函数一定会返回一个promise对象。如果一个async函数的返回值看起来不是promise,那么它将会被隐式地包装在一个promise中。

+

async 函数一定会返回一个 promise 对象。如果一个 async 函数的返回值看起来不是 promise,那么它将会被隐式地包装在一个 promise 中。

-

例如,如下代码:

+

例如,如下代码:

async function foo() {
    return 1
 }
 
-

等价于:

+

等价于:

function foo() {
    return Promise.resolve(1)
 }
 
-

async函数的函数体可以被看作是由0个或者多个await表达式分割开来的。从第一行代码直到(并包括)第一个await表达式(如果有的话)都是同步运行的。这样的话,一个不含await表达式的async函数是会同步运行的。然而,如果函数体内有一个await表达式,async函数就一定会异步执行。

+

async 函数的函数体可以被看作是由 0 个或者多个 await 表达式分割开来的。从第一行代码直到(并包括)第一个 await 表达式(如果有的话)都是同步运行的。这样的话,一个不含 await 表达式的 async 函数是会同步运行的。然而,如果函数体内有一个 await 表达式,async 函数就一定会异步执行。

例如:

@@ -84,14 +84,14 @@

描述

} -

在await表达式之后的代码可以被认为是存在在链式调用的then回调中,多个await表达式都将加入链式调用的then回调中,返回值将作为最后一个then回调的返回值。

+

在 await 表达式之后的代码可以被认为是存在在链式调用的 then 回调中,多个 await 表达式都将加入链式调用的 then 回调中,返回值将作为最后一个 then 回调的返回值。

-

在接下来的例子中,我们将使用await执行两次promise,整个foo函数的执行将会被分为三个阶段。

+

在接下来的例子中,我们将使用 await 执行两次 promise,整个foo函数的执行将会被分为三个阶段。

    -
  1. foo函数的第一行将会同步执行,await将会等待promise的结束。然后暂停通过foo的进程,并将控制权交还给调用foo的函数。
  2. -
  3. 一段时间后,当第一个promise完结的时候,控制权将重新回到foo函数内。示例中将会将1(promise状态为fulfilled)作为结果返回给await表达式的左边即result1。接下来函数会继续进行,到达第二个await区域,此时foo函数的进程将再次被暂停。
  4. -
  5. 一段时间后,同样当第二个promise完结的时候,result2将被赋值为2,之后函数将会正常同步执行,将默认返回undefined 。
  6. +
  7. foo函数的第一行将会同步执行,await 将会等待 promise 的结束。然后暂停通过foo的进程,并将控制权交还给调用foo的函数。
  8. +
  9. 一段时间后,当第一个 promise 完结的时候,控制权将重新回到 foo 函数内。示例中将会将1(promise 状态为 fulfilled)作为结果返回给 await 表达式的左边即result1。接下来函数会继续进行,到达第二个 await 区域,此时foo函数的进程将再次被暂停。
  10. +
  11. 一段时间后,同样当第二个 promise 完结的时候,result2将被赋值为2,之后函数将会正常同步执行,将默认返回undefined 。
async function foo() {
@@ -100,14 +100,14 @@ 

描述

} foo()
-

注意:promise链不是一次就构建好的,相反,promise链是分阶段构造的,因此在处理异步函数时必须注意对错误函数的处理。

+

注意:promise 链不是一次就构建好的,相反,promise 链是分阶段构造的,因此在处理异步函数时必须注意对错误函数的处理。

-

例如,在下面的代码中,在promise链上配置了.catch处理程序,将抛出未处理的promise错误。这是因为p2返回的结果不会被await处理。

+

例如,在下面的代码中,在 promise 链上配置了.catch处理程序,将抛出未处理的 promise 错误。这是因为p2返回的结果不会被 await 处理。

async function foo() {
    const p1 = new Promise((resolve) => setTimeout(() => resolve('1'), 1000))
    const p2 = new Promise((_,reject) => setTimeout(() => reject('2'), 500))
-   const results = [await p1, await p2] // 不推荐使用这种方式,请使用 Promise.all或者Promise.allSettled 
+   const results = [await p1, await p2] // 不推荐使用这种方式,请使用 Promise.all 或者 Promise.allSettled 
 }
 foo().catch(() => {}) // 捕捉所有的错误...
@@ -202,10 +202,10 @@

简单例子

备注:

await and parallelism(并行)

-

sequentialStart中,程序在第一个await停留了2秒,然后又在第二个await停留了1秒。直到第一个计时器结束后,第二个计时器才被创建。程序需要3秒执行完毕。

+

sequentialStart中,程序在第一个await停留了 2 秒,然后又在第二个await停留了 1 秒。直到第一个计时器结束后,第二个计时器才被创建。程序需要 3 秒执行完毕。


- 在 concurrentStart中,两个计时器被同时创建,然后执行await。这两个计时器同时运行,这意味着程序完成运行只需要2秒,而不是3秒,即最慢的计时器的时间。

+ 在 concurrentStart中,两个计时器被同时创建,然后执行await。这两个计时器同时运行,这意味着程序完成运行只需要 2 秒,而不是 3 秒,即最慢的计时器的时间。

但是 await 仍旧是顺序执行的,第二个 await 还是得等待第一个执行完。在这个例子中,这使得先运行结束的输出出现在最慢的输出之后。

@@ -214,20 +214,20 @@

await and parallelism(并行)

警告:

-

async/await和Promise#then对比以及错误处理

+

async/await 和Promise#then 对比以及错误处理

-

大多数async函数也可以使用Promises编写。但是,在错误处理方面,async函数更容易捕获异常错误

+

大多数 async 函数也可以使用 Promises 编写。但是,在错误处理方面,async 函数更容易捕获异常错误

-

上面例子中的concurrentStart函数和concurrentPromise函数在功能上都是等效的。在concurrentStart函数中,如果任一awaited调用失败,它将自动捕获异常,async函数执行中断,并通过隐式返回Promise将错误传递给调用者。

+

上面例子中的concurrentStart函数和concurrentPromise函数在功能上都是等效的。在concurrentStart函数中,如果任一awaited 调用失败,它将自动捕获异常,async 函数执行中断,并通过隐式返回 Promise 将错误传递给调用者。

-

在Promise例子中这种情况同样会发生,该函数必须负责返回一个捕获函数完成的Promise。在concurrentPromise函数中,这意味着它从Promise.all([]).then()返回一个Promise。事实上,在此示例的先前版本忘记了这样做!

+

在 Promise 例子中这种情况同样会发生,该函数必须负责返回一个捕获函数完成的Promise。在concurrentPromise函数中,这意味着它从Promise.all([]).then()返回一个 Promise。事实上,在此示例的先前版本忘记了这样做!

-

但是,async函数仍有可能然可能错误地忽略错误。
- 以parallel async函数为例。 如果它没有等待await(或返回)Promise.all([])调用的结果,则不会传播任何错误。
+

但是,async 函数仍有可能然可能错误地忽略错误。
+ 以parallel async 函数为例。 如果它没有等待await(或返回)Promise.all([])调用的结果,则不会传播任何错误。
虽然parallelPromise函数示例看起来很简单,但它根本不会处理错误! 这样做需要一个类似于return Promise.all([])处理方式。

-

使用async函数重写 promise 链

+

使用 async 函数重写 promise 链

返回 {{jsxref("Promise")}}的 API 将会产生一个 promise 链,它将函数肢解成许多部分。例如下面的代码:

@@ -241,7 +241,7 @@

使用async函数重写 promise 链 }); } -

可以重写为单个async函数:

+

可以重写为单个 async 函数:

async function getProcessedData(url) {
   let v;
@@ -259,9 +259,9 @@ 

使用async函数重写 promise 链

备注:

-

返回值隐式的传递给{{jsxref("Promise.resolve")}},并不意味着return await promiseValue;和return promiseValue;在功能上相同。

+

返回值隐式的传递给{{jsxref("Promise.resolve")}},并不意味着return await promiseValue;和 return promiseValue;在功能上相同。

-

看下下面重写的上面代码,在processDataInWorker抛出异常时返回了null:

+

看下下面重写的上面代码,在processDataInWorker抛出异常时返回了 null:

async function getProcessedData(url) {
   let v;
@@ -277,7 +277,7 @@ 

使用async函数重写 promise 链 } }

-

简单地写上return processDataInworker(v);将导致在processDataInWorker(v)出错时function返回值为{{jsxref("Promise")}}而不是返回null。return foo;return await foo;,有一些细微的差异:return foo;不管foo是promise还是rejects都将会直接返回foo。相反地,如果foo是一个{{jsxref("Promise")}},return await foo;将等待foo执行(resolve)或拒绝(reject),如果是拒绝,将会在返回前抛出异常。

+

简单地写上return processDataInworker(v);将导致在 processDataInWorker(v)出错时 function 返回值为{{jsxref("Promise")}}而不是返回 null。return foo;return await foo;,有一些细微的差异:return foo;不管foo是 promise 还是 rejects 都将会直接返回foo。相反地,如果foo是一个{{jsxref("Promise")}},return await foo;将等待foo执行 (resolve) 或拒绝 (reject),如果是拒绝,将会在返回前抛出异常。

规范

@@ -294,7 +294,7 @@

规范

{{SpecName('ESDraft', '#sec-async-function-definitions', 'async function')}} {{Spec2('ESDraft')}} - 初始定义于ES2017. + 初始定义于 ES2017. {{SpecName('ES8', '#sec-async-function-definitions', 'async function')}} diff --git a/files/zh-cn/web/javascript/reference/statements/block/index.html b/files/zh-cn/web/javascript/reference/statements/block/index.html index 554d185e8e585a..bef5ea385fb90e 100644 --- a/files/zh-cn/web/javascript/reference/statements/block/index.html +++ b/files/zh-cn/web/javascript/reference/statements/block/index.html @@ -38,9 +38,9 @@

描述

块级作用域

-

在非严格模式(non-strict mode)下的var 或者函数声明时

+

在非严格模式 (non-strict mode) 下的var 或者函数声明时

-

通过var声明的变量或者非严格模式下(non-strict mode)创建的函数声明没有块级作用域。在语句块里声明的变量的作用域不仅是其所在的函数或者 script 标签内,所设置变量的影响会在超出语句块本身之外持续存在。 换句话说,这种语句块不会引入一个作用域。尽管单独的语句块是合法的语句,但在JavaScript中你不会想使用单独的语句块,因为它们不像你想象的C或Java中的语句块那样处理事物。例如:

+

通过var声明的变量或者非严格模式下 (non-strict mode) 创建的函数声明没有块级作用域。在语句块里声明的变量的作用域不仅是其所在的函数或者 script 标签内,所设置变量的影响会在超出语句块本身之外持续存在。 换句话说,这种语句块不会引入一个作用域。尽管单独的语句块是合法的语句,但在 JavaScript 中你不会想使用单独的语句块,因为它们不像你想象的 C 或 Java 中的语句块那样处理事物。例如:

var x = 1;
 {
@@ -49,7 +49,7 @@ 

在非 console.log(x); // 输出 2

-

输出结果是 2,因为块中的 var x语句与块前面的var x语句作用域相同。在 C 或 Java中,这段代码会输出 1。

+

输出结果是 2,因为块中的 var x语句与块前面的var x语句作用域相同。在 C 或 Java 中,这段代码会输出 1。

@@ -71,11 +71,11 @@

使用letconst

{ const c = 2; } -console.log(c); // 输出1, 而且不会报错
+console.log(c); // 输出 1,而且不会报错

注意,位于块范围之内的 const c = 2 并不会抛出SyntaxError: Identifier 'c' has already been declared这样的语法错误,因为在它自己的块中它可能是唯一一个被声明的常量。

-

使用let声明的变量在块级作用域内能强制执行更新变量,下面的两个例子对比:
+
使用 let 声明的变量在块级作用域内能强制执行更新变量,下面的两个例子对比:
var a = [];
 for (var i = 0; i < 10; i++) {
@@ -97,7 +97,7 @@ 
使用function
-

函数声明同样被限制在声明他的语句块内:

+

函数声明同样被限制在声明他的语句块内:

diff --git a/files/zh-cn/web/javascript/reference/statements/break/index.html b/files/zh-cn/web/javascript/reference/statements/break/index.html index 0f61d23f95542c..0e2f0ccf61d67f 100644 --- a/files/zh-cn/web/javascript/reference/statements/break/index.html +++ b/files/zh-cn/web/javascript/reference/statements/break/index.html @@ -25,7 +25,7 @@

描述

break语句包含一个可选的标签,可允许程序摆脱一个被标记的语句。break语句需要内嵌在引用的标签中。被标记的语句可以是任何 {{jsxref("Statements/block", "块")}}语句;不一定是循环语句。

-

break语句不能在function函数体中直接使用,break语句应嵌套在要中断的当前循环、switch或label语句中。

+

break 语句不能在 function 函数体中直接使用,break 语句应嵌套在要中断的当前循环、switch 或 label 语句中。

示例

@@ -48,7 +48,7 @@

break in while loop

break in switch statements

-

在下面的代码中, break 使用在 {{jsxref("Statements/switch", "switch")}} 语句中,当遇到匹配到case后,就会执行相应的代码并中断循环体。

+

在下面的代码中, break 使用在 {{jsxref("Statements/switch", "switch")}} 语句中,当遇到匹配到 case 后,就会执行相应的代码并中断循环体。

const food = "sushi";
 
@@ -96,7 +96,7 @@ 

break in labeled blocks that throwbreak within functions

-

在下面的代码同样会产生SyntaxError,因为它并没被正确的使用在循环、switch或label语句中。

+

在下面的代码同样会产生 SyntaxError,因为它并没被正确的使用在循环、switch 或 label 语句中。

function testBreak(x) {
   var i = 0;
diff --git a/files/zh-cn/web/javascript/reference/statements/class/index.html b/files/zh-cn/web/javascript/reference/statements/class/index.html
index f90b560270303f..4329ec2214cfa7 100644
--- a/files/zh-cn/web/javascript/reference/statements/class/index.html
+++ b/files/zh-cn/web/javascript/reference/statements/class/index.html
@@ -39,7 +39,7 @@ 

示例

声明一个类

-

在下面的例子中,我们首先定义一个名为Polygon的类,然后继承它来创建一个名为Square的类。注意,构造函数中使用的 super() 只能在构造函数中使用,并且必须在使用 this 关键字前调用。

+

在下面的例子中,我们首先定义一个名为 Polygon 的类,然后继承它来创建一个名为 Square 的类。注意,构造函数中使用的 super() 只能在构造函数中使用,并且必须在使用 this 关键字前调用。

class Polygon {
   constructor(height, width) {
diff --git a/files/zh-cn/web/javascript/reference/statements/const/index.html b/files/zh-cn/web/javascript/reference/statements/const/index.html
index de8e0c7f394c3b..c1a83426072f1f 100644
--- a/files/zh-cn/web/javascript/reference/statements/const/index.html
+++ b/files/zh-cn/web/javascript/reference/statements/const/index.html
@@ -44,7 +44,7 @@ 

const 基本用法

常量在声明的时候可以使用大小写,但通常情况下全部用大写字母。

-
// 定义常量MY_FAV并赋值7
+
// 定义常量 MY_FAV 并赋值 7
 const MY_FAV = 7;
 
 // 报错 - Uncaught TypeError: Assignment to constant variable.
@@ -81,7 +81,7 @@ 

块作用域

var MY_FAV = 20; } -// MY_FAV 依旧为7 +// MY_FAV 依旧为 7 console.log('my favorite number is ' + MY_FAV);
diff --git a/files/zh-cn/web/javascript/reference/statements/continue/index.html b/files/zh-cn/web/javascript/reference/statements/continue/index.html index d356fdde7fd50a..290eec9c6050ed 100644 --- a/files/zh-cn/web/javascript/reference/statements/continue/index.html +++ b/files/zh-cn/web/javascript/reference/statements/continue/index.html @@ -38,7 +38,7 @@

示例

while 语句中使用 continue

-

下述例子展示了一个在i 为 3时执行continue 语句的 {{jsxref("Statements/while", "while")}} 循环。因此,n 的值在几次迭代后分别为 1, 3, 7 和 12 .

+

下述例子展示了一个在i 为 3 时执行continue 语句的 {{jsxref("Statements/while", "while")}} 循环。因此,n 的值在几次迭代后分别为 1, 3, 7 和 12 .

i = 0;
 n = 0;
diff --git a/files/zh-cn/web/javascript/reference/statements/debugger/index.html b/files/zh-cn/web/javascript/reference/statements/debugger/index.html
index dc8ca259363d9a..645b193b098d1b 100644
--- a/files/zh-cn/web/javascript/reference/statements/debugger/index.html
+++ b/files/zh-cn/web/javascript/reference/statements/debugger/index.html
@@ -24,7 +24,7 @@ 

示例

// do potentially buggy stuff to examine, step through, etc. }
-

当 debugger 被调用时, 执行暂停在 debugger 语句的位置。就像在脚本源代码中的断点一样。

+

当 debugger 被调用时,执行暂停在 debugger 语句的位置。就像在脚本源代码中的断点一样。

Paused at a debugger statement.

@@ -72,6 +72,6 @@

浏览器兼容

相关链接

diff --git a/files/zh-cn/web/javascript/reference/statements/export/index.html b/files/zh-cn/web/javascript/reference/statements/export/index.html index 33dd08fa410624..f49e089a68ac48 100644 --- a/files/zh-cn/web/javascript/reference/statements/export/index.html +++ b/files/zh-cn/web/javascript/reference/statements/export/index.html @@ -11,9 +11,9 @@ ---
{{jsSidebar("Statements")}}
-

在创建JavaScript模块时,export 语句用于从模块中导出实时绑定的函数、对象或原始值,以便其他程序可以通过 {{jsxref("Statements/import", "import")}} 语句使用它们。被导出的绑定值依然可以在本地进行修改。在使用import进行导入时,这些绑定值只能被导入模块所读取,但在export导出模块中对这些绑定值进行修改,所修改的值也会实时地更新。

+

在创建 JavaScript 模块时,export 语句用于从模块中导出实时绑定的函数、对象或原始值,以便其他程序可以通过 {{jsxref("Statements/import", "import")}} 语句使用它们。被导出的绑定值依然可以在本地进行修改。在使用 import 进行导入时,这些绑定值只能被导入模块所读取,但在 export 导出模块中对这些绑定值进行修改,所修改的值也会实时地更新。

-

无论您是否声明,导出的模块都处于{{jsxref("Strict_mode","严格模式")}}。 export语句不能用在嵌入式脚本中。

+

无论您是否声明,导出的模块都处于{{jsxref("Strict_mode","严格模式")}}。 export 语句不能用在嵌入式脚本中。

语法

@@ -66,7 +66,7 @@

描述

// 导出事先定义的特性
 export { myFunction, myVariable };
 
-// 导出单个特性(可以导出var,let,
+// 导出单个特性(可以导出 var,let,
 //const,function,class)
 export let myVariable = Math.sqrt(2);
 export function myFunction() { ... };
@@ -118,7 +118,7 @@

重导出 / 聚合

但这里的 function1 和 function2 在当前模块中变得不可用。

-

备注:尽管与import等效,但以下语法在语法上无效:

+

备注:尽管与 import 等效,但以下语法在语法上无效:

import DefaultExport from 'bar.js'; // 有效的
diff --git a/files/zh-cn/web/javascript/reference/statements/for-await...of/index.html b/files/zh-cn/web/javascript/reference/statements/for-await...of/index.html
index 272bc49fb1b309..0b746ae3d0de0a 100644
--- a/files/zh-cn/web/javascript/reference/statements/for-await...of/index.html
+++ b/files/zh-cn/web/javascript/reference/statements/for-await...of/index.html
@@ -74,7 +74,7 @@ 

迭代异步可迭代对象

迭代异步生成器 

-

异步生成器已经实现了异步迭代器协议, 所以可以用 for await...of循环。

+

异步生成器已经实现了异步迭代器协议,所以可以用 for await...of循环。

async function* asyncGenerator() {
   var i = 0;
@@ -92,7 +92,7 @@ 

迭代异步生成器 

// 1 // 2
-

有关使用for await... of考虑迭代API中获取数据的异步 generator 更具体的例子。这个例子首先为一个数据流创建了一个异步 generator,然后使用它来获得这个API的响应值的大小。

+

有关使用for await... of考虑迭代 API 中获取数据的异步 generator 更具体的例子。这个例子首先为一个数据流创建了一个异步 generator,然后使用它来获得这个 API 的响应值的大小。

async function* streamAsyncIterator(stream) {
   const reader = stream.getReader();
@@ -108,12 +108,12 @@ 

迭代异步生成器 

reader.releaseLock(); } } -// 从url获取数据并使用异步 generator 来计算响应值的大小 +// 从 url 获取数据并使用异步 generator 来计算响应值的大小 async function getResponseSize(url) { const response = await fetch(url); // Will hold the size of the response, in bytes. let responseSize = 0; - // 使用for-await-of循环. 异步 generator 会遍历响应值的每一部分 + // 使用 for-await-of 循环。异步 generator 会遍历响应值的每一部分 for await (const chunk of streamAsyncIterator(response.body)) { // Incrementing the total response length. responseSize += chunk.length; diff --git a/files/zh-cn/web/javascript/reference/statements/for...in/index.html b/files/zh-cn/web/javascript/reference/statements/for...in/index.html index fecaf76f36d9cd..bc30a843f8cadb 100644 --- a/files/zh-cn/web/javascript/reference/statements/for...in/index.html +++ b/files/zh-cn/web/javascript/reference/statements/for...in/index.html @@ -17,9 +17,9 @@

语法

variable
-
在每次迭代时,variable会被赋值为不同的属性名。
+
在每次迭代时,variable 会被赋值为不同的属性名。
object
-
非Symbol类型的可枚举属性被迭代的对象。
+
非 Symbol 类型的可枚举属性被迭代的对象。

@@ -34,7 +34,7 @@

仅迭代自身的属性

如果你只要考虑对象本身的属性,而不是它的原型,那么使用 {{jsxref("Object.getOwnPropertyNames", "getOwnPropertyNames()")}} 或执行 {{jsxref("Object.prototype.hasOwnProperty", "hasOwnProperty()")}} 来确定某属性是否是对象本身的属性(也能使用{{jsxref("Object.prototype.propertyIsEnumerable", "propertyIsEnumerable")}})。或者,如果你知道不会有任何外部代码干扰,您可以使用检查方法扩展内置原型。

-

为什么用for ... in?

+

为什么用 for ... in?

for ... in是为遍历对象属性而构建的,不建议与数组一起使用,数组可以用Array.prototype.forEach()for ... of,那么for ... in的到底有什么用呢?

@@ -130,7 +130,7 @@

兼容性:初始化函数表达 // 3

-

这个非标准行为现在在版本40及更高版本中被忽略,并将在严格模式({{bug(748550)}} 和 {{bug(1164741)}})中呈现{{jsxref("SyntaxError")}}("for-in loop head declarations may not have initializers")错误。

+

这个非标准行为现在在版本 40 及更高版本中被忽略,并将在严格模式({{bug(748550)}} 和 {{bug(1164741)}})中呈现{{jsxref("SyntaxError")}}("for-in loop head declarations may not have initializers")错误。

像其他引擎 V8(Chrome),Chakra (IE/Edge), JSC (WebKit/Safari) 正在研究去除这种不标准的行为。

diff --git a/files/zh-cn/web/javascript/reference/statements/for...of/index.html b/files/zh-cn/web/javascript/reference/statements/for...of/index.html index 477ceaeee48044..707e0719c94e64 100644 --- a/files/zh-cn/web/javascript/reference/statements/for...of/index.html +++ b/files/zh-cn/web/javascript/reference/statements/for...of/index.html @@ -126,7 +126,7 @@

迭代 DOM 集合

迭代 DOM 元素集合,比如一个{{domxref("NodeList")}}对象:下面的例子演示给每一个 article 标签内的 p 标签添加一个 "read" 类。

-
//注意:这只能在实现了NodeList.prototype[Symbol.iterator]的平台上运行
+
//注意:这只能在实现了 NodeList.prototype[Symbol.iterator] 的平台上运行
 let articleParagraphs = document.querySelectorAll("article > p");
 
 for (let paragraph of articleParagraphs) {
@@ -164,7 +164,7 @@ 

迭代生成器

for (let n of fibonacci()) {      console.log(n); -    // 当n大于1000时跳出循环 +    // 当 n 大于 1000 时跳出循环     if (n >= 1000)         break; }
diff --git a/files/zh-cn/web/javascript/reference/statements/for/index.html b/files/zh-cn/web/javascript/reference/statements/for/index.html index 9e8eb05f5177fa..155d8a49c90e65 100644 --- a/files/zh-cn/web/javascript/reference/statements/for/index.html +++ b/files/zh-cn/web/javascript/reference/statements/for/index.html @@ -31,7 +31,7 @@

语法

final-expression
每次循环的最后都要执行的表达式。执行时机是在下一次 condition 的计算之前。通常被用于更新或者递增计数器变量。
statement
-
只要condition的结果为true就会被执行的语句。要在循环体内执行多条语句,使用一个块语句{ ... })来包含要执行的语句。没有任何语句要执行,使用一个空语句;)。
+
只要condition的结果为 true 就会被执行的语句。要在循环体内执行多条语句,使用一个块语句{ ... })来包含要执行的语句。没有任何语句要执行,使用一个空语句;)。

示例

diff --git a/files/zh-cn/web/javascript/reference/statements/function/index.html b/files/zh-cn/web/javascript/reference/statements/function/index.html index 13efc35a6d0ea7..db945562890f68 100644 --- a/files/zh-cn/web/javascript/reference/statements/function/index.html +++ b/files/zh-cn/web/javascript/reference/statements/function/index.html @@ -39,7 +39,7 @@

描述

函数也可以被表达式创建( function expression )

-

函数可以被有条件来声明,这意味着,在一个 if 语句里,函数声明是可以嵌套的。有的浏览器会将这种有条件的声明看成是无条件的声明,无论这里的条件是true还是false,浏览器都会创建函数。因此,它们不应该被使用。

+

函数可以被有条件来声明,这意味着,在一个 if 语句里,函数声明是可以嵌套的。有的浏览器会将这种有条件的声明看成是无条件的声明,无论这里的条件是 true 还是 false,浏览器都会创建函数。因此,它们不应该被使用。

默认情况下,函数是返回 undefined 的。想要返回一个其他的值,函数必须通过一个 return 语句指定返回值。

@@ -53,17 +53,17 @@

有条件的创建函数

function foo(){ return 1; } } -// 在Chrome里: +// 在 Chrome 里: // 'foo' 变量名被提升,但是 typeof foo 为 undefined // -// 在Firefox里: -// 'foo' 变量名被提升. 但是 typeof foo 为 undefined +// 在 Firefox 里: +// 'foo' 变量名被提升。但是 typeof foo 为 undefined // -// 在Edge里: -// 'foo' 变量名未被提升. 而且 typeof foo 为 undefined +// 在 Edge 里: +// 'foo' 变量名未被提升。而且 typeof foo 为 undefined // -// 在Safari里: -// 'foo' 变量名被提升. 而且 typeof foo 为 function
+// 在 Safari 里: +// 'foo' 变量名被提升。而且 typeof foo 为 function

注意,即使把上面代码中的 if(false) 改为 if(true),结果也是一样的

@@ -73,22 +73,22 @@

有条件的创建函数

function foo(){ return 1; } } -// 在Chrome里: +// 在 Chrome 里: // 'foo' 变量名被提升,但是 typeof foo 为 undefined // -// 在Firefox里: -// 'foo' 变量名被提升. 但是 typeof foo 为 undefined +// 在 Firefox 里: +// 'foo' 变量名被提升。但是 typeof foo 为 undefined // -// 在Edge里: -// 'foo' 变量名未被提升. 而且 typeof foo 为 undefined +// 在 Edge 里: +// 'foo' 变量名未被提升。而且 typeof foo 为 undefined // -// 在Safari里: -// 'foo' 变量名被提升. 而且 typeof foo 为 function +// 在 Safari 里: +// 'foo' 变量名被提升。而且 typeof foo 为 function

函数声明提升

-

JavaScript 中的函数声明被提升到了函数定义。你可以在函数声明之前使用该函数:

+

JavaScript 中的函数声明被提升到了函数定义。你可以在函数声明之前使用该函数:

hoisted(); // logs "foo"
 
@@ -98,7 +98,7 @@ 

函数声明提升

-

备注:函数表达式{{jsxref("Operators/function", "function expressions")}} 不会被提升:

+

备注:函数表达式{{jsxref("Operators/function", "function expressions")}} 不会被提升:

notHoisted(); // TypeError: notHoisted is not a function
@@ -112,7 +112,7 @@ 

示例

使用函数

-

下面的代码声明了一个函数,该函数返回了销售的总金额, 参数是产品a,b,c分别的销售的数量.

+

下面的代码声明了一个函数,该函数返回了销售的总金额,参数是产品 a,b,c 分别的销售的数量。

function calc_sales(units_a, units_b, units_c) {functionfunctionfunctionfunctionfunctionfunctionfunctionfunctionfunctionfunctionfunction
    return units_a*79 + units_b * 129 + units_c * 699;
diff --git a/files/zh-cn/web/javascript/reference/statements/function_star_/index.html b/files/zh-cn/web/javascript/reference/statements/function_star_/index.html
index 00e6c291963257..5966082fbd37ee 100644
--- a/files/zh-cn/web/javascript/reference/statements/function_star_/index.html
+++ b/files/zh-cn/web/javascript/reference/statements/function_star_/index.html
@@ -13,7 +13,7 @@
 ---
 
{{jsSidebar("Statements")}}
-

function* 这种声明方式(function关键字后跟一个星号)会定义一个生成器函数 (generator function),它返回一个  {{jsxref("Global_Objects/Generator","Generator")}}  对象。

+

function* 这种声明方式 (function关键字后跟一个星号)会定义一个生成器函数 (generator function),它返回一个  {{jsxref("Global_Objects/Generator","Generator")}}  对象。

{{EmbedInteractiveExample("pages/js/statement-functionasterisk.html")}}
@@ -32,9 +32,9 @@

语法

name
函数名
param
-
要传递给函数的一个参数的名称,一个函数最多可以有255个参数。
+
要传递给函数的一个参数的名称,一个函数最多可以有 255 个参数。
statements
-
普通JS语句。
+
普通 JS 语句。

描述

@@ -45,7 +45,7 @@

描述

next()方法返回一个对象,这个对象包含两个属性:value 和 done,value 属性表示本次 yield 表达式的返回值,done 属性为布尔类型,表示生成器后续是否还有 yield 语句,即生成器函数是否已经执行完毕并返回。

-

调用 next()方法时,如果传入了参数,那么这个参数会传给上一条执行的 yield语句左边的变量,例如下面例子中的 x

+

调用 next()方法时,如果传入了参数,那么这个参数会传给上一条执行的 yield 语句左边的变量,例如下面例子中的 x

function *gen(){
     yield 10;
@@ -118,7 +118,7 @@ 

传递参数

function *createIterator() {
     let first = yield 1;
     let second = yield first + 2; // 4 + 2
-                                  // first =4 是next(4)将参数赋给上一条的
+                                  // first =4 是 next(4) 将参数赋给上一条的
     yield second + 3;             // 5 + 3
 }
 
@@ -153,19 +153,19 @@ 

使用迭
function* iterArr(arr) {            //迭代器返回一个迭代器对象
   if (Array.isArray(arr)) {         // 内节点
       for(let i=0; i < arr.length; i++) {
-          yield* iterArr(arr[i]);   // (*)递归
+          yield* iterArr(arr[i]);   // (*) 递归
       }
   } else {                          // 离开
       yield arr;
   }
 }
-// 使用 for-of 遍历:
+// 使用 for-of 遍历:
 var arr = ['a', ['b', 'c'], ['d', 'e']];
 for(var x of iterArr(arr)) {
         console.log(x);               // a  b  c  d  e
  }
 
-// 或者直接将迭代器展开:
+// 或者直接将迭代器展开:
 var arr = [ 'a', ['b',[ 'c', ['d', 'e']]]];
 var gen = iterArr(arr);
 arr = [...gen];                        // ["a", "b", "c", "d", "e"]
@@ -203,15 +203,15 @@

浏览器兼容性

{{Compat("javascript.statements.generator_function")}} 

-

Firefox浏览器具体事项

+

Firefox 浏览器具体事项

-

Firefox 26之前的生成器和迭代器

+

Firefox 26 之前的生成器和迭代器

-

旧版本的Firefox实施了旧版本的生成器提案。旧版中用普通的function关键字定义(没有星号).

+

旧版本的 Firefox 实施了旧版本的生成器提案。旧版中用普通的function 关键字定义(没有星号).

IteratorResult不再抛出错误

-

从Gecko 29 {{geckoRelease(29)}}开始,完成的生成器函数不再抛出{{jsxref("TypeError")}} "generator has already finished". 而是返回一个IteratorResult对象:{ value: undefined, done: true } ({{bug(958951)}})。

+

从 Gecko 29 {{geckoRelease(29)}}开始,完成的生成器函数不再抛出{{jsxref("TypeError")}} "generator has already finished". 而是返回一个IteratorResult对象:{ value: undefined, done: true } ({{bug(958951)}})。

相关链接

@@ -225,7 +225,7 @@

相关链接

  • {{jsxref("Statements/function", "function declaration")}}
  • {{jsxref("Operators/function", "function expression")}}
  • {{jsxref("Functions_and_function_scope", "Functions and function scope")}}
  • -
  • 其他网络资源: +
  • 其他网络资源:
    • Regenerator an ES2015 generator compiler to ES5
    • Forbes Lindesay: Promises and Generators: control flow utopia -- JSConf EU 2013
    • diff --git a/files/zh-cn/web/javascript/reference/statements/if...else/index.html b/files/zh-cn/web/javascript/reference/statements/if...else/index.html index aca3f842f358bb..ee1a2521bf5359 100644 --- a/files/zh-cn/web/javascript/reference/statements/if...else/index.html +++ b/files/zh-cn/web/javascript/reference/statements/if...else/index.html @@ -68,10 +68,10 @@

      说明

      }
  • -

    不要将原始布尔值的truefalseBoolean对象的真或假混淆。任何一个值,只要它不是 undefinednull、 0NaN或空字符串(""),那么无论是任何对象,即使是值为假的Boolean对象,在条件语句中都为真。例如:

    +

    不要将原始布尔值的truefalseBoolean对象的真或假混淆。任何一个值,只要它不是 undefinednull、 0NaN或空字符串(""),那么无论是任何对象,即使是值为假的 Boolean 对象,在条件语句中都为真。例如:

    var b = new Boolean(false);
    -if (b) //表达式的值为true
    +if (b) //表达式的值为 true
     

    示例

    @@ -88,7 +88,7 @@

    使用 if...else

    使用 else if

    -

    注意,Javascript中没有elseif语句。但可以使用elseif中间有空格的语句:

    +

    注意,Javascript 中没有elseif语句。但可以使用elseif中间有空格的语句:

    if (x > 5) {
      /* do the right thing */
    diff --git a/files/zh-cn/web/javascript/reference/statements/import.meta/index.html b/files/zh-cn/web/javascript/reference/statements/import.meta/index.html
    index ffab140a3789e6..172ba0d4c8922b 100644
    --- a/files/zh-cn/web/javascript/reference/statements/import.meta/index.html
    +++ b/files/zh-cn/web/javascript/reference/statements/import.meta/index.html
    @@ -12,7 +12,7 @@
     ---
     
    {{JSSidebar("Statements")}}
    -

    import.meta是一个给JavaScript模块暴露特定上下文的元数据属性的对象。它包含了这个模块的信息,比如说这个模块的URL。

    +

    import.meta是一个给 JavaScript 模块暴露特定上下文的元数据属性的对象。它包含了这个模块的信息,比如说这个模块的 URL。

    语法

    @@ -22,30 +22,30 @@

    描述

    import.meta对象由一个关键字"import",一个点符号和一个meta属性名组成。通常情况下"import."是作为一个属性访问的上下文,但是在这里"import"不是一个真正的对象。

    -

    import.meta对象是由ECMAScript实现的,它带有一个{{jsxref("null")}}的原型对象。这个对象可以扩展,并且它的属性都是可写,可配置和可枚举的。

    +

    import.meta对象是由 ECMAScript 实现的,它带有一个{{jsxref("null")}}的原型对象。这个对象可以扩展,并且它的属性都是可写,可配置和可枚举的。

    示例

    -

    这里有一个 my-module.mjs模块

    +

    这里有一个 my-module.mjs 模块

    <script type="module" src="my-module.mjs"></script>
     
    -

    你可以通过 import.meta 对象获取这个模块的元数据信息.

    +

    你可以通过 import.meta 对象获取这个模块的元数据信息。

    console.log(import.meta); // { url: "file:///home/user/my-module.mjs" }
    -

    它返回一个带有url属性的对象,指明模块的基本URL。也可以是外部脚本的URL,还可以是内联脚本所属文档的URL。

    +

    它返回一个带有url属性的对象,指明模块的基本 URL。也可以是外部脚本的 URL,还可以是内联脚本所属文档的 URL。

    -

    注意,url也可能包含参数或者哈希(比如后缀?#

    +

    注意,url 也可能包含参数或者哈希(比如后缀?#

    -

    以下面的HTML为例:

    +

    以下面的 HTML 为例:

    <script type="module">
     import './index.mjs?someURLInfo=5';
     </script>
    -

    ...下面的JavaScript会打印someURLInfo这个参数:

    +

    ...下面的 JavaScript 会打印someURLInfo这个参数:

    // index.mjs
     new URL(import.meta.url).searchParams.get('someURLInfo'); // 5
    @@ -58,9 +58,9 @@

    示例

    // index2.mjs new URL(import.meta.url).searchParams.get('someURLInfo'); // 5
    -

    虽然在上述例子中,Node.js允许携带参数(或哈希),但以Node 14.1.0为例,使用node --experimental-modules index.mjs?someURLInfo=5 执行脚本,查询URL参数将会报错(该环境下index.mjs?someURLInfo=5 被视作一个文件而不是URL)

    +

    虽然在上述例子中,Node.js 允许携带参数(或哈希),但以 Node 14.1.0 为例,使用node --experimental-modules index.mjs?someURLInfo=5 执行脚本,查询 URL 参数将会报错(该环境下index.mjs?someURLInfo=5 被视作一个文件而不是 URL)

    -

    像这种特定于文件的参数传递可能是对应用范围内location.href(ps: 通过在HTML路径添加参数或哈希)(而在Node.js中是process.env)的补充

    +

    像这种特定于文件的参数传递可能是对应用范围内location.href(ps: 通过在 HTML 路径添加参数或哈希)(而在 Node.js 中是process.env)的补充

    规范

    diff --git a/files/zh-cn/web/javascript/reference/statements/import/index.html b/files/zh-cn/web/javascript/reference/statements/import/index.html index 130874fb0c5471..0bd1b75523d365 100644 --- a/files/zh-cn/web/javascript/reference/statements/import/index.html +++ b/files/zh-cn/web/javascript/reference/statements/import/index.html @@ -93,7 +93,7 @@

    导入时重命名多个接口

    仅为副作用而导入一个模块

    -

    整个模块仅为副作用(中性词,无贬义含义)而导入,而不导入模块中的任何内容(接口)。 这将运行模块中的全局代码, 但实际上不导入任何值。

    +

    整个模块仅为副作用(中性词,无贬义含义)而导入,而不导入模块中的任何内容(接口)。 这将运行模块中的全局代码,但实际上不导入任何值。

    import '/modules/my-module.js';
    @@ -124,7 +124,7 @@

    导入默认值

    } })();
    -

    动态import

    +

    动态 import

    标准用法的 import 导入的模块是静态的,会使所有被导入的模块,在加载时就被编译(无法做到按需编译,降低首页加载速度)。有些场景中,你可能希望根据条件导入模块或者按需导入模块,这时你可以使用动态导入代替静态导入。下面的是你可能会需要动态导入的场景:

    diff --git a/files/zh-cn/web/javascript/reference/statements/index.html b/files/zh-cn/web/javascript/reference/statements/index.html index eadf850d86769b..6564c68f8a491d 100644 --- a/files/zh-cn/web/javascript/reference/statements/index.html +++ b/files/zh-cn/web/javascript/reference/statements/index.html @@ -69,7 +69,7 @@

    迭代器

    {{jsxref("Statements/do...while", "do...while")}}
    创建一个循环来执行语句,直到该语句条件表达式的值为 false。先执行语句,再执行条件表达式,该语句至少会执行一次。
    {{jsxref("Statements/for", "for")}}
    -
    创建一个由3个可选的表达式组成的循环,该循环用括号包裹,分号分割,并在循环体中执行语句。
    +
    创建一个由 3 个可选的表达式组成的循环,该循环用括号包裹,分号分割,并在循环体中执行语句。
    {{jsxref("Statements/for...in", "for...in")}}
    无序遍历对象的可枚举属性。语句针对每个唯一的属性。
    {{jsxref("Statements/for...of", "for...of")}}
    @@ -77,7 +77,7 @@

    迭代器

    {{jsxref("Statements/for-await...of", "for await...of")}}
    在异步可迭代对象、类数组对象、迭代器和生成器上迭代,调用自定义迭代钩子,其中包含要为每个不同属性的值执行的语句。
    {{jsxref("Statements/while", "while")}}
    -
    创建一个循环语句,循环会一直持续到该语句条件表达式的值为false。先执行条件表达式,然后执行语句。
    +
    创建一个循环语句,循环会一直持续到该语句条件表达式的值为 false。先执行条件表达式,然后执行语句。

    其他

    @@ -88,7 +88,7 @@

    其他

    {{jsxref("Statements/export", "export")}}
    用来导出函数,以便这些函数能够被导入到外部模块或其他脚本中。
    {{jsxref("Statements/import", "import")}}
    -
    用来引入外部的模块或另一个script中导出的函数。
    +
    用来引入外部的模块或另一个 script 中导出的函数。
    import.meta
    向 JavaScript 模块公开上下文特定的元数据的元属性。
    {{jsxref("Statements/label", "label")}}
    diff --git a/files/zh-cn/web/javascript/reference/statements/label/index.html b/files/zh-cn/web/javascript/reference/statements/label/index.html index e05f42627541b5..7fa9dba264c67f 100644 --- a/files/zh-cn/web/javascript/reference/statements/label/index.html +++ b/files/zh-cn/web/javascript/reference/statements/label/index.html @@ -141,7 +141,7 @@

    在标记块中使用 break标记函数声明

    -

    从ECMAScript 2015开始,标准的函数声明现在对规范的 Web 兼容性附件中的非严格代码进行了标准化。

    +

    从 ECMAScript 2015 开始,标准的函数声明现在对规范的 Web 兼容性附件中的非严格代码进行了标准化。

    L: function F() {}
    diff --git a/files/zh-cn/web/javascript/reference/statements/let/index.md b/files/zh-cn/web/javascript/reference/statements/let/index.md index 4f32616a843859..61a79a4ef066f9 100644 --- a/files/zh-cn/web/javascript/reference/statements/let/index.md +++ b/files/zh-cn/web/javascript/reference/statements/let/index.md @@ -40,7 +40,7 @@ let { bar } = foo; // where foo = { bar:10, baz:12 }; ## 描述 -**`let`** 允许你声明一个作用域被限制在{{jsxref("statements/block", "块")}}作用域中的变量、语句或者表达式。与 {{jsxref("statements/var", "var")}} 关键字不同的是,`var` 声明的变量作用域是全局或者整个函数块的。 `var` 和 `let` 的另一个重要区别,`let` 声明的变量不会在作用域中被提升,它是在编译时才初始化(参考下面[暂时性死区](#暂时性死区))。 +**`let`** 允许你声明一个作用域被限制在{{jsxref("statements/block", "块")}}作用域中的变量、语句或者表达式。与 {{jsxref("statements/var", "var")}} 关键字不同的是,`var` 声明的变量作用域是全局或者整个函数块的。 `var` 和 `let` 的另一个重要区别,`let` 声明的变量不会在作用域中被提升,它是在编译时才初始化(参考下面 [暂时性死区](#暂时性死区))。 就像 {{jsxref("statements/const", "const", "描述")}} 一样,`let` 不会在全局声明时(在最顶部的范围)创建 {{domxref('window')}} 对象的属性。 @@ -200,7 +200,7 @@ switch(x) { #### 暂时性死区与 `typeof` -如果使用 `typeof` 检测在暂时性死区中的变量, 会抛出 `ReferenceError` 异常: +如果使用 `typeof` 检测在暂时性死区中的变量,会抛出 `ReferenceError` 异常: ```js example-bad // results in a 'ReferenceError' @@ -231,7 +231,7 @@ test(); 由于外部变量 `foo` 有值,因此会执行 `if` 语句块,但是由于词法作用域,该值在块内不可用:`if` 快内的标识符 `foo` 是 `let foo`。表达式 `(foo + 55)` 会抛出异常,是因为 `let foo` 还没完成初始化,它仍然在暂时性死区里。 -在以下情况下,这种现象可能会使您感到困惑。`let n of n.a` 已经在for循环块的私有范围内,因此,标识符 `n.a` 被解析为位于指令本身(`let n`)中的“ `n` ”对象的属性“ `a` ”。 +在以下情况下,这种现象可能会使您感到困惑。`let n of n.a` 已经在 for 循环块的私有范围内,因此,标识符 `n.a` 被解析为位于指令本身(`let n`)中的“ `n` ”对象的属性“ `a` ”。 在没有执行到它的初始化语句之前,它仍旧存在于暂时性死区中。 @@ -268,7 +268,7 @@ console.log(a); // 11 console.log(b); // 2 ``` -然而,`var` 与 `let` 合并的声明方式会抛出 {{jsxref("SyntaxError")}} 错误, 因为 `var` 会将变量提升至块的顶部, 这会导致隐式地重复声明变量。 +然而,`var` 与 `let` 合并的声明方式会抛出 {{jsxref("SyntaxError")}} 错误,因为 `var` 会将变量提升至块的顶部,这会导致隐式地重复声明变量。 ```js example-bad let x = 1; diff --git a/files/zh-cn/web/javascript/reference/statements/return/index.html b/files/zh-cn/web/javascript/reference/statements/return/index.html index e5a09d5a84ab3a..e71ee6f5b6d7f5 100644 --- a/files/zh-cn/web/javascript/reference/statements/return/index.html +++ b/files/zh-cn/web/javascript/reference/statements/return/index.html @@ -68,11 +68,11 @@

    中断一个函数的执行

    function counter() {
       for (var count = 1; ; count++) {  // 无限循环
    -    console.log(count + "A"); // 执行5次
    +    console.log(count + "A"); // 执行 5 次
         if (count === 5) {
           return;
         }
    -    console.log(count + "B");  // 执行4次
    +    console.log(count + "B");  // 执行 4 次
       }
       console.log(count + "C");  // 永远不会执行
     }
    diff --git a/files/zh-cn/web/javascript/reference/statements/throw/index.html b/files/zh-cn/web/javascript/reference/statements/throw/index.html
    index 913f08361f2dad..8c7271dd5f4e54 100644
    --- a/files/zh-cn/web/javascript/reference/statements/throw/index.html
    +++ b/files/zh-cn/web/javascript/reference/statements/throw/index.html
    @@ -26,8 +26,8 @@ 

    描述

    使用throw语句来抛出一个异常。当你抛出异常时,expression 指定了异常的内容。下面的每行都抛出了一个异常:

    throw "Error2"; // 抛出了一个值为字符串的异常
    -throw 42;       // 抛出了一个值为整数42的异常
    -throw true;     // 抛出了一个值为true的异常
    +throw 42; // 抛出了一个值为整数 42 的异常 +throw true; // 抛出了一个值为 true 的异常

    注意throw语句同样受到自动分号插入(ASI)机制的控制,在throw关键字和值之间不允许有行终止符。

    @@ -67,9 +67,9 @@

    另一个抛出异常对象的示

    下面的示例中测试一个字符串是否是美国邮政编码。如果邮政编码是无效的,那么throw语句将会抛出一个类型为 ZipCodeFormatException的异常对象实例。

    /*
    - * 创建 ZipCode 示例.
    + * 创建 ZipCode 示例。
      *
    - * 可被接受的邮政编码格式:
    + * 可被接受的邮政编码格式:
      *    12345
      *    12345-6789
      *    123456789
    @@ -132,7 +132,7 @@ 

    另一个抛出异常对象的示

    重新抛出异常

    -

    你可以使用throw来抛出异常。下面的例子捕捉了一个异常值为数字的异常,并在其值大于50后重新抛出异常。重新抛出的异常传播到闭包函数或顶层,以便用户看到它。

    +

    你可以使用throw来抛出异常。下面的例子捕捉了一个异常值为数字的异常,并在其值大于 50 后重新抛出异常。重新抛出的异常传播到闭包函数或顶层,以便用户看到它。

    try {
        throw n; // 抛出一个数值异常
    diff --git a/files/zh-cn/web/javascript/reference/statements/try...catch/index.html b/files/zh-cn/web/javascript/reference/statements/try...catch/index.html
    index 6559e9cbb20a88..54d431b2cb73bc 100644
    --- a/files/zh-cn/web/javascript/reference/statements/try...catch/index.html
    +++ b/files/zh-cn/web/javascript/reference/statements/try...catch/index.html
    @@ -46,7 +46,7 @@ 

    语法

    描述

    -

    try语句包含了由一个或者多个语句组成的try块, 和至少一个catch块或者一个finally块的其中一个,或者两个兼有, 下面是三种形式的try声明:

    +

    try语句包含了由一个或者多个语句组成的try块,和至少一个catch块或者一个finally块的其中一个,或者两个兼有, 下面是三种形式的try声明:

    1. try...catch
    2. @@ -75,7 +75,7 @@

      无条件的catch

      }
    -

    catch块指定一个标识符(在上面的示例中为e),该标识符保存由throw语句指定的值。catch块是唯一的,因为当输入catch块时,JavaScript 会创建此标识符,并将其添加到当前作用域;标识符仅在catch块执行时存在;catch块执行完成后,标识符不再可用。

    +

    catch块指定一个标识符(在上面的示例中为 e),该标识符保存由throw语句指定的值。catch块是唯一的,因为当输入catch块时,JavaScript 会创建此标识符,并将其添加到当前作用域;标识符仅在catch块执行时存在;catch块执行完成后,标识符不再可用。

    条件catch

    @@ -101,7 +101,7 @@

    条件catch

    }
    -

    下面用符合 ECMAscript 规范的简单的 JavaScript 来编写相同的“条件catch子句”(显然更加冗长的,但是可以在任何地方运行):

    +

    下面用符合 ECMAscript 规范的简单的 JavaScript 来编写相同的“条件 catch 子句”(显然更加冗长的,但是可以在任何地方运行):

    try {
       myRoutine();
    @@ -132,7 +132,7 @@ 

    finally

    finally块包含的语句在try块和catch之后,try..catch..finally块后的语句之前执行。请注意,无论是否抛出异常finally子句都会执行。此外,如果抛出异常,即使没有catch子句处理异常,finally子句中的语句也会执行。

    -

    以下示例打开一个文件,然后执行使用该文件的语句(服务器端 JavaScript 允许您访问文件)。如果文件打开时抛出异常,则finally子句会在脚本失败之前关闭该文件。finally中的代码最终也会在trycatch block显式返回时执行。

    +

    以下示例打开一个文件,然后执行使用该文件的语句(服务器端 JavaScript 允许您访问文件)。如果文件打开时抛出异常,则finally子句会在脚本失败之前关闭该文件。finally 中的代码最终也会在trycatch block显式返回时执行。

    openMyFile()
     try {
    @@ -236,7 +236,7 @@ 

    从 finally 语句块返回

    console.error("outer", ex.message); } -// 注: 此 try catch 语句需要在 function 中运行才能作为函数的返回值, 否则直接运行会报语法错误 +// 注:此 try catch 语句需要在 function 中运行才能作为函数的返回值,否则直接运行会报语法错误 // Output: // "inner" "oops" // "finally" diff --git a/files/zh-cn/web/javascript/reference/statements/var/index.md b/files/zh-cn/web/javascript/reference/statements/var/index.md index e10b0818467edb..e48d6edfccc7e6 100644 --- a/files/zh-cn/web/javascript/reference/statements/var/index.md +++ b/files/zh-cn/web/javascript/reference/statements/var/index.md @@ -36,7 +36,7 @@ var { bar } = foo; // foo = { bar:10, baz:12 }; 无论在何处声明变量,都会在执行任何代码之前进行处理。这被称为{{Glossary("Hoisting", "变量提升")}},我们将在下面进一步讨论。 -用 `var` 声明的变量的作用域是它当前的执行上下文及其闭包(嵌套函数),或者对于声明在任何函数外的变量来说是全局。使用 `var` 重复声明 JavaScript 变量并不会抛出错误(即使在严格模式(strict mode)下),同时,变量也不会丢失其值,直到调用其它的赋值操作。 +用 `var` 声明的变量的作用域是它当前的执行上下文及其闭包(嵌套函数),或者对于声明在任何函数外的变量来说是全局。使用 `var` 重复声明 JavaScript 变量并不会抛出错误(即使在严格模式 (strict mode) 下),同时,变量也不会丢失其值,直到调用其它的赋值操作。 ```js 'use strict'; @@ -66,7 +66,7 @@ console.log(x); // 1 console.log('still going...'); // still going... ``` -在全局上下文中,使用 `var` 声明的变量将作为全局对象的**不可配置**属性被添加。这意味着它的属性描述符无法被修改,也无法使用 {{JSxRef("Operators/delete", "delete")}} 删除。其对应的名字也将被添加到[全局环境记录(global environment record)](https://www.ecma-international.org/ecma-262/10.0/index.html#sec-global-environment-records)(它构成了全局词法环境(global lexical environment)的一部分)的 `[[VarNames]]` 插槽内的列表中。`[[VarNames]]` 中的命名列表使运行时能够区分“全局变量”和“全局对象的直接属性”。 +在全局上下文中,使用 `var` 声明的变量将作为全局对象的**不可配置**属性被添加。这意味着它的属性描述符无法被修改,也无法使用 {{JSxRef("Operators/delete", "delete")}} 删除。其对应的名字也将被添加到 [全局环境记录(global environment record)](https://www.ecma-international.org/ecma-262/10.0/index.html#sec-global-environment-records)(它构成了全局词法环境 (global lexical environment) 的一部分)的 `[[VarNames]]` 插槽内的列表中。`[[VarNames]]` 中的命名列表使运行时能够区分“全局变量”和“全局对象的直接属性”。 全局变量(以全局对象的属性的形式被创建)不可配置的原因是:该标识符被视为一个变量,而不是全局对象的**直接属性**。JavaScript 具有自动化的内存管理机制,因此“能够使用 `delete` 删除全局变量”是没有意义的。 @@ -105,7 +105,7 @@ foo = 'f' // 在非严格模式下,假设你想在全局对象下创建名为 globalThis.hasOwnProperty('foo') // true ``` -在 ECMAScript 5 的[严格模式]((/zh-CN/docs/Web/JavaScript/Reference/Strict_mode))下,此行为具有不同的表现。在严格模式下,对未限定的标识符赋值将抛出 `ReferenceError`,以避免意外创建全局对象属性。 +在 ECMAScript 5 的[严格模式]((/zh-CN/docs/Web/JavaScript/Reference/Strict_mode)) 下,此行为具有不同的表现。在严格模式下,对未限定的标识符赋值将抛出 `ReferenceError`,以避免意外创建全局对象属性。 注意,上面的说明意味着:与流行的错误信息相反,JavaScript 并没有隐式变量声明,它只是有一个类似的语法。 diff --git a/files/zh-cn/web/javascript/reference/statements/with/index.html b/files/zh-cn/web/javascript/reference/statements/with/index.html index 93d4270d2ebc47..29ba8a0f691d8c 100644 --- a/files/zh-cn/web/javascript/reference/statements/with/index.html +++ b/files/zh-cn/web/javascript/reference/statements/with/index.html @@ -13,7 +13,7 @@
    {{jsSidebar("Statements")}}
    -
    with语句 扩展一个语句的作用域链。
    +
    with 语句 扩展一个语句的作用域链。

    语法

    @@ -26,31 +26,31 @@

    语法

    expression
    将给定的表达式添加到在评估语句时使用的作用域链上。表达式周围的括号是必需的。
    statement
    -
    任何语句。要执行多个语句,请使用一个语句 ({ ... })对这些语句进行分组。
    +
    任何语句。要执行多个语句,请使用一个语句 ({ ... }) 对这些语句进行分组。

    描述

    -

    JavaScript查找某个未使用命名空间的变量时,会通过作用域链来查找,作用域链是跟执行代码的context或者包含这个变量的函数有关。'with'语句将某个对象添加到作用域链的顶部,如果在statement中有某个未使用命名空间的变量,跟作用域链中的某个属性同名,则这个变量将指向这个属性值。如果沒有同名的属性,则将拋出{{jsxref("ReferenceError")}}异常。

    +

    JavaScript 查找某个未使用命名空间的变量时,会通过作用域链来查找,作用域链是跟执行代码的 context 或者包含这个变量的函数有关。'with'语句将某个对象添加到作用域链的顶部,如果在 statement 中有某个未使用命名空间的变量,跟作用域链中的某个属性同名,则这个变量将指向这个属性值。如果沒有同名的属性,则将拋出{{jsxref("ReferenceError")}}异常。

    备注:不推荐使用with,在 ECMAScript 5 严格模式中该标签已被禁止。推荐的替代方案是声明一个临时变量来承载你所需要的属性。

    性能方面的利与弊

    -

    利:with语句可以在不造成性能损失的情況下,减少变量的长度。其造成的附加计算量很少。使用'with'可以减少不必要的指针路径解析运算。需要注意的是,很多情況下,也可以不使用with语句,而是使用一个临时变量来保存指针,来达到同样的效果。

    +

    利:with语句可以在不造成性能损失的情況下,减少变量的长度。其造成的附加计算量很少。使用'with'可以减少不必要的指针路径解析运算。需要注意的是,很多情況下,也可以不使用 with 语句,而是使用一个临时变量来保存指针,来达到同样的效果。

    -

    弊:with语句使得程序在查找变量值时,都是先在指定的对象中查找。所以那些本来不是这个对象的属性的变量,查找起来将会很慢。如果是在对性能要求较高的场合,'with'下面的statement语句中的变量,只应该包含这个指定对象的属性。

    +

    弊:with语句使得程序在查找变量值时,都是先在指定的对象中查找。所以那些本来不是这个对象的属性的变量,查找起来将会很慢。如果是在对性能要求较高的场合,'with'下面的 statement 语句中的变量,只应该包含这个指定对象的属性。

    语义不明的弊端

    -

    弊端:with语句使得代码不易阅读,同时使得JavaScript编译器难以在作用域链上查找某个变量,难以决定应该在哪个对象上来取值。请看下面的例子:

    +

    弊端:with语句使得代码不易阅读,同时使得 JavaScript 编译器难以在作用域链上查找某个变量,难以决定应该在哪个对象上来取值。请看下面的例子:

    function f(x, o) {
       with (o)
         print(x);
     }
    -

    f被调用时,x有可能能取到值,也可能是undefined,如果能取到, 有可能是在o上取的值,也可能是函数的第一个参数x的值(如果o中没有这个属性的话)。如果你忘记在作为第二个参数的对象o中定义x这个属性,程序并不会报错,只是取到另一个值而已。

    +

    f被调用时,x有可能能取到值,也可能是undefined,如果能取到,有可能是在 o 上取的值,也可能是函数的第一个参数x的值(如果 o 中没有这个属性的话)。如果你忘记在作为第二个参数的对象 o 中定义x这个属性,程序并不会报错,只是取到另一个值而已。

    弊端:使用with语句的代码,无法向前兼容,特別是在使用一些原生数据类型的时候。看下面的例子:

    @@ -62,7 +62,7 @@

    语义不明的弊端

    }
    -

    如果是在ECMAScript 5环境调用f([1,2,3], obj),则with语句中变量values将指向函数的第二个参数values。但是,ECMAScript 6标准给Array.prototype添加了一个新属性values,所有数组实例将继承这个属性。所以在ECMAScript 6环境中,with语句中变量values将指向[1,2,3].values

    +

    如果是在 ECMAScript 5 环境调用f([1,2,3], obj),则with语句中变量values将指向函数的第二个参数values。但是,ECMAScript 6 标准给Array.prototype添加了一个新属性values,所有数组实例将继承这个属性。所以在 ECMAScript 6 环境中,with语句中变量values将指向[1,2,3].values

    示例

    diff --git a/files/zh-cn/web/javascript/reference/strict_mode/index.html b/files/zh-cn/web/javascript/reference/strict_mode/index.html index a23cbb565f3a82..429f7592a898b8 100644 --- a/files/zh-cn/web/javascript/reference/strict_mode/index.html +++ b/files/zh-cn/web/javascript/reference/strict_mode/index.html @@ -13,7 +13,7 @@

    备注:有时你会看到非严格模式,被称为“sloppy mode”。这不是一个官方术语,但以防万一,你应该意识到这一点。

    -
    ECMAScript 5严格模式是采用具有限制性JavaScript变体的一种方式,从而使代码隐式地脱离“马虎模式/稀松模式/懒散模式“(sloppy)模式。
    +
    ECMAScript 5严格模式是采用具有限制性 JavaScript 变体的一种方式,从而使代码隐式地脱离“马虎模式/稀松模式/懒散模式“(sloppy)模式。
    严格模式不仅仅是一个子集:它的产生是为了形成与正常代码不同的语义。
    @@ -23,17 +23,17 @@ -
    严格模式对正常的 JavaScript语义做了一些更改。
    +
    严格模式对正常的 JavaScript 语义做了一些更改。
    1. 严格模式通过抛出错误来消除了一些原有静默错误
    2. -
    3. 严格模式修复了一些导致 JavaScript引擎难以执行优化的缺陷:有时候,相同的代码,严格模式可以比非严格模式下运行得更快
    4. -
    5. 严格模式禁用了在ECMAScript的未来版本中可能会定义的一些语法。
    6. +
    7. 严格模式修复了一些导致 JavaScript 引擎难以执行优化的缺陷:有时候,相同的代码,严格模式可以比非严格模式下运行得更快
    8. +
    9. 严格模式禁用了在 ECMAScript 的未来版本中可能会定义的一些语法。
    -

    如果你想改变你的代码,让其工作在具有限制性JavaScript环境中,请参阅转换成严格模式

    +

    如果你想改变你的代码,让其工作在具有限制性 JavaScript 环境中,请参阅转换成严格模式

    调用严格模式

    @@ -54,7 +54,7 @@

    为脚本开启严格模式

    为函数开启严格模式

    -

    同样的,要给某个函数开启严格模式,得把 "use strict";  (或 'use strict'; )声明一字不漏地放在函数体所有语句之前。

    +

    同样的,要给某个函数开启严格模式,得把 "use strict";  (或 'use strict'; ) 声明一字不漏地放在函数体所有语句之前。

    function strict() {
       // 函数级别严格模式语法
    @@ -72,13 +72,13 @@ 

    为函数开启严格模式

    严格模式中的变化

    -

    严格模式同时改变了语法及运行时行为。变化通常分为这几类:将问题直接转化为错误(如语法错误或运行时错误), 简化了如何为给定名称的特定变量计算,简化了 eval 以及 arguments, 将写"安全“JavaScript的步骤变得更简单,以及改变了预测未来ECMAScript行为的方式。

    +

    严格模式同时改变了语法及运行时行为。变化通常分为这几类:将问题直接转化为错误(如语法错误或运行时错误), 简化了如何为给定名称的特定变量计算,简化了 eval 以及 arguments, 将写"安全“JavaScript 的步骤变得更简单,以及改变了预测未来 ECMAScript 行为的方式。

    将过失错误转成异常

    -

    在严格模式下, 某些先前被接受的过失错误将会被认为是异常. JavaScript被设计为能使新人开发者更易于上手, 所以有时候会给本来错误操作赋予新的不报错误的语义(non-error semantics). 有时候这可以解决当前的问题, 但有时候却会给以后留下更大的问题. 严格模式则把这些失误当成错误, 以便可以发现并立即将其改正.

    +

    在严格模式下,某些先前被接受的过失错误将会被认为是异常. JavaScript 被设计为能使新人开发者更易于上手,所以有时候会给本来错误操作赋予新的不报错误的语义 (non-error semantics). 有时候这可以解决当前的问题,但有时候却会给以后留下更大的问题。严格模式则把这些失误当成错误,以便可以发现并立即将其改正。

    -

    第一,严格模式下无法再意外创建全局变量。在普通的JavaScript里面给一个错误命名的变量名赋值会使全局对象新增一个属性并继续“工作”(尽管将来可能会失败:在现代的JavaScript中有可能)。严格模式中意外创建全局变量被抛出错误替代:

    +

    第一,严格模式下无法再意外创建全局变量。在普通的 JavaScript 里面给一个错误命名的变量名赋值会使全局对象新增一个属性并继续“工作”(尽管将来可能会失败:在现代的 JavaScript 中有可能)。严格模式中意外创建全局变量被抛出错误替代:

    "use strict";
                            // 假如有一个全局变量叫做mistypedVariable
    @@ -86,42 +86,42 @@ 

    将过失错误转成异常

      // 这一行代码就会抛出 ReferenceError
    -

    第二, 严格模式会使引起静默失败(silently fail,注:不报错也没有任何效果)的赋值操作抛出异常. 例如, NaN 是一个不可写的全局变量. 在正常模式下, 给 NaN 赋值不会产生任何作用; 开发者也不会受到任何错误反馈. 但在严格模式下, 给 NaN 赋值会抛出一个异常. 任何在正常模式下引起静默失败的赋值操作 (给不可写属性赋值, 给只读属性(getter-only)赋值, 给不可扩展对象(non-extensible object)的新属性赋值) 都会抛出异常:

    +

    第二,严格模式会使引起静默失败 (silently fail,注:不报错也没有任何效果) 的赋值操作抛出异常。例如,NaN 是一个不可写的全局变量。在正常模式下,给 NaN 赋值不会产生任何作用; 开发者也不会受到任何错误反馈。但在严格模式下,给 NaN 赋值会抛出一个异常。任何在正常模式下引起静默失败的赋值操作 (给不可写属性赋值,给只读属性 (getter-only) 赋值,给不可扩展对象 (non-extensible object) 的新属性赋值) 都会抛出异常:

    "use strict";
     
     // 给不可写属性赋值
     var obj1 = {};
     Object.defineProperty(obj1, "x", { value: 42, writable: false });
    -obj1.x = 9; // 抛出TypeError错误
    +obj1.x = 9; // 抛出 TypeError 错误
     
     // 给只读属性赋值
     var obj2 = { get x() { return 17; } };
    -obj2.x = 5; // 抛出TypeError错误
    +obj2.x = 5; // 抛出 TypeError 错误
     
     // 给不可扩展对象的新属性赋值
     var fixed = {};
     Object.preventExtensions(fixed);
    -fixed.newProp = "ohai"; // 抛出TypeError错误
    +fixed.newProp = "ohai"; // 抛出 TypeError 错误
     
    -

    第三, 在严格模式下, 试图删除不可删除的属性时会抛出异常(之前这种操作不会产生任何效果):

    +

    第三,在严格模式下,试图删除不可删除的属性时会抛出异常 (之前这种操作不会产生任何效果):

    "use strict";
    -delete Object.prototype; // 抛出TypeError错误
    +delete Object.prototype; // 抛出 TypeError 错误
     
    -

    第四,在Gecko版本34之前,严格模式要求一个对象内的所有属性名在对象内必须唯一。正常模式下重名属性是允许的,最后一个重名的属性决定其属性值。因为只有最后一个属性起作用,当代码要去改变属性值而不是修改最后一个重名属性的时候,复制这个对象就产生一连串的bug。在严格模式下,重名属性被认为是语法错误:

    +

    第四,在 Gecko 版本 34 之前,严格模式要求一个对象内的所有属性名在对象内必须唯一。正常模式下重名属性是允许的,最后一个重名的属性决定其属性值。因为只有最后一个属性起作用,当代码要去改变属性值而不是修改最后一个重名属性的时候,复制这个对象就产生一连串的 bug。在严格模式下,重名属性被认为是语法错误:

    -

    备注:这个问题在ECMAScript6中已经不复存在({{bug(1041128)}})。

    +

    备注:这个问题在 ECMAScript6 中已经不复存在 ({{bug(1041128)}})。

    "use strict";
     var o = { p: 1, p: 2 }; // !!! 语法错误
     
    -

    第五, 严格模式要求函数的参数名唯一. 在正常模式下, 最后一个重名参数名会掩盖之前的重名参数. 之前的参数仍然可以通过 arguments[i] 来访问, 还不是完全无法访问. 然而, 这种隐藏毫无意义而且可能是意料之外的 (比如它可能本来是打错了), 所以在严格模式下重名参数被认为是语法错误:

    +

    第五,严格模式要求函数的参数名唯一。在正常模式下,最后一个重名参数名会掩盖之前的重名参数。之前的参数仍然可以通过 arguments[i] 来访问, 还不是完全无法访问。然而,这种隐藏毫无意义而且可能是意料之外的 (比如它可能本来是打错了), 所以在严格模式下重名参数被认为是语法错误:

    function sum(a, a, c) { // !!! 语法错误
       "use strict";
    @@ -129,11 +129,11 @@ 

    将过失错误转成异常

    }
    -

    第六, 严格模式禁止八进制数字语法. ECMAScript并不包含八进制语法, 但所有的浏览器都支持这种以零(0)开头的八进制语法: 0644 === 420 还有 "\045" === "%".在ECMAScript 6中支持为一个数字加"0o"的前缀来表示八进制数.

    +

    第六,严格模式禁止八进制数字语法. ECMAScript 并不包含八进制语法,但所有的浏览器都支持这种以零 (0) 开头的八进制语法:0644 === 420 还有 "\045" === "%".在 ECMAScript 6 中支持为一个数字加"0o"的前缀来表示八进制数。

    var a = 0o10; // ES6: 八进制
    -

    有些新手开发者认为数字的前导零没有语法意义, 所以他们会用作对齐措施 — 但其实这会改变数字的意义! 八进制语法很少有用并且可能会错误使用, 所以严格模式下八进制语法会引起语法错误:

    +

    有些新手开发者认为数字的前导零没有语法意义,所以他们会用作对齐措施 — 但其实这会改变数字的意义!八进制语法很少有用并且可能会错误使用,所以严格模式下八进制语法会引起语法错误:

    "use strict";
     var sum = 015 + // !!! 语法错误
    @@ -141,7 +141,7 @@ 

    将过失错误转成异常

    142;
    -

    第七,ECMAScript 6中的严格模式禁止设置{{Glossary("primitive")}}值的属性.不采用严格模式,设置属性将会简单忽略(no-op),采用严格模式,将抛出{{jsxref("TypeError")}}错误

    +

    第七,ECMAScript 6 中的严格模式禁止设置{{Glossary("primitive")}}值的属性。不采用严格模式,设置属性将会简单忽略 (no-op),采用严格模式,将抛出{{jsxref("TypeError")}}错误

    (function() {
       "use strict";
    @@ -153,22 +153,22 @@ 

    将过失错误转成异常

    简化变量的使用

    -

    严格模式简化了代码中变量名字映射到变量定义的方式. 很多编译器的优化是依赖存储变量X位置的能力:这对全面优化JavaScript代码至关重要. JavaScript有些情况会使得代码中名字到变量定义的基本映射只在运行时才产生. 严格模式移除了大多数这种情况的发生, 所以编译器可以更好的优化严格模式的代码.

    +

    严格模式简化了代码中变量名字映射到变量定义的方式。很多编译器的优化是依赖存储变量 X 位置的能力:这对全面优化 JavaScript 代码至关重要. JavaScript 有些情况会使得代码中名字到变量定义的基本映射只在运行时才产生。严格模式移除了大多数这种情况的发生,所以编译器可以更好的优化严格模式的代码。

    -

    第一, 严格模式禁用 withwith所引起的问题是块内的任何名称可以映射(map)到with传进来的对象的属性, 也可以映射到包围这个块的作用域内的变量(甚至是全局变量), 这一切都是在运行时决定的: 在代码运行之前是无法得知的. 严格模式下, 使用 with 会引起语法错误, 所以就不会存在 with 块内的变量在运行时才决定引用到哪里的情况了:

    +

    第一,严格模式禁用 withwith所引起的问题是块内的任何名称可以映射 (map) 到 with 传进来的对象的属性,也可以映射到包围这个块的作用域内的变量 (甚至是全局变量), 这一切都是在运行时决定的:在代码运行之前是无法得知的. 严格模式下,使用 with 会引起语法错误,所以就不会存在 with 块内的变量在运行时才决定引用到哪里的情况了:

    "use strict";
     var x = 17;
     with (obj) { // !!! 语法错误
    -  // 如果没有开启严格模式,with中的这个x会指向with上面的那个x,还是obj.x?
    +  // 如果没有开启严格模式,with 中的这个 x 会指向 with 上面的那个 x,还是 obj.x?
       // 如果不运行代码,我们无法知道,因此,这种代码让引擎无法进行优化,速度也就会变慢。
       x;
     }
     
    -

    一种取代 with的简单方法是,将目标对象赋给一个短命名变量,然后访问这个变量上的相应属性.

    +

    一种取代 with的简单方法是,将目标对象赋给一个短命名变量,然后访问这个变量上的相应属性。

    -

    第二, 严格模式下的 eval 不再为上层范围(surrounding scope,注:包围eval代码块的范围)引入新变量. 在正常模式下,  代码 eval("var x;") 会给上层函数(surrounding function)或者全局引入一个新的变量 x . 这意味着, 一般情况下,  在一个包含 eval 调用的函数内所有没有引用到参数或者局部变量的名称都必须在运行时才能被映射到特定的定义 (因为 eval 可能引入的新变量会覆盖它的外层变量). 在严格模式下 eval 仅仅为被运行的代码创建变量, 所以 eval 不会使得名称映射到外部变量或者其他局部变量:

    +

    第二,严格模式下的 eval 不再为上层范围 (surrounding scope,注:包围 eval 代码块的范围) 引入新变量. 在正常模式下, 代码 eval("var x;") 会给上层函数 (surrounding function) 或者全局引入一个新的变量 x . 这意味着,一般情况下, 在一个包含 eval 调用的函数内所有没有引用到参数或者局部变量的名称都必须在运行时才能被映射到特定的定义 (因为 eval 可能引入的新变量会覆盖它的外层变量). 在严格模式下 eval 仅仅为被运行的代码创建变量,所以 eval 不会使得名称映射到外部变量或者其他局部变量:

    var x = 17;
     var evalX = eval("'use strict'; var x = 42; x");
    @@ -176,19 +176,19 @@ 

    简化变量的使用

    console.assert(evalX === 42);
    -

    相应的, 如果函数 eval 被在严格模式下的eval(...)以表达式的形式调用时, 其代码会被当做严格模式下的代码执行. 当然也可以在代码中显式开启严格模式, 但这样做并不是必须的.

    +

    相应的,如果函数 eval 被在严格模式下的eval(...)以表达式的形式调用时,其代码会被当做严格模式下的代码执行。当然也可以在代码中显式开启严格模式,但这样做并不是必须的。

    function strict1(str) {
       "use strict";
    -  return eval(str); // str中的代码在严格模式下运行
    +  return eval(str); // str 中的代码在严格模式下运行
     }
     function strict2(f, str) {
       "use strict";
    -  return f(str); // 没有直接调用eval(...): 当且仅当str中的代码开启了严格模式时
    +  return f(str); // 没有直接调用 eval(...): 当且仅当 str 中的代码开启了严格模式时
                      // 才会在严格模式下运行
     }
     function nonstrict(str) {
    -  return eval(str); // 当且仅当str中的代码开启了"use strict",str中的代码才会在严格模式下运行
    +  return eval(str); // 当且仅当 str 中的代码开启了"use strict",str 中的代码才会在严格模式下运行
     }
     
     strict1("'Strict mode code!'");
    @@ -201,7 +201,7 @@ 

    简化变量的使用

    因此,在 eval 执行的严格模式代码下,变量的行为与严格模式下非 eval 执行的代码中的变量相同。

    -

    第三, 严格模式禁止删除声明变量。delete name 在严格模式下会引起语法错误:

    +

    第三,严格模式禁止删除声明变量。delete name 在严格模式下会引起语法错误:

    "use strict";
     
    @@ -213,9 +213,9 @@ 

    简化变量的使用

    evalarguments变的简单

    -

    严格模式让argumentseval少了一些奇怪的行为。两者在通常的代码中都包含了很多奇怪的行为: eval会添加删除绑定,改变绑定好的值,还会通过用它索引过的属性给形参取别名的方式修改形参. 虽然在未来的ECMAScript版本解决这个问题之前,是不会有补丁来完全修复这个问题,但严格模式下将eval和arguments作为关键字对于此问题的解决是很有帮助的。

    +

    严格模式让argumentseval少了一些奇怪的行为。两者在通常的代码中都包含了很多奇怪的行为: eval会添加删除绑定,改变绑定好的值,还会通过用它索引过的属性给形参取别名的方式修改形参。虽然在未来的 ECMAScript 版本解决这个问题之前,是不会有补丁来完全修复这个问题,但严格模式下将 eval 和 arguments 作为关键字对于此问题的解决是很有帮助的。

    -

    第一, 名称 eval 和 arguments 不能通过程序语法被绑定(be bound)或赋值. 以下的所有尝试将引起语法错误:

    +

    第一,名称 eval 和 arguments 不能通过程序语法被绑定 (be bound) 或赋值。以下的所有尝试将引起语法错误:

    "use strict";
     eval = 17;
    @@ -251,9 +251,9 @@ 

    evalarguments<

    "安全的" JavaScript

    -

    严格模式下更容易写出“安全”的JavaScript。现在有些网站提供了方式给用户编写能够被网站其他用户执行的JavaScript代码。在浏览器环境下,JavaScript能够获取用户的隐私信息,因此这类Javascript必须在运行前部分被转换成需要申请访问禁用功能的权限。没有很多的执行时检查的情况,Javascript的灵活性让它无法有效率地做这件事。一些语言中的函数普遍出现,以至于执行时检查他们会引起严重的性能损耗。做一些在严格模式下发生的小改动,要求用户提交的JavaScript开启严格模式并且用特定的方式调用,就会大大减少在执行时进行检查的必要。

    +

    严格模式下更容易写出“安全”的 JavaScript。现在有些网站提供了方式给用户编写能够被网站其他用户执行的 JavaScript 代码。在浏览器环境下,JavaScript 能够获取用户的隐私信息,因此这类 Javascript 必须在运行前部分被转换成需要申请访问禁用功能的权限。没有很多的执行时检查的情况,Javascript 的灵活性让它无法有效率地做这件事。一些语言中的函数普遍出现,以至于执行时检查他们会引起严重的性能损耗。做一些在严格模式下发生的小改动,要求用户提交的 JavaScript 开启严格模式并且用特定的方式调用,就会大大减少在执行时进行检查的必要。

    -

    第一,在严格模式下通过this传递给一个函数的值不会被强制转换为一个对象。对一个普通的函数来说,this总会是一个对象:不管调用时this它本来就是一个对象;还是用布尔值,字符串或者数字调用函数时函数里面被封装成对象的this;还是使用undefined或者null调用函数式this代表的全局对象(使用callapply或者bind方法来指定一个确定的this)。这种自动转化为对象的过程不仅是一种性能上的损耗,同时在浏览器中暴露出全局对象也会成为安全隐患,因为全局对象提供了访问那些所谓安全的JavaScript环境必须限制的功能的途径。所以对于一个开启严格模式的函数,指定的this不再被封装为对象,而且如果没有指定this的话它值是undefined

    +

    第一,在严格模式下通过this传递给一个函数的值不会被强制转换为一个对象。对一个普通的函数来说,this总会是一个对象:不管调用时this它本来就是一个对象;还是用布尔值,字符串或者数字调用函数时函数里面被封装成对象的this;还是使用undefined或者null调用函数式this代表的全局对象(使用callapply或者bind方法来指定一个确定的this)。这种自动转化为对象的过程不仅是一种性能上的损耗,同时在浏览器中暴露出全局对象也会成为安全隐患,因为全局对象提供了访问那些所谓安全的 JavaScript 环境必须限制的功能的途径。所以对于一个开启严格模式的函数,指定的this不再被封装为对象,而且如果没有指定this的话它值是undefined

    "use strict";
     function fun() { return this; }
    @@ -264,7 +264,7 @@ 

    "安全的" JavaScript

    console.assert(fun.bind(true)() === true);
    -

    第二,在严格模式中再也不能通过广泛实现的ECMAScript扩展“游走于”JavaScript的栈中。在普通模式下用这些扩展的话,当一个叫fun的函数正在被调用的时候,fun.caller是最后一个调用fun的函数,而且fun.arguments包含调用fun时用的形参。这两个扩展接口对于“安全”JavaScript而言都是有问题的,因为他们允许“安全的”代码访问"专有"函数和他们的(通常是没有经过保护的)形参。如果fun在严格模式下,那么fun.callerfun.arguments都是不可删除的属性而且在存值、取值时都会报错:

    +

    第二,在严格模式中再也不能通过广泛实现的 ECMAScript 扩展“游走于”JavaScript 的栈中。在普通模式下用这些扩展的话,当一个叫fun的函数正在被调用的时候,fun.caller是最后一个调用fun的函数,而且fun.arguments包含调用fun时用的形参。这两个扩展接口对于“安全”JavaScript 而言都是有问题的,因为他们允许“安全的”代码访问"专有"函数和他们的(通常是没有经过保护的)形参。如果fun在严格模式下,那么fun.callerfun.arguments都是不可删除的属性而且在存值、取值时都会报错:

    function restricted() {
       "use strict";
    @@ -279,7 +279,7 @@ 

    "安全的" JavaScript

    privilegedInvoker();
    -

    第三,严格模式下的arguments不会再提供访问与调用这个函数相关的变量的途径。在一些旧时的ECMAScript实现中arguments.caller曾经是一个对象,里面存储的属性指向那个函数的变量。这是一个安全隐患,因为它通过函数抽象打破了本来被隐藏起来的保留值;它同时也是引起大量优化工作的原因。出于这些原因,现在的浏览器没有实现它。但是因为它这种历史遗留的功能,arguments.caller在严格模式下同样是一个不可被删除的属性,在赋值或者取值时会报错:

    +

    第三,严格模式下的arguments不会再提供访问与调用这个函数相关的变量的途径。在一些旧时的 ECMAScript 实现中arguments.caller曾经是一个对象,里面存储的属性指向那个函数的变量。这是一个安全隐患,因为它通过函数抽象打破了本来被隐藏起来的保留值;它同时也是引起大量优化工作的原因。出于这些原因,现在的浏览器没有实现它。但是因为它这种历史遗留的功能,arguments.caller在严格模式下同样是一个不可被删除的属性,在赋值或者取值时会报错:

    "use strict";
     function fun(a, b) {
    @@ -287,12 +287,12 @@ 

    "安全的" JavaScript

    var v = 12; return arguments.caller; // 抛出类型错误 } -fun(1, 2); // 不会暴露v(或者a,或者b) +fun(1, 2); // 不会暴露 v(或者 a,或者 b)
    -

    为未来的ECMAScript版本铺平道路

    +

    为未来的 ECMAScript 版本铺平道路

    -

    未来版本的ECMAScript很有可能会引入新语法,ECMAScript5中的严格模式就提早设置了一些限制来减轻之后版本改变产生的影响。如果提早使用了严格模式中的保护机制,那么做出改变就会变得更容易。

    +

    未来版本的 ECMAScript 很有可能会引入新语法,ECMAScript5 中的严格模式就提早设置了一些限制来减轻之后版本改变产生的影响。如果提早使用了严格模式中的保护机制,那么做出改变就会变得更容易。

    第一,在严格模式中一部分字符变成了保留的关键字。这些字符包括implements, interface, let, package, private, protected, public, staticyield。在严格模式下,你不能再用这些名字作为变量名或者形参名。

    @@ -310,9 +310,9 @@

    为未来的ECMAScript版本 function fun(static) { 'use strict'; } // !!!

    -

    两个针对Mozilla开发的警告:第一,如果你的JavaScript版本在1.7及以上(你的chrome代码或者你正确使用了<script type="">)并且开启了严格模式的话,因为letyield是最先引入的关键字,所以它们会起作用。但是网络上用<script src="">或者<script>...</script>加载的代码,let或者yield都不会作为关键字起作用;第二,尽管ES5无条件的保留了class, enum, export, extends, importsuper关键字,在Firefox 5之前,Mozilla仅仅在严格模式中保留了它们。

    +

    两个针对 Mozilla 开发的警告:第一,如果你的 JavaScript 版本在 1.7 及以上(你的 chrome 代码或者你正确使用了<script type="">)并且开启了严格模式的话,因为letyield是最先引入的关键字,所以它们会起作用。但是网络上用<script src="">或者<script>...</script>加载的代码,let或者yield都不会作为关键字起作用;第二,尽管 ES5 无条件的保留了class, enum, export, extends, importsuper关键字,在 Firefox 5 之前,Mozilla 仅仅在严格模式中保留了它们。

    -

    第二,严格模式禁止了不在脚本或者函数层面上的函数声明。在浏览器的普通代码中,在“所有地方”的函数声明都是合法的。这并不在ES5规范中(甚至是ES3)!这是一种针对不同浏览器中不同语义的一种延伸。未来的ECMAScript版本很有希望制定一个新的,针对不在脚本或者函数层面进行函数声明的语法。在严格模式下禁止这样的函数声明对于将来ECMAScript版本的推出扫清了障碍:

    +

    第二,严格模式禁止了不在脚本或者函数层面上的函数声明。在浏览器的普通代码中,在“所有地方”的函数声明都是合法的。这并不在 ES5 规范中(甚至是 ES3)!这是一种针对不同浏览器中不同语义的一种延伸。未来的 ECMAScript 版本很有希望制定一个新的,针对不在脚本或者函数层面进行函数声明的语法。在严格模式下禁止这样的函数声明对于将来 ECMAScript 版本的推出扫清了障碍:

    "use strict";
     if (true) {
    @@ -330,11 +330,11 @@ 

    为未来的ECMAScript版本 }

    -

    这种禁止放到严格模式中并不是很合适,因为这样的函数声明方式从ES5中延伸出来的。但这是ECMAScript委员会推荐的做法,浏览器就实现了这一点。

    +

    这种禁止放到严格模式中并不是很合适,因为这样的函数声明方式从 ES5 中延伸出来的。但这是 ECMAScript 委员会推荐的做法,浏览器就实现了这一点。

    浏览器的严格模式

    -

    主流浏览器现在实现了严格模式。但是不要盲目的依赖它,因为市场上仍然有大量的浏览器版本只部分支持严格模式或者根本就不支持(比如IE10之前的版本)。严格模式改变了语义。依赖这些改变可能会导致没有实现严格模式的浏览器中出现问题或者错误。谨慎地使用严格模式,通过检测相关代码的功能保证严格模式不出问题。最后,记得在支持或者不支持严格模式的浏览器中测试你的代码。如果你只在不支持严格模式的浏览器中测试,那么在支持的浏览器中就很有可能出问题,反之亦然。

    +

    主流浏览器现在实现了严格模式。但是不要盲目的依赖它,因为市场上仍然有大量的浏览器版本只部分支持严格模式或者根本就不支持(比如 IE10 之前的版本)。严格模式改变了语义。依赖这些改变可能会导致没有实现严格模式的浏览器中出现问题或者错误。谨慎地使用严格模式,通过检测相关代码的功能保证严格模式不出问题。最后,记得在支持或者不支持严格模式的浏览器中测试你的代码。如果你只在不支持严格模式的浏览器中测试,那么在支持的浏览器中就很有可能出问题,反之亦然。

    规范

    diff --git a/files/zh-cn/web/javascript/reference/strict_mode/transitioning_to_strict_mode/index.html b/files/zh-cn/web/javascript/reference/strict_mode/transitioning_to_strict_mode/index.html index c9675cff792ebd..d119062919c44b 100644 --- a/files/zh-cn/web/javascript/reference/strict_mode/transitioning_to_strict_mode/index.html +++ b/files/zh-cn/web/javascript/reference/strict_mode/transitioning_to_strict_mode/index.html @@ -5,9 +5,9 @@ ---

    {{jsSidebar("More")}}

    -

    ECMAScript 5 引入了 strict mode ,现在已经被大多浏览器实现(包括IE10. 会使web浏览器更容易的解析代码(只需要添加 "use strict"; 在源码的最上面), 由现有的代码到严格模式的过渡需要一些事做.

    +

    ECMAScript 5 引入了 strict mode ,现在已经被大多浏览器实现 (包括 IE10. 会使 web 浏览器更容易的解析代码 (只需要添加 "use strict"; 在源码的最上面), 由现有的代码到严格模式的过渡需要一些事做。

    -

    该文章旨在为开发者提供指南.

    +

    该文章旨在为开发者提供指南。

    逐步过渡

    @@ -17,19 +17,19 @@

    非严格模式到严格模式

    语法错误

    -

    如果代码中使用"use strict"开启了严格模式,则下面的情况都会在脚本运行之前抛出SyntaxError异常:

    +

    如果代码中使用"use strict"开启了严格模式,则下面的情况都会在脚本运行之前抛出SyntaxError异常:

      -
    • 八进制语法:var n = 023和var s = "\047"
    • +
    • 八进制语法:var n = 023 和 var s = "\047"
    • with语句
    • -
    • 使用delete删除一个变量名(而不是属性名):delete myVariable
    • +
    • 使用delete删除一个变量名 (而不是属性名):delete myVariable
    • 使用evalarguments作为变量名或函数名
    • -
    • 使用未来保留字(也许会在ECMAScript 6中使用):implements, interface, let, package, private, protected, public, static,和yield作为变量名或函数名
    • -
    • 在语句块中使用函数声明:if(a<b){ function f(){} }
    • +
    • 使用未来保留字 (也许会在 ECMAScript 6 中使用):implements, interface, let, package, private, protected, public, static,和yield作为变量名或函数名
    • +
    • 在语句块中使用函数声明:if(a<b){ function f(){} }
    • 其他错误
        -
      • 对象字面量中使用两个相同的属性名:{a: 1, b: 3, a: 7}
      • -
      • 函数形参中使用两个相同的参数名:function f(a, b, b){}
      • +
      • 对象字面量中使用两个相同的属性名:{a: 1, b: 3, a: 7}
      • +
      • 函数形参中使用两个相同的参数名:function f(a, b, b){}
    @@ -38,7 +38,7 @@

    语法错误

    新的运行时错误

    -

    JavaScript曾经会在一些上下文的某些情况中静默的失败,严格模式会在这些情况下抛出错误。如果你的代码包含这样的场景,请务必测试以确保没有代码受到影响。再说一次,严格模式是可以设置在代码粒度下的。

    +

    JavaScript 曾经会在一些上下文的某些情况中静默的失败,严格模式会在这些情况下抛出错误。如果你的代码包含这样的场景,请务必测试以确保没有代码受到影响。再说一次,严格模式是可以设置在代码粒度下的。

    给一个未声明的变量赋值

    @@ -67,11 +67,11 @@

    尝试删除一个不可配置 delete Object.prototype; // error!

    -

    在非严格模式中,这样的代码只会静默失败,这样可能会导致用户误以为删除操作成功了.

    +

    在非严格模式中,这样的代码只会静默失败,这样可能会导致用户误以为删除操作成功了。

    -

    arguments对象和函数属性

    +

    arguments 对象和函数属性

    -

    在严格模式下,访问arguments.callee, arguments.caller, anyFunction.caller以及anyFunction.arguments都会抛出异常.唯一合法的使用应该是在其中命名一个函数并且重用之

    +

    在严格模式下,访问arguments.callee, arguments.caller, anyFunction.caller以及anyFunction.arguments都会抛出异常。唯一合法的使用应该是在其中命名一个函数并且重用之

    // example taken from vanillajs: http://vanilla-js.com/
     var s = document.getElementById('thing').style;
    @@ -83,7 +83,7 @@ 

    arguments对象和函数属性

    setTimeout(arguments.callee, 40); })();
    -

    可以重新写成:

    +

    可以重新写成:

    "use strict";
     var s = document.getElementById('thing').style;
    @@ -101,28 +101,28 @@ 

    语义差异

    函数调用中的this

    -

    在普通的函数调用f()中,this的值会指向全局对象.在严格模式中,this的值会指向undefined.当函数通过callapply调用时,如果传入的thisvalue参数是一个nullundefined除外的原始值(字符串,数字,布尔值),则this的值会成为那个原始值对应的包装对象,如果thisvalue参数的值是undefinednull,则this的值会指向全局对象.在严格模式中,this的值就是thisvalue参数的值,没有任何类型转换.

    +

    在普通的函数调用f() 中,this的值会指向全局对象。在严格模式中,this的值会指向undefined.当函数通过callapply调用时,如果传入的thisvalue参数是一个nullundefined除外的原始值 (字符串,数字,布尔值),则this 的值会成为那个原始值对应的包装对象,如果thisvalue参数的值是undefinednull,则this 的值会指向全局对象.在严格模式中,this 的值就是thisvalue参数的值,没有任何类型转换。

    arguments对象属性不与对应的形参变量同步更新

    -

    在非严格模式中,修改arguments对象中某个索引属性的值,和这个属性对应的形参变量的值也会同时变化,反之亦然.这会让JavaScript的代码混淆引擎让代码变得更难读和理解。在严格模式中arguments 对象会以形参变量的拷贝的形式被创建和初始化,因此 arguments 对象的改变不会影响形参。

    +

    在非严格模式中,修改arguments对象中某个索引属性的值,和这个属性对应的形参变量的值也会同时变化,反之亦然。这会让 JavaScript 的代码混淆引擎让代码变得更难读和理解。在严格模式中arguments 对象会以形参变量的拷贝的形式被创建和初始化,因此 arguments 对象的改变不会影响形参。

    -

    eval相关的区别

    +

    eval 相关的区别

    -

    在严格模式中,eval不会在当前的作用域内创建新的变量.另外,传入eval的字符串参数也会按照严格模式来解析.你需要全面测试来确保没有代码收到影响。另外,如果你并不是为了解决一个非常实际的解决方案中,尽量不要使用eval。

    +

    在严格模式中,eval不会在当前的作用域内创建新的变量。另外,传入 eval 的字符串参数也会按照严格模式来解析。你需要全面测试来确保没有代码收到影响。另外,如果你并不是为了解决一个非常实际的解决方案中,尽量不要使用eval。

    严格中立的代码

    -

    迁移严格代码至严格模式的一个潜在消极面是,在遗留的老版本浏览器上,由于没有实现严格模式,javascript语义可能会有所不同。在一些罕见的机会下(比如差劲的关联关系或者代码最小化),你的代码可能不能按照你书写或者测试里的模式那样运行。这里有一些让你的代码保持中立的规范:

    +

    迁移严格代码至严格模式的一个潜在消极面是,在遗留的老版本浏览器上,由于没有实现严格模式,javascript 语义可能会有所不同。在一些罕见的机会下(比如差劲的关联关系或者代码最小化),你的代码可能不能按照你书写或者测试里的模式那样运行。这里有一些让你的代码保持中立的规范:

    1. 按照严格模式书写你的代码,并且确保你的代码不会发生仅仅在严格模式下发生的错误(比如上文所说的运行时错误
    2. 远离语义差异
      1. eval: 仅仅在你知道你在干什么的情况下使用它
      2. -
      3. arguments: 总是通过形参的名字获取函数参数,或者在函数的第一行拷贝arguments 
        +
      4. arguments: 总是通过形参的名字获取函数参数,或者在函数的第一行拷贝 arguments 
        var args = Array.prototype.slice.call(arguments)
      5. -
      6. this: 仅在this指向你自己创建的对象时使用它 
      7. +
      8. this: 仅在 this 指向你自己创建的对象时使用它 
    diff --git a/files/zh-cn/web/javascript/reference/template_literals/index.html b/files/zh-cn/web/javascript/reference/template_literals/index.html index 878f8762174293..3bc62b3ae0bcd3 100644 --- a/files/zh-cn/web/javascript/reference/template_literals/index.html +++ b/files/zh-cn/web/javascript/reference/template_literals/index.html @@ -11,7 +11,7 @@ ---
    {{JsSidebar("More")}} 
    -

    模板字面量 是允许嵌入表达式的字符串字面量。你可以使用多行字符串和字符串插值功能。它们在ES2015规范的先前版本中被称为“模板字符串”。

    +

    模板字面量 是允许嵌入表达式的字符串字面量。你可以使用多行字符串和字符串插值功能。它们在 ES2015 规范的先前版本中被称为“模板字符串”。

    语法

    @@ -85,7 +85,7 @@

    嵌套模板

    '' : item.isCollapsed ? ' icon-expander' : ' icon-collapser');
    -

    在ES2015中使用模板文字而没有嵌套:

    +

    在 ES2015 中使用模板文字而没有嵌套:

    const classes = `header ${ isLargeScreen() ? '' :
         (item.isCollapsed ? 'icon-expander' : 'icon-collapser') }`;
    @@ -93,7 +93,7 @@ 

    嵌套模板

     

    -

    在ES2015的嵌套模板字面量中:

    +

    在 ES2015 的嵌套模板字面量中:

     

    @@ -177,25 +177,25 @@

    原始字符串

    带标签的模版字面量及转义序列

    -

    自ES2016起,带标签的模版字面量遵守以下转义序列的规则:

    +

    自 ES2016 起,带标签的模版字面量遵守以下转义序列的规则:

      -
    • Unicode字符以"\u"开头,例如\u00A9
    • -
    • Unicode码位用"\u{}"表示,例如\u{2F804}
    • +
    • Unicode 字符以"\u"开头,例如\u00A9
    • +
    • Unicode 码位用"\u{}"表示,例如\u{2F804}
    • 十六进制以"\x"开头,例如\xA9
    • 八进制以"\"和数字开头,例如\251
    -

    这表示类似下面这种带标签的模版是有问题的,因为对于每一个ECMAScript语法,解析器都会去查找有效的转义序列,但是只能得到这是一个形式错误的语法:

    +

    这表示类似下面这种带标签的模版是有问题的,因为对于每一个 ECMAScript 语法,解析器都会去查找有效的转义序列,但是只能得到这是一个形式错误的语法:

    latex`\unicode`
    -// 在较老的ECMAScript版本中报错(ES2016及更早)
    +// 在较老的 ECMAScript 版本中报错(ES2016 及更早)
     // SyntaxError: malformed Unicode character escape sequence
     
    -

    ES2018关于非法转义序列的修订

    +

    ES2018 关于非法转义序列的修订

    -

    带标签的模版字符串应该允许嵌套支持常见转义序列的语言(例如DSLsLaTeX)。ECMAScript提议模版字面量修订(第4阶段,将要集成到ECMAScript 2018标准) 移除对ECMAScript在带标签的模版字符串中转义序列的语法限制。

    +

    带标签的模版字符串应该允许嵌套支持常见转义序列的语言(例如DSLsLaTeX)。ECMAScript 提议模版字面量修订(第 4 阶段,将要集成到 ECMAScript 2018 标准) 移除对 ECMAScript 在带标签的模版字符串中转义序列的语法限制。

    不过,非法转义序列在"cooked"当中仍然会体现出来。它们将以 {{jsxref("undefined")}} 元素的形式存在于"cooked"之中: