From 01b0e12ba27b5069248fd09235e9a7143915ee30 Mon Sep 17 00:00:00 2001 From: Irvin Date: Wed, 16 Feb 2022 02:02:49 +0800 Subject: remove `notranslate` class in zh-CN --- .../guide/details_of_the_object_model/index.html | 92 +++++++++++----------- .../guide/expressions_and_operators/index.html | 86 ++++++++++---------- .../web/javascript/guide/functions/index.html | 74 ++++++++--------- .../javascript/guide/grammar_and_types/index.html | 92 +++++++++++----------- .../guide/indexed_collections/index.html | 90 ++++++++++----------- .../web/javascript/guide/introduction/index.html | 4 +- .../javascript/guide/meta_programming/index.html | 12 +-- .../javascript/guide/numbers_and_dates/index.html | 28 +++---- .../regular_expressions/assertions/index.html | 16 ++-- .../character_classes/index.html | 6 +- .../groups_and_ranges/index.html | 6 +- .../guide/regular_expressions/index.html | 38 ++++----- .../regular_expressions/quantifiers/index.html | 8 +- .../unicode_property_escapes/index.html | 10 +-- .../javascript/guide/text_formatting/index.html | 30 +++---- .../web/javascript/guide/using_promises/index.html | 54 ++++++------- 16 files changed, 323 insertions(+), 323 deletions(-) (limited to 'files/zh-cn/web/javascript/guide') diff --git a/files/zh-cn/web/javascript/guide/details_of_the_object_model/index.html b/files/zh-cn/web/javascript/guide/details_of_the_object_model/index.html index 5beb697684..36f626ed0e 100644 --- a/files/zh-cn/web/javascript/guide/details_of_the_object_model/index.html +++ b/files/zh-cn/web/javascript/guide/details_of_the_object_model/index.html @@ -121,7 +121,7 @@ translation_of: Web/JavaScript/Guide/Details_of_the_Object_Model -
+    
 function Employee () {
   this.name = "";
   this.dept = "general";
@@ -129,7 +129,7 @@ function Employee () {
 
-
+    
 public class Employee {
    public String name = "";
    public String dept = "general";
@@ -151,7 +151,7 @@ public class Employee {
  
   
    
-    
+    
 function Manager() {
   Employee.call(this);
   this.reports = [];
@@ -165,7 +165,7 @@ function WorkerBee() {
 WorkerBee.prototype = Object.create(Employee.prototype);
-
+    
 public class Manager extends Employee {
    public Employee[] reports = new Employee[0];
 }
@@ -192,7 +192,7 @@ public class WorkerBee extends Employee {
  
   
    
-    
+    
 function SalesPerson() {
    WorkerBee.call(this);
    this.dept = 'sales';
@@ -208,7 +208,7 @@ function Engineer() {
 Engineer.prototype = Object.create(WorkerBee.prototype);
-
+    
 public class SalesPerson extends WorkerBee {
    public String dept = "sales";
    public double quota = 100.0;
@@ -240,7 +240,7 @@ public class Engineer extends WorkerBee {
 
 

个别对象

-
var jim = new Employee; // 如构造函数无须接受任何参数,圆括号可以省略。
+
var jim = new Employee; // 如构造函数无须接受任何参数,圆括号可以省略。
 // jim.name is ''
 // jim.dept is 'general'
 
@@ -274,14 +274,14 @@ var jane = new Engineer;
 
 

假设您通过如下语句创建一个mark对象作为 WorkerBee的实例:

-
var mark = new WorkerBee;
+
var mark = new WorkerBee;
 

当 JavaScript 执行 new 操作符时,它会先创建一个普通对象,并将这个普通对象中的 [[prototype]] 指向 WorkerBee.prototype ,然后再把这个普通对象设置为执行 WorkerBee 构造函数时 this  的值。该普通对象的 [[Prototype]] 决定其用于检索属性的原型链。当构造函数执行完成后,所有的属性都被设置完毕,JavaScript 返回之前创建的对象,通过赋值语句将它的引用赋值给变量 mark

这个过程不会显式的将 mark所继承的原型链中的属性作为本地属性存放在 mark 对象中。当访问属性时,JavaScript 将首先检查对象自身中是否存在该属性,如果有,则返回该属性的值。如果不存在,JavaScript会检查原型链(使用内置的 [[Prototype]] )。如果原型链中的某个对象包含该属性,则返回这个属性的值。如果遍历整条原型链都没有找到该属性,JavaScript 则认为对象中不存在该属性,返回一个 undefined。这样,mark 对象中将具有如下的属性和对应的值:

-
mark.name = "";
+
mark.name = "";
 mark.dept = "general";
 mark.projects = [];
 
@@ -290,7 +290,7 @@ mark.projects = [];

由于这些构造器不支持为实例设置特定的值,所以这些属性值仅仅是创建自 WorkerBee 的所有对象所共享的默认值。当然这些属性的值是可以修改的,所以您可以为 mark指定特定的信息,如下所示:

-
mark.name = "Doe, Mark";
+
mark.name = "Doe, Mark";
 mark.dept = "admin";
 mark.projects = ["navigator"];
@@ -298,14 +298,14 @@ mark.projects = ["navigator"];

在 JavaScript 中,您可以在运行时为任何对象添加属性,而不必受限于构造函数提供的属性。添加特定于某个对象的属性,只需要为该对象指定一个属性值,如下所示:

-
mark.bonus = 3000;
+
mark.bonus = 3000;
 

这样 mark 对象就有了 bonus 属性,而其它 WorkerBee 则没有该属性。

如果您向某个构造函数的原型对象中添加新的属性,那么该属性将添加到从这个原型中继承属性的所有对象的中。例如,可以通过如下的语句向所有雇员中添加 specialty 属性:

-
Employee.prototype.specialty = "none";
+
Employee.prototype.specialty = "none";
 

只要 JavaScript 执行了该语句,则 mark 对象也将具有 specialty 属性,其值为 "none"。下图则表示了在 Employee 原型中添加该属性,然后在 Engineer 的原型中重载该属性的效果。

@@ -332,7 +332,7 @@ mark.projects = ["navigator"];
-
+    
 function Employee (name, dept) {
   this.name = name || "";
   this.dept = dept || "general";
@@ -340,7 +340,7 @@ function Employee (name, dept) {
 
-
+    
 public class Employee {
    public String name;
    public String dept;
@@ -360,7 +360,7 @@ public class Employee {
   
   
    
-    
+    
 function WorkerBee (projs) {
   this.projects = projs || [];
 }
@@ -368,7 +368,7 @@ WorkerBee.prototype = new Employee;
 
-
+    
 public class WorkerBee extends Employee {
    public String[] projects;
    public WorkerBee () {
@@ -384,7 +384,7 @@ public class WorkerBee extends Employee {
   
   
    
-    
+    
 
 function Engineer (mach) {
    this.dept = "engineering";
@@ -394,7 +394,7 @@ Engineer.prototype = new WorkerBee;
 
-
+    
 public class Engineer extends WorkerBee {
    public String machine;
    public Engineer () {
@@ -414,7 +414,7 @@ public class Engineer extends WorkerBee {
 
 

上面使用 JavaScript 定义过程使用了一种设置默认值的特殊惯用法:

-
this.name = name || "";
+
this.name = name || "";
 

JavaScript 的逻辑或操作符(||)会对第一个参数进行判断。如果该参数值运算后结果为真,则操作符返回该值。否则,操作符返回第二个参数的值。因此,这行代码首先检查 name 是否是对name 属性有效的值。如果是,则设置其为 this.name 的值。否则,设置 this.name 的值为空的字符串。尽管这种用法乍看起来有些费解,为了简洁起见,本章将使用这种习惯用法。

@@ -425,12 +425,12 @@ public class Engineer extends WorkerBee {

使用这些定义,当创建对象的实例时,可以为本地定义的属性指定值。你可以使用以下语句创建一个新的Engineer

-
var jane = new Engineer("belau");
+
var jane = new Engineer("belau");
 

此时,Jane 的属性如下所示:

-
jane.name == "";
+
jane.name == "";
 jane.dept == "engineering";
 jane.projects == [];
 jane.machine == "belau"
@@ -445,7 +445,7 @@ jane.machine == "belau"
 
 

我们来详细看一下这些定义。这是Engineer构造函数的新定义:

-
function Engineer (name, projs, mach) {
+
function Engineer (name, projs, mach) {
   this.base = WorkerBee;
   this.base(name, "engineering", projs);
   this.machine = mach || "";
@@ -454,7 +454,7 @@ jane.machine == "belau"
 
 

假设您创建了一个新的 Engineer 对象,如下所示:

-
var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
+
var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
 

JavaScript 会按以下步骤执行:

@@ -475,7 +475,7 @@ jane.machine == "belau"

你可以认为,在 Engineer 的构造器中调用了 WorkerBee 的构造器,也就为 Engineer 对象设置好了继承关系。事实并非如此。调用 WorkerBee 构造器确保了Engineer 对象以所有在构造器中所指定的属性被调用。但是,如果后续在 Employee 或者 WorkerBee 原型中添加了属性,那些属性不会被 Engineer 对象继承。例如,假设如下语句:

-
function Engineer (name, projs, mach) {
+
function Engineer (name, projs, mach) {
   this.base = WorkerBee;
   this.base(name, "engineering", projs);
   this.machine = mach || "";
@@ -486,7 +486,7 @@ Employee.prototype.specialty = "none";
 
 

对象 jane 不会继承 specialty 属性。您必须显式地设置原型才能确保动态的继承。如果修改成如下的语句:

-
function Engineer (name, projs, mach) {
+
function Engineer (name, projs, mach) {
   this.base = WorkerBee;
   this.base(name, "engineering", projs);
   this.machine = mach || "";
@@ -504,7 +504,7 @@ Employee.prototype.specialty = "none";
  
   
    
-    
+    
 function Engineer (name, projs, mach) {
   this.base = WorkerBee;
   this.base(name, "engineering", projs);
@@ -513,7 +513,7 @@ function Engineer (name, projs, mach) {
 
-
+    
 function Engineer (name, projs, mach) {
   WorkerBee.call(this, name, "engineering", projs);
   this.machine = mach || "";
@@ -543,7 +543,7 @@ function Engineer (name, projs, mach) {
 
 

以上步骤的结果依赖于你是如何定义的。最早的例子中有如下定义:

-
function Employee () {
+
function Employee () {
   this.name = "";
   this.dept = "general";
 }
@@ -556,19 +556,19 @@ WorkerBee.prototype = new Employee;
 
 

基于这些定义,假定通过如下的语句创建 WorkerBee 的实例 amy

-
var amy = new WorkerBee;
+
var amy = new WorkerBee;
 

amy 对象将具有一个本地属性 projectsnamedept 则不是 amy 对象的本地属性,而是从 amy 对象的 __proto__ 属性获得的。因此,amy 将具有如下的属性值:

-
amy.name == "";
+
amy.name == "";
 amy.dept == "general";
 amy.projects == [];
 

现在,假设修改了与 Employee 的相关联原型中的 name 属性的值:

-
Employee.prototype.name = "Unknown"
+
Employee.prototype.name = "Unknown"
 

乍一看,你可能觉得新的值会传播给所有 Employee 的实例。然而,并非如此。

@@ -577,7 +577,7 @@ amy.projects == [];

如果想在运行时修改一个对象的属性值并且希望该值被所有该对象的后代所继承,您就不能在该对象的构造器函数中定义该属性。而应该将该属性添加到该对象所关联的原型中。例如,假设将前面的代码作如下修改:

-
function Employee () {
+
function Employee () {
   this.dept = "general";
 }
 Employee.prototype.name = "";
@@ -604,17 +604,17 @@ Employee.prototype.name = "Unknown";
 
 

每个对象都有一个 __proto__ 对象属性(除了 Object);每个函数都有一个 prototype 对象属性。因此,通过“原型继承”,对象与其它对象之间形成关系。通过比较对象的 __proto__ 属性和函数的 prototype 属性可以检测对象的继承关系。JavaScript 提供了便捷方法:instanceof 操作符可以用来将一个对象和一个函数做检测,如果对象继承自函数的原型,则该操作符返回真。例如:

-
var f = new Foo();
+
var f = new Foo();
 var isTrue = (f instanceof Foo);

作为详细一点的例子,假定我们使用和在 Inheriting properties 中相同的一组定义。创建 Engineer 对象如下:

-
var chris = new Engineer("Pigman, Chris", ["jsd"], "fiji");
+
var chris = new Engineer("Pigman, Chris", ["jsd"], "fiji");
 

对于该对象,以下所有语句均为真:

-
chris.__proto__ == Engineer.prototype;
+
chris.__proto__ == Engineer.prototype;
 chris.__proto__.__proto__ == WorkerBee.prototype;
 chris.__proto__.__proto__.__proto__ == Employee.prototype;
 chris.__proto__.__proto__.__proto__.__proto__ == Object.prototype;
@@ -623,7 +623,7 @@ chris.__proto__.__proto__.__proto__.__proto__.__proto__ == null;
 
 

基于此,可以写出一个如下所示的 instanceOf 函数:

-
function instanceOf(object, constructor) {
+
function instanceOf(object, constructor) {
    while (object != null) {
       if (object == constructor.prototype)
          return true;
@@ -642,7 +642,7 @@ chris.__proto__.__proto__.__proto__.__proto__.__proto__ == null;
 
 
-
instanceOf (chris, Engineer)
+
instanceOf (chris, Engineer)
 instanceOf (chris, WorkerBee)
 instanceOf (chris, Employee)
 instanceOf (chris, Object)
@@ -650,13 +650,13 @@ instanceOf (chris, Object)
 
 

但如下表达式为假:

-
instanceOf (chris, SalesPerson)
+
instanceOf (chris, SalesPerson)

构造器中的全局信息

在创建构造器时,在构造器中设置全局信息要小心。例如,假设希望为每一个雇员分配一个唯一标识。可能会为 Employee 使用如下定义:

-
var idCounter = 1;
+
var idCounter = 1;
 
 function Employee (name, dept) {
    this.name = name || "";
@@ -667,13 +667,13 @@ function Employee (name, dept) {
 
 

基于该定义,在创建新的 Employee 时,构造器为其分配了序列中的下一个标识符。然后递增全局的标识符计数器。因此,如果,如果随后的语句如下,则 victoria.id 为 1 而 harry.id 为 2:

-
var victoria = new Employee("Pigbert, Victoria", "pubs")
+
var victoria = new Employee("Pigbert, Victoria", "pubs")
 var harry = new Employee("Tschopik, Harry", "sales")
 

乍一看似乎没问题。但是,无论什么目的,在每一次创建 Employee 对象时,idCounter 都将被递增一次。如果创建本章中所描述的整个 Employee 层级结构,每次设置原型的时候,Employee 构造器都将被调用一次。假设有如下代码:

-
var idCounter = 1;
+
var idCounter = 1;
 
 function Employee (name, dept) {
    this.name = name || "";
@@ -700,7 +700,7 @@ var mac = new Engineer("Wood, Mac");
 
 

依赖于应用程序,计数器额外的递增可能有问题,也可能没问题。如果确实需要准确的计数器,则以下构造器可以作为一个可行的方案:

-
function Employee (name, dept) {
+
function Employee (name, dept) {
    this.name = name || "";
    this.dept = dept || "general";
    if (name)
@@ -712,7 +712,7 @@ var mac = new Engineer("Wood, Mac");
 
 

或者,您可以创建一个 Employee 的原型对象的副本以分配给 WorkerBee:

-
WorkerBee.prototype = Object.create(Employee.prototype);
+
WorkerBee.prototype = Object.create(Employee.prototype);
 // instead of WorkerBee.prototype = new Employee

没有多重继承

@@ -723,7 +723,7 @@ var mac = new Engineer("Wood, Mac");

在 JavaScript 中,可以在构造器函数中调用多个其它的构造器函数。这一点造成了多重继承的假象。例如,考虑如下语句:

-
function Hobbyist (hobby) {
+
function Hobbyist (hobby) {
    this.hobby = hobby || "scuba";
 }
 
@@ -741,7 +741,7 @@ var dennis = new Engineer("Doe, Dennis", ["collabra"], "hugo")
 
 

进一步假设使用本章前面所属的 WorkerBee 的定义。此时 dennis 对象具有如下属性:

-
dennis.name == "Doe, Dennis"
+
dennis.name == "Doe, Dennis"
 dennis.dept == "engineering"
 dennis.projects == ["collabra"]
 dennis.machine == "hugo"
@@ -750,7 +750,7 @@ dennis.hobby == "scuba"
 
 

dennis 确实从 Hobbyist 构造器中获得了 hobby 属性。但是,假设添加了一个属性到 Hobbyist 构造器的原型:

-
Hobbyist.prototype.equipment = ["mask", "fins", "regulator", "bcd"]
+
Hobbyist.prototype.equipment = ["mask", "fins", "regulator", "bcd"]
 

dennis 对象不会继承这个新属性。

diff --git a/files/zh-cn/web/javascript/guide/expressions_and_operators/index.html b/files/zh-cn/web/javascript/guide/expressions_and_operators/index.html index 1ea851d0f7..b90c70b5e0 100644 --- a/files/zh-cn/web/javascript/guide/expressions_and_operators/index.html +++ b/files/zh-cn/web/javascript/guide/expressions_and_operators/index.html @@ -33,18 +33,18 @@ translation_of: Web/JavaScript/Guide/Expressions_and_Operators

JavaScript 拥有二元和一元运算符, 和一个特殊的三元运算符(条件运算符)。一个二元运算符需要两个操作数,分别在运算符的前面和后面:

-
操作数1 运算符 操作数2
+
操作数1 运算符 操作数2
 

例如, 3+4x*y

一个一元运算符需要一个操作数,在运算符前面或后面:

-
运算符 操作数
+
运算符 操作数

-
操作数 运算符
+
操作数 运算符

例如, x++++x

@@ -136,7 +136,7 @@ translation_of: Web/JavaScript/Guide/Expressions_and_Operators

对于更复杂的赋值,解构赋值语法是一个能从数组或对象对应的数组结构或对象字面量里提取数据的 Javascript 表达式。

-
var foo = ["one", "two", "three"];
+
var foo = ["one", "two", "three"];
 
 // 不使用解构
 var one   = foo[0];
@@ -150,7 +150,7 @@ var [one, two, three] = foo;

比较运算符比较它的操作数并返回一个基于表达式是否为真的逻辑值。操作数可以是数字,字符串,逻辑,对象值。字符串比较是基于标准的字典顺序,使用Unicode值。在多数情况下,如果两个操作数不是相同的类型, JavaScript 会尝试转换它们为恰当的类型来比较。这种行为通常发生在数字作为操作数的比较。类型转换的例外是使用 ===!== 操作符,它们会执行严格的相等和不相等比较。这些运算符不会在检查相等之前转换操作数的类型。下面的表格描述了该示例代码中的各比较运算符

-
var var1 = 3;
+
var var1 = 3;
 var var2 = 4;
@@ -224,7 +224,7 @@ var var2 = 4;

算术运算符使用数值(字面量或者变量)作为操作数并返回一个数值.标准的算术运算符就是加减乘除(+ - * /)。当操作数是浮点数时,这些运算符表现得跟它们在大多数编程语言中一样(特殊要注意的是,除零会产生{{jsxref("Infinity")}})。例如:

-
1 / 2;  // 0.5
+
1 / 2;  // 0.5
 1 / 2 == 1.0 / 2.0; // true
 
@@ -378,7 +378,7 @@ var var2 = 4;
-
Before: 11100110111110100000000000000110000000000001
+ 
Before: 11100110111110100000000000000110000000000001
 After:              10100000000000000110000000000001
@@ -507,7 +507,7 @@ After: 10100000000000000110000000000001

下面是&&(逻辑"与")操作符的示例。

-
var a1 =  true && true;     // t && t returns true
+
var a1 =  true && true;     // t && t returns true
 var a2 =  true && false;    // t && f returns false
 var a3 = false && true;     // f && t returns false
 var a4 = false && (3 == 4); // f && f returns false
@@ -518,7 +518,7 @@ var a7 = "Cat" && false;    // t && f returns false
 
 

下面是||(逻辑"或")操作符的示例。

-
var o1 =  true || true;     // t || t returns true
+
var o1 =  true || true;     // t || t returns true
 var o2 = false || true;     // f || t returns true
 var o3 =  true || false;    // t || f returns true
 var o4 = false || (3 == 4); // f || f returns false
@@ -529,7 +529,7 @@ var o7 = "Cat" || false;    // t || f returns Cat
 
 

下面是!(逻辑"非")操作符的示例。

-
var n1 = !true;  // !t returns false
+
var n1 = !true;  // !t returns false
 var n2 = !false; // !f returns true
 var n3 = !"Cat"; // !t returns false
 
@@ -551,11 +551,11 @@ var n3 = !"Cat"; // !t returns false

例如,

-
console.log("my " + "string"); // console logs the string "my string".
+
console.log("my " + "string"); // console logs the string "my string".

简写操作符 += 也可以用来拼接字符串,例如:

-
var myString = "alpha";
+
var myString = "alpha";
 
 myString += "bet"; // 返回 "alphabet"  
 
@@ -564,14 +564,14 @@ var n3 = !"Cat"; // !t returns false

条件运算符是JavaScript中唯一需要三个操作数的运算符。运算的结果根据给定条件在两个值中取其一。语法为:

-
条件 ? 值1 : 值2
+
条件 ? 值1 : 值2
 

如果条件为真,则结果取值1。否则为值2。你能够在任何允许使用标准运算符的地方使用条件运算符。

例如,

-
var status = (age >= 18) ? "adult" : "minor";
+
var status = (age >= 18) ? "adult" : "minor";
 

age 大于等于18的时候,将“adult”赋值给 status;否则将“minor”赋值给 status

@@ -582,7 +582,7 @@ var n3 = !"Cat"; // !t returns false

例如,假如 a 是一个二维数组,每个维度各有10个元素,以下代码利用逗号操作符来同时改变两个变量的值。这段代码的功能是打印出该二维数组的对角线元素的值:

-
var x = [0,1,2,3,4,5,6,7,8,9]
+
var x = [0,1,2,3,4,5,6,7,8,9]
 var a = [x, x, x, x, x];
 
 for (var i = 0, j = 9; i <= j; i++, j--)
@@ -596,7 +596,7 @@ for (var i = 0, j = 9; i <= j; i++, j--)
 
 

delete操作符,删除一个对象的属性或者一个数组中某一个键值。语法如下:

-
delete objectName.property;
+
delete objectName.property;
 delete objectName[index];
 delete property; // legal only within a with statement
 
@@ -609,7 +609,7 @@ delete property; // legal only within a with statement

如果 delete 操作成功,属性或者元素会变成 undefined。如果 delete可行会返回true,如果不成功返回false

-
x = 42;
+
x = 42;
 var y = 43;
 myobj = new Number();
 myobj.h = 4;    // create property h
@@ -626,7 +626,7 @@ delete myobj;   // returns true (can delete if declared implicitly)
 
 

delete 删除数组中的一个元素,这个元素就不在数组中了。例如,trees[3]被删除,trees[3] 仍然可寻址并返回undefined

-
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
+
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
 delete trees[3];
 if (3 in trees) {
   // 不会被执行
@@ -635,7 +635,7 @@ if (3 in trees) {
 
 

如果想让数组中存在一个元素但是是undefined值,使用undefined关键字而不是delete操作. 如下: trees[3]分配一个undefined,但是这个数组元素仍然存在:

-
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
+
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
 trees[3] = undefined;
 if (3 in trees) {
   // this gets executed(会被执行)
@@ -646,7 +646,7 @@ if (3 in trees) {
 
 

typeof操作符 可通过下面2种方式使用:

-
typeof operand
+
typeof operand
 typeof (operand)
 
@@ -654,7 +654,7 @@ typeof (operand)

假设你定义了如下的变量:

-
var myFun = new Function("5 + 2");
+
var myFun = new Function("5 + 2");
 var shape = "round";
 var size = 1;
 var today = new Date();
@@ -662,7 +662,7 @@ var today = new Date();
 
 

typeof 操作符将会返回如下的结果:

-
typeof myFun;     // returns "function"
+
typeof myFun;     // returns "function"
 typeof shape;     // returns "string"
 typeof size;      // returns "number"
 typeof today;     // returns "object"
@@ -671,26 +671,26 @@ typeof dontExist; // returns "undefined"
 
 

对于关键词 true 和 null, typeof 操作符将会返回如下结果:

-
typeof true; // returns "boolean"
+
typeof true; // returns "boolean"
 typeof null; // returns "object"
 

对于一个数值或字符串, typeof 操作符将会返回如下结果:

-
typeof 62;            // returns "number"
+
typeof 62;            // returns "number"
 typeof 'Hello world'; // returns "string"
 

对于属性值,typeof 操作符将会返回属性所包含值的类型:

-
typeof document.lastModified; // returns "string"
+
typeof document.lastModified; // returns "string"
 typeof window.length;         // returns "number"
 typeof Math.LN2;              // returns "number"
 

对于方法和函数,typeof 操作符将会返回如下结果:

-
typeof blur;        // returns "function"
+
typeof blur;        // returns "function"
 typeof eval;        // returns "function"
 typeof parseInt;    // returns "function"
 typeof shape.split; // returns "function"
@@ -698,7 +698,7 @@ typeof shape.split; // returns "function"
 
 

对于预定义的对象,typeof 操作符将会返回如下结果:

-
typeof Date;     // returns "function"
+
typeof Date;     // returns "function"
 typeof Function; // returns "function"
 typeof Math;     // returns "object"
 typeof Option;   // returns "function"
@@ -709,7 +709,7 @@ typeof String;   // returns "function"
 
 

void 运算符运用方法如下:

-
void (expression)
+
void (expression)
 void expression
 
@@ -719,11 +719,11 @@ void expression

如下创建了一个超链接文本,当用户单击该文本时,不会有任何效果。

-
<a href="javascript:void(0)">Click here to do nothing</a>
+
<a href="javascript:void(0)">Click here to do nothing</a>

下面的代码创建了一个超链接,当用户单击它时,提交一个表单。

-
<a href="javascript:void(document.form.submit())">
+
<a href="javascript:void(document.form.submit())">
 Click here to submit</a>

关系操作符

@@ -734,14 +734,14 @@ Click here to submit</a>

in操作符,如果所指定的属性确实存在于所指定的对象中,则会返回true,语法如下:

-
propNameOrNumber in objectName
+
propNameOrNumber in objectName
 

在这里 propNameOrNumber可以是一个代表着属性名的字符串或者是一个代表着数组索引的数值表达式,而objectName则是一个对象名。

下面的例子是 in 操作的常见用法。

-
// Arrays
+
// Arrays
 var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
 0 in trees;        // returns true
 3 in trees;        // returns true
@@ -765,7 +765,7 @@ var mycar = {make: "Honda", model: "Accord", year: 1998};
 
 

如果所判别的对象确实是所指定的类型,则返回true。其语法如下:

-
objectName instanceof objectType
+
objectName instanceof objectType
 

objectName 是需要做判别的对象的名称,而objectType是假定的对象的类型, 例如{{jsxref("Date")}}或 {{jsxref("Array")}}.

@@ -774,7 +774,7 @@ var mycar = {make: "Honda", model: "Accord", year: 1998};

例如, 下面的代码使用instanceof去判断 theDay是否是一个 Date 对象. 因为theDay是一个Date对象, 所以if中的代码会执行.

-
var theDay = new Date(1995, 12, 17);
+
var theDay = new Date(1995, 12, 17);
 if (theDay instanceof Date) {
   // statements to execute
 }
@@ -891,13 +891,13 @@ if (theDay instanceof Date) {
 
 

this关键字被用于指代当前的对象,通常,this指代的是方法中正在被调用的对象。用法如下:

-
this["propertyName"]
+
this["propertyName"]
 this.propertyName
 

假设一个用于验证对象value属性的validate函数,传参有对象,最高值和最低值。

-
function validate(obj, lowval, hival){
+
function validate(obj, lowval, hival){
   if ((obj.value < lowval) || (obj.value > hival))
     console.log("Invalid Value!");
 }
@@ -905,7 +905,7 @@ this.propertyName
 
 

你可以在任何表单元素的onchange事件处理中调用validat函数,用this来指代当前的表单元素,用例如下:

-
<p>Enter a number between 18 and 99:</p>
+
<p>Enter a number between 18 and 99:</p>
 <input type="text" name="age" size=3 onChange="validate(this, 18, 99);">
 
@@ -913,7 +913,7 @@ this.propertyName

分组操作符()控制了表达式中计算的优先级. 举例来说, 你可以改变先乘除后加减的顺序,转而先计算加法。

-
var a = 1;
+
var a = 1;
 var b = 2;
 var c = 3;
 
@@ -941,7 +941,7 @@ a * c + b * c // 9

Comprehensions特性被许多编程语言所采用,该特性能够使你快速地通过一个已有的数组来创建出一个新的数组,比如:

-
[for (i of [ 1, 2, 3 ]) i*i ];
+
[for (i of [ 1, 2, 3 ]) i*i ];
 // [ 1, 4, 9 ]
 
 var abc = [ "A", "B", "C" ];
@@ -956,14 +956,14 @@ var abc = [ "A", "B", "C" ];
 
 

你可以使用new operator 创建一个自定义类型或者是预置类型的对象实例。用法如下:

-
var objectName = new objectType([param1, param2, ..., paramN]);
+
var objectName = new objectType([param1, param2, ..., paramN]);
 

super

super 关键字可以用来调用一个对象父类的函数,它在用来调用一个的父类的构造函数时非常有用,比如:

-
super([arguments]); // calls the parent constructor. super.functionOnParent([arguments]);
+
super([arguments]); // calls the parent constructor. super.functionOnParent([arguments]);

扩展语句

@@ -971,12 +971,12 @@ var abc = [ "A", "B", "C" ];

例如:现在你有一个数组,你想创建一个新数组,并将刚才那个作为它的一部分,用array的字面语法是不够的,你不得不写一些代码实现它,比如用些pushspliceconcat等等。但是用spread syntax就没问题了:

-
var parts = ['shoulder', 'knees'];
+
var parts = ['shoulder', 'knees'];
 var lyrics = ['head', ...parts, 'and', 'toes'];

类似的,扩展语句也可以用在函数调用的时候:

-
function f(x, y, z) { }
+
function f(x, y, z) { }
 var args = [0, 1, 2];
 f(...args);
diff --git a/files/zh-cn/web/javascript/guide/functions/index.html b/files/zh-cn/web/javascript/guide/functions/index.html index 3d43d61305..54e0bffa4b 100644 --- a/files/zh-cn/web/javascript/guide/functions/index.html +++ b/files/zh-cn/web/javascript/guide/functions/index.html @@ -30,21 +30,21 @@ translation_of: Web/JavaScript/Guide/Functions

例如,以下的代码定义了一个简单的square函数:

-
function square(number) {
+
function square(number) {
   return number * number;
 }
 

函数square使用了一个参数,叫作number。这个函数只有一个语句,它说明该函数将函数的参数(即number)自乘后返回。函数的return语句确定了函数的返回值:

-
return number * number;
+
return number * number;
 

原始参数(比如一个具体的数字)被作为传递给函数;值被传递给函数,如果被调用函数改变了这个参数的值,这样的改变不会影响到全局或调用函数。

如果你传递一个对象(即一个非原始值,例如{{jsxref("Array")}}或用户自定义的对象)作为参数,而函数改变了这个对象的属性,这样的改变对函数外部是可见的,如下面的例子所示:

-
function myFunc(theObject) {
+
function myFunc(theObject) {
   theObject.make = "Toyota";
 }
 
@@ -62,19 +62,19 @@ y = mycar.make;     // y获取的值为 "Toyota"
 
 

虽然上面的函数声明在语法上是一个语句,但函数也可以由函数表达式创建。这样的函数可以是匿名的;它不必有一个名称。例如,函数square也可这样来定义:

-
const square = function(number) { return number * number; };
+
const square = function(number) { return number * number; };
 var x = square(4); // x gets the value 16

然而,函数表达式也可以提供函数名,并且可以用于在函数内部代指其本身,或者在调试器堆栈跟踪中识别该函数:

-
const factorial = function fac(n) {return n<2 ? 1 : n*fac(n-1)};
+
const factorial = function fac(n) {return n<2 ? 1 : n*fac(n-1)};
 
 console.log(factorial(3));
 

当将函数作为参数传递给另一个函数时,函数表达式很方便。下面的例子演示了一个叫map的函数如何被定义,而后使用一个表达式函数作为其第一个参数进行调用:

-
function map(f,a) {
+
function map(f,a) {
   let result = []; // 创建一个数组
   let i; // 声明一个值,用来循环
   for (i = 0; i != a.length; i++)
@@ -85,7 +85,7 @@ console.log(factorial(3));
 
 

下面的代码:

-
function map(f, a) {
+
function map(f, a) {
   let result = []; // 创建一个数组
   let i; // 声明一个值,用来循环
   for (i = 0; i != a.length; i++)
@@ -103,7 +103,7 @@ console.log(cube);

在 JavaScript 中,可以根据条件来定义一个函数。比如下面的代码,当num 等于 0 的时候才会定义 myFunc :

-
var myFunc;
+
var myFunc;
 if (num == 0){
   myFunc = function(theObject) {
     theObject.make = "Toyota"
@@ -118,14 +118,14 @@ if (num == 0){
 
 

定义一个函数并不会自动的执行它。定义了函数仅仅是赋予函数以名称并明确函数被调用时该做些什么。调用函数才会以给定的参数真正执行这些动作。例如,一旦你定义了函数square,你可以如下这样调用它:

-
square(5);
+
square(5);
 

上述语句通过提供参数 5 来调用函数。函数执行完它的语句会返回值25。

函数一定要处于调用它们的域中,但是函数的声明可以被提升(出现在调用语句之后),如下例:

-
console.log(square(5));
+
console.log(square(5));
 /* ... */
 function square(n) { return n*n }
 
@@ -136,7 +136,7 @@ function square(n) { return n*n }

提示:注意只有使用如上的语法形式(即 function funcName(){})才可以。而下面的代码是无效的。就是说,函数提升仅适用于函数声明,而不适用于函数表达式。

-
console.log(square); // square is hoisted with an initial value undefined.
+
console.log(square); // square is hoisted with an initial value undefined.
 console.log(square(5)); // Uncaught TypeError: square is not a function
 const square = function (n) {
   return n * n;
@@ -146,7 +146,7 @@ const square = function (n) {
 
 

函数可以被递归,就是说函数可以调用其本身。例如,下面这个函数就是用递归计算阶乘:

-
function factorial(n){
+
function factorial(n){
   if ((n == 0) || (n == 1))
     return 1;
   else
@@ -156,7 +156,7 @@ const square = function (n) {
 
 

你可以计算1-5的阶乘如下:

-
var a, b, c, d, e;
+
var a, b, c, d, e;
 
 a = factorial(1); // 1赋值给a
 b = factorial(2); // 2赋值给b
@@ -171,7 +171,7 @@ e = factorial(5); // 120赋值给e
 
 

在函数内定义的变量不能在函数之外的任何地方访问,因为变量仅仅在该函数的域的内部有定义。相对应的,一个函数可以访问定义在其范围内的任何变量和函数。换言之,定义在全局域中的函数可以访问所有定义在全局域中的变量。在另一个函数中定义的函数也可以访问在其父函数中定义的所有变量和父函数有权访问的任何其他变量。

-
// 下面的变量定义在全局作用域(global scope)中
+
// 下面的变量定义在全局作用域(global scope)中
 var num1 = 20,
     num2 = 3,
     name = "Chamahk";
@@ -212,7 +212,7 @@ getScore(); // 返回 "Chamahk scored 5"
 
 

例如,思考一下如下的函数定义:

-
var foo = function bar() {
+
var foo = function bar() {
    // statements go here
 };
 
@@ -227,7 +227,7 @@ getScore(); // 返回 "Chamahk scored 5"

调用自身的函数我们称之为递归函数。在某种意义上说,递归近似于循环。两者都重复执行相同的代码,并且两者都需要一个终止条件(避免无限循环或者无限递归)。例如以下的循环:

-
var x = 0;
+
var x = 0;
 while (x < 10) { // "x < 10" 是循环条件
    // do stuff
    x++;
@@ -236,7 +236,7 @@ while (x < 10) { // "x < 10" 是循环条件
 
 

可以被转化成一个递归函数和对其的调用:

-
function loop(x) {
+
function loop(x) {
   if (x >= 10) // "x >= 10" 是退出条件(等同于 "!(x < 10)")
     return;
   // 做些什么
@@ -247,7 +247,7 @@ loop(0);
 
 

不过,有些算法并不能简单的用迭代来实现。例如,获取树结构中所有的节点时,使用递归实现要容易得多:

-
function walkTree(node) {
+
function walkTree(node) {
   if (node == null) //
     return;
   // do something with node
@@ -263,7 +263,7 @@ loop(0);
 
 

这种类似堆栈的行为可以在下例中看到:

-
function foo(i) {
+
function foo(i) {
   if (i < 0)
     return;
   console.log('begin:' + i);
@@ -298,7 +298,7 @@ foo(3);
 
 

下面的例子展示了嵌套函数:

-
function addSquares(a, b) {
+
function addSquares(a, b) {
   function square(x) {
     return x * x;
   }
@@ -310,7 +310,7 @@ c = addSquares(4, 5); // returns 41

由于内部函数形成了闭包,因此你可以调用外部函数并为外部函数和内部函数指定参数:

-
function outside(x) {
+
function outside(x) {
   function inside(y) {
     return x + y;
   }
@@ -333,7 +333,7 @@ result1 = outside(3)(5); // returns 8

思考一下下面的例子:

-
function A(x) {
+
function A(x) {
   function B(y) {
     function C(z) {
       console.log(x + y + z);
@@ -360,7 +360,7 @@ A(1); // logs 6 (1 + 2 + 3)

看以下的例子:

-
function outside() {
+
function outside() {
   var x = 5;
   function inside(x) {
     return x * 2;
@@ -380,7 +380,7 @@ outside()(10); // returns 20 instead of 10

此外,由于内部函数可以访问外部函数的作用域,因此当内部函数生存周期大于外部函数时,外部函数中定义的变量和函数的生存周期将比内部函数执行时间长。当内部函数以某一种方式被任何一个外部函数作用域访问时,一个闭包就产生了。

-
var pet = function(name) {          //外部函数定义了一个变量"name"
+
var pet = function(name) {          //外部函数定义了一个变量"name"
   var getName = function() {
     //内部函数可以访问 外部函数定义的"name"
     return name;
@@ -395,7 +395,7 @@ myPet();                            // 返回结果 "Vivie"
 
 

实际上可能会比上面的代码复杂的多。在下面这种情形中,返回了一个包含可以操作外部函数的内部变量方法的对象。

-
var createPet = function(name) {
+
var createPet = function(name) {
   var sex;
 
   return {
@@ -431,7 +431,7 @@ pet.getName();                  // Oliver
 
 

在上面的代码中,外部函数的name变量对内嵌函数来说是可取得的,而除了通过内嵌函数本身,没有其它任何方法可以取得内嵌的变量。内嵌函数的内嵌变量就像内嵌函数的保险柜。它们会为内嵌函数保留“稳定”——而又安全——的数据参与运行。而这些内嵌函数甚至不会被分配给一个变量,或者不必一定要有名字。

-
var getCode = (function(){
+
var getCode = (function(){
   var secureCode = "0]Eal(eh&2";    // A code we do not want outsiders to be able to modify...
 
   return function () {
@@ -445,7 +445,7 @@ getCode();    // Returns the secret code
 

尽管有上述优点,使用闭包时仍然要小心避免一些陷阱。如果一个闭包的函数定义了一个和外部函数的某个变量名称相同的变量,那么这个闭包将无法引用外部函数的这个变量。

-
var createPet = function(name) {  // Outer function defines a variable called "name"
+
var createPet = function(name) {  // Outer function defines a variable called "name"
   return {
     setName: function(name) {    // Enclosed function also defines a variable called "name"
       name = name;               // ??? How do we access the "name" defined by the outer function ???
@@ -459,7 +459,7 @@ getCode();    // Returns the secret code
 
 

函数的实际参数会被保存在一个类似数组的arguments对象中。在函数内,你可以按如下方式找出传入的参数:

-
arguments[i]
+
arguments[i]
 

其中i是参数的序数编号(译注:数组索引),以0开始。所以第一个传来的参数会是arguments[0]。参数的数量由arguments.length表示。

@@ -468,7 +468,7 @@ getCode(); // Returns the secret code

例如,设想有一个用来连接字符串的函数。唯一事先确定的参数是在连接后的字符串中用来分隔各个连接部分的字符(译注:比如例子里的分号“;”)。该函数定义如下:

-
function myConcat(separator) {
+
function myConcat(separator) {
    var result = ''; // 把值初始化成一个字符串,这样就可以用来保存字符串了!!
    var i;
    // iterate through arguments
@@ -480,7 +480,7 @@ getCode();    // Returns the secret code
 
 

你可以给这个函数传递任意数量的参数,它会将各个参数连接成一个字符串“列表”:

-
// returns "red, orange, blue, "
+
// returns "red, orange, blue, "
 myConcat(", ", "red", "orange", "blue");
 
 // returns "elephant; giraffe; lion; cheetah; "
@@ -504,7 +504,7 @@ myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");
 
 

在过去,用于设定默认参数的一般策略是在函数的主体中测试参数值是否为undefined,如果是则赋予这个参数一个默认值。如果在下面的例子中,调用函数时没有实参传递给b,那么它的值就是undefined,于是计算a*b得到、函数返回的是 NaN。但是,在下面的例子中,这个已经被第二行获取处理:

-
function multiply(a, b) {
+
function multiply(a, b) {
   b = (typeof b !== 'undefined') ?  b : 1;
 
   return a*b;
@@ -515,7 +515,7 @@ multiply(5); // 5
 
 

使用默认参数,在函数体的检查就不再需要了。现在,你可以在函数头简单地把1设定为b的默认值:

-
function multiply(a, b = 1) {
+
function multiply(a, b = 1) {
   return a*b;
 }
 
@@ -527,7 +527,7 @@ multiply(5); // 5

剩余参数语法允许将不确定数量的参数表示为数组。在下面的例子中,使用剩余参数收集从第二个到最后参数。然后,我们将这个数组的每一个数与第一个参数相乘。这个例子是使用了一个箭头函数,这将在下一节介绍。

-
function multiply(multiplier, ...theArgs) {
+
function multiply(multiplier, ...theArgs) {
   return theArgs.map(x => multiplier * x);
 }
 
@@ -544,7 +544,7 @@ console.log(arr); // [2, 4, 6]

在一些函数模式中,更简洁的函数很受欢迎。对比一下:

-
var a = [
+
var a = [
   "Hydrogen",
   "Helium",
   "Lithium",
@@ -563,7 +563,7 @@ console.log(a3); // logs [ 8, 6, 7, 9 ]

在箭头函数出现之前,每一个新函数都重新定义了自己的 this 值(在构造函数中是一个新的对象;在严格模式下是未定义的;在作为“对象方法”调用的函数中指向这个对象;等等)。以面向对象的编程风格,这样着实有点恼人。

-
function Person() {
+
function Person() {
   // 构造函数Person()将`this`定义为自身
   this.age = 0;
 
@@ -579,7 +579,7 @@ var p = new Person();

在ECMAScript 3/5里,通过把this的值赋值给一个变量可以修复这个问题。

-
function Person() {
+
function Person() {
   var self = this; // 有的人习惯用`that`而不是`self`,
                    // 无论你选择哪一种方式,请保持前后代码的一致性
   self.age = 0;
@@ -594,7 +594,7 @@ var p = new Person();

箭头函数捕捉闭包上下文的this值,所以下面的代码工作正常。

-
function Person(){
+
function Person(){
   this.age = 0;
 
   setInterval(() => {
diff --git a/files/zh-cn/web/javascript/guide/grammar_and_types/index.html b/files/zh-cn/web/javascript/guide/grammar_and_types/index.html
index 9a3aa594c3..a5e540e163 100644
--- a/files/zh-cn/web/javascript/guide/grammar_and_types/index.html
+++ b/files/zh-cn/web/javascript/guide/grammar_and_types/index.html
@@ -21,7 +21,7 @@ translation_of: Web/JavaScript/Guide/Grammar_and_types
 
 

JavaScript 是区分大小写的,并使用 Unicode 字符集。举个例子,可以将单词 Früh (在德语中意思是“早”)用作变量名。

-
var Früh = "foobar";
+
var Früh = "foobar";

但是,由于 JavaScript 是大小写敏感的,因此变量 früh 和 Früh 则是两个不同的变量。

@@ -35,7 +35,7 @@ translation_of: Web/JavaScript/Guide/Grammar_and_types

Javascript 注释的语法和 C++ 或许多其他语言类似:

-
// 单行注释
+
// 单行注释
 
 /* 这是一个更长的,
    多行注释
@@ -84,7 +84,7 @@ translation_of: Web/JavaScript/Guide/Grammar_and_types
 
 

如果访问一个未声明的变量会导致抛出一个引用错误(ReferenceError)异常:

-
var a;
+
var a;
 console.log("The value of a is " + a); // a 的值是 undefined
 
 console.log("The value of b is " + b);// b 的值是 undefined
@@ -101,7 +101,7 @@ let y;

你可以使用 undefined 来判断一个变量是否已赋值。在以下的代码中,变量input未被赋值,因此 if 条件语句的求值结果是 true 。

-
var input;
+
var input;
 if(input === undefined){
   doThis();
 } else {
@@ -111,19 +111,19 @@ if(input === undefined){
 
 

The following is related to "Variables" section as potential values in assignment.undefined 值在布尔类型环境中会被当作 false 。例如,下面的代码将会执行函数 myFunction,因为数组 myArray 中的元素未被赋值:

-
var myArray = [];
+
var myArray = [];
 if (!myArray[0])   myFunction();
 

数值类型环境中 undefined 值会被转换为 NaN

-
var a;
+
var a;
 a + 2;    // 计算为 NaN
 

当你对一个 null 变量求值时,空值 null 在数值类型环境中会被当作0来对待,而布尔类型环境中会被当作 false。例如:

-
var n = null;
+
var n = null;
 console.log(n * 32); // 在控制台中会显示 0
 
@@ -133,7 +133,7 @@ console.log(n * 32); // 在控制台中会显示 0

ECMAScript 6 之前的 JavaScript 没有 语句块 作用域;相反,语句块中声明的变量将成为语句块所在函数(或全局作用域)的局部变量。例如,如下的代码将在控制台输出 5,因为 x 的作用域是声明了 x 的那个函数(或全局范围),而不是 if 语句块。

-
if (true) {
+
if (true) {
   var x = 5;
 }
 console.log(x); // 5
@@ -141,7 +141,7 @@ console.log(x); // 5
 
 

如果使用 ECMAScript 6 中的 let 声明,上述行为将发生变化。

-
if (true) {
+
if (true) {
   let y = 5;
 }
 console.log(y); // ReferenceError: y 没有被声明
@@ -150,7 +150,7 @@ console.log(y); // ReferenceError: y 没有被声明

JavaScript 变量的另一个不同寻常的地方是,你可以先使用变量稍后再声明变量而不会引发异常。这一概念称为变量提升;JavaScript 变量感觉上是被“提升”或移到了函数或语句的最前面。但是,提升后的变量将返回 undefined 值。因此在使用或引用某个变量之后进行声明和初始化操作,这个被提升的变量仍将返回 undefined 值。

-
/**
+
/**
  * 例子1
  */
 console.log(x === undefined); // true
@@ -171,7 +171,7 @@ var myvar = "my value";
 
 

上面的例子,也可写作:

-
/**
+
/**
  * 例子1
  */
 var x;
@@ -193,14 +193,14 @@ var myvar = "my value";
 
 

在 ECMAScript 6 中,let(const)同样会被提升变量到代码块的顶部但是不会被赋予初始值。在变量声明之前引用这个变量,将抛出引用错误(ReferenceError)。这个变量将从代码块一开始的时候就处在一个“暂时性死区”,直到这个变量被声明为止。

-
console.log(x); // ReferenceError
+
console.log(x); // ReferenceError
 let x = 3;

函数提升

对于函数来说,只有函数声明会被提升到顶部,而函数表达式不会被提升。

-
/* 函数声明 */
+
/* 函数声明 */
 
 foo(); // "bar"
 
@@ -227,7 +227,7 @@ var baz = function() {
 
 

你可以用关键字 const 创建一个只读的常量。常量标识符的命名规则和变量相同:必须以字母、下划线(_)或美元符号($)开头并可以包含有字母、数字或下划线。

-
const PI = 3.14;
+
const PI = 3.14;
 

常量不可以通过重新赋值改变其值,也不可以在代码运行时重新声明。它必须被初始化为某个值。

@@ -236,7 +236,7 @@ var baz = function() {

在同一作用域中,不能使用与变量名或函数名相同的名字来命名常量。例如:

-
// 这会造成错误
+
// 这会造成错误
 function f() {};
 const f = 5;
 
@@ -251,12 +251,12 @@ function f() {
 
 

然而,对象属性被赋值为常量是不受保护的,所以下面的语句执行时不会产生错误。

-
const MY_OBJECT = {"key": "value"};
+
const MY_OBJECT = {"key": "value"};
 MY_OBJECT.key = "otherValue";

同样的,数组的被定义为常量也是不受保护的,所以下面的语句执行时也不会产生错误。

-
const MY_ARRAY = ['HTML','CSS'];
+
const MY_ARRAY = ['HTML','CSS'];
 MY_ARRAY.push('JAVASCRIPT');
 console.log(MY_ARRAY); //logs ['HTML','CSS','JAVASCRIPT'];
 
@@ -288,24 +288,24 @@ console.log(MY_ARRAY); //logs ['HTML','CSS','JAVASCRIPT'];

JavaScript是一种动态类型语言(dynamically typed language)。这意味着你在声明变量时可以不必指定数据类型,而数据类型会在代码执行时会根据需要自动转换。因此,你可以按照如下方式来定义变量:

-
var answer = 42;
+
var answer = 42;
 

然后,你还可以给同一个变量赋予一个字符串值,例如:

-
answer = "Thanks for all the fish...";
+
answer = "Thanks for all the fish...";

因为 JavaScript 是动态类型的,这种赋值方式并不会提示出错。

在包含的数字和字符串的表达式中使用加法运算符(+),JavaScript 会把数字转换成字符串。例如,观察以下语句:

-
x = "The answer is " + 42 // "The answer is 42"
+
x = "The answer is " + 42 // "The answer is 42"
 y = 42 + " is the answer" // "42 is the answer"
 

在涉及其它运算符(译注:如下面的减号'-')时,JavaScript语言不会把数字变为字符串。例如(译注:第一例是数学运算,第二例是字符串运算):

-
"37" - 7 // 30
+
"37" - 7 // 30
 "37" + 7 // "377"
 
@@ -321,7 +321,7 @@ y = 42 + " is the answer" // "42 is the answer"

将字符串转换为数字的另一种方法是使用一元加法运算符

-
"1.1" + "1.1" = "1.11.1"
+
"1.1" + "1.1" = "1.11.1"
 (+"1.1") + (+"1.1") = 2.2
 // 注意:加入括号为清楚起见,不是必需的。
 
@@ -348,7 +348,7 @@ y = 42 + " is the answer" // "42 is the answer"

下面的示例用3个元素生成数组coffees,它的长度是3。

-
var coffees = ["French Roast", "Colombian", "Kona"];
+
var coffees = ["French Roast", "Colombian", "Kona"];
 
 var a=[3];
 
@@ -368,7 +368,7 @@ console.log(a[0]); // 3

(译注:声明时)你不必列举数组字面值中的所有元素。若你在同一行中连写两个逗号(,),数组中就会产生一个没有被指定的元素,其初始值是undefined。以下示例创建了一个名为fish的数组:

-
var fish = ["Lion", , "Angel"];
+
var fish = ["Lion", , "Angel"];
 

在这个数组中,有两个已被赋值的元素,和一个空元素(fish[0]是"Lion",fish[1]是undefined,而fish[2]是"Angel";译注:此时数组的长度属性fish.length是3)。

@@ -381,17 +381,17 @@ console.log(a[0]); // 3

(译注:而“现代”的浏览器似乎鼓励这种方式,这也很好解释原因。尾部逗号可以减少向数组的最后添加元素时,因为忘记为这最后一个元素加逗号 所造成的错误。)

-
var myList = ['home', , 'school', ];
+
var myList = ['home', , 'school', ];
 

在下面的例子中,数组的长度是4,元素myList[0]myList[2]缺失(译注:没被赋值,因而是undefined)。

-
var myList = [ , 'home', , 'school'];
+
var myList = [ , 'home', , 'school'];
 

再看一个例子。在这里,该数组的长度是4,元素myList[1]myList[3]被漏掉了。(但是)只有最后的那个逗号被忽略。

-
var myList = ['home', , 'school', , ];
+
var myList = ['home', , 'school', , ];
 

理解多余的逗号(在脚本运行时会被如何处理)的含义,对于从语言层面理解JavaScript是十分重要的。但是,在你自己写代码时:显式地将缺失的元素声明为undefined,将大大提高你的代码的清晰度和可维护性

@@ -421,7 +421,7 @@ console.log(a[0]); // 3

整数字面量举例:

-
0, 117 and -345 (十进制, 基数为10)
+
0, 117 and -345 (十进制, 基数为10)
 015, 0001 and -0o77 (八进制, 基数为8)
 0x1123, 0x00111 and -0xF1A7 (十六进制, 基数为16或"hex")
 0b11, 0b0011 and -0b11 (二进制, 基数为2)
@@ -441,11 +441,11 @@ console.log(a[0]); // 3

简言之,其语法是:

-
[(+|-)][digits][.digits][(E|e)[(+|-)]digits]
+
[(+|-)][digits][.digits][(E|e)[(+|-)]digits]

例如:

-
3.14
+
3.14
 -.2345789 // -0.23456789
 -3.12e+12  // -3.12*10^12
 .1e-23    // 0.1*10^(-23)=10^(-24)=1e-24
@@ -457,7 +457,7 @@ console.log(a[0]); // 3

以下是一个对象字面值的例子。对象car的第一个元素(译注:即一个属性/值对)定义了属性myCar;第二个元素,属性getCar,引用了一个函数(即CarTypes("Honda"));第三个元素,属性special,使用了一个已有的变量(即Sales)。

-
var Sales = "Toyota";
+
var Sales = "Toyota";
 
 function CarTypes(name) {
   return (name === "Honda") ?
@@ -474,7 +474,7 @@ console.log(car.special); // Toyota
 
 

更进一步的,你可以使用数字或字符串字面值作为属性的名字,或者在另一个字面值内嵌套上一个字面值。如下的示例中使用了这些可选项。

-
var car = { manyCars: {a: "Saab", "b": "Jeep"}, 7: "Mazda" };
+
var car = { manyCars: {a: "Saab", "b": "Jeep"}, 7: "Mazda" };
 
 console.log(car.manyCars.b); // Jeep
 console.log(car[7]); // Mazda
@@ -482,7 +482,7 @@ console.log(car[7]); // Mazda
 
 

对象属性名字可以是任意字符串,包括空串。如果对象属性名字不是合法的javascript标识符,它必须用""包裹。属性的名字不合法,那么便不能用.访问属性值,而是通过类数组标记("[]")访问和赋值。

-
var unusualPropertyNames = {
+
var unusualPropertyNames = {
   "": "An empty string",
   "!": "Bang!"
 }
@@ -495,7 +495,7 @@ console.log(unusualPropertyNames["!"]); // Bang!

在ES2015,对象字面值扩展支持在创建时设置原型,简写了 foo: foo 形式的属性赋值,方法定义,支持父方法调用,以及使用表达式动态计算属性名。总之,这些也使对象字面值和类声明更加紧密地联系起来,让基于对象的设计从这些便利中更加受益。

-
var obj = {
+
var obj = {
     // __proto__
     __proto__: theProtoObj,
     // Shorthand for ‘handler: handler’
@@ -511,7 +511,7 @@ console.log(unusualPropertyNames["!"]); // Bang!

请注意:

-
var foo = {a: "alpha", 2: "two"};
+
var foo = {a: "alpha", 2: "two"};
 console.log(foo.a);    // alpha
 console.log(foo[2]);   // two
 //console.log(foo.2);  // SyntaxError: missing ) after argument list
@@ -523,13 +523,13 @@ console.log(foo["2"]); // two

一个正则表达式是字符被斜线(译注:正斜杠“/”)围成的表达式。下面是一个正则表达式文字的一个例子。

-
var re = /ab+c/;
+
var re = /ab+c/;

字符串字面量 (String literals)

字符串字面量是由双引号(")对或单引号(')括起来的零个或多个字符。字符串被限定在同种引号之间;也即,必须是成对单引号或成对双引号。下面的例子都是字符串字面值:

-
"foo"
+
"foo"
 'bar'
 "1234"
 "one line \n another line"
@@ -537,13 +537,13 @@ console.log(foo["2"]); // two

你可以在字符串字面值上使用字符串对象的所有方法——JavaScript会自动将字符串字面值转换为一个临时字符串对象,调用该方法,然后废弃掉那个临时的字符串对象。你也能用对字符串字面值使用类似String.length的属性:

-
console.log("John's cat".length)
+
console.log("John's cat".length)
 // 将打印字符串中的字符个数(包括空格)
 // 结果为:10

在ES2015中,还提供了一种模板字面量(template literals),模板字符串提供了一些语法糖来帮你构造字符串。这与Perl、Python还有其他语言中的字符串插值(string interpolation)的特性非常相似。除此之外,你可以在通过模板字符串前添加一个tag来自定义模板字符串的解析过程,这可以用来防止注入攻击,或者用来建立基于字符串的高级数据抽象。

-
// Basic literal string creation
+
// Basic literal string creation
 `In JavaScript '\n' is a line-feed.`
 
 // Multiline strings
@@ -568,7 +568,7 @@ POST`http://foo.org/bar?a=${a}&b=${b}
 
 

作为一般字符的扩展,你可以在字符串中使用特殊字符,如下例所示。

-
"one line \n another line"
+
"one line \n another line"
 

以下表格列举了你能在JavaScript的字符串中使用的特殊字符。

@@ -649,23 +649,23 @@ POST`http://foo.org/bar?a=${a}&b=${b}

通过在引号前加上反斜线'\',可以在字符串中插入引号,这就是引号转义。例如:

-
var quote = "He read \"The Cremation of Sam McGee\" by R.W. Service.";
+
var quote = "He read \"The Cremation of Sam McGee\" by R.W. Service.";
 console.log(quote);
 

代码的运行结果为:

-
He read "The Cremation of Sam McGee" by R.W. Service.
+
He read "The Cremation of Sam McGee" by R.W. Service.
 

要在字符串中插入'\'字面值,必须转义反斜线。例如,要把文件路径 c:\temp 赋值给一个字符串,可以采用如下方式:

-
var home = "c:\\temp";
+
var home = "c:\\temp";
 

也可以在换行之前加上反斜线以转义换行(译注:实际上就是一条语句拆成多行书写),这样反斜线和换行都不会出现在字符串的值中。

-
var str = "this string \
+
var str = "this string \
 is broken \
 across multiple\
 lines."
@@ -674,7 +674,7 @@ console.log(str);   // this string is broken across multiplelines.
 
 

Javascript没有“heredoc”语法,但可以用行末的换行符转义和转义的换行来近似实现 

-
var poem =
+
var poem =
 "Roses are red,\n\
 Violets are blue.\n\
 Sugar is sweet,\n\
@@ -683,7 +683,7 @@ and so is foo."
 
 

ECMAScript 2015 增加了一种新的字面量,叫做模板字面量 template literals它包含一些新特征,包括了多行字符串!

-
var poem =
+
var poem =
 `Roses are red,
 Violets are blue.
 Sugar is sweet,
diff --git a/files/zh-cn/web/javascript/guide/indexed_collections/index.html b/files/zh-cn/web/javascript/guide/indexed_collections/index.html
index fae44cbb84..600ec4ed4e 100644
--- a/files/zh-cn/web/javascript/guide/indexed_collections/index.html
+++ b/files/zh-cn/web/javascript/guide/indexed_collections/index.html
@@ -17,7 +17,7 @@ translation_of: Web/JavaScript/Guide/Indexed_collections
 
 

以下语句创建等效的数组:

-
var arr = new Array(element0, element1, ..., elementN);
+
var arr = new Array(element0, element1, ..., elementN);
 var arr = Array(element0, element1, ..., elementN);
 var arr = [element0, element1, ..., elementN];
 
@@ -30,7 +30,7 @@ var arr = [element0, element1, ..., elementN];
 
 

为了创建一个长度不为0,但是又没有任何元素的数组,可选以下任何一种方式:

-
var arr = new Array(arrayLength);
+
var arr = new Array(arrayLength);
 var arr = Array(arrayLength);
 
 // 这样有同样的效果
@@ -44,7 +44,7 @@ arr.length = arrayLength;
 
 

除了如上所示创建新定义的变量,数组(array)也可以作为一个属性(property)分配给一个新的或者已存在的对象(object):

-
var obj = {};
+
var obj = {};
 // ...
 obj.prop = [element0, element1, ..., elementN];
 
@@ -54,7 +54,7 @@ var obj = {prop: [element0, element1, ...., elementN]}
 
 

如果你希望用单个元素初始化一个数组,而这个元素恰好又是数字(Number),那么你必须使用括号语法。当单个的数字(Number)传递给Array()构造函数时,将会被解释为数组长度,并非单个元素。

-
var arr = [42];      // 创建一个只有唯一元素的数组:
+
var arr = [42];      // 创建一个只有唯一元素的数组:
                      // the number 42.
 var arr = Array(42); // 创建一个没有元素的数组,
                      // 但是数组的长度被设置成42.
@@ -66,7 +66,7 @@ arr.length = 42;
 
 

如果N不是一个整数,调用Array(N)将会报RangeError错误, 以下方法说明了这种行为:

-
var arr = Array(9.3);  // RangeError: Invalid array length
+
var arr = Array(9.3);  // RangeError: Invalid array length
 

如果你需要创建任意类型的单元素数组,安全的方式是使用字面值。或者在向数组添加单个元素之前先创建一个空的数组。

@@ -75,7 +75,7 @@ arr.length = 42;

你可以通过给元素赋值来填充数组,例如:

-
var emp = [];
+
var emp = [];
 emp[0] = "Casey Jones";
 emp[1] = "Phil Lesh";
 emp[2] = "August West";
@@ -85,7 +85,7 @@ emp[2] = "August West";
 

注意:如果你在以上代码中给数组操作符的是一个非整形数值,那么将作为一个代表数组的对象的属性(property)创建,而非作为数组的元素。

-
var arr = [];
+
var arr = [];
 arr[3.4] = "Oranges";
 console.log(arr.length);                // 0
 console.log(arr.hasOwnProperty(3.4));   // true
@@ -93,7 +93,7 @@ console.log(arr.hasOwnProperty(3.4));   // true
 
 

你也可以在创建数组的时候去填充它:

-
var myArray = new Array("Hello", myVar, 3.14159);
+
var myArray = new Array("Hello", myVar, 3.14159);
 var myArray = ["Mango", "Apple", "Orange"]
 
@@ -101,7 +101,7 @@ var myArray = ["Mango", "Apple", "Orange"]

您通过可以使用元素的序号来引用数组的元素。例如,假设你定义了如下数组:

-
var myArray = ["Wind", "Rain", "Fire"];
+
var myArray = ["Wind", "Rain", "Fire"];
 

你可以用 myArray[0]引用第一个元素,myArray[1]引用第二个元素。元素的索引是从0开始的。

@@ -110,7 +110,7 @@ var myArray = ["Mango", "Apple", "Orange"]

注意:数组操作符(方括号 [ ])也可以用来访问数组的属性(在 JavaScript 中,数组也是对象)。例如:

-
var arr = ["one", "two", "three"];
+
var arr = ["one", "two", "three"];
 arr[2];  // three
 arr["length"];  // 3
 
@@ -119,14 +119,14 @@ arr["length"]; // 3

在实施层面, JavaScript实际上是将元素作为标准的对象属性来存储,把数组索引作为属性名。长度属性是特殊的,它总是返回最后一个元素的索引值加1(下例中, Dusty 的索引是30,所以cats.length 返回 30 + 1)。记住, JavaScript 数组索引是基于0的: 他们从0开始,而不是1。这意味着数组长度属性将比最大的索引值大1:

-
var cats = [];
+
var cats = [];
 cats[30] = ['Dusty'];
 console.log(cats.length); // 31
 

你也可以分配length属性。写一个小于数组元素数量的值会缩短数组,写0会彻底清空数组:

-
var cats = ['Dusty', 'Misty', 'Twiggy'];
+
var cats = ['Dusty', 'Misty', 'Twiggy'];
 console.log(cats.length); // 3
 
 cats.length = 2;
@@ -143,7 +143,7 @@ console.log(cats); // [undefined, undefined, undefined]
 
 

遍历数组元素并以某种方式处理每个元素是一个常见的操作。以下是最简单的方式:

-
var colors = ['red', 'green', 'blue'];
+
var colors = ['red', 'green', 'blue'];
 for (var i = 0; i < colors.length; i++) {
   console.log(colors[i]);
 }
@@ -151,7 +151,7 @@ for (var i = 0; i < colors.length; i++) {
 
 

如果你确定数组中没有一个元素的求值是false —— 如果你的数组只包含DOM节点,如下,你可以选择一个更高效的土法子:

-
var divs = document.getElementsByTagName('div');
+
var divs = document.getElementsByTagName('div');
 for (var i = 0, div; div = divs[i]; i++) {
   /* Process div in some way */
 }
@@ -161,7 +161,7 @@ for (var i = 0, div; div = divs[i]; i++) {
 
 

{{jsxref("Array.forEach", "forEach()")}} 方法提供了遍历数组元素的其他方法:

-
var colors = ['red', 'green', 'blue'];
+
var colors = ['red', 'green', 'blue'];
 colors.forEach(function(color) {
   console.log(color);
 });
@@ -171,7 +171,7 @@ colors.forEach(function(color) {
 
 

注意,在数组定义时省略的元素不会在forEach遍历时被列出,但是手动赋值为undefined的元素是会被列出的:

-
var array = ['first', 'second', , 'fourth'];
+
var array = ['first', 'second', , 'fourth'];
 
 // returns ['first', 'second', 'fourth'];
 array.forEach(function(element) {
@@ -195,53 +195,53 @@ array.forEach(function(element) {
 
 

{{jsxref("Array.concat", "concat()")}} 连接两个数组并返回一个新的数组。

-
var myArray = new Array("1", "2", "3");
+
var myArray = new Array("1", "2", "3");
 myArray = myArray.concat("a", "b", "c");
 // myArray is now ["1", "2", "3", "a", "b", "c"]
 

{{jsxref("Array.join", "join(deliminator = ',')")}} 将数组的所有元素连接成一个字符串。

-
var myArray = new Array("Wind", "Rain", "Fire");
+
var myArray = new Array("Wind", "Rain", "Fire");
 var list = myArray.join(" - "); // list is "Wind - Rain - Fire"
 

{{jsxref("Array.push", "push()")}} 在数组末尾添加一个或多个元素,并返回数组操作后的长度。

-
var myArray = new Array("1", "2");
+
var myArray = new Array("1", "2");
 myArray.push("3"); // myArray is now ["1", "2", "3"]
 

{{jsxref("Array.pop", "pop()")}} 从数组移出最后一个元素,并返回该元素。

-
var myArray = new Array("1", "2", "3");
+
var myArray = new Array("1", "2", "3");
 var last = myArray.pop();
 // myArray is now ["1", "2"], last = "3"
 

{{jsxref("Array.shift", "shift()")}} 从数组移出第一个元素,并返回该元素。

-
var myArray = new Array ("1", "2", "3");
+
var myArray = new Array ("1", "2", "3");
 var first = myArray.shift();
 // myArray is now ["2", "3"], first is "1"
 

{{jsxref("Array.shift", "unshift()")}} 在数组开头添加一个或多个元素,并返回数组的新长度。

-
var myArray = new Array ("1", "2", "3");
+
var myArray = new Array ("1", "2", "3");
 myArray.unshift("4", "5");
 // myArray becomes ["4", "5", "1", "2", "3"]

{{jsxref("Array.slice", "slice(start_index, upto_index)")}} 从数组提取一个片段,并作为一个新数组返回。

-
var myArray = new Array ("a", "b", "c", "d", "e");
+
var myArray = new Array ("a", "b", "c", "d", "e");
 myArray = myArray.slice(1, 4); // 包含索引1,不包括索引4
                                // returning [ "b", "c", "d"]
 

{{jsxref("Array.splice", "splice(index, count_to_remove, addElement1, addElement2, ...)")}}从数组移出一些元素,(可选)并替换它们。

-
var myArray = new Array ("1", "2", "3", "4", "5");
+
var myArray = new Array ("1", "2", "3", "4", "5");
 myArray.splice(1, 3, "a", "b", "c", "d");
 // myArray is now ["1", "a", "b", "c", "d", "5"]
 // This code started at index one (or where the "2" was),
@@ -251,14 +251,14 @@ myArray.splice(1, 3, "a", "b", "c", "d");
 
 

{{jsxref("Array.reverse", "reverse()")}} 颠倒数组元素的顺序:第一个变成最后一个,最后一个变成第一个。

-
var myArray = new Array ("1", "2", "3");
+
var myArray = new Array ("1", "2", "3");
 myArray.reverse();
 // transposes the array so that myArray = [ "3", "2", "1" ]
 

{{jsxref("Array.sort", "sort()")}} 给数组元素排序。

-
var myArray = new Array("Wind", "Rain", "Fire");
+
var myArray = new Array("Wind", "Rain", "Fire");
 myArray.sort();
 // sorts the array so that myArray = [ "Fire", "Rain", "Wind" ]
 
@@ -267,7 +267,7 @@ myArray.sort();

例如,下面的代码通过字符串的最后一个字母进行排序:

-
var sortFn = function(a, b){
+
var sortFn = function(a, b){
   if (a[a.length - 1] < b[b.length - 1]) return -1;
   if (a[a.length - 1] > b[b.length - 1]) return 1;
   if (a[a.length - 1] == b[b.length - 1]) return 0;
@@ -283,7 +283,7 @@ myArray.sort(sortFn);
 
 

{{jsxref("Array.indexOf", "indexOf(searchElement[, fromIndex])")}} 在数组中搜索searchElement 并返回第一个匹配的索引。

-
var a = ['a', 'b', 'a', 'b', 'a'];
+
var a = ['a', 'b', 'a', 'b', 'a'];
 console.log(a.indexOf('b')); // logs 1
 // Now try again, starting from after the last match
 console.log(a.indexOf('b', 2)); // logs 3
@@ -292,7 +292,7 @@ console.log(a.indexOf('z')); // logs -1, because 'z' was not found
 
 

{{jsxref("Array.lastIndexOf", "lastIndexOf(searchElement[, fromIndex])")}} 和 indexOf 差不多,但这是从结尾开始,并且是反向搜索。

-
var a = ['a', 'b', 'c', 'd', 'a', 'b'];
+
var a = ['a', 'b', 'c', 'd', 'a', 'b'];
 console.log(a.lastIndexOf('b')); // logs 5
 // Now try again, starting from before the last match
 console.log(a.lastIndexOf('b', 4)); // logs 1
@@ -301,28 +301,28 @@ console.log(a.lastIndexOf('z')); // logs -1
 
 

{{jsxref("Array.forEach", "forEach(callback[, thisObject])")}} 在数组每个元素项上执行callback

-
var a = ['a', 'b', 'c'];
+
var a = ['a', 'b', 'c'];
 a.forEach(function(element) { console.log(element);} );
 // logs each item in turn
 

{{jsxref("Array.map", "map(callback[, thisObject])")}} 在数组的每个单元项上执行callback函数,并把返回包含回调函数返回值的新数组(译者注:也就是遍历数组,并通过callback对数组元素进行操作,并将所有操作结果放入数组中并返回该数组)。

-
var a1 = ['a', 'b', 'c'];
+
var a1 = ['a', 'b', 'c'];
 var a2 = a1.map(function(item) { return item.toUpperCase(); });
 console.log(a2); // logs A,B,C
 

{{jsxref("Array.filter", "filter(callback[, thisObject])")}} 返回一个包含所有在回调函数上返回为true的元素的新数组(译者注:callback在这里担任的是过滤器的角色,当元素符合条件,过滤器就返回true,而filter则会返回所有符合过滤条件的元素)。

-
var a1 = ['a', 10, 'b', 20, 'c', 30];
+
var a1 = ['a', 10, 'b', 20, 'c', 30];
 var a2 = a1.filter(function(item) { return typeof item == 'number'; });
 console.log(a2); // logs 10,20,30
 

{{jsxref("Array.every", "every(callback[, thisObject])")}} 当数组中每一个元素在callback上被返回true时就返回true(译者注:同上,every其实类似filter,只不过它的功能是判断是不是数组中的所有元素都符合条件,并且返回的是布尔值)。

-
function isNumber(value){
+
function isNumber(value){
   return typeof value == 'number';
 }
 var a1 = [1, 2, 3];
@@ -333,7 +333,7 @@ console.log(a2.every(isNumber)); // logs false
 
 

{{jsxref("Array.some", "some(callback[, thisObject])")}} 只要数组中有一项在callback上被返回true,就返回true(译者注:同上,类似every,不过前者要求都符合筛选条件才返回true,后者只要有符合条件的就返回true)。

-
function isNumber(value){
+
function isNumber(value){
   return typeof value == 'number';
 }
 var a1 = [1, 2, 3];
@@ -350,7 +350,7 @@ console.log(a3.some(isNumber)); // logs false
 
 

{{jsxref("Array.reduce", "reduce(callback[, initialValue])")}} 使用回调函数 callback(firstValue, secondValue) 把数组列表计算成一个单一值(译者注:他数组元素两两递归处理的方式把数组计算成一个值)

-
var a = [10, 20, 30];
+
var a = [10, 20, 30];
 var total = a.reduce(function(first, second) { return first + second; }, 0);
 console.log(total) // Prints 60
 
@@ -365,7 +365,7 @@ console.log(total) // Prints 60

以下代码创建了一个二维数组。

-
var a = new Array(4);
+
var a = new Array(4);
 for (i = 0; i < 4; i++) {
   a[i] = new Array(4);
   for (j = 0; j < 4; j++) {
@@ -376,7 +376,7 @@ for (i = 0; i < 4; i++) {
 
 

这个例子创建的数组拥有以下行数据:

-
Row 0: [0,0] [0,1] [0,2] [0,3]
+
Row 0: [0,0] [0,1] [0,2] [0,3]
 Row 1: [1,0] [1,1] [1,2] [1,3]
 Row 2: [2,0] [2,1] [2,2] [2,3]
 Row 3: [3,0] [3,1] [3,2] [3,3]
@@ -393,7 +393,7 @@ Objects/String/split">String.split() 的返回值是一个数组。
 
 

Array的原生(prototype)方法可以用来处理类似数组行为的对象,例如: :

-
function printArguments() {
+
function printArguments() {
   Array.prototype.forEach.call(arguments, function(item) {
     console.log(item);
   });
@@ -401,7 +401,7 @@ Objects/String/split">String.split() 的返回值是一个数组。
 
 

Array的常规方法也可以用于处理字符串,因为它提供了序列访问字符转为数组的简单方法:

-
Array.prototype.forEach.call("a string", function(chr) {
+
Array.prototype.forEach.call("a string", function(chr) {
   console.log(chr);
 });
@@ -411,31 +411,31 @@ Objects/String/split">String.split() 的返回值是一个数组。

下面的推导式创建一个数字数组并且创建一个新的数组,数组的每个元素都是原来数值的两倍(译者注:这种形式类似于Python的列表推导式)。

-
var numbers = [1, 2, 3, 4];
+
var numbers = [1, 2, 3, 4];
 var doubled = [for (i of numbers) i * 2];
 console.log(doubled); // logs 2,4,6,8
 

这跟下面的map()方法的操作是等价的。

-
var doubled = numbers.map(function(i){return i * 2;});
+
var doubled = numbers.map(function(i){return i * 2;});
 

推导式也可以用来筛选满足条件表达式的元素. 下面的推导式用来筛选是2的倍数的元素:

-
var numbers = [1, 2, 3, 21, 22, 30];
+
var numbers = [1, 2, 3, 21, 22, 30];
 var evens = [i for (i of numbers) if (i % 2 === 0)];
 console.log(evens); // logs 2,22,30
 

filter() 也可以达到相同的目的:

-
var evens = numbers.filter(function(i){return i % 2 === 0;});
+
var evens = numbers.filter(function(i){return i % 2 === 0;});
 

map() 和filter() 类型的操作可以被组合(等效)为单个数组推导式。这里就有一个过滤出偶数,创建一个它的倍数数组的例子:

-
var numbers = [1, 2, 3, 21, 22, 30];
+
var numbers = [1, 2, 3, 21, 22, 30];
 var doubledEvens = [i * 2 for (i of numbers) if (i % 2 === 0)];
 console.log(doubledEvens); // logs 4,44,60
 
@@ -446,7 +446,7 @@ console.log(doubledEvens); // logs 4,44,60

甚至字符串也可以用来作为输入; 实现filter或者map行为 (参考上面类似数组行为的对象)如下:

-
var str = 'abcdef';
+
var str = 'abcdef';
 var consonantsOnlyStr = [c for (c of str) if (!(/[aeiouAEIOU]/).test(c))  ].join(''); // 'bcdf'
 var interpolatedZeros = [c+'0' for (c of str) ].join(''); // 'a0b0c0d0e0f0'
 
diff --git a/files/zh-cn/web/javascript/guide/introduction/index.html b/files/zh-cn/web/javascript/guide/introduction/index.html index 8a6a283d5c..3848d00603 100644 --- a/files/zh-cn/web/javascript/guide/introduction/index.html +++ b/files/zh-cn/web/javascript/guide/introduction/index.html @@ -117,7 +117,7 @@ translation_of: Web/JavaScript/Guide/Introduction

控制台的工作方式与eval完全相同:返回最后输入的表达式。为了简单起见,可以想象每次输入到控制台的东西实际上都被 console.log 所包围。

-
function greetMe(yourName) { alert('Hello ' + yourName); } console.log(eval('3 + 5'));
+
function greetMe(yourName) { alert('Hello ' + yourName); } console.log(eval('3 + 5'));

代码草稿纸(Scratchpad)

@@ -133,7 +133,7 @@ translation_of: Web/JavaScript/Guide/Introduction

学习JavaScript 的第一步,打开浏览器的代码草稿纸尝试编写你的第一个 JavaScript 版本的 “Hello world” 程序。

-
function greetMe(user) {
+
function greetMe(user) {
   alert('Hi ' + user);
 }
 
diff --git a/files/zh-cn/web/javascript/guide/meta_programming/index.html b/files/zh-cn/web/javascript/guide/meta_programming/index.html
index 723165c93f..65747f4058 100644
--- a/files/zh-cn/web/javascript/guide/meta_programming/index.html
+++ b/files/zh-cn/web/javascript/guide/meta_programming/index.html
@@ -16,7 +16,7 @@ translation_of: Web/JavaScript/Guide/Meta_programming
 
 

在 ECMAScript 6 中引入的 {{jsxref("Proxy")}} 对象可以拦截某些操作并实现自定义行为。例如获取一个对象上的属性:

-
let handler = {
+
let handler = {
   get: function(target, name){
     return name in target ? target[name] : 42;
 }};
@@ -204,7 +204,7 @@ console.log(p.a, p.b); // 1, 42
 
 

{{jsxref("Proxy.revocable()")}} 方法被用来创建可撤销的 Proxy 对象。这意味着 proxy 可以通过 revoke 函数来撤销,并且关闭代理。此后,代理上的任意的操作都会导致{{jsxref("TypeError")}}。

-
var revocable = Proxy.revocable({}, {
+
var revocable = Proxy.revocable({}, {
   get: function(target, name) {
     return "[[" + name + "]]";
   }
@@ -227,18 +227,18 @@ typeof proxy            // "object", typeof doesn't trigger any trap

以 {{jsxref("Reflect.has()")}} 为例,你可以将 in 运算符作为函数:

-
Reflect.has(Object, "assign"); // true
+
Reflect.has(Object, "assign"); // true
 

更好的 apply 函数

在 ES5 中,我们通常使用 {{jsxref("Function.prototype.apply()")}} 方法调用一个具有给定 this 值和 arguments 数组(或类数组对象)的函数。

-
Function.prototype.apply.call(Math.floor, undefined, [1.75]);
+
Function.prototype.apply.call(Math.floor, undefined, [1.75]);

使用 {{jsxref("Reflect.apply")}},这变得不那么冗长和容易理解:

-
Reflect.apply(Math.floor, undefined, [1.75]);
+
Reflect.apply(Math.floor, undefined, [1.75]);
 // 1;
 
 Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]);
@@ -254,7 +254,7 @@ Reflect.apply(''.charAt, 'ponies', [3]);
 
 

使用 {{jsxref("Object.defineProperty")}},如果成功返回一个对象,否则抛出一个 {{jsxref("TypeError")}},你将使用 {{jsxref("Statements/try...catch","try...catch")}} 块来捕获定义属性时发生的任何错误。因为 {{jsxref("Reflect.defineProperty")}} 返回一个布尔值表示的成功状态,你可以在这里使用 {{jsxref("Statements/if...else","if...else")}} 块:

-
if (Reflect.defineProperty(target, property, attributes)) {
+
if (Reflect.defineProperty(target, property, attributes)) {
   // success
 } else {
   // failure
diff --git a/files/zh-cn/web/javascript/guide/numbers_and_dates/index.html b/files/zh-cn/web/javascript/guide/numbers_and_dates/index.html
index 48a950b5ed..79bdc48877 100644
--- a/files/zh-cn/web/javascript/guide/numbers_and_dates/index.html
+++ b/files/zh-cn/web/javascript/guide/numbers_and_dates/index.html
@@ -26,7 +26,7 @@ translation_of: Web/JavaScript/Guide/Numbers_and_dates
 
 

十进制数字(Decimal numbers)

-
1234567890
+
1234567890
 42
 // 以零开头的数字的注意事项:
 0888 // 888 将被当做十进制处理
@@ -39,7 +39,7 @@ translation_of: Web/JavaScript/Guide/Numbers_and_dates
 
 

二进制数字语法是以零为开头,后面接一个小写或大写的拉丁文字母B(0b或者是0B)。 假如0b后面的数字不是0或者1,那么就会提示这样的语法错误( SyntaxError): "Missing binary digits after 0b(0b之后缺失二有效的二进制数据)"。

-
var FLT_SIGNBIT  = 0b10000000000000000000000000000000; // 2147483648
+
var FLT_SIGNBIT  = 0b10000000000000000000000000000000; // 2147483648
 var FLT_EXPONENT = 0b01111111100000000000000000000000; // 2139095040
 var FLT_MANTISSA = 0B00000000011111111111111111111111; // 8388607
@@ -47,26 +47,26 @@ var FLT_MANTISSA = 0B00000000011111111111111111111111; // 8388607

八进制数字语法是以0为开头的。假如0后面的数字不在0到7的范围内,该数字将会被转换成十进制数字。

-
var n = 0755; // 493
+
var n = 0755; // 493
 var m = 0644; // 420
 

在ECMAScript 5 严格模式下禁止使用八进制语法。八进制语法并不是ECMAScript 5规范的一部分,但是通过在八进制数字添加一个前缀0就可以被所有的浏览器支持:0644 === 420 而且 "\045" === "%"。在ECMAScript 6中使用八进制数字是需要给一个数字添加前缀"0o"。

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

十六进制(Hexadecimal numbers)

十六进制数字语法是以零为开头,后面接一个小写或大写的拉丁文字母X(0x或者是0X)。假如0x后面的数字超出规定范围(0123456789ABCDEF),那么就会提示这样的语法错误(SyntaxError):"Identifier starts immediately after numeric literal".

-
0xFFFFFFFFFFFFFFFFF // 295147905179352830000
+
0xFFFFFFFFFFFFFFFFF // 295147905179352830000
 0x123456789ABCDEF   // 81985529216486900
 0XA                 // 10
 

指数形式(Exponentiation)

-
1E3   // 1000
+
1E3   // 1000
 2e6   // 2000000
 0.1e2 // 10
 
@@ -75,7 +75,7 @@ var m = 0644; // 420

内置的{{jsxref("Number")}}对象有一些有关数字的常量属性,如最大值、不是一个数字和无穷大的。你不能改变这些属性,但可以按下边的方式使用它们:

-
var biggestNum = Number.MAX_VALUE;
+
var biggestNum = Number.MAX_VALUE;
 var smallestNum = Number.MIN_VALUE;
 var infiniteNum = Number.POSITIVE_INFINITY;
 var negInfiniteNum = Number.NEGATIVE_INFINITY;
@@ -210,12 +210,12 @@ var notANum = Number.NaN;
 
 

对于内置的{{jsxref("Math")}}数学常项和函数也有一些属性和方法。 比方说, Math对象的 PI 属性会有属性值 pi (3.141...),你可以像这样调用它:

-
Math.PI // π
+
Math.PI // π
 

同理,标准数学函数也是Math的方法。 这些包括三角函数​​,对数,指数,和其他函数。比方说你想使用三角函数 sin, 你可以这么写:

-
Math.sin(1.56)
+
Math.sin(1.56)
 

需要注意的是Math的所有三角函数参数都是弧度制。

@@ -312,7 +312,7 @@ var notANum = Number.NaN;

创建一个日期对象:

-
var dateObjectName = new Date([parameters]);
+
var dateObjectName = new Date([parameters]);
 

这里的 dateObjectName 对象是所创建的Date对象的一个名字,它可以成为一个新的对象或者已存在的其他对象的一个属性。

@@ -352,7 +352,7 @@ var notANum = Number.NaN;

例如, 假设你定义了如下日期:

-
var Xmas95 = new Date("December 25, 1995");
+
var Xmas95 = new Date("December 25, 1995");
 

Then Xmas95.getMonth() 返回 11, and Xmas95.getFullYear() 返回 1995.

@@ -361,7 +361,7 @@ var notANum = Number.NaN;

例如,以下代码展示了今年剩下的天数:

-
var today = new Date();
+
var today = new Date();
 var endYear = new Date(1995, 11, 31, 23, 59, 59, 999); // 设置日和月,注意,月份是0-11
 endYear.setFullYear(today.getFullYear()); // 把年设置为今年
 var msPerDay = 24 * 60 * 60 * 1000; // 每天的毫秒数
@@ -373,7 +373,7 @@ var daysLeft = Math.round(daysLeft); //返回今年剩下的天数
 
 

parse方法对于从日期字符串赋值给现有的Date对象很有用,例如:以下代码使用parsesetTime分配了一个日期值给IPOdate对象:

-
var IPOdate = new Date();
+
var IPOdate = new Date();
 IPOdate.setTime(Date.parse("Aug 9, 1995"));
 
@@ -381,7 +381,7 @@ IPOdate.setTime(Date.parse("Aug 9, 1995"));

在下边的例子中,JSClock()函数返回了用数字时钟格式的时间:

-
function JSClock() {
+
function JSClock() {
   var time = new Date();
   var hour = time.getHours();
   var minute = time.getMinutes();
diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/assertions/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/assertions/index.html
index b7468ef5be..0d3757acd6 100644
--- a/files/zh-cn/web/javascript/guide/regular_expressions/assertions/index.html
+++ b/files/zh-cn/web/javascript/guide/regular_expressions/assertions/index.html
@@ -140,7 +140,7 @@ translation_of: Web/JavaScript/Guide/Regular_Expressions/Assertions
 
 

一般边界类型概述示例

-
// 使用 正则表达式边界修复错误字符串
+
// 使用 正则表达式边界修复错误字符串
 buggyMultiline = `tey, ihe light-greon apple
 tangs on ihe greon traa`;
 
@@ -164,7 +164,7 @@ console.log(4, fixedMultiline); // 修复  'greon'  不影响'on'.

使用 ^匹配输入的开头。在这个例子中,我们可以通过 /^A/ 正则表达式得到以A开头的水果。为了选择合适的水果,我们可以使用带有箭头函数的过滤方法.

-
let fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
+
let fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
 
 // 使用正则 /^A/ 选择以'A'开头的水果.
 // 这里的 '^' 只有一种含义: 匹配输入的开头.
@@ -174,7 +174,7 @@ console.log(fruitsStartsWithA); // [ 'Apple', 'Avocado' ]

在第二个示例中,^用于在输入的开始处匹配,以及在内部使用时用于创建否定或被补充的字符集 组和范围.

-
let fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
+
let fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
 
 // 使用正则 /^[^A]/ 选择 不是以 ‘A’ 开头的水果
 // 在这个例子中,“^” 控件符号表示两种含义:
@@ -187,7 +187,7 @@ console.log(fruitsStartsWithNotA); // [ 'Watermelon', 'Orange', 'Strawberry' ]匹配字边界
 
-
let fruitsWithDescription = ["Red apple", "Orange orange", "Green Avocado"];
+
let fruitsWithDescription = ["Red apple", "Orange orange", "Green Avocado"];
 
 // 选择包含以 “en” 或 “ed” 结尾的单词的描述:
 let enEdSelection = fruitsWithDescription.filter(descr => /(en|ed)\b/.test(descr));
@@ -196,7 +196,7 @@ console.log(enEdSelection); // [ 'Red apple', 'Green Avocado' ]

向前断言

-
// JS 向前断言 x(?=y) 匹配被 y 跟随的 x
+
// JS 向前断言 x(?=y) 匹配被 y 跟随的 x
 
 let regex = /First(?= test)/g;
 
@@ -209,13 +209,13 @@ console.log('This is a First peach in a month.'.match(regex)); // null

例如, /\d+(?!\.)/ 匹配没有被小数点跟随且至少有一位的数字。 /\d+(?!\.)/.exec('3.141') 匹配 "141" 而不是 "3" 

-
console.log(/\d+(?!\.)/g.exec('3.141')); // [ '141', index: 2, input: '3.141' ]
+
console.log(/\d+(?!\.)/g.exec('3.141')); // [ '141', index: 2, input: '3.141' ]

不同含义的'?!':断言和范围的组合用法

不同含义的?! 结合使用 断言  /x(?!y)/ 和  范围 [^?!].

-
let orangeNotLemon = "Do you want to have an orange? Yes, I do not want to have a lemon!";
+
let orangeNotLemon = "Do you want to have an orange? Yes, I do not want to have a lemon!";
 
 let selectNotLemonRegex = /[^?!]+have(?! a lemon)[^?!]+[?!]/gi
 console.log(orangeNotLemon.match(selectNotLemonRegex)); // [ 'Do you want to have an orange?' ]
@@ -225,7 +225,7 @@ console.log(orangeNotLemon.match(selectNotOrangeRegex)); // [ ' Yes, I do not wa
 
 

向后断言

-
let oranges = ['ripe orange A ', 'green orange B', 'ripe orange C',];
+
let oranges = ['ripe orange A ', 'green orange B', 'ripe orange C',];
 
 let ripe_oranges = oranges.filter( fruit => fruit.match(/(?<=ripe )orange/));
 console.log(ripe_oranges); // [ 'ripe orange A ', 'ripe orange C' ]
diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/character_classes/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/character_classes/index.html index 26b1f4ee4a..80f9181f89 100644 --- a/files/zh-cn/web/javascript/guide/regular_expressions/character_classes/index.html +++ b/files/zh-cn/web/javascript/guide/regular_expressions/character_classes/index.html @@ -144,7 +144,7 @@ translation_of: Web/JavaScript/Guide/Regular_Expressions/Character_Classes

Looking for a series of digits

-
var randomData = "015 354 8787 687351 3512 8735";
+
var randomData = "015 354 8787 687351 3512 8735";
 var regexpFourDigits = /\b\d{4}\b/g;
 // \b indicates a boundary (i.e. do not start matching in the middle of a word)
 // \d{4} indicates a digit, four times
@@ -157,7 +157,7 @@ console.table(randomData.match(regexpFourDigits));
 
 

Looking for a word (from the latin alphabet) starting with A

-
var aliceExcerpt = "I’m sure I’m not Ada,’ she said, ‘for her hair goes in such long ringlets, and mine doesn’t go in ringlets at all.";
+
var aliceExcerpt = "I’m sure I’m not Ada,’ she said, ‘for her hair goes in such long ringlets, and mine doesn’t go in ringlets at all.";
 var regexpWordStartingWithA = /\b[aA]\w+/g;
 // \b indicates a boundary (i.e. do not start matching in the middle of a word)
 // [aA] indicates the letter a or A
@@ -171,7 +171,7 @@ console.table(aliceExcerpt.match(regexpWordStartingWithA));
 
 

Instead of the Latin alphabet, we can use a range of Unicode characters to identify a word (thus being able to deal with text in other languages like Russian or Arabic). The "Basic Multilingual Plane" of Unicode contains most of the characters used around the world and we can use character classes and ranges to match words written with those characters.

-
var nonEnglishText = "Приключения Алисы в Стране чудес";
+
var nonEnglishText = "Приключения Алисы в Стране чудес";
 var regexpBMPWord = /([\u0000-\u0019\u0021-\uFFFF])+/gu;
 // BMP goes through U+0000 to U+FFFF but space is U+0020
 
diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/groups_and_ranges/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/groups_and_ranges/index.html
index 9a73c9b8ef..8aac5048dc 100644
--- a/files/zh-cn/web/javascript/guide/regular_expressions/groups_and_ranges/index.html
+++ b/files/zh-cn/web/javascript/guide/regular_expressions/groups_and_ranges/index.html
@@ -94,7 +94,7 @@ translation_of: Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges
 
 

计算元音数

-
var aliceExcerpt = "There was a long silence after this, and Alice could only hear whispers now and then.";
+
var aliceExcerpt = "There was a long silence after this, and Alice could only hear whispers now and then.";
 var regexpVowels = /[aeiouy]/g;
 
 console.log("Number of vowels:", aliceExcerpt.match(regexpVowels).length);
@@ -102,7 +102,7 @@ console.log("Number of vowels:", aliceExcerpt.match(regexpVowels).length);
 
 

使用 组

-
let personList = `First_Name: John, Last_Name: Doe
+
let personList = `First_Name: John, Last_Name: Doe
 First_Name: Jane, Last_Name: Smith`;
 
 let regexpNames =  /First_Name: (\w+), Last_Name: (\w+)/mg;
@@ -114,7 +114,7 @@ do {
 
 

使用命名组

-
let users= `姓氏: 李, 名字: 雷
+
let users= `姓氏: 李, 名字: 雷
 姓氏: 韩, 名字: 梅梅`;
 
 let regexpNames =  /姓氏: (?<first>.+), 名字: (?<last>.+)/mg;
diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/index.html
index 4d88167c80..b38f643ced 100644
--- a/files/zh-cn/web/javascript/guide/regular_expressions/index.html
+++ b/files/zh-cn/web/javascript/guide/regular_expressions/index.html
@@ -21,14 +21,14 @@ translation_of: Web/JavaScript/Guide/Regular_Expressions
 
 

使用一个正则表达式字面量,其由包含在斜杠之间的模式组成,如下所示:

-
var re = /ab+c/;
+
var re = /ab+c/;
 

脚本加载后,正则表达式字面量就会被编译。当正则表达式保持不变时,使用此方法可获得更好的性能。

或者调用RegExp对象的构造函数,如下所示:

-
var re = new RegExp("ab+c");
+
var re = new RegExp("ab+c");
 

在脚本运行过程中,用构造函数创建的正则表达式会被编译。如果正则表达式将会改变,或者它将会从用户输入等来源中动态地产生,就需要使用构造函数来创建正则表达式。

@@ -384,7 +384,7 @@ translation_of: Web/JavaScript/Guide/Regular_Expressions

将用户输入转义为正则表达式中的一个字面字符串, 可以通过简单的替换来实现:

-
function escapeRegExp(string) {
+
function escapeRegExp(string) {
   return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
   //$&表示整个被匹配的字符串
 }
@@ -451,13 +451,13 @@ translation_of: Web/JavaScript/Guide/Regular_Expressions

在接下来的例子中,脚本将使用exec方法在一个字符串中查找一个匹配。

-
var myRe = /d(b+)d/g;
+
var myRe = /d(b+)d/g;
 var myArray = myRe.exec("cdbbdbsbz");
 

如果你不需要访问正则表达式的属性,这个脚本通过另一个方法来创建myArray:

-
var myArray = /d(b+)d/g.exec("cdbbdbsbz");
+
var myArray = /d(b+)d/g.exec("cdbbdbsbz");
 // 和 "cdbbdbsbz".match(/d(b+)d/g); 相似。
 // 但是 "cdbbdbsbz".match(/d(b+)d/g) 输出数组 [ "dbbd" ],
 // 而 /d(b+)d/g.exec('cdbbdbsbz') 输出数组 [ "dbbd", "bb", index: 1, input: "cdbbdbsbz" ].
@@ -466,7 +466,7 @@ var myArray = myRe.exec("cdbbdbsbz");
 
 

如果你想通过一个字符串构建正则表达式,那么这个脚本还有另一种方法:

-
var myRe = new RegExp("d(b+)d", "g");
+
var myRe = new RegExp("d(b+)d", "g");
 var myArray = myRe.exec("cdbbdbsbz");
 
@@ -520,25 +520,25 @@ var myArray = myRe.exec("cdbbdbsbz");

如这个例子中的第二种形式所示,你可以使用对象初始器创建一个正则表达式实例,但不分配给变量。如果你这样做,那么,每一次使用时都会创建一个新的正则表达式实例。因此,如果你不把正则表达式实例分配给一个变量,你以后将不能访问这个正则表达式实例的属性。例如,假如你有如下脚本:

-
var myRe = /d(b+)d/g;
+
var myRe = /d(b+)d/g;
 var myArray = myRe.exec("cdbbdbsbz");
 console.log("The value of lastIndex is " + myRe.lastIndex);
 

这个脚本输出如下:

-
The value of lastIndex is 5
+
The value of lastIndex is 5
 

然而,如果你有如下脚本:

-
var myArray = /d(b+)d/g.exec("cdbbdbsbz");
+
var myArray = /d(b+)d/g.exec("cdbbdbsbz");
 console.log("The value of lastIndex is " + /d(b+)d/g.lastIndex);
 

它显示为:

-
The value of lastIndex is 0
+
The value of lastIndex is 0
 

当发生/d(b+)d/g使用两个不同状态的正则表达式对象,lastIndex属性会得到不同的值。如果你需要访问一个正则表达式的属性,则需要创建一个对象初始化生成器,你应该首先把它赋值给一个变量。

@@ -551,7 +551,7 @@ console.log("The value of lastIndex is " + /d(b+)d/g.lastIndex);

下面的脚本使用replace()方法来转换字符串中的单词。在匹配到的替换文本中,脚本使用替代的$ 1,$ 2表示第一个和第二个括号的子字符串匹配。

-
var re = /(\w+)\s(\w+)/;
+
var re = /(\w+)\s(\w+)/;
 var str = "John Smith";
 var newstr = str.replace(re, "$2, $1");
 console.log(newstr);
@@ -601,19 +601,19 @@ console.log(newstr);
 
 

为了在正则表达式中包含标志,请使用以下语法:

-
var re = /pattern/flags;
+
var re = /pattern/flags;
 

或者

-
var re = new RegExp("pattern", "flags");
+
var re = new RegExp("pattern", "flags");
 

值得注意的是,标志是一个正则表达式的一部分,它们在接下来的时间将不能添加或删除。

例如,re = /\w+\s/g 将创建一个查找一个或多个字符后有一个空格的正则表达式,或者组合起来像此要求的字符串。

-
var re = /\w+\s/g;
+
var re = /\w+\s/g;
 var str = "fee fi fo fum";
 var myArray = str.match(re);
 console.log(myArray);
@@ -623,19 +623,19 @@ console.log(myArray);
 
 

这段代码将输出 ["fee ", "fi ", "fo "]。在这个例子中,你可以将:

-
var re = /\w+\s/g;
+
var re = /\w+\s/g;
 

替换成:

-
var re = new RegExp("\\w+\\s", "g");
+
var re = new RegExp("\\w+\\s", "g");
 

并且能获取到相同的结果。

使用.exec()方法时,与'g'标志关联的行为是不同的。 (“class”和“argument”的作用相反:在.match()的情况下,字符串类(或数据类型)拥有该方法,而正则表达式只是一个参数,而在.exec()的情况下,它是拥有该方法的正则表达式,其中字符串是参数。对比str.match(re)re.exec(str) ), 'g'标志与.exec()方法一起使用获得迭代进展。

-
var xArray; while(xArray = re.exec(str)) console.log(xArray);
+
var xArray; while(xArray = re.exec(str)) console.log(xArray);
 // produces:
 // ["fee ", index: 0, input: "fee fi fo fum"]
 // ["fi ", index: 4, input: "fee fi fo fum"]
@@ -651,7 +651,7 @@ console.log(myArray);
 
 

以下例子解释了正则表达式的构成和 string.split() 以及 string.replace()的用途。它会整理一个只有粗略格式的含有全名(名字首先出现)的输入字符串,这个字符串被空格、换行符和一个分号分隔。最终,它会颠倒名字顺序(姓氏首先出现)和list的类型。

-
// 下面这个姓名字符串包含了多个空格和制表符,
+
// 下面这个姓名字符串包含了多个空格和制表符,
 // 且在姓和名之间可能有多个空格和制表符。
 var names = "Orange Trump ;Fred Barney; Helen Rigby ; Bill Abel ; Chris Hand ";
 
@@ -716,7 +716,7 @@ console.log(output.join("\n"));
 
 

当用户按下 Enter 设置 RegExp.input,这些变化也能被激活。

-
<!DOCTYPE html>
+
<!DOCTYPE html>
 <html>
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/quantifiers/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/quantifiers/index.html
index d705953a69..1173553f2d 100644
--- a/files/zh-cn/web/javascript/guide/regular_expressions/quantifiers/index.html
+++ b/files/zh-cn/web/javascript/guide/regular_expressions/quantifiers/index.html
@@ -85,14 +85,14 @@ original_slug: Web/JavaScript/Guide/Regular_Expressions/量词
 
 

重复模式

-
var wordEndingWithAs = /\w+a+/;
+
var wordEndingWithAs = /\w+a+/;
 var delicateMessage = "This is Spartaaaaaaa";
 
 console.table(delicateMessage.match(wordEndingWithAs)); // [ "Spartaaaaaaa" ]

计算字符集

-
var singleLetterWord = /\b\w\b/g;
+
var singleLetterWord = /\b\w\b/g;
 var notSoLongWord = /\b\w{1,6}\b/g;
 var loooongWord = /\b\w{13,}\b/g;
 
@@ -105,7 +105,7 @@ console.table(sentence.match(loooongWord));      // ["multiplication"]可选可
 
 

 可选字符

-
var britishText = "He asked his neighbour a favour.";
+
var britishText = "He asked his neighbour a favour.";
 var americanText = "He asked his neighbor a favor.";
 
 var regexpEnding = /\w+ou?r/g;
@@ -123,7 +123,7 @@ console.table(americanText.match(regexpEnding));
 
 

贪婪 与 非贪婪的

-
var text = "I must be getting somewhere near the centre of the earth.";
+
var text = "I must be getting somewhere near the centre of the earth.";
 var greedyRegexp = /[\w ]+/;
 // [\w ]      a letter of the latin alphabet or a whitespace
 //      +     one or several times
diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/unicode_property_escapes/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/unicode_property_escapes/index.html
index db7312bea4..973820343c 100644
--- a/files/zh-cn/web/javascript/guide/regular_expressions/unicode_property_escapes/index.html
+++ b/files/zh-cn/web/javascript/guide/regular_expressions/unicode_property_escapes/index.html
@@ -21,7 +21,7 @@ translation_of: Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escape
 
 
 
-
// Non-binary 属性
+
// Non-binary 属性
 \p{Unicode属性值}
 \p{Unicode属性名=Unicode属性值}
 
@@ -66,7 +66,7 @@ translation_of: Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escape
 
 

它们可匹配字母、数字、符号、标点符号、空格等等。一般类别详见 the Unicode specification.

-
// finding all the letters of a text
+
// finding all the letters of a text
 let story = "It’s the Cheshire Cat: now I shall have somebody to talk to.";
 
 // Most explicit form
@@ -88,7 +88,7 @@ story.match(/\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}/gu);
 
 

比如,A 属于 拉丁文ε 属于希腊(Greek)文。

-
let mixedCharacters = "aεЛ";
+
let mixedCharacters = "aεЛ";
 
 // Using the canonical "long" name of the script
 mixedCharacters.match(/\p{Script=Latin}/u); // a
@@ -104,7 +104,7 @@ mixedCharacters.match(/\p{Sc=Cyrillic}/u); // Л
 
 

某字符用于多种文字时,Script 优先匹配最主要使用那个字符的文字。如果想要根据非主要的文字进行匹配,我们可以使用 Script_Extensions 属性 (简写为Scx).

-
// ٢ is the digit 2 in Arabic-Indic notation
+
// ٢ is the digit 2 in Arabic-Indic notation
 // while it is predominantly written within the Arabic script
 // it can also be written in the Thaana script
 
@@ -121,7 +121,7 @@ mixedCharacters.match(/\p{Sc=Cyrillic}/u); // Л
 
 

Unicode 属性转义 categories 包含更多字符, \p{Letter} 或 \p{Number} 将会适用于任何文字。

-
// Trying to use ranges to avoid \w limitations:
+
// Trying to use ranges to avoid \w limitations:
 
 const nonEnglishText = "Приключения Алисы в Стране чудес";
 const regexpBMPWord = /([\u0000-\u0019\u0021-\uFFFF])+/gu;
diff --git a/files/zh-cn/web/javascript/guide/text_formatting/index.html b/files/zh-cn/web/javascript/guide/text_formatting/index.html
index fbe34d2cd6..b0f8b412fe 100644
--- a/files/zh-cn/web/javascript/guide/text_formatting/index.html
+++ b/files/zh-cn/web/javascript/guide/text_formatting/index.html
@@ -18,7 +18,7 @@ translation_of: Web/JavaScript/Guide/Text_formatting
 
 

可以使用单引号或双引号创建简单的字符串:

-
'foo'
+
'foo'
 "bar"

可以使用转义序列来创建更复杂的字符串:

@@ -27,14 +27,14 @@ translation_of: Web/JavaScript/Guide/Text_formatting

\x之后的数值将被认为是一个16进制数.

-
'\xA9' // "©"
+
'\xA9' // "©"
 

Unicode转义序列

Unicode转义序列在\u之后需要至少4个字符.

-
'\u00A9' // "©"
+
'\u00A9' // "©"

Unicode字元逸出

@@ -42,7 +42,7 @@ translation_of: Web/JavaScript/Guide/Text_formatting

请参阅 {{jsxref("String.fromCodePoint()")}} 或 {{jsxref("String.prototype.codePointAt()")}}。

-
'\u{2F804}'
+
'\u{2F804}'
 
 // the same with simple Unicode escapes
 '\uD87E\uDC04'
@@ -51,7 +51,7 @@ translation_of: Web/JavaScript/Guide/Text_formatting

{{jsxref("String")}} 对象是对原始string类型的封装 .

-
const foo = new String('foo'); // 创建一个 String 对象
+
const foo = new String('foo'); // 创建一个 String 对象
 console.log(foo); // 输出: [String: 'foo']
 typeof foo; // 返回 'object'
@@ -59,14 +59,14 @@ typeof foo; // 返回 'object'

除非必要, 应该尽量使用 String 字面值,因为String对象的某些行为可能并不与直觉一致。举例:

-
const firstString = '2 + 2'; //创建一个字符串字面量
+
const firstString = '2 + 2'; //创建一个字符串字面量
 const secondString = new String('2 + 2'); // 创建一个字符串对象
 eval(firstString); // 返回数字 4
 eval(secondString); // 返回包含 "2 + 2" 的字符串对象

String 对象有一个属性 length,标识了字符串中 UTF-16 的码点个数。举例,下面的代码把 13 赋值给了helloLength,因为 "Hello, World!" 包含 13 个字符,每个字符用一个 UTF-16 码点表示。你可以通过数组的方式访问每一个码点,但你不能修改每个字符,因为字符串是不变的类数组对象: 

-
const hello = 'Hello, World!';
+
const hello = 'Hello, World!';
 const helloLength = hello.length;
 hello[0] = 'L'; // 无效,因为字符串是不变的
 hello[0]; // 返回 "H"
@@ -155,14 +155,14 @@ hello[0]; // 返回 "H"

源代码中插入的任何新行开始字符都作为模板字符串的内容. 使用一般的字符串时, 为了创建多行的字符串不得不用如下语法:

-
console.log("string text line 1\n\
+
console.log("string text line 1\n\
 string text line 2");
 // "string text line 1
 // string text line 2"

为了实现同样效果的多行字符串, 现在可以写成如下形式:

-
console.log(`string text line 1
+
console.log(`string text line 1
 string text line 2`);
 // "string text line 1
 // string text line 2"
@@ -171,14 +171,14 @@ string text line 2`);

为了在一般的字符串中嵌入表达式, 需要使用如下语法:

-
const five = 5;
+
const five = 5;
 const ten = 10;
 console.log('Fifteen is ' + (five + ten) + ' and not ' + (2 * five + ten) + '.');
 // "Fifteen is 15 and not 20."

现在, 使用模板字符串, 可以使用语法糖让类似功能的实现代码更具可读性:

-
const five = 5;
+
const five = 5;
 const ten = 10;
 console.log(`Fifteen is ${five + ten} and not ${2 * five + ten}.`);
 // "Fifteen is 15 and not 20."
@@ -193,7 +193,7 @@ console.log(`Fifteen is ${five + ten} and not ${2 * five + ten}.`);

{{jsxref("DateTimeFormat")}} 对象在日期和时间的格式化方面很有用. 下面的代码把一个日期格式化为美式英语格式. (不同时区结果不同.)

-
const msPerDay = 24 * 60 * 60 * 1000;
+
const msPerDay = 24 * 60 * 60 * 1000;
 
 // July 17, 2014 00:00:00 UTC.
 const july172014 = new Date(msPerDay * (44 * 365 + 11 + 197));//2014-1970=44年
@@ -211,7 +211,7 @@ console.log(americanDateTime(july172014)); // 07/16/14, 5:00 PM PDT
 
 

{{jsxref("NumberFormat")}} 对象在数字的格式化方面很有用, 比如货币数量值.

-
var gasPrice = new Intl.NumberFormat("en-US",
+
var gasPrice = new Intl.NumberFormat("en-US",
                         { style: "currency", currency: "USD",
                           minimumFractionDigits: 3 });
 
@@ -229,7 +229,7 @@ console.log(hanDecimalRMBInChina.format(1314.25)); // ¥ 一,三一四.二五
 
 

举例, 德语中有两种不同的排序方式 电话本(phonebook) 和 字典(dictionary). 电话本排序强调发音, 比如在排序前 “ä”, “ö”等被扩展为 “ae”, “oe”等发音.

-
var names = ["Hochberg", "Hönigswald", "Holzman"];
+
var names = ["Hochberg", "Hönigswald", "Holzman"];
 
 var germanPhonebook = new Intl.Collator("de-DE-u-co-phonebk");
 
@@ -240,7 +240,7 @@ console.log(names.sort(germanPhonebook.compare).join(", "));
 
 

有些德语词包含变音, 所以在字典中忽略变音进行排序是合理的 (除非待排序的单词只有变音部分不同: schon 先于 schön).

-
var germanDictionary = new Intl.Collator("de-DE-u-co-dict");
+
var germanDictionary = new Intl.Collator("de-DE-u-co-dict");
 
 // as if sorting ["Hochberg", "Honigswald", "Holzman"]:
 console.log(names.sort(germanDictionary.compare).join(", "));
diff --git a/files/zh-cn/web/javascript/guide/using_promises/index.html b/files/zh-cn/web/javascript/guide/using_promises/index.html
index c714260d7f..22a0163216 100644
--- a/files/zh-cn/web/javascript/guide/using_promises/index.html
+++ b/files/zh-cn/web/javascript/guide/using_promises/index.html
@@ -20,7 +20,7 @@ translation_of: Web/JavaScript/Guide/Using_promises
 
 

以下为使用 createAudioFileAsync() 的示例:

-
// 成功的回调函数
+
// 成功的回调函数
 function successCallback(result) {
   console.log("音频文件创建成功: " + result);
 }
@@ -36,13 +36,13 @@ createAudioFileAsync(audioSettings, successCallback, failureCallback)

如果函数 createAudioFileAsync() 被重写为返回 Promise 的形式,那么我们可以像下面这样简单地调用它:

-
const promise = createAudioFileAsync(audioSettings);
+
const promise = createAudioFileAsync(audioSettings);
 promise.then(successCallback, failureCallback);
 

或者简写为:

-
createAudioFileAsync(audioSettings).then(successCallback, failureCallback);
+
createAudioFileAsync(audioSettings).then(successCallback, failureCallback);
 

我们把这个称为 异步函数调用,这种形式有若干优点,下面我们将会逐一讨论。

@@ -65,13 +65,13 @@ promise.then(successCallback, failureCallback);

见证奇迹的时刻:then() 函数会返回一个和原来不同的新的 Promise

-
const promise = doSomething();
+
const promise = doSomething();
 const promise2 = promise.then(successCallback, failureCallback);
 

或者

-
const promise2 = doSomething().then(successCallback, failureCallback);
+
const promise2 = doSomething().then(successCallback, failureCallback);

promise2 不仅表示 doSomething() 函数的完成,也代表了你传入的 successCallback 或者 failureCallback 的完成,这两个函数也可以返回一个 Promise 对象,从而形成另一个异步操作,这样的话,在 promise2 上新增的回调函数会排在这个 Promise 对象的后面。

@@ -79,7 +79,7 @@ const promise2 = promise.then(successCallback, failureCallback);

在过去,要想做多重的异步操作,会导致经典的回调地狱:

-
doSomething(function(result) {
+
doSomething(function(result) {
   doSomethingElse(result, function(newResult) {
     doThirdThing(newResult, function(finalResult) {
       console.log('Got the final result: ' + finalResult);
@@ -90,7 +90,7 @@ const promise2 = promise.then(successCallback, failureCallback);
 
 

现在,我们可以把回调绑定到返回的 Promise 上,形成一个 Promise 链:

-
doSomething().then(function(result) {
+
doSomething().then(function(result) {
   return doSomethingElse(result);
 })
 .then(function(newResult) {
@@ -104,7 +104,7 @@ const promise2 = promise.then(successCallback, failureCallback);
 
 

then 里的参数是可选的,catch(failureCallback)then(null, failureCallback) 的缩略形式。如下所示,我们也可以用箭头函数来表示:

-
doSomething()
+
doSomething()
 .then(result => doSomethingElse(result))
 .then(newResult => doThirdThing(newResult))
 .then(finalResult => {
@@ -119,7 +119,7 @@ const promise2 = promise.then(successCallback, failureCallback);
 
 

有可能会在一个回调失败之后继续使用链式操作,即,使用一个 catch,这对于在链式操作中抛出一个失败之后,再次进行新的操作会很有用。请阅读下面的例子:

-
new Promise((resolve, reject) => {
+
new Promise((resolve, reject) => {
     console.log('初始化');
 
     resolve();
@@ -139,7 +139,7 @@ const promise2 = promise.then(successCallback, failureCallback);
 
 

输出结果如下:

-
初始化
+
初始化
 执行“那个”
 执行“这个”,无论前面发生了什么
 
@@ -150,7 +150,7 @@ const promise2 = promise.then(successCallback, failureCallback);

在之前的回调地狱示例中,你可能记得有 3 次 failureCallback 的调用,而在 Promise 链中只有尾部的一次调用。

-
doSomething()
+
doSomething()
 .then(result => doSomethingElse(result))
 .then(newResult => doThirdThing(newResult))
 .then(finalResult => console.log(`Got the final result: ${finalResult}`))
@@ -160,7 +160,7 @@ const promise2 = promise.then(successCallback, failureCallback);
 
 

通常,一遇到异常抛出,浏览器就会顺着 Promise 链寻找下一个 onRejected 失败回调函数或者由 .catch() 指定的回调函数。这和以下同步代码的工作原理(执行过程)非常相似。

-
try {
+
try {
   let result = syncDoSomething();
   let newResult = syncDoSomethingElse(result);
   let finalResult = syncDoThirdThing(newResult);
@@ -172,7 +172,7 @@ const promise2 = promise.then(successCallback, failureCallback);
 
 

在 ECMAScript 2017 标准的 async/await 语法糖中,这种异步代码的对称性得到了极致的体现:

-
async function foo() {
+
async function foo() {
   try {
     const result = await doSomething();
     const newResult = await doSomethingElse(result);
@@ -204,7 +204,7 @@ const promise2 = promise.then(successCallback, failureCallback);
 
 

一个特别有用的例子:当你使用 {{Glossary("Node.js")}} 时,有些依赖模块可能会有未被处理的 rejected promises,这些都会在运行时打印到控制台。你可以在自己的代码中捕捉这些信息,然后添加与 {{domxref("Window.unhandledrejection_event", "unhandledrejection")}} 相应的处理函数来做分析和处理,或只是为了让你的输出更整洁。举例如下:

-
window.addEventListener("unhandledrejection", event => {
+
window.addEventListener("unhandledrejection", event => {
   /* 你可以在这里添加一些代码,以便检查
      event.promise 中的 promise 和
      event.reason 中的 rejection 原因 */
@@ -223,14 +223,14 @@ const promise2 = promise.then(successCallback, failureCallback);
 
 

理想状态下,所有的异步函数都已经返回 Promise 了。但有一些 API 仍然使用旧方式来传入的成功(或者失败)的回调。典型的例子就是 {{domxref("WindowTimers.setTimeout", "setTimeout()")}} 函数:

-
setTimeout(() => saySomething("10 seconds passed"), 10000);
+
setTimeout(() => saySomething("10 seconds passed"), 10000);
 

混用旧式回调和 Promise 可能会造成运行时序问题。如果 saySomething 函数失败了,或者包含了编程错误,那就没有办法捕获它了。这得怪 setTimeout

幸运地是,我们可以用 Promise 来封装它。最好的做法是,将这些有问题的函数封装起来,留在底层,并且永远不要再直接调用它们:

-
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
+
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
 
 wait(10000).then(() => saySomething("10 seconds")).catch(failureCallback);
 
@@ -245,33 +245,33 @@ wait(10000).then(() => saySomething("10 seconds")).catch(failureCallback);

我们可以发起并行操作,然后等多个操作全部结束后进行下一步操作,如下:

-
Promise.all([func1(), func2(), func3()])
+
Promise.all([func1(), func2(), func3()])
 .then(([result1, result2, result3]) => { /* use result1, result2 and result3 */ });

可以使用一些聪明的 JavaScript 写法实现时序组合:

-
[func1, func2, func3].reduce((p, f) => p.then(f), Promise.resolve())
+
[func1, func2, func3].reduce((p, f) => p.then(f), Promise.resolve())
 .then(result3 => { /* use result3 */ });

通常,我们递归调用一个由异步函数组成的数组时,相当于一个 Promise 链:

-
Promise.resolve().then(func1).then(func2).then(func3);
+
Promise.resolve().then(func1).then(func2).then(func3);

我们也可以写成可复用的函数形式,这在函数式编程中极为普遍:

-
const applyAsync = (acc,val) => acc.then(val);
+
const applyAsync = (acc,val) => acc.then(val);
 const composeAsync = (...funcs) => x => funcs.reduce(applyAsync, Promise.resolve(x));
 

composeAsync() 函数将会接受任意数量的函数作为其参数,并返回一个新的函数,该函数接受一个通过 composition pipeline 传入的初始值。这对我们来说非常有益,因为任一函数可以是异步或同步的,它们能被保证按顺序执行:

-
const transformData = composeAsync(func1, func2, func3);
+
const transformData = composeAsync(func1, func2, func3);
 const result3 = transformData(data);
 

在 ECMAScript 2017 标准中, 时序组合可以通过使用 async/await 而变得更简单:

-
let result;
+
let result;
 for (const f of [func1, func2, func3]) {
   result = await f(result);
 }
@@ -281,13 +281,13 @@ for (const f of [func1, func2, func3]) {
 
 

为了避免意外,即使是一个已经变成 resolve 状态的 Promise,传递给 then() 的函数也总是会被异步调用:

-
Promise.resolve().then(() => console.log(2));
+
Promise.resolve().then(() => console.log(2));
 console.log(1); // 1, 2
 

传递到 then() 中的函数被置入到一个微任务队列中,而不是立即执行,这意味着它是在 JavaScript 事件队列的所有运行时结束了,且事件队列被清空之后,才开始执行:

-
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
+
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
 
 wait().then(() => console.log(4));
 Promise.resolve().then(() => console.log(2)).then(() => console.log(3));
@@ -299,7 +299,7 @@ console.log(1); // 1, 2, 3, 4

嵌套 Promise 是一种可以限制 catch 语句的作用域的控制结构写法。明确来说,嵌套的 catch 仅捕捉在其之前同时还必须是其作用域的 failureres,而捕捉不到在其链式以外或者其嵌套域以外的 error。如果使用正确,那么可以实现高精度的错误修复。

-
doSomethingCritical()
+
doSomethingCritical()
 .then(result => doSomethingOptional()
   .then(optionalResult => doSomethingExtraNice(optionalResult))
   .catch(e => {console.log(e.message)})) // 即使有异常也会忽略,继续运行;(最后会输出)
@@ -314,7 +314,7 @@ console.log(1); // 1, 2, 3, 4

在编写 Promise 链时,需要注意以下示例中展示的几个错误:

-
// 错误示例,包含 3 个问题!
+
// 错误示例,包含 3 个问题!
 
 doSomething().then(function(result) {
   doSomethingElse(result) // 没有返回 Promise 以及没有必要的嵌套 Promise
@@ -330,7 +330,7 @@ doSomething().then(function(result) {
 
 

一个好的经验法则是总是返回或终止 Promise 链,并且一旦你得到一个新的 Promise,返回它。下面是修改后的平面化的代码:

-
doSomething()
+
doSomething()
 .then(function(result) {
   return doSomethingElse(result);
 })
-- 
cgit v1.2.3-54-g00ecf