fix(i18n): update Chinese translation of es6 (#38038)
Co-authored-by: Zhicheng Chen <chenzhicheng@dayuwuxian.com>
This commit is contained in:
@ -2,26 +2,93 @@
|
||||
id: 587d7b87367417b2b2512b40
|
||||
title: Compare Scopes of the var and let Keywords
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 比较var的范围并让关键字
|
||||
forumTopicId: 301195
|
||||
localeTitle: 比较 var 和 let 关键字的作用域
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">使用<code>var</code>关键字声明变量时,它将全局声明,如果在函数内声明,则声明为本地。 <code>let</code>关键字的行为类似,但具有一些额外的功能。在块,语句或表达式中使用<code>let</code>关键字声明变量时,其范围仅限于该块,语句或表达式。例如: <blockquote> var numArray = []; <br> for(var i = 0; i <3; i ++){ <br> numArray.push(ⅰ); <br> } <br>的console.log(numArray); <br> //返回[0,1,2] <br>的console.log(ⅰ); <br> //返回3 </blockquote>使用<code>var</code>关键字, <code>i</code>被全局声明。因此,当执行<code>i++</code>时,它会更新全局变量。此代码类似于以下内容: <blockquote> var numArray = []; <br> var i; <br> for(i = 0; i <3; i ++){ <br> numArray.push(ⅰ); <br> } <br>的console.log(numArray); <br> //返回[0,1,2] <br>的console.log(ⅰ); <br> //返回3 </blockquote>如果您要创建一个函数并将其存储以供以后在使用<code>i</code>变量的for循环中使用,则此行为将导致问题。这是因为存储的函数将始终引用更新的全局<code>i</code>变量的值。 <blockquote> var printNumTwo; <br> for(var i = 0; i <3; i ++){ <br> if(i === 2){ <br> printNumTwo = function(){ <br>return i; <br> }; <br> } <br> } <br>的console.log(printNumTwo()); <br> //返回3 </blockquote>正如你所看到的, <code>printNumTwo()</code>打印3,而不是2.这是因为分配给该值<code>i</code>进行了更新和<code>printNumTwo()</code>返回全球<code>i</code> ,而不是价值<code>i</code>的作用是在创建for循环的时候了。 <code>let</code>关键字不遵循此行为: <blockquote> 'use strict'; <br>让printNumTwo; <br> for(let i = 0; i <3; i ++){ <br> if(i === 2){ <br> printNumTwo = function(){ <br>return i;<br> }; <br> } <br> } <br>的console.log(printNumTwo()); <br> //返回2 <br>的console.log(ⅰ); <br> //返回“i没有定义” </blockquote> <code>i</code>没有定义,因为它没有在全局范围内声明。它仅在for循环语句中声明。 <code>printNumTwo()</code>返回正确的值,因为循环语句中的<code>let</code>关键字创建了具有唯一值(0,1和2)的三个不同的<code>i</code>变量。 </section>
|
||||
<section id='description'>
|
||||
当你使用<code>var</code>关键字来声明一个变量的时候,这个变量会被声明成全局变量,或是函数内的局部变量。
|
||||
<code>let</code>关键字的作用类似,但会有一些额外的特性。如果你在代码块、语句或表达式中使用关键字<code>let</code>声明变量,这个变量的作用域就被限制在当前的代码块,语句或表达式之中。
|
||||
举个例子:
|
||||
|
||||
```js
|
||||
var numArray = [];
|
||||
for (var i = 0; i < 3; i++) {
|
||||
numArray.push(i);
|
||||
}
|
||||
console.log(numArray);
|
||||
// 返回 [0, 1, 2]
|
||||
console.log(i);
|
||||
// 返回 3
|
||||
```
|
||||
|
||||
当使用<code>var</code>关键字的时候,<code>i</code>会被声明成全局变量。当<code>i++</code>执行的时候,它会改变全局变量的值。这段代码可以看做下面这样:
|
||||
|
||||
```js
|
||||
var numArray = [];
|
||||
var i;
|
||||
for (i = 0; i < 3; i++) {
|
||||
numArray.push(i);
|
||||
}
|
||||
console.log(numArray);
|
||||
// 返回 [0, 1, 2]
|
||||
console.log(i);
|
||||
// 返回 3
|
||||
```
|
||||
|
||||
如果你在<code>for</code>循环中创建了使用<code>i</code>变量的函数,那么在后续调用函数的时候,上面提到的这种行为就会出现问题。这是因为函数存储的值会因为全局变量<code>i</code>的变化而不断的改变。
|
||||
|
||||
```js
|
||||
var printNumTwo;
|
||||
for (var i = 0; i < 3; i++) {
|
||||
if (i === 2) {
|
||||
printNumTwo = function() {
|
||||
return i;
|
||||
};
|
||||
}
|
||||
}
|
||||
console.log(printNumTwo());
|
||||
// 返回 3
|
||||
```
|
||||
|
||||
可以看到,<code>printNumTwo()</code>打印了 3 而不是 2。这是因为<code>i</code>发生了改变,并且函数<code>printNumTwo()</code>返回的是全局变量<code>i</code>的值,而不是<code>for</code>循环中创建函数时<code>i</code>的值。<code>let</code>关键字就不会有这种现象:
|
||||
|
||||
```js
|
||||
'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 未定义"
|
||||
```
|
||||
|
||||
<code>i</code>在全局作用域中没有声明,所以它没有被定义,它的声明只会发生在<code>for</code>循环内。在循环执行的时候,<code>let</code>关键字创建了三个不同的<code>i</code>变量,他们的值分别为 0、1 和 2,所以<code>printNumTwo()</code>返回了正确的值。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">修复代码,以便<code>i</code>在if语句中声明的是一个单独的变量,而不是<code>i</code>在函数的第一行声明的变量。确保不要在代码中的任何位置使用<code>var</code>关键字。本练习旨在说明<code>var</code>和<code>let</code>关键字如何将范围分配给声明的变量之间的区别。在编写与本练习中使用的函数类似的函数时,通常最好使用不同的变量名来避免混淆。 </section>
|
||||
<section id='instructions'>
|
||||
修改这段代码,使得在<code>if</code>语句中声明的<code>i</code>变量与在函数的第一行声明的<code>i</code>变量是彼此独立的。请注意不要在你的代码的任何地方使用<code>var</code>关键字。
|
||||
这个练习说明了使用<code>var</code>与<code>let</code>关键字声明变量时,作用域之间的不同。当编写类似这个练习中的函数的时候,通常来说最好还是使用不同的变量名来避免误会。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>var</code>在代码中不存在。
|
||||
- text: <code>var</code>不应该在代码中存在。
|
||||
testString: getUserInput => assert(!getUserInput('index').match(/var/g));
|
||||
- text: 在if语句中声明的变量<code>i</code>应该等于“块范围”。
|
||||
- text: "在<code>if</code>语句中声明的<code>i</code>变量的值是 'block scope'。"
|
||||
testString: getUserInput => assert(getUserInput('index').match(/(i\s*=\s*).*\s*.*\s*.*\1('|")block\s*scope\2/g));
|
||||
- text: <code>checkScope()</code>应该返回“函数范围”
|
||||
- text: "<code>checkScope()</code>应当返回 'function scope'"
|
||||
testString: assert(checkScope() === "function scope");
|
||||
|
||||
```
|
||||
@ -35,16 +102,15 @@ tests:
|
||||
|
||||
```js
|
||||
function checkScope() {
|
||||
"use strict";
|
||||
var i = "function scope";
|
||||
'use strict';
|
||||
var i = 'function scope';
|
||||
if (true) {
|
||||
i = "block scope";
|
||||
console.log("Block scope i is: ", i);
|
||||
i = 'block scope';
|
||||
console.log('Block scope i is: ', i);
|
||||
}
|
||||
console.log("Function scope i is: ", i);
|
||||
console.log('Function scope i is: ', i);
|
||||
return i;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -57,6 +123,17 @@ function checkScope() {
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
function checkScope() {
|
||||
'use strict';
|
||||
let i = 'function scope';
|
||||
if (true) {
|
||||
let i = 'block scope';
|
||||
console.log('Block scope i is: ', i);
|
||||
}
|
||||
|
||||
console.log('Function scope i is: ', i);
|
||||
return i;
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -0,0 +1,89 @@
|
||||
---
|
||||
id: 5cdafbc32913098997531680
|
||||
title: Complete a Promise with resolve and reject
|
||||
challengeType: 1
|
||||
forumTopicId: 301196
|
||||
localeTitle: 通过 resolve 和 reject 完成 Promise
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
promise 有三个状态:<code>pending</code>、<code>fulfilled</code> 和 <code>rejected</code>。上一个挑战里创建的 promise 一直阻塞在 <code>pending</code> 状态里,因为没有调用 promise 的完成方法。promise 提供的 <code>resolve</code> 和 <code>reject</code> 参数就是用来结束 promise 的。promise 成功时调用 <code>resolve</code>,promise 执行失败时调用 <code>reject</code>,这两个方法接收一个参数,如下所示。
|
||||
|
||||
```js
|
||||
const myPromise = new Promise((resolve, reject) => {
|
||||
if(condition here) {
|
||||
resolve("Promise was fulfilled");
|
||||
} else {
|
||||
reject("Promise was rejected");
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
上面的例子使用字符串做为函数的参数,也可以是任意类型,通常会是对象,里面可能是将要放到页面或其它地方的数据。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
使 promise 可以处理成功和失败情况。如果 <code>responseFromServer</code> 是 <code>true</code>,调用 <code>resolve</code> 方法使 promise 成功。给 <code>resolve</code> 传递值为 <code>We got the data</code> 的字符串。如果 <code>responseFromServer</code> 是 <code>false</code>, 使用 <code>reject</code> 方法并传入值为 <code>Data not received</code> 的字符串。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 当 <code>if</code> 条件是 <code>true</code> 时应该执行 <code>resolve</code>。
|
||||
testString: assert(removeJSComments(code).match(/if\s*\(\s*responseFromServer\s*\)\s*{\s*resolve\s*\(\s*('|"|`)We got the data\1\s*\)(\s*|\s*;\s*)}/g));
|
||||
- text: 当 <code>if</code> 条件是 <code>false</code> 时应该执行 <code>reject</code>。
|
||||
testString: assert(removeJSComments(code).match(/}\s*else\s*{\s*reject\s*\(\s*('|"|`)Data not received\1\s*\)(\s*|\s*;\s*)}/g));
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
const makeServerRequest = new Promise((resolve, reject) => {
|
||||
// responseFromServer represents a response from a server
|
||||
let responseFromServer;
|
||||
|
||||
if(responseFromServer) {
|
||||
// change this line
|
||||
} else {
|
||||
// change this line
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
const removeJSComments = str => str.replace(/\/\*[\s\S]*?\*\/|\/\/.*$/gm, '');
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
const makeServerRequest = new Promise((resolve, reject) => {
|
||||
// responseFromServer represents a response from a server
|
||||
let responseFromServer;
|
||||
|
||||
if(responseFromServer) {
|
||||
resolve("We got the data");
|
||||
} else {
|
||||
reject("Data not received");
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
</section>
|
@ -0,0 +1,59 @@
|
||||
---
|
||||
id: 5cdafbb0291309899753167f
|
||||
title: Create a JavaScript Promise
|
||||
challengeType: 1
|
||||
forumTopicId: 301197
|
||||
localeTitle: 创建一个 JavaScript Promise
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Promise 是异步编程的一种解决方案 - 它在未来的某时会生成一个值。任务完成,分执行成功和执行失败两种情况。<code>Promise</code> 是构造器函数,需要通过 <code>new</code> 关键字来创建。构造器参数是一个函数,该函数有两个参数 - <code>resolve</code> 和 <code>reject</code>。通过它们来判断 promise 的执行结果。用法如下:
|
||||
|
||||
```js
|
||||
const myPromise = new Promise((resolve, reject) => {
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
创建一个名为 <code>makeServerRequest</code> 的 promise。给构造器函数传入 <code>resolve</code> 和 <code>reject</code> 两个参数。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 应该给名为 <code>makeServerRequest</code> 的变量指定一个 promise。
|
||||
testString: assert(makeServerRequest instanceof Promise);
|
||||
- text: promise 应该接收一个函数做为参数,该函数应该包含 <code>resolve</code> 和 <code>reject</code> 两个参数。
|
||||
testString: assert(code.match(/Promise\(\s*(function\s*\(\s*resolve\s*,\s*reject\s*\)\s*{|\(\s*resolve\s*,\s*reject\s*\)\s*=>\s*{)[^}]*}/g));
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
const makeServerRequest = new Promise((resolve, reject) => {
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
</section>
|
@ -0,0 +1,70 @@
|
||||
---
|
||||
id: 5cddbfd622f1a59093ec611d
|
||||
title: Create a Module Script
|
||||
challengeType: 6
|
||||
forumTopicId: 301198
|
||||
localeTitle: 创建一个模块脚本
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
起初,JavaScript 几乎只在 HTML web 扮演一个很小的角色。今天,一切不同了,很多网站几乎全是用 JavaScript 所写。为了让 JavaScript 更模块化、更整洁以及更易于维护,ES6 引入了在多个 JavaScript 文件之间共享代码的机制。它可以导出文件的一部分供其它文件使用,然后在需要它的地方按需导入。为了使用这一功能, 需要在 HTML 文档里创建一个类型为 <code>module</code> 的脚本。例子如下:
|
||||
|
||||
```html
|
||||
<script type="module" src="filename.js"></script>
|
||||
```
|
||||
|
||||
使用了 <code>module</code> 类型的脚本后可以再接下来的挑战里使用 <code>import</code> 和 <code>export</code> 特性。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
给 HTML 文档添加 <code>module</code> 类型的脚本,指定源文件为 <code>index.js</code>。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 应该创建一个 <code>script</code> 标签。
|
||||
testString: assert(code.match(/<\s*script[^>]*>\s*<\/\s*script\s*>/g));
|
||||
- text: <code>script</code> 标签的类型应该为 <code>module</code>。
|
||||
testString: assert(code.match(/<\s*script\s+[^t]*type\s*=\s*('|")module\1[^>]*>\s*<\/\s*script\s*>/g));
|
||||
- text: <code>script</code> 标签的 <code>src</code> 属性应该为 <code>index.js</code>。
|
||||
testString: assert(code.match(/<\s*script\s+[^s]*src\s*=\s*('|")index\.js\1[^>]*>\s*<\/\s*script\s*>/g));
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='html-seed'>
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
<!-- add your code below -->
|
||||
|
||||
<!-- add your code above -->
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
<!-- add your code below -->
|
||||
<script type="module" src="index.js"></script>
|
||||
<!-- add your code above -->
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
</section>
|
@ -2,58 +2,67 @@
|
||||
id: 587d7b8c367417b2b2512b58
|
||||
title: Create an Export Fallback with export default
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用导出默认值创建导出回退
|
||||
forumTopicId: 301199
|
||||
localeTitle: 用 export default 创建一个默认导出
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">在<code>export</code>课程中,您了解了称为<dfn>命名导出</dfn>的语法。这使您可以使多个函数和变量可用于其他文件。您需要知道另一种<code>export</code>语法,称为<dfn>导出默认值</dfn> 。通常,如果只从文件导出一个值,您将使用此语法。它还用于为文件或模块创建回退值。以下是<code>export default</code>的快速示例: <blockquote> export default function add(x,y){ <br> return x + y; <br> } </blockquote>注意:由于<code>export default</code>用于声明模块或文件的回退值,因此每个模块或文件中只能有一个值作为默认导出。此外,您不能将<code>export default</code>用于<code>var</code> , <code>let</code>或<code>const</code> </section>
|
||||
<section id='description'>
|
||||
在<code>export</code>的课程中,学习了<dfn>命名导出</dfn>语法。这可以在其他文件中引用一些函数或者变量。
|
||||
还需要了解另外一种被称为<dfn>默认导出</dfn>的<code>export</code>的语法。在文件中只有一个值需要导出的时候,通常会使用这种语法。它也常常用于给文件或者模块创建返回值。
|
||||
下面是一个简单的<code>export default</code>例子:
|
||||
|
||||
```js
|
||||
// named function
|
||||
export default function add(x, y) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
// anonymous function
|
||||
export default function(x, y) {
|
||||
return x + y;
|
||||
}
|
||||
```
|
||||
|
||||
注意:当使用<code>export default</code>去声明一个文件或者模块的返回值时,在每个文件或者模块中应当只默认导出一个值。特别地,能将<code>export deafult</code>与<code>var</code>,<code>let</code>与<code>const</code>一起使用。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">以下函数应该是模块的回退值。请添加必要的代码。 </section>
|
||||
<section id='instructions'>
|
||||
下面的函数应该在这个模块中返回一个值。请添加需要的代码:
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 适当使用<code>export</code>回落。
|
||||
- text: 正确的使用<code>export</code>进行返回。
|
||||
testString: assert(code.match(/export\s+default\s+function(\s+subtract\s*|\s*)\(\s*x,\s*y\s*\)\s*{/g));
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
"use strict";
|
||||
function subtract(x,y) {return x - y;}
|
||||
|
||||
function subtract(x, y) {
|
||||
return x - y;
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### Before Test
|
||||
<div id='js-setup'>
|
||||
|
||||
```js
|
||||
window.exports = function(){};
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
export default function subtract(x, y) {
|
||||
return x - y;
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,28 +2,58 @@
|
||||
id: 587d7b8a367417b2b2512b4e
|
||||
title: Create Strings using Template Literals
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用模板文字创建字符串
|
||||
forumTopicId: 301200
|
||||
localeTitle: 使用模板字面量创建字符串
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description"> ES6的一个新功能是<dfn>模板文字</dfn> 。这是一种特殊类型的字符串,可以更轻松地创建复杂字符串。模板文字允许您创建多行字符串并使用字符串插值功能来创建字符串。考虑以下代码: <blockquote> const person = { <br>name: "Zodiac Hasbro", <br>age: 56<br> }; <br><br> //具有多行和字符串插值的模板文字<br> const greeting =`您好,我的名字是${person.name}! <br>我是${person.age}岁。` <br><br>的console.log(greeting); //打印<br> //你好,我的名字是Zodiac Hasbro! <br> //我今年56岁<br></blockquote>那里发生了很多事情。首先,例如使用反引号( <code>`</code> ),而不是引号( <code>'</code>或<code>"</code> ),换行字符串。其次,请注意,该字符串是多线,无论是在代码和输出。这节省了插入<code>\n</code>串内。上面使用的<code>${variable}</code>语法是占位符。基本上,您不必再使用<code>+</code>运算符连接。要将变量添加到字符串,只需将变量放在模板字符串中并用<code>${</code>包装它<code>}</code>同样,您可以在您的字符串表达式的其他文字,例如<code>${a + b}</code>这个新创建的字符串的方式为您提供了更大的灵活性,以创建强大的字符串。 </section>
|
||||
<section id='description'>
|
||||
模板字符串是 ES6 的另外一项新的功能。这是一种可以轻松构建复杂字符串的方法。
|
||||
模板字符串可以使用多行字符串和字符串插值功能。
|
||||
请看以下代码:
|
||||
|
||||
```js
|
||||
const person = {
|
||||
name: "Zodiac Hasbro",
|
||||
age: 56
|
||||
};
|
||||
|
||||
// Template literal with multi-line and string interpolation
|
||||
const greeting = `Hello, my name is ${person.name}!
|
||||
I am ${person.age} years old.`;
|
||||
|
||||
console.log(greeting); // prints
|
||||
// Hello, my name is Zodiac Hasbro!
|
||||
// I am 56 years old.
|
||||
|
||||
```
|
||||
|
||||
这段代码有许多的不同:
|
||||
首先,上面的例子使用了反引号(<code>`</code>)而不是引号(<code>'</code> 或者 <code>"</code>)定义字符串。
|
||||
其次,注意字符串是多行的,不管是代码还是输出。这是因为在字符串内插入了 <code>\n</code>。
|
||||
上面使用的<code>${variable}</code>语法是一个占位符。这样一来,你将不再需要使用<code>+</code>运算符来连接字符串。当需要在字符串里增加变量的时候,你只需要在变量的外面括上<code>${</code>和<code>}</code>,并将其放在字符串里就可以了。
|
||||
这个新的方式使你可以更灵活的创建复杂的字符串。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">使用带有反引号的模板文字语法来显示<code>result</code>对象的<code>failure</code>数组的每个条目。每个条目都应该包含在一个带有class属性<code>text-warning</code>的<code>li</code>元素中,并列在<code>resultDisplayArray</code> 。 </section>
|
||||
<section id='instructions'>
|
||||
使用模板字符串的反引号的语法来展示<code>result</code>对象的<code>failure</code>数组内的每个条目。每个条目应该括在带有<code>text-warning</code>类属性的<code>li</code>标签中,并赋值给<code>resultDisplayArray</code>。
|
||||
使用遍历方法(可以是任意形式的循环)输出指定值。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>resultDisplayArray</code>是一个包含<code>result failure</code>消息的数组。
|
||||
testString: 'assert(typeof makeList(result.failure) === "object" && resultDisplayArray.length === 3, "<code>resultDisplayArray</code> is a list containing <code>result failure</code> messages.");'
|
||||
- text: <code>resultDisplayArray</code>是所需的输出。
|
||||
testString: 'assert(makeList(result.failure).every((v, i) => v === `<li class="text-warning">${result.failure[i]}</li>` || v === `<li class="text-warning">${result.failure[i]}</li>`), "<code>resultDisplayArray</code> is the desired output.");'
|
||||
- text: 使用了模板字符串
|
||||
testString: 'getUserInput => assert(getUserInput("index").match(/`.*`/g), "Template strings were not used");'
|
||||
|
||||
- text: <code>resultDisplayArray</code> 是一个包含了 <code>result failure</code> 内的消息的数组。
|
||||
testString: assert(typeof makeList(result.failure) === 'object' && resultDisplayArray.length === 3);
|
||||
- text: <code>resultDisplayArray</code> 要有正确的输出。
|
||||
testString: assert(makeList(result.failure).every((v, i) => v === `<li class="text-warning">${result.failure[i]}</li>` || v === `<li class='text-warning'>${result.failure[i]}</li>`));
|
||||
- text: 应使用模板字符串。
|
||||
testString: getUserInput => assert(getUserInput('index').match(/(`.*\${.*}.*`)/));
|
||||
- text: 应该遍历。
|
||||
testString: getUserInput => assert(getUserInput('index').match(/for|map|reduce|forEach|while/));
|
||||
```
|
||||
|
||||
</section>
|
||||
@ -55,7 +85,6 @@ function makeList(arr) {
|
||||
* `<li class="text-warning">linebreak</li>` ]
|
||||
**/
|
||||
const resultDisplayArray = makeList(result.failure);
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -68,6 +97,25 @@ const resultDisplayArray = makeList(result.failure);
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
const result = {
|
||||
success: ["max-length", "no-amd", "prefer-arrow-functions"],
|
||||
failure: ["no-var", "var-on-top", "linebreak"],
|
||||
skipped: ["id-blacklist", "no-dup-keys"]
|
||||
};
|
||||
function makeList(arr) {
|
||||
"use strict";
|
||||
|
||||
const resultDisplayArray = arr.map(val => `<li class="text-warning">${val}</li>`);
|
||||
|
||||
return resultDisplayArray;
|
||||
}
|
||||
/**
|
||||
* makeList(result.failure) should return:
|
||||
* [ `<li class="text-warning">no-var</li>`,
|
||||
* `<li class="text-warning">var-on-top</li>`,
|
||||
* `<li class="text-warning">linebreak</li>` ]
|
||||
**/
|
||||
const resultDisplayArray = makeList(result.failure);
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,28 +2,43 @@
|
||||
id: 587d7b87367417b2b2512b41
|
||||
title: Declare a Read-Only Variable with the const Keyword
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用const关键字声明只读变量
|
||||
forumTopicId: 301201
|
||||
localeTitle: 用 const 关键字声明只读变量
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description"> <code>let</code>不是声明变量的唯一新方法。在ES6中,您还可以使用<code>const</code>关键字声明变量。 <code>const</code>拥有所有的真棒功能, <code>let</code>具有,与额外的奖励,使用声明的变量<code>const</code>是只读的。它们是一个常量值,这意味着一旦变量被赋值为<code>const</code> ,就无法重新赋值。 <blockquote> "use strict" <br> const FAV_PET ="Cats"; <br> FAV_PET = "Dogs"; //返回错误</blockquote>如您所见,尝试重新分配使用<code>const</code>声明的变量将引发错误。您应该始终使用<code>const</code>关键字命名您不想重新分配的变量。当您意外尝试重新分配一个旨在保持不变的变量时,这会有所帮助。命名常量时的常见做法是使用全部大写字母,单词用下划线分隔。 </section>
|
||||
<section id='description'>
|
||||
<code>let</code>并不是唯一的新的声明变量的方式。在 ES6里面,你还可以使用<code>const</code>关键字来声明变量。
|
||||
<code>const</code>拥有<code>let</code>的所有优点,所不同的是,通过<code>const</code>声明的变量是只读的。这意味着通过<code>const</code>声明的变量只能被赋值一次,而不能被再次赋值。
|
||||
|
||||
```js
|
||||
"use strict";
|
||||
const FAV_PET = "Cats";
|
||||
FAV_PET = "Dogs"; // returns error
|
||||
```
|
||||
|
||||
可以看见,尝试给通过<code>const</code>声明的变量再次赋值会报错。你应该使用<code>const</code>关键字来对所有不打算再次赋值的变量进行声明。这有助于你避免给一个常量进行额外的再次赋值。一个最佳实践是对所有常量的命名采用全大写字母,并在单词之间使用下划线进行分隔。
|
||||
|
||||
<strong>注意:</strong> 一般开发者会以大写做为常量标识符,小写字母或者驼峰命名做为变量(对象或数组)标识符。接下来的挑战里会涉及到小写变量标识符的数组。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">更改代码,以便使用<code>let</code>或<code>const</code>声明所有变量。如果希望变量更改,请使用<code>let</code> ;如果希望变量保持不变,请使用<code>const</code> 。此外,重命名用<code>const</code>声明的变量以符合常规做法,这意味着常量应该全部大写。 </section>
|
||||
<section id='instructions'>
|
||||
改变以下代码,使得所有的变量都使用<code>let</code>或<code>const</code>关键词来声明。当变量将会改变的时候使用<code>let</code>关键字,当变量要保持常量的时候使用<code>const</code>关键字。同时,对使用<code>const</code>声明的变量按照最佳实践重命名,变量名中的字母应该都是大写的。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>var</code>在您的代码中不存在。
|
||||
- text: <code>var</code>在代码中不存在。
|
||||
testString: getUserInput => assert(!getUserInput('index').match(/var/g));
|
||||
- text: <code>SENTENCE</code>应该是用<code>const</code>声明的常量变量。
|
||||
- text: <code>SENTENCE</code>应该是使用<code>const</code>声明的常量。
|
||||
testString: getUserInput => assert(getUserInput('index').match(/(const SENTENCE)/g));
|
||||
- text: <code>i</code>应该以<code>let</code>来宣布。
|
||||
- text: <code>i</code>应该是使用<code>let</code>声明的变量。
|
||||
testString: getUserInput => assert(getUserInput('index').match(/(let i)/g));
|
||||
- text: 应更改<code>console.log</code>以打印<code>SENTENCE</code>变量。
|
||||
- text: <code>console.log</code>应该修改为用于打印<code>SENTENCE</code>变量。
|
||||
testString: getUserInput => assert(getUserInput('index').match(/console\.log\(\s*SENTENCE\s*\)\s*;?/g));
|
||||
|
||||
```
|
||||
@ -42,7 +57,7 @@ function printManyTimes(str) {
|
||||
// change code below this line
|
||||
|
||||
var sentence = str + " is cool!";
|
||||
for(var i = 0; i < str.length; i+=2) {
|
||||
for (var i = 0; i < str.length; i+=2) {
|
||||
console.log(sentence);
|
||||
}
|
||||
|
||||
@ -50,7 +65,6 @@ function printManyTimes(str) {
|
||||
|
||||
}
|
||||
printManyTimes("freeCodeCamp");
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -63,6 +77,20 @@ printManyTimes("freeCodeCamp");
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
function printManyTimes(str) {
|
||||
"use strict";
|
||||
|
||||
// change code below this line
|
||||
|
||||
const SENTENCE = str + " is cool!";
|
||||
for (let i = 0; i < str.length; i+=2) {
|
||||
console.log(SENTENCE);
|
||||
}
|
||||
|
||||
// change code above this line
|
||||
|
||||
}
|
||||
printManyTimes("freeCodeCamp");
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,31 +2,58 @@
|
||||
id: 587d7b87367417b2b2512b3f
|
||||
title: Explore Differences Between the var and let Keywords
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 探索var和let关键字之间的差异
|
||||
forumTopicId: 301202
|
||||
localeTitle: 探索 var 和 let 关键字之间的差异
|
||||
---
|
||||
|
||||
<section id="description">使用<code>var</code>关键字声明变量的最大问题之一是您可以在没有错误的情况下覆盖变量声明。
|
||||
<blockquote>var camper = 'James';<br>var camper = 'David';<br>console.log(camper);<br>// 输出 'David'</blockquote>
|
||||
正如您在上面的代码中看到的那样, <code>camper</code>变量最初被声明为<code>James</code> ,然后被重写为<code>David</code> 。在小型应用程序中,您可能不会遇到此类问题,但是当您的代码变大时,您可能会意外覆盖您不打算覆盖的变量。因为这种行为不会引发错误,所以搜索和修复错误变得更加困难。 <br>在ES6中引入了一个名为<code>let</code>的新关键字,用<code>var</code>关键字解决了这个潜在的问题。如果要在上面代码的变量声明中用<code>let</code>替换<code>var</code> ,结果将是一个错误。
|
||||
<blockquote>let camper = 'James';<br>let camper = 'David'; // 抛出一个错误</blockquote>
|
||||
您可以在浏览器的控制台中看到此错误。因此与<code>var</code>不同,使用<code>let</code> ,具有相同名称的变量只能声明一次。注意<code>"use strict"</code> 。这启用了严格模式,可以捕获常见的编码错误和“不安全”操作。例如:
|
||||
<blockquote>"use strict";<br>x = 3.14; // 抛出一个错误,因为 x 未定义</blockquote>
|
||||
## Description
|
||||
<section id='description'>
|
||||
使用<code>var</code>关键字来声明变量,会出现重复声明导致变量被覆盖却不会报错的问题:
|
||||
|
||||
```js
|
||||
var camper = 'James';
|
||||
var camper = 'David';
|
||||
console.log(camper);
|
||||
// logs 'David'
|
||||
```
|
||||
|
||||
在上面的代码中,<code>camper</code>的初始值为<code>'James'</code>,然后又被覆盖成了<code>'David'</code>。
|
||||
在小型的应用中,你可能不会遇到这样的问题,但是当你的代码规模变得更加庞大的时候,就可能会在不经意间覆盖了之前定义的变量。
|
||||
这样的行为不会报错,导致了 debug 非常困难。<br>
|
||||
在 ES6 中引入了新的关键字<code>let</code>来解决<code>var</code>关键字带来的潜在问题。
|
||||
如果你在上面的代码中,使用了<code>let</code>关键字来代替<code>var</code>关键字,结果会是一个报错。
|
||||
|
||||
```js
|
||||
let camper = 'James';
|
||||
let camper = 'David'; // throws an error
|
||||
```
|
||||
|
||||
你可以在浏览器的控制台里看见这个错误。
|
||||
与<code>var</code>不同的是,当使用<code>let</code>的时候,同一名字的变量只能被声明一次。
|
||||
请注意<code>"use strict"</code>。这代表着开启了严格模式,用于检测常见的代码错误以及"不安全"的行为,例如:
|
||||
|
||||
```js
|
||||
"use strict";
|
||||
x = 3.14; // throws an error because x is not declared
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">更新代码,使其仅使用<code>let</code>关键字。 </section>
|
||||
<section id='instructions'>
|
||||
请更新这段代码,并且在其中只使用<code>let</code>关键字
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>var</code>在代码中不存在。
|
||||
- text: 在代码中不应存在<code>var</code>。
|
||||
testString: getUserInput => assert(!getUserInput('index').match(/var/g));
|
||||
- text: <code>catName</code>应该是<code>Oliver</code> 。
|
||||
- text: "<code>catName</code>变量的值应该为<code>'Oliver'</code>。"
|
||||
testString: assert(catName === "Oliver");
|
||||
- text: <code>quote</code>应该是<code>"Oliver says Meow!"</code>
|
||||
- text: "<code>quote</code>变量的值应该为<code>'Oliver says Meow!'</code>"
|
||||
testString: assert(quote === "Oliver says Meow!");
|
||||
|
||||
```
|
||||
@ -49,7 +76,6 @@ function catTalk() {
|
||||
|
||||
}
|
||||
catTalk();
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -62,6 +88,15 @@ catTalk();
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
let catName;
|
||||
let quote;
|
||||
function catTalk() {
|
||||
'use strict';
|
||||
|
||||
catName = 'Oliver';
|
||||
quote = catName + ' says Meow!';
|
||||
}
|
||||
catTalk();
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -0,0 +1,92 @@
|
||||
---
|
||||
id: 5cdafbd72913098997531681
|
||||
title: Handle a Fulfilled Promise with then
|
||||
challengeType: 1
|
||||
forumTopicId: 301203
|
||||
localeTitle: 在 then 中处理 Promise 完成的情况
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
当程序需要花费未知的时间才能完成时 Promise 很有用(比如,一些异步操作),一般是网络请求。网络请求会花费一些时间,当结束时需要根据服务器的响应执行一些操作。这可以用 <code>then</code> 方法来实现,当 promise 完成 <code>resolve</code> 时会触发 <code>then</code> 方法。例子如下:
|
||||
|
||||
```js
|
||||
myPromise.then(result => {
|
||||
// do something with the result.
|
||||
});
|
||||
```
|
||||
|
||||
<code>result</code> 即传入 <code>resolve</code> 方法的参数。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
给 promise 添加 <code>then</code> 方法。用 <code>result</code> 做为回调函数的参数并将 <code>result</code> 打印在控制台。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 应该给 promise 方法调用 <code>then</code> 方法。
|
||||
testString: assert(codeWithoutSpaces.match(/(makeServerRequest|\))\.then\(/g));
|
||||
- text: <code>then</code> 方法应该有一个回调函数,回调函数参数为 <code>result</code>。
|
||||
testString: assert(resultIsParameter);
|
||||
- text: 应该打印 <code>result</code> 到控制台。
|
||||
testString: assert(resultIsParameter && codeWithoutSpaces.match(/\.then\(.*?result.*?console.log\(result\).*?\)/));
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
const makeServerRequest = new Promise((resolve, reject) => {
|
||||
// responseFromServer is set to true to represent a successful response from a server
|
||||
let responseFromServer = true;
|
||||
|
||||
if(responseFromServer) {
|
||||
resolve("We got the data");
|
||||
} else {
|
||||
reject("Data not received");
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
const codeWithoutSpaces = code.replace(/\s/g, '');
|
||||
const resultIsParameter = /\.then\((function\(result\){|result|\(result\)=>)/.test(codeWithoutSpaces);
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
const makeServerRequest = new Promise((resolve, reject) => {
|
||||
// responseFromServer is set to true to represent a successful response from a server
|
||||
let responseFromServer = true;
|
||||
|
||||
if(responseFromServer) {
|
||||
resolve("We got the data");
|
||||
} else {
|
||||
reject("Data not received");
|
||||
}
|
||||
});
|
||||
|
||||
makeServerRequest.then(result => {
|
||||
console.log(result);
|
||||
});
|
||||
```
|
||||
|
||||
</section>
|
@ -0,0 +1,103 @@
|
||||
---
|
||||
id: 5cdafbe72913098997531682
|
||||
title: Handle a Rejected Promise with catch
|
||||
challengeType: 1
|
||||
forumTopicId: 301204
|
||||
localeTitle: 在 catch 中处理 Promise 失败的情况
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
当 promise 失败时会调用 <code>catch</code> 方法。当 promise 的 <code>reject</code> 方法执行时会直接调用。用法如下:
|
||||
|
||||
```js
|
||||
myPromise.catch(error => {
|
||||
// do something with the error.
|
||||
});
|
||||
```
|
||||
|
||||
<code>error</code> 是传入 <code>reject</code> 方法的参数。
|
||||
|
||||
<strong>注意:</strong> <code>then</code> 和 <code>catch</code> 方法可以在 promise 后面链式调用。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
给 promise 添加 <code>catch</code> 方法。用 <code>error</code> 做为回调函数的参数并把 <code>error</code> 打印到控制台。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 应该在 promise 上调用 <code>catch</code> 方法。
|
||||
testString: assert(codeWithoutSpaces.match(/(makeServerRequest|\))\.catch\(/g));
|
||||
- text: <code>catch</code> 方法应该有一个回调函数,函数参数为<code>error</code>。
|
||||
testString: assert(errorIsParameter);
|
||||
- text: 应该打印<code>error</code>到控制台。
|
||||
testString: assert(errorIsParameter && codeWithoutSpaces.match(/\.catch\(.*?error.*?console.log\(error\).*?\)/));
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
const makeServerRequest = new Promise((resolve, reject) => {
|
||||
// responseFromServer is set to false to represent an unsuccessful response from a server
|
||||
let responseFromServer = false;
|
||||
|
||||
if(responseFromServer) {
|
||||
resolve("We got the data");
|
||||
} else {
|
||||
reject("Data not received");
|
||||
}
|
||||
});
|
||||
|
||||
makeServerRequest.then(result => {
|
||||
console.log(result);
|
||||
});
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
const codeWithoutSpaces = code.replace(/\s/g, '');
|
||||
const errorIsParameter = /\.catch\((function\(error\){|error|\(error\)=>)/.test(codeWithoutSpaces);
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
const makeServerRequest = new Promise((resolve, reject) => {
|
||||
// responseFromServer is set to false to represent an unsuccessful response from a server
|
||||
let responseFromServer = false;
|
||||
|
||||
if(responseFromServer) {
|
||||
resolve("We got the data");
|
||||
} else {
|
||||
reject("Data not received");
|
||||
}
|
||||
});
|
||||
|
||||
makeServerRequest.then(result => {
|
||||
console.log(result);
|
||||
});
|
||||
|
||||
makeServerRequest.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
```
|
||||
|
||||
</section>
|
@ -2,62 +2,60 @@
|
||||
id: 587d7b8d367417b2b2512b59
|
||||
title: Import a Default Export
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 导入默认导出
|
||||
forumTopicId: 301205
|
||||
localeTitle: 导入一个默认的导出
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">在上一次挑战中,您了解了<code>export default</code>及其用途。请务必注意,要导入默认导出,您需要使用不同的<code>import</code>语法。在下面的示例中,我们有一个函数<code>add</code> ,它是文件的默认导出<code>"math_functions"</code> 。以下是如何导入它: <blockquote>从“math_functions”导入添加; <br>添加(5,4); //将返回9 </blockquote>语法在一个关键位置有所不同 - 导入的值<code>add</code>不会被花括号<code>{}</code>包围。与导出值不同,导入默认导出的主要方法是在<code>import</code>后简单地写入值的名称。 </section>
|
||||
<section id='description'>
|
||||
在上一个挑战里,学习了<code>export default</code>的用法。还需要一种<code>import</code>的语法来导入默认的导出。
|
||||
在下面的例子里有一个<code>add</code>函数, 它在<code>"math_functions"</code>文件里默认被导出。来看看来如何导入它:
|
||||
|
||||
```js
|
||||
import add from "./math_functions.js";
|
||||
```
|
||||
|
||||
这个语法只有一处不同的地方 —— 被导入的<code>add</code>值,并没有被花括号<code>{}</code>所包围。与导出值的方法不同,导入默认导出的写法仅仅只是简单的将变量名写在<code>import</code>之后。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">在下面的代码中,请从文件<code>"math_functions"</code>导入默认导出, <code>subtract</code> ,该文件位于与此文件相同的目录中。 </section>
|
||||
<section id='instructions'>
|
||||
在下面的代码中,请导入在同目录下的<code>"math_functions"</code>文件中默认导出的<code>subtract</code>值。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 正确导入<code>export default</code>方法。
|
||||
- text: 正确导入<code>export default</code>方法导出的值。
|
||||
testString: assert(code.match(/import\s+subtract\s+from\s+('|")\.\/math_functions\.js\1/g));
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
"use strict";
|
||||
|
||||
// add code above this line
|
||||
|
||||
subtract(7,4);
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### Before Test
|
||||
<div id='js-setup'>
|
||||
|
||||
```js
|
||||
window.require = function(str) {
|
||||
if (str === 'math_functions') {
|
||||
return function(a, b) {
|
||||
return a - b;
|
||||
}}};
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
import subtract from "./math_functions.js";
|
||||
// add code above this line
|
||||
|
||||
subtract(7,4);
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,15 +2,31 @@
|
||||
id: 587d7b87367417b2b2512b42
|
||||
title: Mutate an Array Declared with const
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 改变用const声明的数组
|
||||
forumTopicId: 301206
|
||||
localeTitle: 改变一个用 const 声明的数组
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description"> <code>const</code>声明在现代JavaScript中有许多用例。一些开发人员更喜欢默认使用<code>const</code>分配所有变量,除非他们知道需要重新分配值。只有在这种情况下,他们才会使用<code>let</code> 。但是,重要的是要理解使用<code>const</code>分配给变量的对象(包括数组和函数)仍然是可变的。使用<code>const</code>声明仅阻止重新分配变量标识符。 <blockquote> “严格使用”; <br> const s = [5,6,7]; <br> s = [1,2,3]; //抛出错误,尝试分配const <br> s [2] = 45; //就像使用var或let声明的数组一样工作<br>的console.log(一个或多个); //返回[5,6,45] </blockquote>如您所见,您可以改变对象<code>[5, 6, 7]</code>本身,变量<code>s</code>仍将指向更改的数组<code>[5, 6, 45]</code> 。与所有数组一样, <code>s</code>中的数组元素是可变的,但由于使用了<code>const</code> ,因此不能使用变量标识符<code>s</code>使用赋值运算符指向不同的数组。 </section>
|
||||
<section id='description'>
|
||||
在现代的 JavaScript 里,<code>const</code>声明有很多用法。
|
||||
一些开发者倾向默认使用<code>const</code>来声明所有变量,但如果它们打算在后续的代码中修改某个值,那在声明的时候就会用<code>let</code>。
|
||||
然而,你要注意,对象(包括数组和函数)在使用<code>const</code>声明的时候依然是可变的。使用<code>const</code>来声明只会保证它的标识不会被重新赋值。
|
||||
|
||||
```js
|
||||
"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]
|
||||
```
|
||||
|
||||
从以上代码看出,你可以改变<code>[5, 6, 7]</code>自身,所以<code>s</code>变量指向了改变后的数组<code>[5, 6, 45]</code>。和所有数组一样,数组<code>s</code>中的数组元素是可以被改变的,但是因为使用了<code>const</code>关键字,你不能使用赋值操作符将变量标识<code>s</code>指向另外一个数组。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">数组声明为<code>const s = [5, 7, 2]</code> 。使用各种元素分配将数组更改为<code>[2, 5, 7]</code> 。 </section>
|
||||
<section id='instructions'>
|
||||
这里有一个使用<code>const s = [5, 7, 2]</code>声明的数组。使用对各元素赋值的方法将数组改成<code>[2, 5, 7]</code>。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
@ -19,11 +35,11 @@ localeTitle: 改变用const声明的数组
|
||||
tests:
|
||||
- text: 不要替换<code>const</code>关键字。
|
||||
testString: getUserInput => assert(getUserInput('index').match(/const/g));
|
||||
- text: <code>s</code>应该是一个常量变量(使用<code>const</code> )。
|
||||
- text: <code>s</code>应该为常量 (通过使用<code>const</code>)。
|
||||
testString: getUserInput => assert(getUserInput('index').match(/const\s+s/g));
|
||||
- text: 不要更改原始数组声明。
|
||||
- text: 不要改变原数组的声明。
|
||||
testString: getUserInput => assert(getUserInput('index').match(/const\s+s\s*=\s*\[\s*5\s*,\s*7\s*,\s*2\s*\]\s*;?/g));
|
||||
- text: '<code>s</code>应该等于<code>[2, 5, 7]</code> 。'
|
||||
- text: <code>s</code>应该等于<code>[2, 5, 7]</code>。
|
||||
testString: assert.deepEqual(s, [2, 5, 7]);
|
||||
|
||||
```
|
||||
@ -38,7 +54,7 @@ tests:
|
||||
```js
|
||||
const s = [5, 7, 2];
|
||||
function editInPlace() {
|
||||
"use strict";
|
||||
'use strict';
|
||||
// change code below this line
|
||||
|
||||
// s = [2, 5, 7]; <- this is invalid
|
||||
@ -46,7 +62,6 @@ function editInPlace() {
|
||||
// change code above this line
|
||||
}
|
||||
editInPlace();
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -59,6 +74,18 @@ editInPlace();
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
const s = [5, 7, 2];
|
||||
function editInPlace() {
|
||||
'use strict';
|
||||
// change code below this line
|
||||
|
||||
// s = [2, 5, 7]; <- this is invalid
|
||||
s[0] = 2;
|
||||
s[1] = 5;
|
||||
s[2] = 7;
|
||||
// change code above this line
|
||||
}
|
||||
editInPlace();
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,15 +2,33 @@
|
||||
id: 598f48a36c8c40764b4e52b3
|
||||
title: Prevent Object Mutation
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 防止对象突变
|
||||
forumTopicId: 301207
|
||||
localeTitle: 防止对象改变
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">正如之前的挑战所示, <code>const</code>声明本身并不能真正保护您的数据免受突变。为确保您的数据不会发生变化,JavaScript提供了一个<code>Object.freeze</code>函数来防止数据突变。对象冻结后,您将无法再从中添加,更新或删除属性。任何更改对象的尝试都将被拒绝而不会出现错误。 <blockquote>让obj = { <br>名称:“FreeCodeCamp” <br>点评:“真棒” <br> }; <br> Object.freeze(OBJ); <br> obj.review =“坏”; //将被忽略。不允许变异<br> obj.newProp =“测试”; //将被忽略。不允许变异<br>的console.log(OBJ); <br> // {name:“FreeCodeCamp”,评论:“很棒”} </blockquote></section>
|
||||
<section id='description'>
|
||||
通过之前的挑战可以看出,<code>const</code>声明并不会真的保护你的数据不被改变。为了确保数据不被改变,JavaScript 提供了一个函数<code>Object.freeze</code>来防止数据改变。
|
||||
当一个对象被冻结的时候,你不能再对它的属性再进行增、删、改的操作。任何试图改变对象的操作都会被阻止,却不会报错。
|
||||
|
||||
```js
|
||||
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"}
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">在这个挑战中,您将使用<code>Object.freeze</code>来防止数学常量发生变化。您需要冻结<code>MATH_CONSTANTS</code>对象,以便没有人能够更改<code>PI</code>的值,添加或删除属性。 </section>
|
||||
<section id='instructions'>
|
||||
在这个挑战中,你将使用<code>Object.freeze</code>来防止数学常量被改变。你需要冻结<code>MATH_CONSTANTS</code>对象,使得没有人可以改变<code>PI</code>的值,抑或增加或删除属性。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
@ -19,11 +37,11 @@ localeTitle: 防止对象突变
|
||||
tests:
|
||||
- text: 不要替换<code>const</code>关键字。
|
||||
testString: getUserInput => assert(getUserInput('index').match(/const/g));
|
||||
- text: <code>MATH_CONSTANTS</code>应该是一个常量变量(使用<code>const</code> )。
|
||||
- text: <code>MATH_CONSTANTS</code>应该为一个常量 (使用<code>const</code>)。
|
||||
testString: getUserInput => assert(getUserInput('index').match(/const\s+MATH_CONSTANTS/g));
|
||||
- text: 请勿更改原始<code>MATH_CONSTANTS</code> 。
|
||||
- text: 不要改变原始的<code>MATH_CONSTANTS</code>。
|
||||
testString: getUserInput => assert(getUserInput('index').match(/const\s+MATH_CONSTANTS\s+=\s+{\s+PI:\s+3.14\s+};/g));
|
||||
- text: <code>PI</code>等于<code>3.14</code> 。
|
||||
- text: <code>PI</code>等于<code>3.14</code>。
|
||||
testString: assert(PI === 3.14);
|
||||
|
||||
```
|
||||
@ -37,7 +55,7 @@ tests:
|
||||
|
||||
```js
|
||||
function freezeObj() {
|
||||
"use strict";
|
||||
'use strict';
|
||||
const MATH_CONSTANTS = {
|
||||
PI: 3.14
|
||||
};
|
||||
@ -47,13 +65,12 @@ function freezeObj() {
|
||||
// change code above this line
|
||||
try {
|
||||
MATH_CONSTANTS.PI = 99;
|
||||
} catch( ex ) {
|
||||
} catch(ex) {
|
||||
console.log(ex);
|
||||
}
|
||||
return MATH_CONSTANTS.PI;
|
||||
}
|
||||
const PI = freezeObj();
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -66,6 +83,23 @@ const PI = freezeObj();
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
function freezeObj() {
|
||||
'use strict';
|
||||
const MATH_CONSTANTS = {
|
||||
PI: 3.14
|
||||
};
|
||||
// change code below this line
|
||||
Object.freeze(MATH_CONSTANTS);
|
||||
|
||||
// change code above this line
|
||||
try {
|
||||
MATH_CONSTANTS.PI = 99;
|
||||
} catch(ex) {
|
||||
console.log(ex);
|
||||
}
|
||||
return MATH_CONSTANTS.PI;
|
||||
}
|
||||
const PI = freezeObj();
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -0,0 +1,71 @@
|
||||
---
|
||||
id: 587d7b8c367417b2b2512b55
|
||||
title: Reuse Javascript Code Using import
|
||||
challengeType: 1
|
||||
forumTopicId: 301208
|
||||
localeTitle: 通过 import 复用 JavaScript 代码
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<code>import</code> 可以导入文件或模块的一部分。在之前的课程里,例子从 <code>math_functions.js</code> 文件里导出了 <code>add</code>,下面看一下如何在其它的文件导入它:
|
||||
|
||||
```js
|
||||
import { add } from './math_functions.js';
|
||||
```
|
||||
|
||||
在这里,<code>import</code> 会在 <code>math_functions.js</code> 里找到 <code>add</code>,只导入这个函数,忽略剩余的部分。<code>./</code> 告诉程序在当前文件的相同目录寻找 <code>math_functions.js</code> 文件。用这种方式导入时,相对路径(<code>./</code>)和文件扩展名(<code>.js</code>)都是必需的。
|
||||
|
||||
可以在导入语句里导入多个项目,如下:
|
||||
|
||||
```js
|
||||
import { add, subtract } from './math_functions.js';
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
添加 <code>import</code> 语句,使当前文件可以使用你在之前课程里导出的 <code>uppercaseString</code> 和 <code>lowercaseString</code> 函数,函数在当前路径下的 <code>string_functions.js</code> 文件里。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 应该导入 <code>uppercaseString</code>、
|
||||
testString: assert(code.match(/import\s*{\s*(uppercaseString[^}]*|[^,]*,\s*uppercaseString\s*)}\s+from\s+('|")\.\/string_functions\.js\2/g));
|
||||
- text: 应该导入 <code>lowercaseString</code>、
|
||||
testString: assert(code.match(/import\s*{\s*(lowercaseString[^}]*|[^,]*,\s*lowercaseString\s*)}\s+from\s+('|")\.\/string_functions\.js\2/g));
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
|
||||
// add code above this line
|
||||
|
||||
uppercaseString("hello");
|
||||
lowercaseString("WORLD!");
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
import { uppercaseString, lowercaseString } from './string_functions.js';
|
||||
// add code above this line
|
||||
|
||||
uppercaseString("hello");
|
||||
lowercaseString("WORLD!");
|
||||
```
|
||||
|
||||
</section>
|
@ -2,26 +2,40 @@
|
||||
id: 587d7b88367417b2b2512b46
|
||||
title: Set Default Parameters for Your Functions
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
forumTopicId: 301209
|
||||
localeTitle: 设置函数的默认参数
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">为了帮助我们创建更灵活的函数,ES6引入了函数的<dfn>默认参数</dfn> 。看看这段代码: <blockquote> function greeting(name =“Anonymous”){ <br>返回“你好”+名字; <br> } <br>的console.log(问候语( “约翰”)); // 你好约翰<br>的console.log(问候()); //你好匿名</blockquote>默认参数在未指定参数时启动(未定义)。正如您在上面的示例中所看到的,当您未为参数提供值时,参数<code>name</code>将接收其默认值<code>"Anonymous"</code> 。您可以根据需要为任意数量的参数添加默认值。 </section>
|
||||
<section id='description'>
|
||||
ES6 里允许给函数传入<dfn>默认参数</dfn>,来构建更加灵活的函数。
|
||||
请看以下代码:
|
||||
|
||||
```js
|
||||
const greeting = (name = "Anonymous") => "Hello " + name;
|
||||
|
||||
console.log(greeting("John")); // Hello John
|
||||
console.log(greeting()); // Hello Anonymous
|
||||
```
|
||||
|
||||
默认参数会在参数没有被指定(值为 undefined )的时候起作用。在上面的例子中,参数<code>name</code>会在没有得到新的值的时候,默认使用值 "Anonymous"。你还可以给多个参数赋予默认值。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">修改函数<code>increment</code>加入默认参数,这样它会加1 <code>number</code> ,如果<code>value</code>未指定。 </section>
|
||||
<section id='instructions'>
|
||||
给函数<code>increment</code>加上默认参数,使得在<code>value</code>没有被赋值的时候,默认给<code>number</code>加1。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: '<code>increment(5, 2)</code>应为<code>7</code> 。'
|
||||
- text: <code>increment(5, 2)</code>的结果应该为<code>7</code>。
|
||||
testString: assert(increment(5, 2) === 7);
|
||||
- text: <code>increment(5)</code>的结果应为<code>6</code> 。
|
||||
- text: <code>increment(5)</code>的结果应该为<code>6</code>。
|
||||
testString: assert(increment(5) === 6);
|
||||
- text: 默认参数<code>1</code>用于<code>value</code> 。
|
||||
- text: 参数<code>value</code>的默认值应该为<code>1</code>。
|
||||
testString: assert(code.match(/value\s*=\s*1/g));
|
||||
|
||||
```
|
||||
@ -34,15 +48,10 @@ tests:
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
const increment = (function() {
|
||||
"use strict";
|
||||
return function increment(number, value) {
|
||||
return number + value;
|
||||
};
|
||||
})();
|
||||
const increment = (number, value) => number + value;
|
||||
|
||||
console.log(increment(5, 2)); // returns 7
|
||||
console.log(increment(5)); // returns 6
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -55,6 +64,7 @@ console.log(increment(5)); // returns 6
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
const increment = (number, value = 1) => number + value;
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -1,63 +0,0 @@
|
||||
---
|
||||
id: 587d7b8c367417b2b2512b55
|
||||
title: Understand the Differences Between import and require
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 理解import和require之间的差异
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">过去,函数<code>require()</code>将用于导入外部文件和模块中的函数和代码。虽然方便,但这会带来一个问题:某些文件和模块相当大,您可能只需要来自这些外部资源的某些代码。 ES6为我们提供了一个非常方便的工具,称为<dfn>import</dfn> 。有了它,我们可以选择加载到给定文件中的模块或文件的哪些部分,从而节省时间和内存。请考虑以下示例。想象一下<code>math_array_functions</code>有大约20个函数,但我在当前文件中只需要一个<code>countItems</code> 。旧的<code>require()</code>方法会迫使我引入所有20个函数。使用这种新的<code>import</code>语法,我可以引入所需的功能,如下所示: <blockquote>从“math_array_functions”导入{countItems} </blockquote>上面代码的描述: <blockquote>从“file_path_goes_here”导入{function} <br> //我们也可以用同样的方式导入变量! </blockquote>有几种方法可以编写<code>import</code>语句,但上面是一个非常常见的用例。 <strong>注意</strong> <br>花括号内的函数周围的空格是最佳实践 - 它使得读取<code>import</code>语句更容易。 <strong>注意</strong> <br>本节中的课程处理非浏览器功能。 <code>import</code>以及我们在其余课程中介绍的语句将无法直接在浏览器上运行。但是,我们可以使用各种工具来创建代码,使其在浏览器中工作。 <strong>注意</strong> <br>在大多数情况下,文件路径在它之前需要<code>./</code> ;否则,node将首先尝试将其作为依赖项加载到<code>node_modules</code>目录中。 </section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">添加适当的<code>import</code>语句,允许当前文件使用<code>capitalizeString</code>函数。此函数所在的文件称为<code>"string_functions"</code> ,它与当前文件位于同一目录中。 </section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 有效的<code>import</code>声明
|
||||
testString: 'getUserInput => assert(getUserInput("index").match(/import\s+\{\s*capitalizeString\s*\}\s+from\s+("|")string_functions\1/g), "valid <code>import</code> statement");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
"use strict";
|
||||
capitalizeString("hello!");
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### Before Test
|
||||
<div id='js-setup'>
|
||||
|
||||
```js
|
||||
window.require = function (str) {
|
||||
if (str === 'string_functions') {
|
||||
return {
|
||||
capitalizeString: str => str.toUpperCase()
|
||||
}}};
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@ -2,15 +2,31 @@
|
||||
id: 587d7b8c367417b2b2512b57
|
||||
title: Use * to Import Everything from a File
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用*从文件导入所有内容
|
||||
forumTopicId: 301210
|
||||
localeTitle: 用 * 从文件中导入所有内容
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">假设您有一个文件要将其所有内容导入当前文件。这可以使用<dfn>import *</dfn>语法完成。这是一个示例,其中名为<code>"math_functions"</code>的文件的内容被导入到同一目录中的文件中: <blockquote>从“math_functions”导入*作为myMathModule; <br> myMathModule.add(2,3); <br> myMathModule.subtract(5,3); </blockquote>并打破代码: <blockquote>从“file_path_goes_here”导入* as object_with_name_of_your_choice <br> object_with_name_of_your_choice.imported_function </blockquote>您可以使用<code>import * as</code>后面的任何名称<code>import * as</code>语句的一部分。为了使用此方法,它需要一个接收导入值的对象。从这里,您将使用点表示法来调用导入的值。 </section>
|
||||
<section id='description'>
|
||||
我们还可以用<code>import</code>语法从文件中导入所有的内容。下面是一个从同目录下的<code>"math_functions"</code>文件中导入所有内容的例子:
|
||||
|
||||
```js
|
||||
import * as myMathModule from "./math_functions.js";
|
||||
```
|
||||
|
||||
上面的 <code>import</code> 语句会创建一个叫做 <code>myMathModule</code> 的对象。这只是一个变量名,可以随便命名。对象包含 <code>math_functions.js</code> 文件里的所有导出,可以像访问对象的属性那样访问里面的函数。下面是使用导入的 <code>add</code> 和 <code>subtract</code> 函数的例子:
|
||||
|
||||
```js
|
||||
myMathModule.add(2,3);
|
||||
myMathModule.subtract(5,3);
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">下面的代码需要在导入的同一目录中找到的文件<code>"capitalize_strings"</code>的内容。使用提供的对象将相应的<code>import *</code>语句添加到文件的顶部。 </section>
|
||||
<section id='instructions'>
|
||||
下面的代码需要从同目录下的<code>"string_functions"</code>文件中导入所有内容。使用提供的对象,在当前文件的顶部添加正确的<code>import *</code>语句
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
@ -19,45 +35,34 @@ localeTitle: 使用*从文件导入所有内容
|
||||
tests:
|
||||
- text: 正确使用<code>import * as</code>语法。
|
||||
testString: assert(code.match(/import\s*\*\s*as\s+stringFunctions\s+from\s*('|")\.\/string_functions\.js\1/g));
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
"use strict";
|
||||
|
||||
// add code above this line
|
||||
|
||||
stringFunctions.uppercaseString("hello");
|
||||
stringFunctions.lowercaseString("WORLD!");
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### Before Test
|
||||
<div id='js-setup'>
|
||||
|
||||
```js
|
||||
window.require = function(str) {
|
||||
if (str === 'capitalize_strings') {
|
||||
return {
|
||||
capitalize: str => str.toUpperCase(),
|
||||
lowercase: str => str.toLowerCase()
|
||||
}}};
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
import * as stringFunctions from "./string_functions.js";
|
||||
// add code above this line
|
||||
|
||||
stringFunctions.uppercaseString("hello");
|
||||
stringFunctions.lowercaseString("WORLD!");
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,30 +2,59 @@
|
||||
id: 587d7b87367417b2b2512b43
|
||||
title: Use Arrow Functions to Write Concise Anonymous Functions
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用箭头函数编写简明的匿名函数
|
||||
forumTopicId: 301211
|
||||
localeTitle: 使用箭头函数编写简洁的匿名函数
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">在JavaScript中,我们通常不需要命名我们的函数,特别是在将函数作为参数传递给另一个函数时。相反,我们创建内联函数。我们不需要命名这些函数,因为我们不会在其他任何地方重用它们。为此,我们经常使用以下语法: <blockquote> const myFunc = function(){ <br> const myVar =“value”; <br>返回myVar; <br> } </blockquote> ES6为我们提供了语法糖,而不必以这种方式编写匿名函数。相反,您可以使用<strong>箭头函数语法</strong> : <blockquote> const myFunc =()=> { <br> const myVar =“value”; <br>返回myVar; <br> } </blockquote>当没有函数体,并且只有返回值时,箭头函数语法允许您省略关键字<code>return</code>以及代码周围的括号。这有助于将较小的函数简化为单行语句: <blockquote> const myFunc =()=>“value” </blockquote>默认情况下,此代码仍将返回<code>value</code> 。 </section>
|
||||
<section id='description'>
|
||||
在 JavaScript 里,我们会经常遇到不需要给函数命名的情况,尤其是在需要将一个函数作为参数传给另外一个函数的时候。这时,我们会创建匿名函数。因为这些函数不会在其他地方复用,所以我们不需要给它们命名。
|
||||
这种情况下,我们通常会使用以下语法:
|
||||
|
||||
```js
|
||||
const myFunc = function() {
|
||||
const myVar = "value";
|
||||
return myVar;
|
||||
}
|
||||
```
|
||||
|
||||
ES6 提供了其他写匿名函数的方式的语法糖。你可以使用箭头函数:
|
||||
|
||||
```js
|
||||
const myFunc = () => {
|
||||
const myVar = "value";
|
||||
return myVar;
|
||||
}
|
||||
```
|
||||
|
||||
当不需要函数体,只返回一个值的时候,箭头函数允许你省略<code>return</code>关键字和外面的大括号。这样就可以将一个简单的函数简化成一个单行语句。
|
||||
|
||||
```js
|
||||
const myFunc = () => "value";
|
||||
```
|
||||
|
||||
这段代码仍然会返回<code>value</code>。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">重写分配给变量<code>magic</code>的函数,该函数返回一个新的<code>Date()</code>以使用箭头函数语法。还要确保使用关键字<code>var</code>定义任何内容。 </section>
|
||||
<section id='instructions'>
|
||||
使用箭头函数的语法重写<code>magic</code>函数,使其返回一个新的<code>Date()</code>。同时不要用<code>var</code>关键字来定义任何变量。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 用户确实替换了<code>var</code>关键字。
|
||||
- text: 替换掉<code>var</code>关键字。
|
||||
testString: getUserInput => assert(!getUserInput('index').match(/var/g));
|
||||
- text: <code>magic</code>应该是一个常量变量(通过使用<code>const</code> )。
|
||||
- text: <code>magic</code>应该为一个常量 (使用<code>const</code>)。
|
||||
testString: getUserInput => assert(getUserInput('index').match(/const\s+magic/g));
|
||||
- text: <code>magic</code>是一种<code>function</code> 。
|
||||
- text: <code>magic</code>是一个<code>function</code>。
|
||||
testString: assert(typeof magic === 'function');
|
||||
- text: <code>magic()</code>返回正确的日期。
|
||||
testString: assert(magic().setHours(0,0,0,0) === new Date().setHours(0,0,0,0));
|
||||
- text: <code>function</code>关键字未使用。
|
||||
- text: 不要使用<code>function</code>关键字。
|
||||
testString: getUserInput => assert(!getUserInput('index').match(/function/g));
|
||||
|
||||
```
|
||||
@ -42,7 +71,6 @@ var magic = function() {
|
||||
"use strict";
|
||||
return new Date();
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -55,6 +83,10 @@ var magic = function() {
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
const magic = () => {
|
||||
"use strict";
|
||||
return new Date();
|
||||
};
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,28 +2,59 @@
|
||||
id: 587d7b8b367417b2b2512b53
|
||||
title: Use class Syntax to Define a Constructor Function
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用类语法定义构造函数
|
||||
forumTopicId: 301212
|
||||
localeTitle: 使用 class 语法定义构造函数
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description"> ES6使用关键字<dfn>class</dfn>提供了一种帮助创建对象的新语法。需要注意的是, <code>class</code>语法只是一种语法,而不是面向对象范例的完整的基于类的实现,不像Java,Python或Ruby等语言。在ES5中,我们通常定义一个构造函数function,并使用<code>new</code>关键字实例化一个对象。 <blockquote> var SpaceShuttle = function(targetPlanet){ <br> this.targetPlanet = targetPlanet; <br> } <br> var zeus = new SpaceShuttle('Jupiter'); </blockquote>类语法只是替换构造函数创建: <blockquote> class SpaceShuttle { <br>构造(targetPlanet){ <br> this.targetPlanet = targetPlanet; <br> } <br> } <br> const zeus = new SpaceShuttle('Jupiter'); </blockquote>请注意, <code>class</code>关键字声明了一个新函数,并添加了一个构造函数,该函数将在调用<code>new</code>调用 - 以创建新对象。 </section>
|
||||
<section id='description'>
|
||||
ES6 提供了一个新的创建对象的语法,使用关键字<code>class</code>。
|
||||
值得注意的是,<code>class</code>只是一个语法糖,它并不像 Java、Python 或者 Ruby 这一类的语言一样,严格履行了面向对象的开发规范。
|
||||
在 ES5 里面,我们通常会定义一个构造函数,然后使用 <code>new</code> 关键字来实例化一个对象:
|
||||
|
||||
```js
|
||||
var SpaceShuttle = function(targetPlanet){
|
||||
this.targetPlanet = targetPlanet;
|
||||
}
|
||||
var zeus = new SpaceShuttle('Jupiter');
|
||||
```
|
||||
|
||||
<code>class</code>的语法只是简单地替换了构造函数的写法:
|
||||
|
||||
```js
|
||||
class SpaceShuttle {
|
||||
constructor(targetPlanet) {
|
||||
this.targetPlanet = targetPlanet;
|
||||
}
|
||||
}
|
||||
const zeus = new SpaceShuttle('Jupiter');
|
||||
```
|
||||
|
||||
应该注意 <code>class</code> 关键字声明了一个函数,里面添加了一个构造器(constructor)。当调用 <code>new</code> 来创建一个新对象时构造器会被调用。
|
||||
|
||||
<strong>注意:</strong><br><ul>
|
||||
<li> 首字母大写驼峰命名法是 ES6 class 名的惯例,就像上面的 <code>SpaceShuttle</code>。</li>
|
||||
<li> 构造函数是一个特殊的函数,在用 class 创建时来创建和初始化对象。在 JavaScript 算法和数据结构证书的面向对象章节里会更深入介绍。</li></ul>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">使用<code>class</code>关键字并编写适当的构造函数来创建<code>Vegetable</code>类。使用<code>Vegetable</code>可以创建具有属性<code>name</code>的蔬菜对象,以传递给构造函数。 </section>
|
||||
<section id='instructions'>
|
||||
使用<code>class</code>关键字,并写出正确的构造函数,来创建<code>Vegetable</code>这个类:
|
||||
<code>Vegetable</code>这个类可以创建 vegetable 对象,这个对象拥有一个在构造函数中赋值的<code>name</code>属性。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>Vegetable</code>应该是一个<code>class</code>具有限定<code>constructor</code>方法。
|
||||
- text: <code>Vegetable</code> 应该是一个 <code>class</code>,并在其中定义了<code>constructor</code>方法。
|
||||
testString: assert(typeof Vegetable === 'function' && typeof Vegetable.constructor === 'function');
|
||||
- text: <code>class</code>关键字。
|
||||
- text: 使用了<code>class</code>关键字。
|
||||
testString: assert(code.match(/class/g));
|
||||
- text: <code>Vegetable</code>可以实例化。
|
||||
- text: <code>Vegetable</code>可以被实例化。
|
||||
testString: assert(() => {const a = new Vegetable("apple"); return typeof a === 'object';});
|
||||
- text: <code>carrot.name</code>应该返回<code>carrot</code> 。
|
||||
- text: <code>carrot.name</code> 应该返回 <code>carrot</code>.
|
||||
testString: assert(carrot.name=='carrot');
|
||||
|
||||
```
|
||||
@ -36,17 +67,12 @@ tests:
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function makeClass() {
|
||||
"use strict";
|
||||
/* Alter code below this line */
|
||||
/* Alter code below this line */
|
||||
|
||||
/* Alter code above this line */
|
||||
|
||||
/* Alter code above this line */
|
||||
return Vegetable;
|
||||
}
|
||||
const Vegetable = makeClass();
|
||||
const carrot = new Vegetable('carrot');
|
||||
console.log(carrot.name); // => should be 'carrot'
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -59,6 +85,12 @@ console.log(carrot.name); // => should be 'carrot'
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
class Vegetable {
|
||||
constructor(name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
const carrot = new Vegetable('carrot');
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,26 +2,46 @@
|
||||
id: 587d7b89367417b2b2512b4b
|
||||
title: Use Destructuring Assignment to Assign Variables from Arrays
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用解构分配从数组中分配变量
|
||||
forumTopicId: 301213
|
||||
localeTitle: 使用解构赋值从数组中分配变量
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description"> ES6使解构数组像解构对象一样简单。扩展运算符和数组解构之间的一个关键区别是扩展运算符将数组的所有内容解包为逗号分隔列表。因此,您无法选择或选择要分配给变量的元素。对阵列进行解构可以让我们做到这一点: <blockquote> const [a,b] = [1,2,3,4,5,6]; <br> console.log(a,b); // 1,2 </blockquote>变量<code>a</code>被赋予数组的第一个值,而<code>b</code>被赋予数组的第二个值。我们还可以通过使用逗号来访问所需索引,从而在数组中的任何索引处访问该值: <blockquote> const [a,b ,,, c] = [1,2,3,4,5,6]; <br> console.log(a,b,c); // 1,2,5 </blockquote></section>
|
||||
<section id='description'>
|
||||
在 ES6 里面,解构数组可以如同解构对象一样简单。
|
||||
与数组解构不同,数组的扩展运算会将数组里的所有内容分解成一个由逗号分隔的列表。所以,你不能选择哪个元素来给变量赋值。
|
||||
而对数组进行解构却可以让我们做到这一点:
|
||||
|
||||
```js
|
||||
const [a, b] = [1, 2, 3, 4, 5, 6];
|
||||
console.log(a, b); // 1, 2
|
||||
```
|
||||
|
||||
变量<code>a</code>以及<code>b</code>分别被数组的第一、第二个元素赋值。
|
||||
我们甚至能在数组解构中使用逗号分隔符,来获取任意一个想要的值:
|
||||
|
||||
```js
|
||||
const [a, b,,, c] = [1, 2, 3, 4, 5, 6];
|
||||
console.log(a, b, c); // 1, 2, 5
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">使用解构赋值来交换<code>a</code>和<code>b</code>的值,以便<code>a</code>接收存储在<code>b</code>的值,并且<code>b</code>接收存储在<code>a</code>的值。 </section>
|
||||
<section id='instructions'>
|
||||
使用数组解构来交换变量<code>a</code>与<code>b</code>的值。使<code>a</code>、<code>b</code>能分别获得对方的值。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 交换后<code>a</code>值应为6。
|
||||
- text: 在交换后,<code>a</code>的值应该为6。
|
||||
testString: assert(a === 6);
|
||||
- text: 交换后<code>b</code>值应为8。
|
||||
- text: 在交换后,<code>b</code>的值应该为8。
|
||||
testString: assert(b === 8);
|
||||
- text: 使用数组解构来交换a和b。
|
||||
- text: 使用数组解构来交换<code>a</code>和<code>b</code>。
|
||||
testString: assert(/\[\s*(\w)\s*,\s*(\w)\s*\]\s*=\s*\[\s*\2\s*,\s*\1\s*\]/g.test(code));
|
||||
|
||||
```
|
||||
@ -35,15 +55,11 @@ tests:
|
||||
|
||||
```js
|
||||
let a = 8, b = 6;
|
||||
(() => {
|
||||
"use strict";
|
||||
// change code below this line
|
||||
// change code below this line
|
||||
|
||||
// change code above this line
|
||||
})();
|
||||
// change code above this line
|
||||
console.log(a); // should be 6
|
||||
console.log(b); // should be 8
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -56,6 +72,8 @@ console.log(b); // should be 8
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
let a = 8, b = 6;
|
||||
[a, b] = [b, a];
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,63 +2,102 @@
|
||||
id: 587d7b89367417b2b2512b4a
|
||||
title: Use Destructuring Assignment to Assign Variables from Nested Objects
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用解构分配从嵌套对象分配变量
|
||||
forumTopicId: 301214
|
||||
localeTitle: 使用解构赋值从嵌套对象中分配变量
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">我们可以类似地将<em>嵌套</em>对象解构为变量。请考虑以下代码: <blockquote> const a = { <br>开始:{x:5,y:6}, <br>结束:{x:6,y:-9} <br> }; <br> const {start:{x:startX,y:startY}} = a; <br> console.log(startX,startY); // 5,6 </blockquote>在上面的示例中,变量<code>start</code>被赋予<code>a.start</code>的值,该值也是一个对象。 </section>
|
||||
<section id='description'>
|
||||
同样,我们可以将 <em>嵌套的对象</em>解构到变量中。
|
||||
|
||||
请看以下代码:
|
||||
|
||||
```js
|
||||
const user = {
|
||||
johnDoe: {
|
||||
age: 34,
|
||||
email: 'johnDoe@freeCodeCamp.com'
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
这是解构对象的属性并赋值给相同名字的变量:
|
||||
|
||||
```js
|
||||
const { johnDoe: { age, email }} = user;
|
||||
```
|
||||
|
||||
这是将对象的属性值指定给一个不同的名字:
|
||||
|
||||
```js
|
||||
const { johnDoe: { age: userAge, email: userEmail }} = user;
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">用解构赋值来获得<code>max</code>的<code>forecast.tomorrow</code>并将其分配给<code>maxOfTomorrow</code> 。 </section>
|
||||
<section id='instructions'>
|
||||
将两个赋值语句替换成等价的解构赋值。<code>lowToday</code> 和 <code>highToday</code> 应该为 <code>LOCAL_FORECAST</code> 中 <code>today.low</code> 和 <code>today.high</code> 的值。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>maxOfTomorrow</code>等于<code>84.6</code>
|
||||
testString: 'assert(getMaxOfTmrw(LOCAL_FORECAST) === 84.6, "<code>maxOfTomorrow</code> equals <code>84.6</code>");'
|
||||
- text: 使用嵌套解构
|
||||
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: 不能使用 ES5 的赋值语句。
|
||||
testString: assert(!code.match(/lowToday = LOCAL_FORECAST\.today\.low/g) && !code.match(/highToday = LOCAL_FORECAST\.today.high/g))
|
||||
- text: 应该使用解构创建 <code>lowToday</code> 变量。
|
||||
testString: assert(code.match(/(var|const|let)\s*{\s*today\s*:\s*{\s*(low\s*:\s*lowToday[^}]*|[^,]*,\s*low\s*:\s*lowToday\s*)}\s*}\s*=\s*LOCAL_FORECAST(;|\s+|\/\/)/g));
|
||||
- text: 应该使用解构创建 <code>highToday</code> 变量。
|
||||
testString: assert(code.match(/(var|const|let)\s*{\s*today\s*:\s*{\s*(high\s*:\s*highToday[^}]*|[^,]*,\s*high\s*:\s*highToday\s*)}\s*}\s*=\s*LOCAL_FORECAST(;|\s+|\/\/)/g));
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
const LOCAL_FORECAST = {
|
||||
today: { min: 72, max: 83 },
|
||||
tomorrow: { min: 73.3, max: 84.6 }
|
||||
yesterday: { low: 61, high: 75 },
|
||||
today: { low: 64, high: 77 },
|
||||
tomorrow: { low: 68, high: 80 }
|
||||
};
|
||||
|
||||
function getMaxOfTmrw(forecast) {
|
||||
"use strict";
|
||||
// change code below this line
|
||||
const maxOfTomorrow = undefined; // change this line
|
||||
// change code above this line
|
||||
return maxOfTomorrow;
|
||||
}
|
||||
// change code below this line
|
||||
|
||||
const lowToday = LOCAL_FORECAST.today.low;
|
||||
const highToday = LOCAL_FORECAST.today.high;
|
||||
|
||||
console.log(getMaxOfTmrw(LOCAL_FORECAST)); // should be 84.6
|
||||
// change code above this line
|
||||
|
||||
console.log(lowToday); // should be 64
|
||||
console.log(highToday); // should be 77
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
const LOCAL_FORECAST = {
|
||||
yesterday: { low: 61, high: 75 },
|
||||
today: { low: 64, high: 77 },
|
||||
tomorrow: { low: 68, high: 80 }
|
||||
};
|
||||
|
||||
// change code below this line
|
||||
|
||||
const { today: { low: lowToday, high: highToday }} = LOCAL_FORECAST;
|
||||
|
||||
// change code above this line
|
||||
|
||||
console.log(highToday); // should be 77
|
||||
console.log(highTomorrow); // should be 80
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,63 +2,94 @@
|
||||
id: 587d7b89367417b2b2512b49
|
||||
title: Use Destructuring Assignment to Assign Variables from Objects
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用解构分配从对象分配变量
|
||||
forumTopicId: 301215
|
||||
localeTitle: 使用解构赋值从对象中分配变量
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">我们之前看到扩展运算符如何有效地扩展或解包数组的内容。我们也可以用对象做类似的事情。 <dfn>解构赋值</dfn>是一种特殊的语法,用于将直接从对象获取的值整齐地分配给变量。请考虑以下ES5代码: <blockquote> var voxel = {x:3.6,y:7.4,z:6.54}; <br> var x = voxel.x; // x = 3.6 <br> var y = voxel.y; // y = 7.4 <br> var z = voxel.z; // z = 6.54 </blockquote>这是与ES6解构语法相同的赋值语句: <blockquote> const {x,y,z} =体素; // x = 3.6,y = 7.4,z = 6.54 </blockquote>相反,如果你想将<code>voxel.x</code>的值存储到<code>a</code> ,将<code>voxel.y</code>到<code>b</code> ,将<code>voxel.z</code>到<code>c</code> ,那么你也有这种自由。 <blockquote> const {x:a,y:b,z:c} =体素// a = 3.6,b = 7.4,c = 6.54 </blockquote>您可以将其读作“获取字段<code>x</code>并将值复制到<code>a</code>中”,依此类推。 </section>
|
||||
<section id='description'>
|
||||
可以在解构的属性后添加冒号和新的变量名来给解构的值赋予一个新的变量名。
|
||||
|
||||
还是以上个例子的对象来举例:
|
||||
|
||||
```js
|
||||
const user = { name: 'John Doe', age: 34 };
|
||||
```
|
||||
|
||||
这是指定新的变量名的例子:
|
||||
|
||||
```js
|
||||
const { name: userName, age: userAge } = user;
|
||||
// userName = 'John Doe', userAge = 34
|
||||
```
|
||||
|
||||
获取到了 <code>user.name</code> 的值并赋值给名为 <code>userName</code> 的变量。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">使用解构从输入对象<code>AVG_TEMPERATURES</code>获得明天的平均温度,并在<code>tomorrow</code>将关键值赋值给<code>tempOfTomorrow</code> 。 </section>
|
||||
<section id='instructions'>
|
||||
使用解构赋值语句替换两个赋值语句。确保 <code>HIGH_TEMPERATURES</code> 的 <code>today</code> 和 <code>tomorrow</code> 属性赋值给 <code>highToday</code> 和 <code>highTomorrow</code>。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>getTempOfTmrw(AVG_TEMPERATURES)</code>应为<code>79</code>
|
||||
testString: 'assert(getTempOfTmrw(AVG_TEMPERATURES) === 79, "<code>getTempOfTmrw(AVG_TEMPERATURES)</code> should be <code>79</code>");'
|
||||
- text: 使用了重新分配的解构
|
||||
testString: 'getUserInput => assert(getUserInput("index").match(/\{\s*tomorrow\s*:\s*tempOfTomorrow\s*}\s*=\s*avgTemperatures/g),"destructuring with reassignment was used");'
|
||||
|
||||
- text: 应该移除 ES5 赋值语句。
|
||||
testString: assert(!code.match(/highToday = HIGH_TEMPERATURES\.today/g) && !code.match(/highTomorrow = HIGH_TEMPERATURES\.tomorrow/g))
|
||||
- text: 应该使用解构赋值语句创建 <code>highToday</code> 变量。
|
||||
testString: assert(code.match(/(var|const|let)\s*{\s*(today:\s*highToday[^}]*|[^,]*,\s*today\s*:\s*highToday\s*)}\s*=\s*HIGH_TEMPERATURES(;|\s+|\/\/)/g));
|
||||
- text: 应该使用解构赋值语句创建 <code>highTomorrow</code> 变量。
|
||||
testString: assert(code.match(/(var|const|let)\s*{\s*(tomorrow:\s*highTomorrow[^}]*|[^,]*,\s*tomorrow\s*:\s*highTomorrow\s*)}\s*=\s*HIGH_TEMPERATURES(;|\s+|\/\/)/g));
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
const AVG_TEMPERATURES = {
|
||||
today: 77.5,
|
||||
tomorrow: 79
|
||||
const HIGH_TEMPERATURES = {
|
||||
yesterday: 75,
|
||||
today: 77,
|
||||
tomorrow: 80
|
||||
};
|
||||
|
||||
function getTempOfTmrw(avgTemperatures) {
|
||||
"use strict";
|
||||
// change code below this line
|
||||
const tempOfTomorrow = undefined; // change this line
|
||||
// change code above this line
|
||||
return tempOfTomorrow;
|
||||
}
|
||||
// change code below this line
|
||||
|
||||
const highToday = HIGH_TEMPERATURES.today;
|
||||
const highTomorrow = HIGH_TEMPERATURES.tomorrow;
|
||||
|
||||
console.log(getTempOfTmrw(AVG_TEMPERATURES)); // should be 79
|
||||
// change code above this line
|
||||
|
||||
console.log(yesterday) // should be not defined
|
||||
console.log(highToday); // should be 77
|
||||
console.log(highTomorrow); // should be 80
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
const HIGH_TEMPERATURES = {
|
||||
yesterday: 75,
|
||||
today: 77,
|
||||
tomorrow: 80
|
||||
};
|
||||
|
||||
// change code below this line
|
||||
|
||||
const { today: highToday, tomorrow: highTomorrow } = HIGH_TEMPERATURES;
|
||||
|
||||
// change code above this line
|
||||
|
||||
console.log(highToday); // should be 77
|
||||
console.log(highTomorrow); // should be 80
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -0,0 +1,101 @@
|
||||
---
|
||||
id: 5cfa550e84205a357704ccb6
|
||||
title: Use Destructuring Assignment to Extract Values from Objects
|
||||
challengeType: 1
|
||||
forumTopicId: 301216
|
||||
localeTitle: 使用解构赋值来获取对象的值
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<dfn>解构赋值</dfn> 是 ES6 引入的新语法,用来从数组和对象中提取值,并优雅的对变量进行赋值。
|
||||
|
||||
有如下 ES5 代码:
|
||||
|
||||
```js
|
||||
const user = { name: 'John Doe', age: 34 };
|
||||
|
||||
const name = user.name; // name = 'John Doe'
|
||||
const age = user.age; // age = 34
|
||||
```
|
||||
|
||||
下面是使用 ES6 解构赋值的等价语句:
|
||||
|
||||
```js
|
||||
const { name, age } = user;
|
||||
// name = 'John Doe', age = 34
|
||||
```
|
||||
|
||||
在这里,<code>name</code> 和 <code>age</code> 被自动创建并赋予 <code>user</code> 对象相应属性的值。一目了然。
|
||||
|
||||
解构赋值的参数数量可以任意。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
把两个赋值语句替换成等价的解构赋值。<code>today</code> 和 <code>tomorrow</code> 的值应该还为 <code>HIGH_TEMPERATURES</code> 对象的 <code>today</code> 和 <code>tomorrow</code> 属性的值。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 应该移除 ES5 赋值语句。
|
||||
testString: assert(!code.match(/today = HIGH_TEMPERATURES\.today/g) && !code.match(/tomorrow = HIGH_TEMPERATURES\.tomorrow/g))
|
||||
- text: 应该解构创建 <code>today</code> 变量。
|
||||
testString: assert(code.match(/(var|let|const)\s*{\s*(today[^}]*|[^,]*,\s*today)\s*}\s*=\s*HIGH_TEMPERATURES(;|\s+|\/\/)/g));
|
||||
- text: 应该解构创建 <code>tomorrow</code> 变量。
|
||||
testString: assert(code.match(/(var|let|const)\s*{\s*(tomorrow[^}]*|[^,]*,\s*tomorrow)\s*}\s*=\s*HIGH_TEMPERATURES(;|\s+|\/\/)/g));
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
const HIGH_TEMPERATURES = {
|
||||
yesterday: 75,
|
||||
today: 77,
|
||||
tomorrow: 80
|
||||
};
|
||||
|
||||
// change code below this line
|
||||
|
||||
const today = HIGH_TEMPERATURES.today;
|
||||
const tomorrow = HIGH_TEMPERATURES.tomorrow;
|
||||
|
||||
// change code above this line
|
||||
|
||||
console.log(yesterday) // should be not defined
|
||||
console.log(today); // should be 77
|
||||
console.log(tomorrow); // should be 80
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
const HIGH_TEMPERATURES = {
|
||||
yesterday: 75,
|
||||
today: 77,
|
||||
tomorrow: 80
|
||||
};
|
||||
|
||||
// change code below this line
|
||||
|
||||
const { today, tomorrow } = HIGH_TEMPERATURES;
|
||||
|
||||
// change code above this line
|
||||
|
||||
console.log(yesterday) // should be not defined
|
||||
console.log(today); // should be 77
|
||||
console.log(tomorrow); // should be 80
|
||||
```
|
||||
|
||||
</section>
|
@ -2,27 +2,52 @@
|
||||
id: 587d7b8a367417b2b2512b4d
|
||||
title: Use Destructuring Assignment to Pass an Object as a Function's Parameters
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用解构分配将对象作为函数的参数传递
|
||||
forumTopicId: 301217
|
||||
localeTitle: 使用解构赋值将对象作为函数的参数传递
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">在某些情况下,您可以在函数参数本身中对对象进行解构。考虑以下代码: <blockquote> const profileUpdate =(profileData)=> { <br> const {name,age,nationality,location} = profileData; <br> //用这些变量做点什么<br> } </blockquote>这有效地破坏了发送到函数中的对象。这也可以就地完成: <blockquote> const profileUpdate =({name,age,nationality,location})=> { <br> / *用这些字段做某事* / <br> } </blockquote>这将删除一些额外的行,使我们的代码看起来整洁。这具有额外的好处,即不必操纵函数中的整个对象;只有所需的字段才会复制到函数内部。 </section>
|
||||
<section id='description'>
|
||||
在某些情况下,你可以在函数的参数里直接解构对象。
|
||||
请看以下代码:
|
||||
|
||||
```js
|
||||
const profileUpdate = (profileData) => {
|
||||
const { name, age, nationality, location } = profileData;
|
||||
// do something with these variables
|
||||
}
|
||||
```
|
||||
|
||||
上面的操作解构了传给函数的对象。这样的操作也可以直接在参数里完成:
|
||||
|
||||
```js
|
||||
const profileUpdate = ({ name, age, nationality, location }) => {
|
||||
/* do something with these fields */
|
||||
}
|
||||
```
|
||||
|
||||
这样的操作去除了多余的代码,使代码更加整洁。
|
||||
这样做还有个额外的好处:函数不需要再去操作整个对象,而仅仅是操作复制到函数作用域内部的参数。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">在函数<code>half</code>的参数内使用解构赋值,仅在函数内发送<code>max</code>和<code>min</code> 。 </section>
|
||||
<section id='instructions'>
|
||||
对<code>half</code>的参数进行解构赋值,使得仅仅将<code>max</code>与<code>min</code>的值传进函数。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>stats</code>应该是一个<code>object</code> 。
|
||||
testString: 'assert(typeof stats === "object", "<code>stats</code> should be an <code>object</code>.");'
|
||||
- text: <code>half(stats)</code>应为<code>28.015</code>
|
||||
testString: 'assert(half(stats) === 28.015, "<code>half(stats)</code> should be <code>28.015</code>");'
|
||||
- text: 使用了解构。
|
||||
testString: 'getUserInput => assert(getUserInput("index").match(/\(\s*\{\s*\w+\s*,\s*\w+\s*\}\s*\)/g), "Destructuring was used.");'
|
||||
- text: <code>stats</code>的类型应该是一个<code>object</code>。
|
||||
testString: assert(typeof stats === 'object');
|
||||
- text: <code>half(stats)</code>应该等于<code>28.015</code>
|
||||
testString: assert(half(stats) === 28.015);
|
||||
- text: 应该使用解构赋值。
|
||||
testString: assert(code.replace(/\s/g, '').match(/half=\({\w+,\w+}\)/));
|
||||
- text: 应该使用解构参数。
|
||||
testString: assert(!code.match(/stats\.max|stats\.min/));
|
||||
|
||||
```
|
||||
|
||||
@ -42,20 +67,13 @@ const stats = {
|
||||
min: -0.75,
|
||||
average: 35.85
|
||||
};
|
||||
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
|
||||
// change code below this line
|
||||
const half = (stats) => (stats.max + stats.min) / 2.0; // use function argument destructuring
|
||||
// change code above this line
|
||||
|
||||
})();
|
||||
console.log(stats); // should be object
|
||||
console.log(half(stats)); // should be 28.015
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -68,6 +86,16 @@ console.log(half(stats)); // should be 28.015
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
const stats = {
|
||||
max: 56.78,
|
||||
standard_deviation: 4.34,
|
||||
median: 34.54,
|
||||
mode: 23.87,
|
||||
min: -0.75,
|
||||
average: 35.85
|
||||
};
|
||||
|
||||
const half = ( {max, min} ) => (max + min) / 2.0;
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -1,63 +0,0 @@
|
||||
---
|
||||
id: 587d7b8a367417b2b2512b4c
|
||||
title: Use Destructuring Assignment with the Rest Operator to Reassign Array Elements
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用与Rest运算符的Destructuring Assignment重新分配数组元素
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">在某些涉及数组解构的情况下,我们可能希望将其余元素收集到一个单独的数组中。结果类似于<code>Array.prototype.slice()</code> ,如下所示: <blockquote> const [a,b,... arr] = [1,2,3,4,5,7]; <br> console.log(a,b); // 1,2 <br>的console.log(ARR); // [3,4,5,7] </blockquote>变量<code>a</code>和<code>b</code>从数组中获取第一个和第二个值。之后,由于rest操作符的存在, <code>arr</code>以数组的形式获取其余的值。 rest元素仅作为列表中的最后一个变量正常工作。在中,您不能使用rest运算符来捕获一个子数组,该子数组会遗漏原始数组的最后一个元素。 </section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">使用与rest运算符的解构赋值来执行有效的<code>Array.prototype.slice()</code>以便<code>arr</code>是原始数组<code>source</code>的子数组,省略前两个元素。 </section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: '<code>arr</code>应为<code>[3,4,5,6,7,8,9,10]</code>'
|
||||
testString: 'assert(arr.every((v, i) => v === i + 3) && arr.length === 8,"<code>arr</code> should be <code>[3,4,5,6,7,8,9,10]</code>");'
|
||||
- text: 应该使用解构。
|
||||
testString: 'getUserInput => assert(getUserInput("index").match(/\[\s*\w*\s*,\s*\w*\s*,\s*...\w+\s*\]/g),"Destructuring should be used.");'
|
||||
- text: 不应使用<code>Array.slice()</code> 。
|
||||
testString: 'getUserInput => assert(!getUserInput("index").match(/slice/g), "<code>Array.slice()</code> should not be used.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
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);
|
||||
console.log(arr); // should be [3,4,5,6,7,8,9,10]
|
||||
console.log(source); // should be [1,2,3,4,5,6,7,8,9,10];
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@ -0,0 +1,85 @@
|
||||
---
|
||||
id: 587d7b8a367417b2b2512b4c
|
||||
title: Use Destructuring Assignment with the Rest Parameter to Reassign Array Elements
|
||||
challengeType: 1
|
||||
forumTopicId: 301218
|
||||
localeTitle: 使用解构赋值配合 rest 操作符来重新分配数组元素
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
在解构数组的某些情况下,我们可能希望将剩下的元素放进另一个数组里面。
|
||||
以下代码的结果与使用<code>Array.prototype.slice()</code>相同:
|
||||
|
||||
```js
|
||||
const [a, b, ...arr] = [1, 2, 3, 4, 5, 7];
|
||||
console.log(a, b); // 1, 2
|
||||
console.log(arr); // [3, 4, 5, 7]
|
||||
```
|
||||
|
||||
变量<code>a</code>与<code>b</code>分别获取了数组的前两个元素的值。之后,因为<code>rest</code>操作符的存在,<code>arr</code>获取了原数组剩余的元素的值,并构成了一个新的数组。
|
||||
<code>rest</code>操作只能对数组列表最后的元素起作用。这意味着你不能使用<code>rest</code>操作符来截取原数组中间元素的子数组。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
使用解构赋值以及<code>rest</code>操作符来进行一个<code>Array.prototype.slice</code>相同的操作。使得<code>arr</code>是原数组<code>source</code>除开前两个元素的子数组。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>arr</code>应该为<code>[3,4,5,6,7,8,9,10]</code>
|
||||
testString: assert(arr.every((v, i) => v === i + 3) && arr.length === 8);
|
||||
- text: 没有使用<code>Array.slice()</code>。
|
||||
testString: getUserInput => assert(!getUserInput('index').match(/slice/g));
|
||||
- text: 使用了解构赋值。
|
||||
testString: assert(code.replace(/\s/g, '').match(/\[(([_$a-z]\w*)?,){1,}\.\.\.arr\]=list/i));
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
const source = [1,2,3,4,5,6,7,8,9,10];
|
||||
function removeFirstTwo(list) {
|
||||
"use strict";
|
||||
// change code below this line
|
||||
const arr = list; // change this
|
||||
// change code above this line
|
||||
return arr;
|
||||
}
|
||||
const arr = removeFirstTwo(source);
|
||||
console.log(arr); // should be [3,4,5,6,7,8,9,10]
|
||||
console.log(source); // should be [1,2,3,4,5,6,7,8,9,10];
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
const source = [1,2,3,4,5,6,7,8,9,10];
|
||||
function removeFirstTwo(list) {
|
||||
"use strict";
|
||||
// change code below this line
|
||||
const [, , ...arr] = list;
|
||||
// change code above this line
|
||||
return arr;
|
||||
}
|
||||
const arr = removeFirstTwo(source);
|
||||
```
|
||||
|
||||
</section>
|
@ -1,62 +0,0 @@
|
||||
---
|
||||
id: 587d7b8c367417b2b2512b56
|
||||
title: Use export to Reuse a Code Block
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用export重用代码块
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">在之前的挑战中,您了解了<code>import</code>以及如何利用它从大型文件导入少量代码。但是,为了使其工作,我们必须使用<code>import</code>一个语句,称为<dfn>导出</dfn> 。当我们想要一些代码 - 一个函数或一个变量 - 可以在另一个文件中使用时,我们必须将其导出才能将其导入另一个文件。与<code>import</code>一样, <code>export</code>是非浏览器功能。以下是我们称为<dfn>命名导出的内容</dfn> 。有了这个,我们可以使用您在上一课中学到的<code>import</code>语法将我们导出的任何代码导入到另一个文件中。这是一个例子: <blockquote> const capitalizeString =(string)=> { <br> return string.charAt(0).toUpperCase()+ string.slice(1); <br> } <br> export {capitalizeString} //如何导出函数。 <br> export const foo =“bar”; //如何导出变量</blockquote>或者,如果您想将所有<code>export</code>语句压缩成一行,则可以采用以下方法: <blockquote> const capitalizeString =(string)=> { <br> return string.charAt(0).toUpperCase()+ string.slice(1); <br> } <br> const foo =“bar”; <br> export {capitalizeString,foo} </blockquote>两种方法都是完全可以接受的。 </section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">下面是我想让其他文件使用的两个变量。利用我演示<code>export</code>的第一种方式,导出两个变量。 </section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>foo</code>被导出了。
|
||||
testString: 'getUserInput => assert(getUserInput("index").match(/export\s+const\s+foo\s*=\s*"bar"/g), "<code>foo</code> is exported.");'
|
||||
- text: <code>bar</code>出口。
|
||||
testString: 'getUserInput => assert(getUserInput("index").match(/export\s+const\s+bar\s*=\s*"foo"/g), "<code>bar</code> is exported.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
"use strict";
|
||||
const foo = "bar";
|
||||
const bar = "foo";
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### Before Test
|
||||
<div id='js-setup'>
|
||||
|
||||
```js
|
||||
window.exports = function(){};
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@ -0,0 +1,86 @@
|
||||
---
|
||||
id: 587d7b8c367417b2b2512b56
|
||||
title: Use export to Share a Code Block
|
||||
challengeType: 1
|
||||
forumTopicId: 301219
|
||||
localeTitle: 用 export 来重用代码块
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
假设有一个文件 <code>math_functions.js</code>,该文件包含了数学运算相关的一些函数。其中一个存储在变量 <code>add</code> 里,该函数接受两个数字做为参数返回它们的和。如果想在其它不同的 JavaScript 文件里使用这个函数,就需要 <code>export</code> 它。
|
||||
|
||||
```js
|
||||
export const add = (x, y) => {
|
||||
return x + y;
|
||||
}
|
||||
```
|
||||
|
||||
上面是导出单个函数常用方法,还可以这样导出:
|
||||
|
||||
```js
|
||||
const add = (x, y) => {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
export { add };
|
||||
```
|
||||
|
||||
导出变量和函数后,就可以在其它文件里导入使用从而避免了代码冗余。重复第一个例子的代码可以导出多个对象或函数,在第二个例子里面的导出语句中添加更多值也可以导出多项,例子如下:
|
||||
|
||||
```js
|
||||
export { add, subtract };
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
下面有两个变量需要在别的文件中可以使用。利用刚才展示的第一种方式,导出两个变量。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 应该导出<code>uppercaseString</code>变量。
|
||||
testString: assert(code.match(/(export\s+const\s+uppercaseString|export\s*{\s*(uppercaseString[^}]*|[^,]*,\s*uppercaseString\s*)})/g));
|
||||
- text: 应该导出<code>lowercaseString</code>变量。
|
||||
testString: assert(code.match(/(export\s+const\s+lowercaseString|export\s*{\s*(lowercaseString[^}]*|[^,]*,\s*lowercaseString\s*)})/g));
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
const uppercaseString = (string) => {
|
||||
return string.toUpperCase();
|
||||
}
|
||||
|
||||
const lowercaseString = (string) => {
|
||||
return string.toLowerCase()
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
export const uppercaseString = (string) => {
|
||||
return string.toUpperCase();
|
||||
}
|
||||
|
||||
export const lowercaseString = (string) => {
|
||||
return string.toLowerCase()
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@ -2,27 +2,70 @@
|
||||
id: 587d7b8c367417b2b2512b54
|
||||
title: Use getters and setters to Control Access to an Object
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用getter和setter来控制对象的访问
|
||||
forumTopicId: 301220
|
||||
localeTitle: 使用 getter 和 setter 来控制对象的访问
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">您可以从对象获取值,并在对象中设置属性的值。这些通常被称为<dfn>getter</dfn>和<dfn>setter</dfn> 。 Getter函数旨在简单地将对象的私有变量的值返回(获取)给用户,而无需用户直接访问私有变量。 Setter函数用于根据传递给setter函数的值修改(设置)对象私有变量的值。此更改可能涉及计算,甚至完全覆盖先前的值。 <blockquote> class Book { <br>构造函数(作者){ <br> this._author = author; <br> } <br> // getter <br> get writer(){ <br> return this._author; <br> } <br> // setter <br> set writer(updatedAuthor){ <br> this._author = updatedAuthor; <br> } <br> } <br> const lol = new Book('anonymous'); <br>的console.log(lol.writer); //匿名<br> lol.writer ='wut'; <br>的console.log(lol.writer); //哇</blockquote>注意我们用来调用getter和setter的语法 - 就好像它们甚至不是函数一样。 Getter和setter很重要,因为它们隐藏了内部实现细节。 </section>
|
||||
<section id='description'>
|
||||
你可以从对象中获得一个值,也可以给对象的属性赋值。
|
||||
这些通常行为被称为 <dfn>getters</dfn> 以及 <dfn>setters</dfn>。
|
||||
Getter 函数的作用是可以让对象返回一个私有变量,而不需要直接去访问私有变量。
|
||||
Setter 函数的作用是可以基于传进的参数来修改对象中私有变量。这些修改可以是计算,或者是直接替换之前的值。
|
||||
|
||||
```js
|
||||
class Book {
|
||||
constructor(author) {
|
||||
this._author = author;
|
||||
}
|
||||
// getter
|
||||
get writer() {
|
||||
return this._author;
|
||||
}
|
||||
// setter
|
||||
set writer(updatedAuthor) {
|
||||
this._author = updatedAuthor;
|
||||
}
|
||||
}
|
||||
const lol = new Book('anonymous');
|
||||
console.log(lol.writer); // anonymous
|
||||
lol.writer = 'wut';
|
||||
console.log(lol.writer); // wut
|
||||
```
|
||||
|
||||
注意我们调用 getter 和 setter 的语法,它们看起来并不像一个函数调用。
|
||||
Getter 和 Setter 非常重要,因为它们隐藏了内部的实现细节。
|
||||
|
||||
<strong>注意:</strong> 通常会在私有变量前添加下划线(<code>_</code>)。这里并没有真正意义上让变量私有。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">使用<code>class</code>关键字创建Thermostat类。构造函数接受华氏温度。现在在类中创建<code>getter</code>和<code>setter</code> ,以获得摄氏温度。请记住, <code>C = 5/9 * (F - 32)</code>和<code>F = C * 9.0 / 5 + 32</code> ,其中F是华氏温标的温度值,C是摄氏温度相同温度的值注意当你实现这一点,你将在一个等级中跟踪班级内的温度 - 华氏温度或摄氏温度。这是getter或setter的强大功能 - 您正在为另一个用户创建一个API,无论您追踪哪个用户,都可以获得正确的结果。换句话说,您正在从使用者那里抽象出实现细节。 </section>
|
||||
<section id='instructions'>
|
||||
使用<code>class</code>关键字来创建<code>Thermostat</code>类,它的构造函数应该可以接收 fahrenheit(华氏温度)作为参数。
|
||||
在类中创建 temperature 的 <code>getter</code>和<code>setter</code>,将温度转换成摄氏温度。
|
||||
温度转换的公式是<code>C = 5/9 * (F - 32)</code>以及<code>F = C * 9.0 / 5 + 32</code>,F 代表华氏温度,C 代表摄氏温度。
|
||||
<strong>注意:</strong> 当你实现这个作业的时候,你应当在类中使用一个温度标准,无论是华氏温度还是摄氏温度。
|
||||
是时候展现 getter 和 setter 的威力了——无论你的 API 内部使用的是哪种温度标准,用户都能得到正确的结果。
|
||||
或者说,你从用户需求中抽象出了实现细节。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>Thermostat</code>应该是一个<code>class</code>具有限定<code>constructor</code>方法。
|
||||
testString: 'assert(typeof Thermostat === "function" && typeof Thermostat.constructor === "function","<code>Thermostat</code> should be a <code>class</code> with a defined <code>constructor</code> method.");'
|
||||
- text: <code>class</code>关键字。
|
||||
testString: 'getUserInput => assert(getUserInput("index").match(/class/g),"<code>class</code> keyword was used.");'
|
||||
- text: <code>Thermostat</code>可以实例化。
|
||||
testString: 'assert(() => {const t = new Thermostat(32); return typeof t === "object" && t.temperature === 0;}, "<code>Thermostat</code> can be instantiated.");'
|
||||
- text: <code>Thermostat</code>应该是一个<code>class</code>,并且在其中定义了<code>constructor</code>方法。
|
||||
testString: assert(typeof Thermostat === 'function' && typeof Thermostat.constructor === 'function');
|
||||
- text: 应该使用 <code>class</code> 关键字。
|
||||
testString: assert(code.match(/class/g));
|
||||
- text: <code>Thermostat</code>应该可以被实例化。
|
||||
testString: assert((() => {const t = new Thermostat(32);return typeof t === 'object' && t.temperature === 0;})());
|
||||
- text: 应该定义一个 <code>getter</code>。
|
||||
testString: assert((() => {const desc = Object.getOwnPropertyDescriptor(Thermostat.prototype, 'temperature');return !!desc && typeof desc.get === 'function';})());
|
||||
- text: 应该定义一个 <code>setter</code>。
|
||||
testString: assert((() => {const desc = Object.getOwnPropertyDescriptor(Thermostat.prototype, 'temperature');return !!desc && typeof desc.set === 'function';})());
|
||||
- text: 调用 <code>setter</code> 应该设置 temperature。
|
||||
testString: assert((() => {const t = new Thermostat(32); t.temperature = 26;return t.temperature !== 0;})());
|
||||
|
||||
```
|
||||
|
||||
@ -34,19 +77,14 @@ tests:
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function makeClass() {
|
||||
"use strict";
|
||||
/* Alter code below this line */
|
||||
/* Alter code below this line */
|
||||
|
||||
/* Alter code above this line */
|
||||
|
||||
/* Alter code above this line */
|
||||
return Thermostat;
|
||||
}
|
||||
const Thermostat = makeClass();
|
||||
const thermos = new Thermostat(76); // setting in Fahrenheit scale
|
||||
let temp = thermos.temperature; // 24.44 in C
|
||||
thermos.temperature = 26;
|
||||
temp = thermos.temperature; // 26 in C
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -59,6 +97,25 @@ temp = thermos.temperature; // 26 in C
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
|
||||
/* Alter code below this line */
|
||||
class Thermostat {
|
||||
constructor(fahrenheit) {
|
||||
this._tempInCelsius = 5/9 * (fahrenheit - 32);
|
||||
}
|
||||
get temperature(){
|
||||
return this._tempInCelsius;
|
||||
}
|
||||
set temperature(newTemp){
|
||||
this._tempInCelsius = newTemp;
|
||||
}
|
||||
}
|
||||
/* Alter code above this line */
|
||||
|
||||
const thermos = new Thermostat(76); // setting in Fahrenheit scale
|
||||
let temp = thermos.temperature; // 24.44 in C
|
||||
thermos.temperature = 26;
|
||||
temp = thermos.temperature; // 26 in C
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -1,64 +0,0 @@
|
||||
---
|
||||
id: 587d7b88367417b2b2512b47
|
||||
title: Use the Rest Operator with Function Parameters
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 将Rest运算符与函数参数一起使用
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">为了帮助我们创建更灵活的函数,ES6引入了函数参数的<dfn>rest运算符</dfn> 。使用rest运算符,您可以创建带有可变数量参数的函数。这些参数存储在一个数组中,以后可以从函数内部访问。看看这段代码: <blockquote> function howMany(... args){ <br>返回“你已经通过”+ args.length +“arguments。”; <br> } <br> console.log(howMany(0,1,2)); //你已经传递了3个参数<br> console.log(howMany(“string”,null,[1,2,3],{})); //你已经传递了4个参数。 </blockquote>其余运算符无需检查<code>args</code>数组,并允许我们在<code>args</code>数组上应用<code>map()</code> , <code>filter()</code>和<code>reduce()</code> 。 </section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">修改函数<code>sum</code> ,使其使用rest运算符,并以相同的方式使用任意数量的参数。 </section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: '<code>sum(0,1,2)</code>的结果应为3'
|
||||
testString: 'assert(sum(0,1,2) === 3, "The result of <code>sum(0,1,2)</code> should be 3");'
|
||||
- text: '<code>sum(1,2,3,4)</code>的结果应为10'
|
||||
testString: 'assert(sum(1,2,3,4) === 10, "The result of <code>sum(1,2,3,4)</code> should be 10");'
|
||||
- text: <code>sum(5)</code>的结果应为5
|
||||
testString: 'assert(sum(5) === 5, "The result of <code>sum(5)</code> should be 5");'
|
||||
- text: <code>sum()</code>的结果应为0
|
||||
testString: 'assert(sum() === 0, "The result of <code>sum()</code> should be 0");'
|
||||
- text: <code>sum</code>函数在<code>args</code>参数上使用<code>...</code> spread运算符。
|
||||
testString: 'getUserInput => assert(getUserInput("index").match(/function\s+sum\s*\(\s*...args\s*\)\s*{/g), "The <code>sum</code> function uses the <code>...</code> spread operator on the <code>args</code> parameter.");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
const sum = (function() {
|
||||
"use strict";
|
||||
return function sum(x, y, z) {
|
||||
const args = [ x, y, z ];
|
||||
return args.reduce((a, b) => a + b, 0);
|
||||
};
|
||||
})();
|
||||
console.log(sum(1, 2, 3)); // 6
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
@ -0,0 +1,78 @@
|
||||
---
|
||||
id: 587d7b88367417b2b2512b47
|
||||
title: Use the Rest Parameter with Function Parameters
|
||||
challengeType: 1
|
||||
forumTopicId: 301221
|
||||
localeTitle: 将 rest 操作符与函数参数一起使用
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
ES6 推出了用于函数参数的<dfn> rest 操作符</dfn>帮助我们创建更加灵活的函数。在<code>rest</code>操作符的帮助下,你可以创建有一个变量来接受多个参数的函数。这些参数被储存在一个可以在函数内部读取的数组中。
|
||||
请看以下代码:
|
||||
|
||||
```js
|
||||
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.
|
||||
```
|
||||
|
||||
<code>rest</code>操作符可以避免查看<code>args</code>数组的需求,并且允许我们在参数数组上使用<code>map()</code>、<code>fiter()</code> 和 <code>reduce()</code>。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
修改<code>sum</code>函数,来让它使用<code>rest</code>操作符,并且它可以在有任何数量的参数时以相同的形式工作。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>sum(0,1,2)</code>的返回结果应该为3。
|
||||
testString: assert(sum(0,1,2) === 3);
|
||||
- text: <code>sum(1,2,3,4)</code>的返回结果应该为10。
|
||||
testString: assert(sum(1,2,3,4) === 10);
|
||||
- text: <code>sum(5)</code>的返回结果应该为5。
|
||||
testString: assert(sum(5) === 5);
|
||||
- text: <code>sum()</code>的返回结果应该为 0。
|
||||
testString: assert(sum() === 0);
|
||||
- text: 对<code>sum</code>函数的<code>args</code>参数使用了<code>...</code>展开操作符。
|
||||
testString: assert(code.replace(/\s/g,'').match(/sum=\(\.\.\.args\)=>/));
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
const sum = (x, y, z) => {
|
||||
const args = [x, y, z];
|
||||
return args.reduce((a, b) => a + b, 0);
|
||||
}
|
||||
console.log(sum(1, 2, 3)); // 6
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
const sum = (...args) => {
|
||||
return args.reduce((a, b) => a + b, 0);
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@ -2,26 +2,52 @@
|
||||
id: 587d7b89367417b2b2512b48
|
||||
title: Use the Spread Operator to Evaluate Arrays In-Place
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 使用Spread运算符来就地评估数组
|
||||
forumTopicId: 301222
|
||||
localeTitle: 使用 spread 运算符展开数组项
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description"> ES6引入了<dfn>扩展运算符</dfn> ,它允许我们在需要多个参数或元素的位置扩展数组和其他表达式。下面的ES5代码使用<code>apply()</code>来计算数组中的最大值: <blockquote> var arr = [6,89,3,45]; <br> var maximus = Math.max.apply(null,arr); //返回89 </blockquote>我们必须使用<code>Math.max.apply(null, arr)</code>因为<code>Math.max(arr)</code>返回<code>NaN</code> 。 <code>Math.max()</code>期望以逗号分隔的参数,但不是数组。扩展运算符使这种语法更易于阅读和维护。 <blockquote> const arr = [6,89,3,45]; <br> const maximus = Math.max(... arr); //返回89 </blockquote> <code>...arr</code>返回一个解压缩的数组。换句话说,它<em>传播</em>阵列。但是,扩展运算符只能在就地工作,就像在函数的参数或数组文字中一样。以下代码不起作用: <blockquote> const spreaded = ... arr; //将抛出语法错误</blockquote></section>
|
||||
<section id='description'>
|
||||
ES6 允许我们使用 <dfn>展开操作符</dfn> 来展开数组,以及需要多个参数或元素的表达式。
|
||||
下面的 ES5 代码使用了<code>apply()</code>来计算数组的最大值:
|
||||
|
||||
```js
|
||||
var arr = [6, 89, 3, 45];
|
||||
var maximus = Math.max.apply(null, arr); // returns 89
|
||||
```
|
||||
|
||||
我们必须使用<code>Math.max.apply(null,arr)</code>,是因为直接调用<code>Math.max(arr)</code>会返回<code>NaN</code>。<code>Math.max()</code>函数需要传入的是一系列由逗号分隔的参数,而不是一个数组。
|
||||
展开操作符可以提升代码的可读性,这对后续的代码维护是有积极作用的。
|
||||
|
||||
```js
|
||||
const arr = [6, 89, 3, 45];
|
||||
const maximus = Math.max(...arr); // returns 89
|
||||
```
|
||||
|
||||
<code>...arr</code>返回了一个“打开”的数组。或者说它 <em>展开</em> 了数组。
|
||||
然而,展开操作符只能够在函数的参数中,或者数组之中使用。下面的代码将会报错:
|
||||
|
||||
```js
|
||||
const spreaded = ...arr; // will throw a syntax error
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">使用spread运算符将<code>arr1</code>所有内容复制到另一个数组<code>arr2</code> 。 </section>
|
||||
<section id='instructions'>
|
||||
使用展开操作符将<code>arr1</code>中的内容都赋值到<code>arr2</code>中去。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>arr2</code>是<code>arr1</code>正确副本。
|
||||
- text: <code>arr2</code>的值是由<code>arr1</code>拷贝而来的。
|
||||
testString: assert(arr2.every((v, i) => v === arr1[i]));
|
||||
- text: <code>...</code>传播运算符用于复制<code>arr1</code> 。
|
||||
- text: 用<code>...</code>展开操作符来赋值<code>arr1</code>。
|
||||
testString: assert(code.match(/Array\(\s*\.\.\.arr1\s*\)|\[\s*\.\.\.arr1\s*\]/));
|
||||
- text: 更改<code>arr1</code>时, <code>arr2</code>保持不变。
|
||||
- text: 当<code>arr1</code>改变的时候,<code>arr2</code>不会改变。
|
||||
testString: assert((arr1, arr2) => {arr1.push('JUN'); return arr2.length < arr1.length});
|
||||
|
||||
```
|
||||
@ -36,12 +62,10 @@ tests:
|
||||
```js
|
||||
const arr1 = ['JAN', 'FEB', 'MAR', 'APR', 'MAY'];
|
||||
let arr2;
|
||||
(function() {
|
||||
"use strict";
|
||||
arr2 = []; // change this line
|
||||
})();
|
||||
console.log(arr2);
|
||||
|
||||
arr2 = []; // change this line
|
||||
|
||||
console.log(arr2);
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -54,6 +78,10 @@ console.log(arr2);
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
const arr1 = ['JAN', 'FEB', 'MAR', 'APR', 'MAY'];
|
||||
let arr2;
|
||||
|
||||
arr2 = [...arr1];
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,30 +2,54 @@
|
||||
id: 587d7b88367417b2b2512b44
|
||||
title: Write Arrow Functions with Parameters
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 用参数写箭头函数
|
||||
forumTopicId: 301223
|
||||
localeTitle: 编写带参数的箭头函数
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">就像普通函数一样,您可以将参数传递给箭头函数。 <blockquote> //将输入值加倍并返回<br> const doubler =(item)=> item * 2; </blockquote>您也可以将多个参数传递给箭头函数。 </section>
|
||||
<section id='description'>
|
||||
和一般的函数一样,你也可以给箭头函数传递参数。
|
||||
|
||||
```js
|
||||
// 给传入的数值乘以 2 并返回结果
|
||||
const doubler = (item) => item * 2;
|
||||
```
|
||||
|
||||
如果箭头函数只有一个参数,则可以省略包含该参数的括号。
|
||||
|
||||
```js
|
||||
// the same function, without the argument parentheses
|
||||
const doubler = item => item * 2;
|
||||
```
|
||||
|
||||
可以将多个参数传递到箭头函数中。
|
||||
|
||||
```js
|
||||
// multiplies the first input value by the second and returns it
|
||||
const multiplier = (item, multi) => item * multi;
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">重写<code>myConcat</code>函数,该函数将<code>arr2</code>内容追加到<code>arr1</code>以便该函数使用箭头函数语法。 </section>
|
||||
<section id='instructions'>
|
||||
使用箭头函数的语法重写<code>myConcat</code>函数,使其可以将<code>arr2</code>的内容填充在<code>arr1</code>里。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 用户确实替换了<code>var</code>关键字。
|
||||
- text: 替换掉所有的<code>var</code>关键字。
|
||||
testString: getUserInput => assert(!getUserInput('index').match(/var/g));
|
||||
- text: <code>myConcat</code>应该是一个常量变量(使用<code>const</code> )。
|
||||
- text: <code>myConcat</code>应该是一个常量 (使用<code>const</code>)。
|
||||
testString: getUserInput => assert(getUserInput('index').match(/const\s+myConcat/g));
|
||||
- text: <code>myConcat</code>应该是一个函数
|
||||
- text: <code>myConcat</code>应该是一个函数。
|
||||
testString: assert(typeof myConcat === 'function');
|
||||
- text: <code>myConcat()</code>返回正确的<code>array</code>
|
||||
- text: <code>myConcat()</code> 应该返回 <code>[1, 2, 3, 4, 5]</code>。
|
||||
testString: assert(() => { const a = myConcat([1], [2]); return a[0] == 1 && a[1] == 2; });
|
||||
- text: <code>function</code>关键字未使用。
|
||||
- text: 不要使用<code>function</code>关键字。
|
||||
testString: getUserInput => assert(!getUserInput('index').match(/function/g));
|
||||
|
||||
```
|
||||
@ -44,7 +68,6 @@ var myConcat = function(arr1, arr2) {
|
||||
};
|
||||
// test your code
|
||||
console.log(myConcat([1, 2], [3, 4, 5]));
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
@ -57,6 +80,12 @@ console.log(myConcat([1, 2], [3, 4, 5]));
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
const myConcat = (arr1, arr2) => {
|
||||
"use strict";
|
||||
return arr1.concat(arr2);
|
||||
};
|
||||
// test your code
|
||||
console.log(myConcat([1, 2], [3, 4, 5]));
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -2,26 +2,51 @@
|
||||
id: 587d7b8b367417b2b2512b50
|
||||
title: Write Concise Declarative Functions with ES6
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 用ES6编写简明的声明函数
|
||||
forumTopicId: 301224
|
||||
localeTitle: 用 ES6 编写简洁的函数声明
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">在ES5中定义对象内的函数时,我们必须使用关键字<code>function</code> ,如下所示: <blockquote> const person = { <br>名称:“泰勒”, <br> sayHello:function(){ <br>回来`你好!我的名字是$ {this.name} .`; <br> } <br> }; </blockquote>使用ES6,您可以在定义对象中的函数时完全删除<code>function</code>关键字和冒号。以下是此语法的示例: <blockquote> const person = { <br>名称:“泰勒”, <br>问好() { <br>回来`你好!我的名字是$ {this.name} .`; <br> } <br> }; </blockquote></section>
|
||||
<section id='description'>
|
||||
在 ES5 中,当我们需要在对象中定义一个函数的时候,我们必须如下面这般使用<code>function</code>关键字:
|
||||
|
||||
```js
|
||||
const person = {
|
||||
name: "Taylor",
|
||||
sayHello: function() {
|
||||
return `Hello! My name is ${this.name}.`;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
在 ES6 语法的对象中定义函数的时候,你可以完全删除<code>function</code>关键字和冒号。请看以下例子:
|
||||
|
||||
```js
|
||||
const person = {
|
||||
name: "Taylor",
|
||||
sayHello() {
|
||||
return `Hello! My name is ${this.name}.`;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">重构对象<code>bicycle</code>内的函数<code>setGear</code>以使用上述简写语法。 </section>
|
||||
<section id='instructions'>
|
||||
使用以上这种简短的语法,重构在<code>bicycle</code>对象中的<code>setGear</code>函数。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 未使用传统函数表达式。
|
||||
- text: 不应使用<code>function</code>关键字定义方法。
|
||||
testString: getUserInput => assert(!removeJSComments(code).match(/function/));
|
||||
- text: <code>setGear</code>是一个声明函数。
|
||||
- text: <code>setGear</code>应是一个函数。
|
||||
testString: assert(typeof bicycle.setGear === 'function' && code.match(/setGear\s*\(.+\)\s*\{/));
|
||||
- text: <code>bicycle.setGear(48)</code>应该返回48。
|
||||
- text: 执行<code>bicycle.setGear(48)</code>应可以让<code>gear</code>的值变为 48。
|
||||
testString: assert((new bicycle.setGear(48)).gear === 48);
|
||||
|
||||
```
|
||||
@ -38,19 +63,24 @@ tests:
|
||||
const bicycle = {
|
||||
gear: 2,
|
||||
setGear: function(newGear) {
|
||||
"use strict";
|
||||
this.gear = newGear;
|
||||
}
|
||||
};
|
||||
// change code above this line
|
||||
bicycle.setGear(3);
|
||||
console.log(bicycle.gear);
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### After Test
|
||||
<div id='js-teardown'>
|
||||
|
||||
```js
|
||||
const removeJSComments = str => str.replace(/\/\*[\s\S]*?\*\/|\/\/.*$/gm, '');
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
@ -58,6 +88,13 @@ console.log(bicycle.gear);
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
const bicycle = {
|
||||
gear: 2,
|
||||
setGear(newGear) {
|
||||
this.gear = newGear;
|
||||
}
|
||||
};
|
||||
bicycle.setGear(3);
|
||||
```
|
||||
|
||||
</section>
|
||||
|
@ -0,0 +1,89 @@
|
||||
---
|
||||
id: 587d7b8a367417b2b2512b4f
|
||||
title: Write Concise Object Literal Declarations Using Object Property Shorthand
|
||||
challengeType: 1
|
||||
forumTopicId: 301225
|
||||
localeTitle: 使用简单字段编写简洁的对象字面量声明
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
ES6 添加了一些很棒的功能,以便于更方便地定义对象。
|
||||
请看以下代码:
|
||||
|
||||
```js
|
||||
const getMousePosition = (x, y) => ({
|
||||
x: x,
|
||||
y: y
|
||||
});
|
||||
```
|
||||
|
||||
<code>getMousePosition</code>是一个返回了拥有2个属性的对象的简单函数。
|
||||
ES6 提供了一个语法糖,消除了类似<code>x: x</code>这种冗余的写法.你可以仅仅只写一次<code>x</code>,解释器会自动将其转换成<code>x: x</code>。
|
||||
下面是使用这种语法重写的同样的函数:
|
||||
|
||||
```js
|
||||
const getMousePosition = (x, y) => ({ x, y });
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
请使用简单属性对象的语法来创建并返回一个<code>Person</code>对象。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: '输出是<code>{name: "Zodiac Hasbro", age: 56, gender: "male"}</code>。'
|
||||
testString: assert.deepEqual({name:"Zodiac Hasbro",age:56,gender:"male"}, createPerson("Zodiac Hasbro", 56, "male"));
|
||||
- text: '不要使用<code>key:value</code>。'
|
||||
testString: getUserInput => assert(!getUserInput('index').match(/:/g));
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
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
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
const createPerson = (name, age, gender) => {
|
||||
"use strict";
|
||||
return {
|
||||
name,
|
||||
age,
|
||||
gender
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
</section>
|
@ -1,69 +0,0 @@
|
||||
---
|
||||
id: 587d7b88367417b2b2512b45
|
||||
title: Write Higher Order Arrow Functions
|
||||
challengeType: 1
|
||||
videoUrl: ''
|
||||
localeTitle: 编写高阶箭头函数
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id="description">是时候我们看到处理数据时箭头功能有多强大了。 Arrow函数与高阶函数(例如<code>map()</code> , <code>filter()</code>和<code>reduce()</code>非常兼容,它们将其他函数作为处理数据集合的参数。阅读以下代码: <blockquote> FBPosts.filter(function(post){ <br> return post.thumbnail!== null && post.shares> 100 && post.likes> 500; <br> }) </blockquote>我们用<code>filter()</code>写了这个,至少使它有点可读。现在将它与以下使用箭头函数语法的代码进行比较: <blockquote> FBPosts.filter((post)=> post.thumbnail!== null && post.shares> 100 && post.likes> 500) </blockquote>此代码更简洁,使用更少的代码行完成相同的任务。 </section>
|
||||
|
||||
## Instructions
|
||||
<section id="instructions">使用箭头函数语法计算数组<code>realNumberArray</code>中只有正整数(十进制数不是整数)的<code>realNumberArray</code> ,并将新数组存储在变量<code>squaredIntegers</code> 。 </section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>squaredIntegers</code>应该是一个常量变量(通过使用<code>const</code> )。
|
||||
testString: 'getUserInput => assert(getUserInput("index").match(/const\s+squaredIntegers/g), "<code>squaredIntegers</code> should be a constant variable (by using <code>const</code>).");'
|
||||
- text: <code>squaredIntegers</code>应该是一个<code>array</code>
|
||||
testString: 'assert(Array.isArray(squaredIntegers), "<code>squaredIntegers</code> should be an <code>array</code>");'
|
||||
- text: '<code>squaredIntegers</code>应该是<code>[16, 1764, 36]</code> <code>squaredIntegers</code> <code>[16, 1764, 36]</code>'
|
||||
testString: 'assert.deepStrictEqual(squaredIntegers, [16, 1764, 36], "<code>squaredIntegers</code> should be <code>[16, 1764, 36]</code>");'
|
||||
- text: <code>function</code>关键字未使用。
|
||||
testString: 'getUserInput => assert(!getUserInput("index").match(/function/g), "<code>function</code> keyword was not used.");'
|
||||
- text: 不应该使用循环
|
||||
testString: 'getUserInput => assert(!getUserInput("index").match(/(for)|(while)/g), "loop should not be used");'
|
||||
- text: 应使用<code>map</code> , <code>filter</code>或<code>reduce</code>
|
||||
testString: 'getUserInput => assert(getUserInput("index").match(/map|filter|reduce/g), "<code>map</code>, <code>filter</code>, or <code>reduce</code> should be used");'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
const realNumberArray = [4, 5.6, -9.8, 3.14, 42, 6, 8.34, -2];
|
||||
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);
|
||||
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
Reference in New Issue
Block a user