diff --git a/02-javascript-algorithms-and-data-structures/es6.json b/02-javascript-algorithms-and-data-structures/es6.json index 75464f1..12f060b 100644 --- a/02-javascript-algorithms-and-data-structures/es6.json +++ b/02-javascript-algorithms-and-data-structures/es6.json @@ -8,33 +8,33 @@ "id": "587d7b87367417b2b2512b3f", "title": "Explore Differences Between the var and let Keywords", "description": [ - "One of the biggest problems with declaring variables with the var keyword is that you can overwrite variable declarations without an error.", - "
var camper = 'James';
var camper = 'David';
console.log(camper);
// logs 'David'
", - "As you can see in the code above, the camper variable is originally declared as James and then overridden to be David.", - "In a small application, you might not run into this type of problem, but when your code becomes larger, you might accidentally overwrite a variable that you did not intend to overwrite.", - "Because this behavior does not throw an error, searching and fixing bugs becomes more difficult.
", - "A new keyword called let was introduced in ES6 to solve this potential issue with the var keyword.", - "If you were to replace var with let in the variable declarations of the code above, the result would be an error.", - "
let camper = 'James';
let camper = 'David'; // throws an error
", - "This error can be seen in the console of your browser.", - "So unlike var, when using let, a variable with the same name can only be declared once.", - "Note the \"use strict\". This enables Strict Mode, which catches common coding mistakes and \"unsafe\" actions. For instance:", - "
\"use strict\";
x = 3.14; // throws an error because x is not declared
", + "使用 var 关键字来声明变量,会出现重复声明导致变量被覆盖却不会报错的问题:", + "
var camper = 'James';
var camper = 'David';
console.log(camper);
// 打印出 'David'
", + "在上面的代码中, camper 的初始值为 'James',然后又被覆盖成了 'David'。", + "在小型的应用中,你可能不会遇到这样的问题,但是当你的代码规模变得更加庞大的时候,就可能会在不经意间覆盖了之前定义的变量。", + "这样的行为不会报错导致了 debug 非常困难。
", + "在 ES6 中引入了新的关键字 let 来解决 var 关键字带来的潜在问题。", + "如果你在上面的代码中,使用了 let 关键字来代替 var关键字,结果会是一个报错。", + "
let camper = 'James';
let camper = 'David'; // 报错
", + "你可以在浏览器的控制台里看见这个错误。", + "与 var 不同的是, 当使用 let 的时候,同一名字的变量只能被声明一次。", + "请注意 \"use strict\"。这代表着开启了严格模式, 用于检测常见的代码错误以及\"不安全\"的行为,例如:", + "
\"use strict\";
x = 3.14; // x 没有声明导致了报错
", "
", - "Update the code so it only uses the let keyword." + "请更新这段代码,并且在其中只使用 let 关键字" ], "tests": [ { - "text": "var does not exist in code.", - "testString": "getUserInput => assert(!getUserInput('index').match(/var/g),'var does not exist in code.');" + "text": "在代码中不应存在 var。", + "testString": "getUserInput => assert(!getUserInput('index').match(/var/g),'在代码中不应存在 var。');" }, { - "text": "catName should be Oliver.", - "testString": "assert(catName === \"Oliver\", 'catName should be Oliver.');" + "text": "catName 变量的值应该为 \"Oliver\"。", + "testString": "assert(catName === \"Oliver\", 'catName 变量的值应该为 \"Oliver\"。');" }, { - "text": "quote should be \"Oliver says Meow!\"", - "testString": "assert(quote === \"Oliver says Meow!\", 'quote should be \"Oliver says Meow!\"');" + "text": "quote 变量的值应该为 \"Oliver says Meow!\"", + "testString": "assert(quote === \"Oliver says Meow!\", 'quote 变量的值应该为 \"Oliver says Meow!\"');" } ], "releasedOn": "Feb 17, 2017", @@ -65,33 +65,33 @@ "id": "587d7b87367417b2b2512b40", "title": "Compare Scopes of the var and let Keywords", "description": [ - "When you declare a variable with the var keyword, it is declared globally, or locally if declared inside a function.", - "The let keyword behaves similarly, but with some extra features. When you declare a variable with the let keyword inside a block, statement, or expression, its scope is limited to that block, statement, or expression.", - "For example:", - "
var numArray = [];
for (var i = 0; i < 3; i++) {
  numArray.push(i);
}
console.log(numArray);
// returns [0, 1, 2]
console.log(i);
// returns 3
", - "With the var keyword, i is declared globally. So when i++ is executed, it updates the global variable. This code is similar to the following:", + "当你使用 var 关键字来声明一个变量的时候,这个变量会被声明成全局变量,或是函数内的局部变量。", + "let 关键字的作用类似,但会有一些额外的特性。如果你在代码块、语句或表达式中使用关键字 let 声明变量,这个变量的作用域就被限制在当前的代码块,语句或表达式之中。", + "举个例子:", + "
var numArray = [];
for (var i = 0; i < 3; i++) {
  numArray.push(i);
}
console.log(numArray);
// 返回 [0, 1, 2]
console.log(i);
// 返回 3
", + "当使用 var 关键字的时候, i 会被声明成全局变量。 当 i++ 执行的时候, 它会改变全局变量的值。 这段代码可以看做下面这样:", "
var numArray = [];
var i;
for (i = 0; i < 3; i++) {
  numArray.push(i);
}
console.log(numArray);
// returns [0, 1, 2]
console.log(i);
// returns 3
", - "This behavior will cause problems if you were to create a function and store it for later use inside a for loop that uses the i variable. This is because the stored function will always refer to the value of the updated global i variable.", - "
var printNumTwo;
for (var i = 0; i < 3; i++) {
  if(i === 2){
    printNumTwo = function() {
      return i;
    };
  }
}
console.log(printNumTwo());
// returns 3
", - "As you can see, printNumTwo() prints 3 and not 2. This is because the value assigned to i was updated and the printNumTwo() returns the global i and not the value i had when the function was created in the for loop. The let keyword does not follow this behavior:", - "
'use strict';
let printNumTwo;
for (let i = 0; i < 3; i++) {
  if (i === 2) {
    printNumTwo = function() {
      return i;
    };
  }
}
console.log(printNumTwo());
// returns 2
console.log(i);
// returns \"i is not defined\"
", - "i is not defined because it was not declared in the global scope. It is only declared within the for loop statement. printNumTwo() returned the correct value because three different i variables with unique values (0, 1, and 2) were created by the let keyword within the loop statement.", + "如果你在 for 循环中创建了使用 i 变量的函数,那么在后续调用函数的时候,上面提到的这种行为就会导致问题。这是因为函数存储的值会因为全局变量 i的变化而不断的改变。", + "
var printNumTwo;
for (var i = 0; i < 3; i++) {
  if(i === 2){
    printNumTwo = function() {
      return i;
    };
  }
}
console.log(printNumTwo());
// 返回 3
", + "可以看到, printNumTwo() 打印了 3 而不是 2。 这是因为 i 发生了改变,并且函数 printNumTwo() 返回的是全局变量 i的值,而不是 for 循环中创建函数时 i 的值。let 关键字就不会有这种现象:", + "
'use strict';
let printNumTwo;
for (let i = 0; i < 3; i++) {
  if (i === 2) {
    printNumTwo = function() {
      return i;
    };
  }
}
console.log(printNumTwo());
// 返回 2
console.log(i);
// 返回 \"没有定义 i 变量\"
", + "i 在全局作用域中没有声明,所以它没有被定义,它的声明只会发生在 for 循环内。在循环执行的时候,let 关键字创建了三个不同的 i 变量,他们的值分别为 0、1 和 2,所以 printNumTwo() 返回了正确的值。", "
", - "Fix the code so that i declared in the if statement is a separate variable than i declared in the first line of the function. Be certain not to use the var keyword anywhere in your code.", - "This exercise is designed to illustrate the difference between how var and let keywords assign scope to the declared variable. When programming a function similar to the one used in this exercise, it is often better to use different variable names to avoid confusion." + "修改这段代码,使得在 if 语句中声明的 i 变量与在函数的第一行声明的 i 变量是彼此独立的。 请注意不要在你的代码的任何地方使用 var 关键字。", + "这个练习说明了使用 varlet关键字声明变量时,作用域之间的不同。当编写类似这个练习中的函数的时候,通常来说最好还是使用不同的变量名来避免误会。" ], "tests": [ { - "text": "var does not exist in code.", - "testString": "getUserInput => assert(!getUserInput('index').match(/var/g),'var does not exist in code.');" + "text": "var 不应该在代码中存在。", + "testString": "getUserInput => assert(!getUserInput('index').match(/var/g),'var 不应该在代码中存在。');" }, { - "text": "The variable i declared in the if statement should equal \"block scope\".", - "testString": "getUserInput => assert(getUserInput('index').match(/(i\\s*=\\s*).*\\s*.*\\s*.*\\1('|\")block\\s*scope\\2/g), 'The variable i declared in the if statement should equal \"block scope\".');" + "text": "在 if 语句中声明的 i 变量的值是 \"block scope\"。", + "testString": "getUserInput => assert(getUserInput('index').match(/(i\\s*=\\s*).*\\s*.*\\s*.*\\1('|\")block\\s*scope\\2/g), '在 if 语句中声明的 i 变量应该是 \"block scope\"。');" }, { - "text": "checkScope() should return \"function scope\"", - "testString": "assert(checkScope() === \"function scope\", 'checkScope() should return \"function scope\"');" + "text": "checkScope() 应当返回 \"function scope\"", + "testString": "assert(checkScope() === \"function scope\", 'checkScope() 应该返回 \"function scope\"');" } ], "releasedOn": "Feb 17, 2017", @@ -122,29 +122,29 @@ "id": "587d7b87367417b2b2512b41", "title": "Declare a Read-Only Variable with the const Keyword", "description": [ - "let is not the only new way to declare variables. In ES6, you can also declare variables using the const keyword.", - "const has all the awesome features that let has, with the added bonus that variables declared using const are read-only. They are a constant value, which means that once a variable is assigned with const, it cannot be reassigned.", - "
\"use strict\"
const FAV_PET = \"Cats\";
FAV_PET = \"Dogs\"; // returns error
", - "As you can see, trying to reassign a variable declared with const will throw an error. You should always name variables you don't want to reassign using the const keyword. This helps when you accidentally attempt to reassign a variable that is meant to stay constant. A common practice when naming constants is to use all uppercase letters, with words separated by an underscore.", + "let 并不是唯一的新的声明变量的方式。在 ES6里面,你还可以使用 const 关键字来声明变量。", + "const 拥有 let 的所有优点,所不同的是,通过code 声明的变量是只读的。这意味着通过 const 声明的变量只能被赋值一次,而不能被再次赋值。", + "
\"use strict\"
const FAV_PET = \"Cats\";
FAV_PET = \"Dogs\"; // 报错
", + "可以看见,尝试给通过 const 声明的变量再次赋值会报错。你应该使用 const 关键字来对所有不打算再次赋值的变量进行声明。这有助于你避免给一个常量进行额外的再次赋值。一个最佳实践是对所有常量的命名采用全大写字母,并在单词之间使用下划线进行分隔。", "
", - "Change the code so that all variables are declared using let or const. Use let when you want the variable to change, and const when you want the variable to remain constant. Also, rename variables declared with const to conform to common practices, meaning constants should be in all caps." + "改变以下代码,使得所有的变量都使用 letconst 关键词来声明。当变量将会改变的时候使用 let关键字,当变量要保持常量的时候使用 const 关键字。同时,对使用 const 声明的变量进行最佳实践的重命名,变量名中的字母应该都是大写的。" ], "tests": [ { - "text": "var does not exist in your code.", - "testString": "getUserInput => assert(!getUserInput('index').match(/var/g),'var does not exist in your code.');" + "text": "var 在代码中不存在。", + "testString": "getUserInput => assert(!getUserInput('index').match(/var/g),'var 在代码中不存在。');" }, { - "text": "SENTENCE should be a constant variable declared with const.", - "testString": "getUserInput => assert(getUserInput('index').match(/(const SENTENCE)/g), 'SENTENCE should be a constant variable declared with const.');" + "text": "SENTENCE 应该是使用 const 声明的常量。", + "testString": "getUserInput => assert(getUserInput('index').match(/(const SENTENCE)/g), 'SENTENCE 应该是使用 const 声明的常量。');" }, { - "text": "i should be declared with let.", - "testString": "getUserInput => assert(getUserInput('index').match(/(let i)/g), 'i should be declared with let.');" + "text": "i 应该是使用 let 声明的变量。", + "testString": "getUserInput => assert(getUserInput('index').match(/(let i)/g), 'i 应该是使用 let 声明的变量。');" }, { - "text": "console.log should be changed to print the SENTENCE variable.", - "testString": "getUserInput => assert(getUserInput('index').match(/console\\.log\\(\\s*SENTENCE\\s*\\)\\s*;?/g), 'console.log should be adjusted to print the variable SENTENCE.');" + "text": "console.log 应该修改为用于打印 SENTENCE 变量。", + "testString": "getUserInput => assert(getUserInput('index').match(/console\\.log\\(\\s*SENTENCE\\s*\\)\\s*;?/g), 'console.log 应该修改为用于打印 SENTENCE 变量。');" } ], "releasedOn": "Feb 17, 2017", @@ -158,14 +158,14 @@ "function printManyTimes(str) {", " \"use strict\";", "", - " // change code below this line", + " // 在这行以下修改代码", "", " var sentence = str + \" is cool!\";", " for(var i = 0; i < str.length; i+=2) {", " console.log(sentence);", " }", "", - " // change code above this line", + " // 在这行以上修改代码", "", "}", "printManyTimes(\"freeCodeCamp\");" @@ -179,30 +179,30 @@ "id": "587d7b87367417b2b2512b42", "title": "Mutate an Array Declared with const", "description": [ - "The const declaration has many use cases in modern JavaScript.", - "Some developers prefer to assign all their variables using const by default, unless they know they will need to reassign the value. Only in that case, they use let.", - "However, it is important to understand that objects (including arrays and functions) assigned to a variable using const are still mutable. Using the const declaration only prevents reassignment of the variable identifier.", - "
\"use strict\";
const s = [5, 6, 7];
s = [1, 2, 3]; // throws error, trying to assign a const
s[2] = 45; // works just as it would with an array declared with var or let
console.log(s); // returns [5, 6, 45]
", - "As you can see, you can mutate the object [5, 6, 7] itself and the variable s will still point to the altered array [5, 6, 45]. Like all arrays, the array elements in s are mutable, but because const was used, you cannot use the variable identifier s to point to a different array using the assignment operator.", + "在现代的 JavaScript 里,const 声明有很多用法", + "一些开发者倾向默认使用 const 来声明所有变量,除非在他们知道需要更改某个变量的值的时候,才会使用 let", + "然而,重点是要理解对象(包括数组和函数)在使用 const 声明的时候依然是可变的。使用 const来声明只会保证它的标识不会被重新赋值。", + "
\"use strict\";
const s = [5, 6, 7];
s = [1, 2, 3]; // 试图给 const 变量赋值,报错
s[2] = 45; // 与用 var 或 let 声明的数组一样,这个操作也会成功
console.log(s); // 返回 [5, 6, 45]
", + "可以看见,你可以改变 [5, 6, 7] 自身,所以 s 变量指向了改变后的数组 [5, 6, 45]。和所有数组一样,数组 s中的数组元素是可以被改变的,但是因为使用了 const 关键字,你不能使用赋值操作符将变量标识 s 指向另外一个数组", "
", - "An array is declared as const s = [5, 7, 2]. Change the array to [2, 5, 7] using various element assignment." + "这里有一个使用 const s = [5, 7, 2] 声明的数组。使用对各元素赋值的方法将数组改成 [2, 5, 7]。" ], "tests": [ { - "text": "Do not replace const keyword.", - "testString": "getUserInput => assert(getUserInput('index').match(/const/g), 'Do not replace const keyword.');" + "text": "不要替换 const 关键字。", + "testString": "getUserInput => assert(getUserInput('index').match(/const/g), '不要替换 const 关键字。');" }, { - "text": "s should be a constant variable (by using const).", - "testString": "getUserInput => assert(getUserInput('index').match(/const\\s+s/g), 's should be a constant variable (by using const).');" + "text": "s 应该为常量 (通过使用 const)。", + "testString": "getUserInput => assert(getUserInput('index').match(/const\\s+s/g), 's 应该为常量 (通过使用 const)。');" }, { - "text": "Do not change the original array declaration.", - "testString": "getUserInput => assert(getUserInput('index').match(/const\\s+s\\s*=\\s*\\[\\s*5\\s*,\\s*7\\s*,\\s*2\\s*\\]\\s*;?/g), 'Do not change the original array declaration.');" + "text": "不要改变原数组的声明。", + "testString": "getUserInput => assert(getUserInput('index').match(/const\\s+s\\s*=\\s*\\[\\s*5\\s*,\\s*7\\s*,\\s*2\\s*\\]\\s*;?/g), '不要改变原数组的声明。');" }, { - "text": "s should be equal to [2, 5, 7].", - "testString": "assert.deepEqual(s, [2, 5, 7], 's should be equal to [2, 5, 7].');" + "text": "s 应该等于 [2, 5, 7]。", + "testString": "assert.deepEqual(s, [2, 5, 7], 's 应该等于 [2, 5, 7]。');" } ], "releasedOn": "Feb 17, 2017", @@ -216,11 +216,11 @@ "const s = [5, 7, 2];", "function editInPlace() {", " \"use strict\";", - " // change code below this line", + " // 在这行以下修改代码", "", " // s = [2, 5, 7]; <- this is invalid", "", - " // change code above this line", + " // 在这行以上修改代码", "}", "editInPlace();" ], @@ -233,28 +233,28 @@ "id": "598f48a36c8c40764b4e52b3", "title": "Prevent Object Mutation", "description": [ - "As seen in the previous challenge, const declaration alone doesn't really protect your data from mutation. To ensure your data doesn't change, JavaScript provides a function Object.freeze to prevent data mutation.", - "Once the object is frozen, you can no longer add, update, or delete properties from it. Any attempt at changing the object will be rejected without an error.", - "
let obj = {
  name:\"FreeCodeCamp\",
  review:\"Awesome\"
};
Object.freeze(obj);
obj.review = \"bad\"; //will be ignored. Mutation not allowed
obj.newProp = \"Test\"; // will be ignored. Mutation not allowed
console.log(obj);
// { name: \"FreeCodeCamp\", review:\"Awesome\"}
", + "通过之前的挑战可以看出, const 声明并不会真的保护你的数据不被改变. 为了确保数据不被改变, Javascript 提供了一个函数 Object.freeze 来防止数据改变。", + "当一个对象被冻结的时候,你不能再对它的属性再进行增、删、改的操作。任何试图改变对象的操作都会被阻止,却不会报错。", + "
let obj = {
  name:\"FreeCodeCamp\",
  review:\"Awesome\"
};
Object.freeze(obj);
obj.review = \"bad\"; //obj 对象被冻结了,这个操作会被忽略
obj.newProp = \"Test\"; // will be ignored. Mutation not allowed
console.log(obj);
// { name: \"FreeCodeCamp\", review:\"Awesome\"}
", "
", - "In this challenge you are going to use Object.freeze to prevent mathematical constants from changing. You need to freeze the MATH_CONSTANTS object so that no one is able alter the value of PI, add, or delete properties ." + "在这个挑战中,你将使用 Object.freeze 来防止数学常量被改变。你需要冻结 MATH_CONSTANTS 对象,使得没有人可以改变 PI 的值,抑或增加或删除属性。" ], "tests": [ { - "text": "Do not replace const keyword.", - "testString": "getUserInput => assert(getUserInput('index').match(/const/g), 'Do not replace const keyword.');" + "text": "不要替换 const 关键字。", + "testString": "getUserInput => assert(getUserInput('index').match(/const/g), '不要替换 const 关键字。');" }, { - "text": "MATH_CONSTANTS should be a constant variable (by using const).", - "testString": "getUserInput => assert(getUserInput('index').match(/const\\s+MATH_CONSTANTS/g), 'MATH_CONSTANTS should be a constant variable (by using const).');" + "text": "MATH_CONSTANTS 应该为一个常量 (使用 const)。", + "testString": "getUserInput => assert(getUserInput('index').match(/const\\s+MATH_CONSTANTS/g), 'MATH_CONSTANTS 应该为一个常量 (使用 const)。');" }, { - "text": "Do not change original MATH_CONSTANTS.", - "testString": "getUserInput => assert(getUserInput('index').match(/const\\s+MATH_CONSTANTS\\s+=\\s+{\\s+PI:\\s+3.14\\s+};/g), 'Do not change original MATH_CONSTANTS.');" + "text": "不要改变原始的 MATH_CONSTANTS。", + "testString": "getUserInput => assert(getUserInput('index').match(/const\\s+MATH_CONSTANTS\\s+=\\s+{\\s+PI:\\s+3.14\\s+};/g), '不要改变原始的 MATH_CONSTANTS。');" }, { - "text": "PI equals 3.14.", - "testString": "assert(PI === 3.14, 'PI equals 3.14.');" + "text": "PI 等于 3.14。", + "testString": "assert(PI === 3.14, 'PI 等于 3.14。');" } ], "releasedOn": "Aug 12, 2017", @@ -270,10 +270,10 @@ " const MATH_CONSTANTS = {", " PI: 3.14", " };", - " // change code below this line", + " // 在这行以下修改代码", "", "", - " // change code above this line", + " // 在这行以上修改代码", " try {", " MATH_CONSTANTS.PI = 99;", " } catch( ex ) {", @@ -292,37 +292,37 @@ "id": "587d7b87367417b2b2512b43", "title": "Use Arrow Functions to Write Concise Anonymous Functions", "description": [ - "In JavaScript, we often don't need to name our functions, especially when passing a function as an argument to another function. Instead, we create inline functions. We don't need to name these functions because we do not reuse them anywhere else.", - "To achieve this, we often use the following syntax:", + "在JavaScript里,我们会经常遇到不需要给函数命名的情况,尤其是在需要将以个函数作为参数传给另外一个函数的时候,在这些时候,我们会创建行内函数。因为这些函数不会再其他地方复用,所以我们不要给它们命名。", + "这种情况下,我们通常会使用以下语法:", "
const myFunc = function() {
  const myVar = \"value\";
  return myVar;
}
", - "ES6 provides us with the syntactic sugar to not have to write anonymous functions this way. Instead, you can use arrow function syntax:", + "ES6 提供了其他写匿名函数的方式的语法糖。你可以使用箭头函数:", "
const myFunc = () => {
  const myVar = \"value\";
  return myVar;
}
", - "When there is no function body, and only a return value, arrow function syntax allows you to omit the keyword return as well as the brackets surrounding the code. This helps simplify smaller functions into one-line statements:", + "当不需要函数体,只返回一个值的时候,箭头函数允许你省略 return 关键字和外面的大括号。这样就可以将一个简单的函数简化成一个单行语句。", "
const myFunc= () => \"value\"
", - "This code will still return value by default.", + "这段代码仍然会返回 value", "
", - "Rewrite the function assigned to the variable magic which returns a new Date() to use arrow function syntax. Also make sure nothing is defined using the keyword var." + "使用箭头函数的语法重写 magic 函数,使其返回一个新的 Date()。同时不要用 var 关键字来定义任何变量。" ], "tests": [ { - "text": "User did replace var keyword.", - "testString": "getUserInput => assert(!getUserInput('index').match(/var/g), 'User did replace var keyword.');" + "text": "替换掉 var 关键字。", + "testString": "getUserInput => assert(!getUserInput('index').match(/var/g), '替换掉 var 关键字。');" }, { - "text": "magic should be a constant variable (by using const).", - "testString": "getUserInput => assert(getUserInput('index').match(/const\\s+magic/g), 'magic should be a constant variable (by using const).');" + "text": "magic 应该为一个常量 (使用 const)。", + "testString": "getUserInput => assert(getUserInput('index').match(/const\\s+magic/g), 'magic 应该为一个常量 (使用 const)。');" }, { - "text": "magic is a function.", - "testString": "assert(typeof magic === 'function', 'magic is a function.');" + "text": "magic 是一个 function。", + "testString": "assert(typeof magic === 'function', 'magic 是一个 function。');" }, { - "text": "magic() returns correct date.", - "testString": "assert(magic().getDate() == new Date().getDate(), 'magic() returns correct date.');" + "text": "magic() 返回正确的日期。", + "testString": "assert(magic().getDate() == new Date().getDate(), 'magic() 返回正确的日期。');" }, { - "text": "function keyword was not used.", - "testString": "getUserInput => assert(!getUserInput('index').match(/function/g), 'function keyword was not used.');" + "text": "不要使用 function 关键字。", + "testString": "getUserInput => assert(!getUserInput('index').match(/function/g), '不要使用 function 关键字。');" } ], "releasedOn": "Feb 17, 2017", @@ -347,32 +347,32 @@ "id": "587d7b88367417b2b2512b44", "title": "Write Arrow Functions with Parameters", "description": [ - "Just like a normal function, you can pass arguments into arrow functions.", + "和一般的函数一样,你也可以给箭头函数传递参数。", "
// doubles input value and returns it
const doubler = (item) => item * 2;
", - "You can pass more than one argument into arrow functions as well.", + "你可以同样可以给箭头函数传递多个参数。", "
", - "Rewrite the myConcat function which appends contents of arr2 to arr1 so that the function uses arrow function syntax." + "使用箭头函数的语法重写 myConcat 函数,使其可以将 arr2 的内容粘贴在 arr1里。" ], "tests": [ { - "text": "User did replace var keyword.", - "testString": "getUserInput => assert(!getUserInput('index').match(/var/g), 'User did replace var keyword.');" + "text": "替换掉所有的 var 关键字。", + "testString": "getUserInput => assert(!getUserInput('index').match(/var/g), '替换掉所有的 var 关键字。');" }, { - "text": "myConcat should be a constant variable (by using const).", - "testString": "getUserInput => assert(getUserInput('index').match(/const\\s+myConcat/g), 'myConcat should be a constant variable (by using const).');" + "text": "myConcat 应该是一个常量 (使用 const)。", + "testString": "getUserInput => assert(getUserInput('index').match(/const\\s+myConcat/g), 'myConcat 应该是一个常量 (使用 const)。');" }, { - "text": "myConcat should be a function", - "testString": "assert(typeof myConcat === 'function', 'myConcat should be a function');" + "text": "myConcat 应该是一个函数。", + "testString": "assert(typeof myConcat === 'function', 'myConcat 应该是一个函数。');" }, { - "text": "myConcat() returns the correct array", - "testString": "assert(() => { const a = myConcat([1], [2]); return a[0] == 1 && a[1] == 2; }, 'myConcat() returns the correct array');" + "text": "myConcat() 返回正确的 array。", + "testString": "assert(() => { const a = myConcat([1], [2]); return a[0] == 1 && a[1] == 2; }, 'myConcat() 返回正确的 array。');" }, { - "text": "function keyword was not used.", - "testString": "getUserInput => assert(!getUserInput('index').match(/function/g), 'function keyword was not used.');" + "text": "不要使用 function 关键字。", + "testString": "getUserInput => assert(!getUserInput('index').match(/function/g), '不要使用 function 关键字。');" } ], "releasedOn": "Feb 17, 2017", @@ -387,7 +387,7 @@ " \"use strict\";", " return arr1.concat(arr2);", "};", - "// test your code", + "// 测试你的代码", "console.log(myConcat([1, 2], [3, 4, 5]));" ], "head": [], @@ -399,44 +399,44 @@ "id": "587d7b88367417b2b2512b45", "title": "Write Higher Order Arrow Functions", "description": [ - "It's time we see how powerful arrow functions are when processing data.", - "Arrow functions work really well with higher order functions, such as map(), filter(), and reduce(), that take other functions as arguments for processing collections of data.", - "Read the following code:", + "我们已经见识到了箭头函数在处理数据时候的强大之处。", + "箭头函数在类似 map, filter, reduce 等需要其他函数作为参数来处理数据的高阶函数里会很好用。" , + "阅读以下代码:", "
FBPosts.filter(function(post) {
  return post.thumbnail !== null && post.shares > 100 && post.likes > 500;
})
", - "We have written this with filter() to at least make it somewhat readable. Now compare it to the following code which uses arrow function syntax instead:", + "我们写下了 filter 函数,并尽量保证可读性。现在让我们用箭头函数来写同样的代码看看:", "
FBPosts.filter((post) => post.thumbnail !== null && post.shares > 100 && post.likes > 500)
", - "This code is more succinct and accomplishes the same task with fewer lines of code.", + "这段代码完成了同样的任务,却变得更加剪短易懂了。", "
", - "Use arrow function syntax to compute the square of only the positive integers (fractions are not integers) in the array realNumberArray and store the new array in the variable squaredIntegers." + "使用箭头函数的语法来计算 squaredIntegers 数组里正整数的平方(分数不是整数)" ], "tests": [ { - "text": "User did replace var keyword.", - "testString": "getUserInput => assert(!getUserInput('index').match(/var/g), 'User did replace var keyword.');" + "text": "替换掉所有的 var 关键字。", + "testString": "getUserInput => assert(!getUserInput('index').match(/var/g), '替换掉所有的 var 关键字。');" }, { - "text": "squaredIntegers should be a constant variable (by using const).", - "testString": "getUserInput => assert(getUserInput('index').match(/const\\s+squaredIntegers/g), 'squaredIntegers should be a constant variable (by using const).');" + "text": "squaredIntegers 应该是一个常量 (使用 const)。", + "testString": "getUserInput => assert(getUserInput('index').match(/const\\s+squaredIntegers/g), 'squaredIntegers 应该是一个常量 (使用 const)。');" }, { - "text": "squaredIntegers should be an array", - "testString": "assert(Array.isArray(squaredIntegers), 'squaredIntegers should be an array');" + "text": "squaredIntegers 应该是一个 array。", + "testString": "assert(Array.isArray(squaredIntegers), 'squaredIntegers 应该是一个 array');" }, { - "text": "squaredIntegers should be [16, 1764, 36]", - "testString": "assert(squaredIntegers[0] === 16 && squaredIntegers[1] === 1764 && squaredIntegers[2] === 36, 'squaredIntegers should be [16, 1764, 36]');" + "text": "squaredIntegers 应该是 [16, 1764, 36]", + "testString": "assert(squaredIntegers[0] === 16 && squaredIntegers[1] === 1764 && squaredIntegers[2] === 36, 'squaredIntegers 应该是 [16, 1764, 36]');" }, { - "text": "function keyword was not used.", - "testString": "getUserInput => assert(!getUserInput('index').match(/function/g), 'function keyword was not used.');" + "text": "不要使用 function 关键字。", + "testString": "getUserInput => assert(!getUserInput('index').match(/function/g), '不要使用 function 关键字。');" }, { - "text": "loop should not be used", - "testString": "getUserInput => assert(!getUserInput('index').match(/(for)|(while)/g), 'loop should not be used');" + "text": "不要使用循环", + "testString": "getUserInput => assert(!getUserInput('index').match(/(for)|(while)/g), '不要使用循环');" }, { - "text": "map, filter, or reduce should be used", - "testString": "getUserInput => assert(getUserInput('index').match(/map|filter|reduce/g), 'map, filter, or reduce should be used');" + "text": "请使用 map, filter, 或者 reduce。", + "testString": "getUserInput => assert(getUserInput('index').match(/map|filter|reduce/g), '请使用 map, filter, 或者 reduce。');" } ], "releasedOn": "Feb 17, 2017", @@ -450,12 +450,12 @@ "const realNumberArray = [4, 5.6, -9.8, 3.14, 42, 6, 8.34];", "const squareList = (arr) => {", " \"use strict\";", - " // change code below this line", + " // 在这行以下修改代码", " const squaredIntegers = arr;", - " // change code above this line", + " // 在这行以上修改代码", " return squaredIntegers;", "};", - "// test your code", + "// 测试你的代码", "const squaredIntegers = squareList(realNumberArray);", "console.log(squaredIntegers);" ], @@ -468,24 +468,24 @@ "id": "587d7b88367417b2b2512b46", "title": "Set Default Parameters for Your Functions", "description": [ - "In order to help us create more flexible functions, ES6 introduces default parameters for functions.", - "Check out this code:", + "ES6 里允许给函数传入默认参数,来构建更加灵活的函数。", + "查看以下代码:", "
function greeting(name = \"Anonymous\") {
  return \"Hello \" + name;
}
console.log(greeting(\"John\")); // Hello John
console.log(greeting()); // Hello Anonymous
", - "The default parameter kicks in when the argument is not specified (it is undefined). As you can see in the example above, the parameter name will receive its default value \"Anonymous\" when you do not provide a value for the parameter. You can add default values for as many parameters as you want.", + "默认参数会在参数没有被指定(值为 undefined )的时候起作用。在上面的例子中,参数 name 会在没有得到新的值的时候,默认使用值 \"Anonymous\"。你还可以给多个参数赋予默认值。", "
", - "Modify the function increment by adding default parameters so that it will add 1 to number if value is not specified." + "给函数 increment 加上默认参数,使得在 value 没有被赋值的时候,默认给 number 加1。" ], "tests": [ { - "text": "The result of increment(5, 2) should be 7.", - "testString": "assert(increment(5, 2) === 7, 'The result of increment(5, 2) should be 7.');" + "text": "increment(5, 2) 的结果应该为 7。", + "testString": "assert(increment(5, 2) === 7, 'increment(5, 2) 的结果应该为 7。');" }, { - "text": "The result of increment(5) should be 6.", - "testString": "assert(increment(5) === 6, 'The result of increment(5) should be 6.');" + "text": "increment(5) 的结果应该为 6。", + "testString": "assert(increment(5) === 6, 'increment(5) 的结果应该为 6。');" }, { - "text": "default parameter 1 was used for value.", + "text": "参数 value 的默认值应该为 1。", "testString": "getUserInput => assert(getUserInput('index').match(/value\\s*=\\s*1/g), 'default parameter 1 was used for value.');" } ], @@ -503,8 +503,8 @@ " return number + value;", " };", "})();", - "console.log(increment(5, 2)); // returns 7", - "console.log(increment(5)); // returns NaN" + "console.log(increment(5, 2)); // 返回 7", + "console.log(increment(5)); // 返回 NaN" ], "head": [], "tail": [] @@ -515,33 +515,33 @@ "id": "587d7b88367417b2b2512b47", "title": "Use the Rest Operator with Function Parameters", "description": [ - "In order to help us create more flexible functions, ES6 introduces the rest operator for function parameters. With the rest operator, you can create functions that take a variable number of arguments. These arguments are stored in an array that can be accessed later from inside the function.", - "Check out this code:", - "
function howMany(...args) {
  return \"You have passed \" + args.length + \" arguments.\";
}
console.log(howMany(0, 1, 2)); // You have passed 3 arguments
console.log(howMany(\"string\", null, [1, 2, 3], { })); // You have passed 4 arguments.
", - "The rest operator eliminates the need to check the args array and allows us to apply map(), filter() and reduce() on the parameters array.", + "ES6 推出了用于函数参数的rest 操作符 帮助我们创建更加灵活的函数。 在 rest 操作符的帮助下,你可以创建有一个变量来接受多个参数的函数。 这些参数被储存在一个可以在函数内部读取的数组中。", + "请看以下代码:", + "
function howMany(...args) {
  return \"You have passed \" + args.length + \" arguments.\";
}
console.log(howMany(0, 1, 2)); // 你需要输入3个参数。
console.log(howMany(\"string\", null, [1, 2, 3], { })); //你需要输入4个参数。
", + "rest 操作符可以避免查看 args 数组的需求,并且允许我们在参数数组上使用 map(), fiter(),和 reduce()", "
", - "Modify the function sum so that it uses the rest operator and it works in the same way with any number of parameters." + "修改 sum 函数,来让它使用 rest操作符,并且它可以在有任何数量的参数时以相同的形式工作" ], "tests": [ { - "text": "The result of sum(0,1,2) should be 3", - "testString": "assert(sum(0,1,2) === 3, 'The result of sum(0,1,2) should be 3');" + "text": "sum(0,1,2) 的返回结果应该为3。", + "testString": "assert(sum(0,1,2) === 3, 'sum(0,1,2) 的返回结果应该为3。');" }, { - "text": "The result of sum(1,2,3,4) should be 10", - "testString": "assert(sum(1,2,3,4) === 10, 'The result of sum(1,2,3,4) should be 10');" + "text": "sum(1,2,3,4) 的返回结果应该为10。", + "testString": "assert(sum(1,2,3,4) === 10, 'sum(1,2,3,4) 的返回结果应该为10。');" }, { - "text": "The result of sum(5) should be 5", - "testString": "assert(sum(5) === 5, 'The result of sum(5) should be 5');" + "text": "sum(5) 的返回结果应该为5。", + "testString": "assert(sum(5) === 5, 'sum(5) 的返回结果应该为5。');" }, { - "text": "The result of sum() should be 0", - "testString": "assert(sum() === 0, 'The result of sum() should be 0');" + "text": "sum()的返回结果应该为 0。", + "testString": "assert(sum() === 0, 'sum()的返回结果应该为 0。');" }, { - "text": "The sum function uses the ... spread operator on the args parameter.", - "testString": "getUserInput => assert(getUserInput('index').match(/function\\s+sum\\s*\\(\\s*...args\\s*\\)\\s*{/g), 'The sum function uses the ... spread operator on the args parameter.');" + "text": "对 sum 函数的 args 参数使用了 ... 展开操作符。", + "testString": "getUserInput => assert(getUserInput('index').match(/function\\s+sum\\s*\\(\\s*...args\\s*\\)\\s*{/g), '对 sum 函数的 args 参数使用了 ... 展开操作符。');" } ], "releasedOn": "Feb 17, 2017", @@ -570,30 +570,30 @@ "id": "587d7b89367417b2b2512b48", "title": "Use the Spread Operator to Evaluate Arrays In-Place", "description": [ - "ES6 introduces the spread operator, which allows us to expand arrays and other expressions in places where multiple parameters or elements are expected.", - "The ES5 code below uses apply() to compute the maximum value in an array:", - "
var arr = [6, 89, 3, 45];
var maximus = Math.max.apply(null, arr); // returns 89
", - "We had to use Math.max.apply(null, arr) because Math.max(arr) returns NaN. Math.max() expects comma-separated arguments, but not an array.", + "ES6 允许我们使用 展开操作符 来展开数组,以及需要多个参数或元素的表达式。", + "下面的 ES5 代码使用了 apply() 来计算数组的最大值:", + "
var arr = [6, 89, 3, 45];
var maximus = Math.max.apply(null, arr); // 返回 89
", + "我们必须使用 Math.max.apply(null,arr),是因为直接调用 Math.max(arr) 会返回 NaNMath.max() 函数需要传入的是一系列由逗号分隔的参数,而不是一个数组。", "The spread operator makes this syntax much better to read and maintain.", - "
const arr = [6, 89, 3, 45];
const maximus = Math.max(...arr); // returns 89
", - "...arr returns an unpacked array. In other words, it spreads the array.", - "However, the spread operator only works in-place, like in an argument to a function or in an array literal. The following code will not work:", - "
const spreaded = ...arr; // will throw a syntax error
", + "
const arr = [6, 89, 3, 45];
const maximus = Math.max(...arr); // 返回 89
", + "...arr 返回了一个“打开”的数组。 或者说它 展开 了数组。", + "然而,展开操作符只能够在函数的参数中,或者数组之中使用。下面的代码将会报错:", + "
const spreaded = ...arr; // 将会发生语法错误
", "
", - "Copy all contents of arr1 into another array arr2 using the spread operator." + "使用展开操作符将 arr1 中的内容都赋值到 arr2 中去。" ], "tests": [ { - "text": "arr2 is correct copy of arr1.", - "testString": "assert(arr2.every((v, i) => v === arr1[i]), 'arr2 is correct copy of arr1.');" + "text": "arr2 的值是由 arr1 拷贝而来的。", + "testString": "assert(arr2.every((v, i) => v === arr1[i]), 'arr2 的值是由 arr1 拷贝而来的。');" }, { - "text": "... spread operator was used to duplicate arr1.", - "testString": "getUserInput => assert(getUserInput('index').match(/\\[\\s*...arr1\\s*\\]/g),'... spread operator was used to duplicate arr1.');" + "text": "用... 展开操作符来赋值 arr1。", + "testString": "getUserInput => assert(getUserInput('index').match(/\\[\\s*...arr1\\s*\\]/g),'用... 展开操作符来赋值 arr1。');" }, { - "text": "arr2 remains unchanged when arr1 is changed.", - "testString": "assert((arr1, arr2) => {arr1.push('JUN'); return arr2.length < arr1.length},'arr2 remains unchanged when arr1 is changed.');" + "text": "当 arr1 改变的时候,arr2 不会改变。", + "testString": "assert((arr1, arr2) => {arr1.push('JUN'); return arr2.length < arr1.length},'当 arr1 改变的时候,arr2 不会改变。');" } ], "releasedOn": "Feb 17, 2017", @@ -608,7 +608,7 @@ "let arr2;", "(function() {", " \"use strict\";", - " arr2 = []; // change this line", + " arr2 = []; // 改变这一行", "})();", "console.log(arr2);" ], @@ -621,30 +621,30 @@ "id": "587d7b89367417b2b2512b49", "title": "Use Destructuring Assignment to Assign Variables from Objects", "description": [ - "We saw earlier how spread operator can effectively spread, or unpack, the contents of the array.", - "We can do something similar with objects as well. Destructuring assignment is special syntax for neatly assigning values taken directly from an object to variables.", - "Consider the following ES5 code:", + "我们之前看到了展开操作符是如何展开数组的内容的。", + "我们队对象也可以做同样的操作。 解构赋值 就是可以从对象中直接获取对应值的语法。", + "看看以下 ES5 的代码:", "
var voxel = {x: 3.6, y: 7.4, z: 6.54 };
var x = voxel.x; // x = 3.6
var y = voxel.y; // y = 7.4
var z = voxel.z; // z = 6.54
", - "Here's the same assignment statement with ES6 destructuring syntax:", + "使用 ES6 的解构语法可以完成同样的赋值语句:", "
const { x, y, z } = voxel; // x = 3.6, y = 7.4, z = 6.54
", - "If instead you want to store the values of voxel.x into a, voxel.y into b, and voxel.z into c, you have that freedom as well.", + "如果你想将 voxel.x, voxel.y, voxel.z 的值分别赋给 a, b, c,可以用以下这种很棒的方式:", "
const { x : a, y : b, z : c } = voxel // a = 3.6, b = 7.4, c = 6.54
", - "You may read it as \"get the field x and copy the value into a,\" and so on.", + "你可以这样理解:“将 x 地址中的值拷贝到 a 当中去。”,等等。", "
", - "Use destructuring to obtain the length of the input string str, and assign the length to len in line." + "使用解构语法去得到输入的 str 字符串的长度,并将长度赋值给 len。" ], "tests": [ { - "text": "the function getLength() returns a number.", - "testString": "assert(typeof getLength('') === 'number', 'the function getLength() returns a number.');" + "text": "函数 getLength() 返回一个数字。", + "testString": "assert(typeof getLength('') === 'number', '函数 getLength() 返回一个数字。');" }, { - "text": "getLength(\"FreeCodeCamp\") should be 12", - "testString": "assert(getLength(\"FreeCodeCamp\") === 12, 'getLength(\"FreeCodeCamp\") should be 12');" + "text": "getLength(\"FreeCodeCamp\") 应该返回 12。", + "testString": "assert(getLength(\"FreeCodeCamp\") === 12, 'getLength(\"FreeCodeCamp\") 应该返回 12。');" }, { - "text": "destructuring with reassignment was used", - "testString": "getUserInput => assert(getUserInput('index').match(/\\{\\s*length\\s*:\\s*len\\s*}\\s*=\\s*str/g),'destructuring with reassignment was used');" + "text": "使用解构语法来重新赋值。", + "testString": "getUserInput => assert(getUserInput('index').match(/\\{\\s*length\\s*:\\s*len\\s*}\\s*=\\s*str/g),'使用解构语法来重新赋值。');" } ], "releasedOn": "Feb 17, 2017", @@ -658,11 +658,11 @@ "function getLength(str) {", " \"use strict\";", "", - " // change code below this line", + " // 在这行以下修改代码", " const length = 0; // change this", - " // change code above this line", + " // 在这行以上修改代码", "", - " return len; // you must assign length to len in line", + " return len; // 你必须在这行将 length 赋值给 len", "", "}", "", @@ -677,21 +677,21 @@ "id": "587d7b89367417b2b2512b4a", "title": "Use Destructuring Assignment to Assign Variables from Nested Objects", "description": [ - "We can similarly destructure nested objects into variables.", - "Consider the following code:", + "同样,我们可以将 嵌套的对象解构到变量中。", + "请看以下代码:", "
const a = {
  start: { x: 5, y: 6},
  end: { x: 6, y: -9 }
};
const { start : { x: startX, y: startY }} = a;
console.log(startX, startY); // 5, 6
", - "In the example above, the variable start is assigned the value of a.start, which is also an object.", + "在上面的例子里,a.start 将值赋给了变量 startstart 同样也是个对象。", "
", - "Use destructuring assignment to obtain max of forecast.tomorrow and assign it to maxOfTomorrow." + "使用解构赋值来得到 forecast.tomorrowmax,并将其赋值给 maxOfTomorrow。" ], "tests": [ { - "text": "maxOfTomorrow equals 84.6", - "testString": "assert(getMaxOfTmrw(LOCAL_FORECAST) === 84.6, 'maxOfTomorrow equals 84.6');" + "text": "maxOfTomorrow 等于 84.6", + "testString": "assert(getMaxOfTmrw(LOCAL_FORECAST) === 84.6, 'maxOfTomorrow 等于 84.6');" }, { - "text": "nested destructuring was used", - "testString": "getUserInput => assert(getUserInput('index').match(/\\{\\s*tomorrow\\s*:\\s*\\{\\s*max\\s*:\\s*maxOfTomorrow\\s*\\}\\s*\\}\\s*=\\s*forecast/g),'nested destructuring was used');" + "text": "使用嵌套解构", + "testString": "getUserInput => assert(getUserInput('index').match(/\\{\\s*tomorrow\\s*:\\s*\\{\\s*max\\s*:\\s*maxOfTomorrow\\s*\\}\\s*\\}\\s*=\\s*forecast/g),'使用嵌套解构');" } ], "releasedOn": "Feb 17, 2017", @@ -709,13 +709,13 @@ "", "function getMaxOfTmrw(forecast) {", " \"use strict\";", - " // change code below this line", - " const maxOfTomorrow = undefined; // change this line", - " // change code above this line", + " // 在这行以下修改代码", + " const maxOfTomorrow = undefined; // 改变这一行", + " // 在这行以上修改代码", " return maxOfTomorrow;", "}", "", - "console.log(getMaxOfTmrw(LOCAL_FORECAST)); // should be 84.6" + "console.log(getMaxOfTmrw(LOCAL_FORECAST)); // 应该为 84.6" ], "head": [], "tail": [] @@ -761,9 +761,9 @@ "let a = 8, b = 6;", "(() => {", " \"use strict\";", - " // change code below this line", + " // 在这行以下修改代码", " ", - " // change code above this line", + " // 在这行以上修改代码", "})();", "console.log(a); // should be 6", "console.log(b); // should be 8" @@ -810,9 +810,9 @@ "const source = [1,2,3,4,5,6,7,8,9,10];", "function removeFirstTwo(list) {", " \"use strict\";", - " // change code below this line", + " // 在这行以下修改代码", " arr = list; // change this", - " // change code above this line", + " // 在这行以上修改代码", " return arr;", "}", "const arr = removeFirstTwo(source);", @@ -871,12 +871,12 @@ "const half = (function() {", " \"use strict\"; // do not change this line", "", - " // change code below this line", + " // 在这行以下修改代码", " return function half(stats) {", " // use function argument destructuring", " return (stats.max + stats.min) / 2.0;", " };", - " // change code above this line", + " // 在这行以上修改代码", "", "})();", "console.log(stats); // should be object", @@ -931,9 +931,9 @@ "function makeList(arr) {", " \"use strict\";", "", - " // change code below this line", + " // 在这行以下修改代码", " const resultDisplayArray = null;", - " // change code above this line", + " // 在这行以上修改代码", "", " return resultDisplayArray;", "}", @@ -984,13 +984,13 @@ "contents": [ "const createPerson = (name, age, gender) => {", " \"use strict\";", - " // change code below this line", + " // 在这行以下修改代码", " return {", " name: name,", " age: age,", " gender: gender", " };", - " // change code above this line", + " // 在这行以上修改代码", "};", "console.log(createPerson(\"Zodiac Hasbro\", 56, \"male\")); // returns a proper object" ], @@ -1028,7 +1028,7 @@ "ext": "js", "name": "index", "contents": [ - "// change code below this line", + "// 在这行以下修改代码", "const bicycle = {", " gear: 2,", " setGear: function(newGear) {", @@ -1036,7 +1036,7 @@ " this.gear = newGear;", " }", "};", - "// change code above this line", + "// 在这行以上修改代码", "bicycle.setGear(3);", "console.log(bicycle.gear);" ], @@ -1362,4 +1362,4 @@ } } ] -} \ No newline at end of file +}