chore(i18n,learn): processed translations (#47963)

This commit is contained in:
camperbot
2022-10-10 20:35:19 +01:00
committed by GitHub
parent 97c5e1b67c
commit 960eb4bb31
153 changed files with 10789 additions and 311 deletions

View File

@@ -15,7 +15,7 @@ dashedName: practice-comparing-different-values
**示例**
`3 == '3'` 返回 `true` ,因爲 JavaScript 執行了從字符串到數字類型的轉換。 `3 === '3'` 返回 false因爲類型不同且類型轉換沒有執行
`3 == '3'` 返回 `true` ,因爲 JavaScript 執行了從字符串到數字類型的轉換。 `3 === '3'` 返回 `false`,因爲類型不同,沒有進行類型轉換
**提示** 在 JavaScript 中,你可以使用 `typeof` 運算符確定變量或值的類型,如下所示:

View File

@@ -11,14 +11,14 @@ dashedName: understand-string-immutability
在 JavaScript 中,字符串(`String`)的值是不可變的(<dfn>immutable</dfn>),這意味着一旦字符串被創建就不能被改變。
例如,下面的代碼
例如,以下代碼將產生錯誤,因爲字符串 `Bob` 中的字母 `B` 不能更改爲字母 `J`
```js
let myStr = "Bob";
myStr[0] = "J";
```
是不會把變量 `myStr` 的值改變成 `Job` 的,因爲變量 `myStr` 是不可變的。 注意,這*不*意味着 `myStr` 永遠不能被改變,只是字符串字面量 <dfn>string literal</dfn> 的各個字符不能被改變。 改變 `myStr` 的唯一方法是重新給它賦一個值,如:
注意,這*不*意味着無法重新分配 `myStr`。 更改 `myStr` 的唯一方法是爲其分配一個值,如下所示
```js
let myStr = "Bob";

View File

@@ -8,7 +8,7 @@ dashedName: mutate-an-array-declared-with-const
# --description--
如果你不熟悉 `const`,請查看[這個挑戰](/learn/javascript-algorithms-and-data-structures/basic-javascript/declare-a-read-only-variable-with-the-const-keyword)
如果你不熟悉 `const`,請查看 <a href="/learn/javascript-algorithms-and-data-structures/basic-javascript/declare-a-read-only-variable-with-the-const-keyword" target="_blank" rel="noopener noreferrer nofollow">這個 <code>const</code> 關鍵詞的挑戰</a>
`const` 聲明在現代 JavaScript 中有很多用例。
@@ -23,7 +23,7 @@ s[2] = 45;
console.log(s);
```
`s = [1, 2, 3]` 將導致錯誤。 `console.log` 將顯示值 `[5, 6, 45]`
`s = [1, 2, 3]` 將導致錯誤。 註釋掉該行後,`console.log` 將顯示值 `[5, 6, 45]`
如你所見,你可以改變對象 `[5, 6, 7]` 本身,變量 `s` 仍將指向更改後的數組 `[5, 6, 45]`。 像所有數組一樣,`s` 中的數組元素是可變的,但是因爲使用了 `const`,所以不能使用變量標識符 `s` 來指向一個使用賦值運算符的不同數組。

View File

@@ -8,9 +8,9 @@ dashedName: build-a-25--5-clock
# --description--
**目標:** 在 [CodePen.io](https://codepen.io) 上實現一個功能類似 <https://codepen.io/freeCodeCamp/full/XpKrrW> 的 App
**目標:** 構建一個應用,功能和 <a href="https://codepen.io/freeCodeCamp/full/XpKrrW" target="_blank" rel="noopener noreferrer nofollow">https://codepen.io/freeCodeCamp/full/XpKrrW</a> 類似
在滿足以下 [需求](https://en.wikipedia.org/wiki/User_story) 並能通過所有測試的前提下, 賦予它你自己的個人風格。
完成以下需求,並且通過所有測試。 可以使用你需要的任何庫或 API。 賦予它你自己的個人風格。
可以使用 HTML、JavaScript、CSS、Bootstrap、SASS、React、Redux、jQuery 來完成這個挑戰。 但鑑於這個章節的學習內容與前端框架相關,推薦使用一款前端框架(比如 React來完成這個挑戰不推薦使用前面沒有提到的技術否則風險自負。 不推薦使用前面沒有提到的技術,否則風險自擔。 我們有計劃新增其他前端框架課程,例如 Angular 和 Vue不過目前還沒有這些內容。 我們會接受並嘗試修復你在使用推薦技術棧創建項目時報告的問題。 編碼愉快!
@@ -70,7 +70,7 @@ dashedName: build-a-25--5-clock
**需求 28** 當點擊 id 屬性爲 `reset` 的元素時id 屬性爲 `beep` 的音頻元素必須停止播放並回到開頭。
你可以<a href='https://codepen.io/pen?template=MJjpwO' target='_blank' rel='nofollow'>使用這個 CodePen 模</a>,點擊 `Save` 即可創建你自己的項目。 或者你可以在任何你喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
你可以<a href='https://codepen.io/pen?template=MJjpwO' target='_blank' rel="noopener noreferrer nofollow">使用 CodePen 模</a>創建你的新項目,點擊 `Save` 即可創建你的項目。 或者你可以在任何你喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
當你完成了本項目,並且該項目所有測試運行通過, 請提交項目的 URL。

View File

@@ -8,9 +8,9 @@ dashedName: build-a-drum-machine
# --description--
**目標:** 在 [CodePen.io](https://codepen.io) 上實現一個功能類似 <https://codepen.io/freeCodeCamp/full/MJyNMd> 的 App
**目標:** 構建一個應用,功能和 <a href="https://codepen.io/freeCodeCamp/full/MJyNMd" target="_blank" rel="noopener noreferrer nofollow">https://codepen.io/freeCodeCamp/full/MJyNMd</a> 類似
在滿足以下 [需求](https://en.wikipedia.org/wiki/User_story) 並能通過所有測試的前提下, 賦予它你自己的個人風格。
完成以下需求,並且通過所有測試。 可以使用你需要的任何庫或 API。 賦予它你自己的個人風格。
可以使用 HTML、JavaScript、CSS、Bootstrap、SASS、React、Redux、jQuery 來完成這個挑戰。 但鑑於這個章節的學習內容與前端框架相關,推薦使用一款前端框架(比如 React來完成這個挑戰。 不推薦使用前面沒有提到的技術,否則風險自擔。 我們有計劃新增其他前端框架課程,例如 Angular 和 Vue不過目前還沒有這些內容。 我們會接受並嘗試修復你在使用推薦技術棧創建項目時報告的問題。 編碼愉快!
@@ -28,9 +28,21 @@ dashedName: build-a-drum-machine
**需求 7** 當觸發一個具有 `.drum-pad` 屬性的元素時,`#display` 元素內應該展示這個觸發元素關聯音頻片段的描述字符串(每一個字符串都應該是獨一無二的)。
你可以<a href='https://codepen.io/pen?template=MJjpwO' target='_blank' rel='nofollow'>使用這個 CodePen 模板</a>,點擊 `Save` 即可創建你自己的項目。 或者可以在任何喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
以下是一些可用於鼓機的音頻樣本:
當你完成了本項目,並且該項目所有測試運行通過,請提交項目的 URL。
- [Heater 1](https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3)
- [Heater 2](https://s3.amazonaws.com/freecodecamp/drums/Heater-2.mp3)
- [Heater 3](https://s3.amazonaws.com/freecodecamp/drums/Heater-3.mp3)
- [Heater 4](https://s3.amazonaws.com/freecodecamp/drums/Heater-4_1.mp3)
- [Clap](https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3)
- [Open-HH](https://s3.amazonaws.com/freecodecamp/drums/Dsc_Oh.mp3)
- [Kick-n'-Hat](https://s3.amazonaws.com/freecodecamp/drums/Kick_n_Hat.mp3)
- [Kick](https://s3.amazonaws.com/freecodecamp/drums/RP4_KICK_1.mp3)
- [Closed-HH](https://s3.amazonaws.com/freecodecamp/drums/Cev_H2.mp3)
你可以<a href='https://codepen.io/pen?template=MJjpwO' target='_blank' rel="noopener noreferrer nofollow">使用 CodePen 模版</a>創建你的新項目,點擊 `Save` 即可創建你的新項目。 或者你可以在任何你喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
當你完成了本項目,並且項目通過所有測試,請提交項目的 URL。
# --solutions--

View File

@@ -8,9 +8,9 @@ dashedName: build-a-javascript-calculator
# --description--
**目標:** 在 [CodePen.io](https://codepen.io) 上實現一個功能類似 <https://codepen.io/freeCodeCamp/full/wgGVVX> 的 App
**目標:** 構建一個應用,功能和 <a href="https://codepen.io/freeCodeCamp/full/wgGVVX" target="_blank" rel="noopener noreferrer nofollow">https://codepen.io/freeCodeCamp/full/wgGVVX</a> 類似
在滿足以下 [需求](https://en.wikipedia.org/wiki/User_story) 並能通過所有測試的前提下, 賦予它你自己的個人風格。
完成以下需求,並且通過所有測試。 可以使用你需要的任何庫或 API。 賦予它你自己的個人風格。
可以使用 HTML、JavaScript、CSS、Bootstrap、SASS、React、Redux、jQuery 來完成這個挑戰。 但鑑於這個章節的學習內容與前端框架相關,推薦使用一款前端框架(比如 React來完成這個挑戰不推薦使用前面沒有提到的技術否則風險自負。 不推薦使用前面沒有提到的技術,否則風險自擔。 我們有計劃新增其他前端框架課程,例如 Angular 和 Vue不過目前還沒有這些內容。 我們會接受並嘗試修復你在使用推薦技術棧創建項目時報告的問題。 編碼愉快!
@@ -51,7 +51,7 @@ dashedName: build-a-javascript-calculator
- **立即執行邏輯:** `11.5`
- **公式/表達式邏輯:** `32.5`
你可以<a href='https://codepen.io/pen?template=MJjpwO' target='_blank' rel='nofollow'>使用這個 CodePen 模</a>,點擊 `Save` 即可創建你自己的項目。 或者可以在任何喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
你可以<a href='https://codepen.io/pen?template=MJjpwO' target="_blank" rel="noopener noreferrer nofollow">使用 CodePen 模</a>創建你的新項目,點擊 `Save` 即可創建你的項目。 或者可以在任何喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
當你完成了本項目,並且該項目所有測試運行通過,請提交項目的 URL。

View File

@@ -8,9 +8,9 @@ dashedName: build-a-markdown-previewer
# --description--
**目標:** 在 [CodePen.io](https://codepen.io) 上實現一個功能類似 <https://codepen.io/freeCodeCamp/full/GrZVVO> 的 App
**目標:** 構建一個應用,功能和 <a href="https://codepen.io/freeCodeCamp/full/GrZVVO" target="_blank" rel="noopener noreferrer nofollow">https://codepen.io/freeCodeCamp/full/GrZVVO</a> 類似
在滿足以下 [需求](https://en.wikipedia.org/wiki/User_story) 並能通過所有測試的前提下, 賦予它你自己的個人風格。
完成以下需求,並且通過所有測試。 可以使用你需要的任何庫或 API。 賦予它你自己的個人風格。
可以使用 HTML、JavaScript、CSS、Bootstrap、SASS、React、Redux、jQuery 來完成這個挑戰。 但鑑於這個章節的學習內容與前端框架相關,推薦使用一款前端框架(比如 React來完成這個挑戰不推薦使用前面沒有提到的技術否則風險自負。 不推薦使用前面沒有提到的技術,否則風險自擔。 我們有計劃新增其他前端框架課程,例如 Angular 和 Vue不過目前還沒有這些內容。 我們會接受並嘗試修復你在使用推薦技術棧創建項目時報告的問題。 編碼愉快!
@@ -28,7 +28,7 @@ dashedName: build-a-markdown-previewer
**可選需求(你無需通過這項測試):** Markdown 預覽器能夠解析回車符並且將他們以 `br`(換行)元素的形式渲染出來。
你可以<a href='https://codepen.io/pen?template=MJjpwO' target='_blank' rel='nofollow'>使用這個 CodePen 模</a>,點擊 `Save` 即可創建你自己的項目。 或者可以在任何喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
你可以<a href='https://codepen.io/pen?template=MJjpwO' target="_blank" rel="noopener noreferrer nofollow">使用 CodePen 模</a>創建你的新項目,點擊 `Save` 即可創建你的項目。 或者可以在任何喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
當你完成了本項目,並且該項目所有測試運行通過,請提交項目的 URL。

View File

@@ -8,9 +8,9 @@ dashedName: build-a-random-quote-machine
# --description--
**目標:** 在 [CodePen.io](https://codepen.io) 上實現一個功能類似 <https://codepen.io/freeCodeCamp/full/qRZeGZ> 的 App
**目標:** 構建一個應用,功能和 <a href="https://codepen.io/freeCodeCamp/full/qRZeGZ" target="_blank" rel="noopener noreferrer nofollow">https://codepen.io/freeCodeCamp/full/qRZeGZ</a> 類似
在滿足以下 [需求](https://en.wikipedia.org/wiki/User_story) 並能通過所有測試的前提下, 賦予它你自己的個人風格。
完成以下需求,並且通過所有測試。 可以使用你需要的任何庫或 API。 賦予它你自己的個人風格。
可以使用 HTML、JavaScript、CSS、Bootstrap、SASS、React、Redux、jQuery 來完成這個挑戰。 但鑑於這個章節的學習內容與前端框架相關,推薦使用一款前端框架(比如 React來完成這個挑戰不推薦使用前面沒有提到的技術否則風險自負。 不推薦使用前面沒有提到的技術,否則風險自擔。 我們有計劃新增其他前端框架課程,例如 Angular 和 Vue不過目前還沒有這些內容。 我們會接受並嘗試修復你在使用推薦技術棧創建項目時報告的問題。 編碼愉快!
@@ -36,7 +36,7 @@ dashedName: build-a-random-quote-machine
**需求 11** 具有 `#quote-box` 屬性的包裹元素應該水平居中。 請在瀏覽器縮放尺寸爲 100% 且頁面窗口最大化時運行測試。
你可以<a href='https://codepen.io/pen?template=MJjpwO' target='_blank' rel='nofollow'>使用這個 CodePen 模</a>,點擊 `Save` 創建即可你自己的項目 或者可以在任何喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
你可以<a href='https://codepen.io/pen?template=MJjpwO' target="_blank" rel="noopener noreferrer nofollow">使用 CodePen 模</a>創建你的新項目,點擊 `Save` 即可創建你的新項目 或者可以在任何喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
一旦完成了本項目並且該項目所有測試運行通過,請提交項目的 URL。

View File

@@ -22,7 +22,7 @@ jQuery 還有一個類似的函數 `.text()`,可以在不添加標籤的前提
給 id 爲 `target4` 的按鈕的文本添加強調效果。
查看這篇[關於 &lt;em> 的文章](https://www.freecodecamp.org/news/html-elements-explained-what-are-html-tags/#em-element)來了解更多 `<i>``<em>` 的區別和用法
<a href="https://www.freecodecamp.org/news/html-elements-explained-what-are-html-tags/#em-element" target="_blank" rel="noopener noreferrer nofollow">查看我們的專欄文章 &lt;em&gt;</a>來了解 `<i>``<em>` 及其用途之間的差異
注意,`<i>` 標籤雖然傳統上用來強調文本,但此後常用作圖標的標籤。 `<em>` 標籤作爲強調標籤現在已被廣泛接受。 可以使用任意一種完成這個挑戰。

View File

@@ -10,7 +10,7 @@ dashedName: moving-forward-from-here
恭喜! 你完成了 React 和 Redux 的所有課程! 結束之前,還要再提一點。 通常,我們不會在這樣的編輯器中編寫 React 應用代碼。 如果你在自己的計算機上使用 npm 和文件系統,這個挑戰可讓你一瞥 React 應用的語法之貌。 除了使用 `import` 語句(這些語句引入了各挑戰中提供的所有依賴關係),其代碼看起來類似。 “管理包(含 npm”這一節更詳細地介紹了 npm。
最後,寫 React 和 Redux 的代碼通常需要一些配置, 且很快會變得複雜起來。 如果你有興趣在自己的電腦上嘗試<a href="https://github.com/facebookincubator/create-react-app" target="_blank" rel="nofollow">Create React App</a> 已配置好並準備就緒。
最後,寫 React 和 Redux 的代碼通常需要一些配置, 且很快會變得複雜起來。 如果你有興趣在自己的機器上進行實驗<a href="https: www.freecodecamp.org/news/install-react-with-create-react-app/" target="_blank" rel="noopener noreferrer nofollow">Create React App</a> 已配置好並準備就緒。
或者,你可以在 CodePen 中啓用 Babel 作爲 JavaScript 預處理器,將 React 和 ReactDOM 添加爲外部 JavaScript 資源,這樣編寫應用。

View File

@@ -22,7 +22,7 @@ this.state = {
# --instructions--
代碼編輯器有一個組件試圖從其 `state`渲染一個 `name` 屬性 但是 `state` 還沒有定義。 在 `constructor` 中使用 `state` 初始化組件,並將你的名字賦給 `name` 屬性。
代碼編輯器裏,有一個組件嘗試渲染 `state``firstName` 屬性 但是 `state` 還沒有定義。 在 `constructor` 中使用 `state` 初始化這個組件,並將你的名字賦`firstName` 屬性。
# --hints--
@@ -55,7 +55,7 @@ assert(
);
```
應使用被設置爲字符串的 `name` 屬性來初始化 `StatefulComponent` 的 state。
`StatefulComponent` 的 state 應該初始化爲被設置成字符串的 `firstName` 屬性
```js
assert(
@@ -65,13 +65,13 @@ assert(
);
const initialState = mockedComponent.state();
return (
typeof initialState === 'object' && typeof initialState.name === 'string'
typeof initialState === 'object' && typeof initialState.firstName === 'string'
);
})()
);
```
`StatefulComponent` 中 state 的 `name` 屬性應該渲染`h1` 元素
`StatefulComponent` 狀態中的屬性 `firstName` 應該呈現`h1` 元素
```js
assert(
@@ -80,7 +80,7 @@ assert(
React.createElement(StatefulComponent)
);
const initialState = mockedComponent.state();
return mockedComponent.find('h1').text() === initialState.name;
return mockedComponent.find('h1').text() === initialState.firstName;
})()
);
```
@@ -106,7 +106,7 @@ class StatefulComponent extends React.Component {
render() {
return (
<div>
<h1>{this.state.name}</h1>
<h1>{this.state.firstName}</h1>
</div>
);
}
@@ -120,13 +120,13 @@ class StatefulComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'freeCodeCamp!'
firstName: 'freeCodeCamp!'
}
}
render() {
return (
<div>
<h1>{this.state.name}</h1>
<h1>{this.state.firstName}</h1>
</div>
);
}

View File

@@ -8,7 +8,7 @@ dashedName: introducing-inline-styles
# --description--
還有其他複雜的概念可以爲 React 代碼增加強大的功能。 但是,你可能會想知道更簡單的問題,比如:如何對在 React 中創建的 JSX 元素添加樣式。 你可能知道,由於[將 class 應用於 JSX 元素的方式](/learn/front-end-development-libraries/react/define-an-html-class-in-jsx)與 HTML 中的使用並不完全相同。
還有其他複雜的概念可以爲 React 代碼增加強大的功能。 但是,你可能會想知道更簡單的問題,比如:如何對在 React 中創建的 JSX 元素添加樣式。 你可能知道,鑑於<a href="/learn/front-end-development-libraries/react/define-an-html-class-in-jsx" target="_blank" rel="noopener noreferrer nofollow">將 class 應用於 JSX 元素的方式</a>,它與使用 HTML 並不完全相同。
如果從樣式表導入樣式,它就沒有太大的不同。 使用 `className` 屬性將 class 應用於 JSX 元素,並將樣式應用於樣式表中的 class。 另一種選擇是使用內聯樣式,這在 ReactJS 開發中非常常見。

View File

@@ -123,7 +123,7 @@ assert.strictEqual(
})();
```
`GameOfChance` 組件第一次掛載到 DOM 上時,每次按鈕被點擊,都應該返回一個 `h1` 元素,元素中隨機渲染 `You Win!` 或者 `You Lose!`
`GameOfChance` 組件第一次掛載到 DOM 上時,每次按鈕被點擊,都應該返回一個 `h1` 元素,元素中隨機渲染 `You Win!` 或者 `You Lose!` 注意:這有時可能會失敗。 如果發生這種情況,請再試一次。
```js
(() => {
@@ -265,6 +265,11 @@ class GameOfChance extends React.Component {
# --solutions--
```jsx
// We want this to be deterministic for testing purposes.
const randomSequence = [true, false, false, true, true, false, false, true, true, false];
let index = 0;
const fiftyFifty = () => randomSequence[index++ % randomSequence.length];
class Results extends React.Component {
constructor(props) {
super(props);
@@ -290,11 +295,10 @@ class GameOfChance extends React.Component {
});
}
render() {
const expression = Math.random() >= 0.5;
return (
<div>
<button onClick={this.handleClick}>Play Again</button>
<Results fiftyFifty={expression} />
<Results fiftyFifty={fiftyFifty()} />
<p>{'Turn: ' + this.state.counter}</p>
</div>
);

View File

@@ -16,7 +16,7 @@ this.setState({
});
```
React 要求永遠不要直接修改 `state`,而是在 state 發生改變時始終使用 `this.setState()`。 此外應該注意React 可以批量處理多個 state 更新以提高性能。 這意味着通過 `setState` 方法進行的 state 更新可以是異步的。 `setState` 方法有一種替代語法可以解決異步問題, 雖然這很少用到,但是最好還是記住它! 有關詳細信息,請參閱[React 文檔](https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous)
React 要求永遠不要直接修改 `state`,而是在 state 發生改變時始終使用 `this.setState()`。 此外應該注意React 可以批量處理多個 state 更新以提高性能。 這意味着通過 `setState` 方法進行的 state 更新可以是異步的。 `setState` 方法有一種替代語法可以解決異步問題, 雖然這很少用到,但是最好還是記住它! 請查閱我們的 <a href="https://www.freecodecamp.org/news/what-is-state-in-react-explained-with-examples/" target="_blank" rel="noopener noreferrer nofollow">React 文章</a>瞭解更多詳情
# --instructions--

View File

@@ -16,7 +16,7 @@ dashedName: use-array-map-to-dynamically-render-elements
代碼編輯器完成了 `MyToDoList` 組件的大部分設置。 如果完成了受控表單挑戰,這些代碼中的一些應該看起來很熟悉。 你會注意到一個 `textarea` 和一個 `button`,以及一些跟蹤它們狀態的方法,但是頁面當前還沒有任何東西被渲染。
`constructor` 中,創建一個 `this.state` 對象並定義兩個 state`userInput` 應該初始化爲空字符串,`toDoList` 應該初始化爲空數組。 接下來,刪除 `items` 變量旁邊 `render()` 方法中的註釋。 取而代之的是,將存儲在組件內部 state 中的 `toDoList` 數組一一遍歷並相應的動態呈現 `li` 元素中。 嘗試在 `textarea` 中輸入 `eat, code, sleep, repeat`,然後點擊按鈕,看看會發生什麼。
`constructor` 中,創建一個 `this.state` 對象並定義兩個 state`userInput` 應該初始化爲空字符串,`toDoList` 應該初始化爲空數組。 接下來,`render()` 方法中刪除 `items` 變量 `null`。 取而代之的是,將存儲在組件內部 state 中的 `toDoList` 數組一一遍歷並相應的動態呈現 `li` 元素中。 嘗試在 `textarea` 中輸入 `eat, code, sleep, repeat`,然後點擊按鈕,看看會發生什麼。
**注意:** 像這樣的映射操作創建的所有兄弟子元素都需要提供唯一的 `key` 屬性。 別擔心,這是下一個挑戰的主題。

View File

@@ -16,7 +16,7 @@ React 提供了有用的類型檢查特性,以驗證組件是否接收了正
MyComponent.propTypes = { handleClick: PropTypes.func.isRequired }
```
在上面的示例中,`PropTypes.func` 部分檢查 `handleClick` 是否爲函數。 添加 `isRequired`,告訴 React `handleClick` 是該組件的必需屬性。 如果沒有那個屬性,將出現警告。 還要注意 `func` 代表 `function` 。 在 7 種 JavaScript 原語類型中, `function``boolean` (寫爲 `bool` )是唯一使用異常拼寫的兩種類型。 除了原始類型,還有其他類型可用。 例如,你可以檢查 prop 是否爲 React 元素。 請參閱[文檔](https://reactjs.org/docs/typechecking-with-proptypes.html#proptypes)以獲取所有選項。
在上面的示例中,`PropTypes.func` 部分檢查 `handleClick` 是否爲函數。 添加 `isRequired`,告訴 React `handleClick` 是該組件的必需屬性。 如果沒有那個屬性,將出現警告。 還要注意 `func` 代表 `function` 。 在 7 種 JavaScript 原語類型中, `function``boolean` (寫爲 `bool` )是唯一使用異常拼寫的兩種類型。 除了原始類型,還有其他類型可用。 例如,你可以檢查 prop 是否爲 React 元素。 請查看<a href="https://reactjs.org/docs/typechecking-with-proptypes.html#proptypes" target="_blank" rel="noopener noreferrer nofollow">文檔</a>以獲取所有選項。
**注意:**在 React v15.5.0 中, `PropTypes` 可以從 React 中單獨引入,例如:`import PropTypes from 'prop-types';`

View File

@@ -10,7 +10,7 @@ dashedName: use-the-lifecycle-method-componentwillmount
React 組件有幾種特殊方法,可以在組件生命週期的特定點執行操作。 這些稱爲生命週期方法或生命週期鉤子,允許在特定時間點捕獲組件。 這可以在渲染之前、更新之前、接收 props 之前、卸載之前等等。 以下是一些主要生命週期方法的列表: `componentWillMount()` `componentDidMount()` `shouldComponentUpdate()` `componentDidUpdate()` `componentWillUnmount()` 接下來的幾節課將講述這些生命週期方法的一些基本用例。
**注意:** `componentWillMount` 生命週期方法會在版本 16.X 廢棄在版本 17 移除。 [(來源)](https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html)
**注意:** `componentWillMount` 生命週期方法會在版本 16.X 廢棄在版本 17 移除。 在這篇<a href="https://www.freecodecamp.org/news/how-to-safely-use-reacts-life-cycles-with-fiber-s-async-rendering-fd4469ebbd8f/" target="_blank" rel="noopener noreferrer nofollow">文章</a>中瞭解更多。
# --instructions--

View File

@@ -20,7 +20,7 @@ Redux `store` 是一個保存和管理應用程序狀態的`state` 可以使
聲明一個 `store` 變量並把它分配給 `createStore()` 方法,然後把 `reducer` 作爲一個參數傳入即可。
**注意**: 編輯器中的代碼使用 ES6 默認參數語法將 state 的值初始化爲 `5` 如果你不熟悉默認參數,可以參考[ES6 全部課程](https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/es6/set-default-parameters-for-your-functions),它裏面涵蓋了這個內容
**注意**: 編輯器中的代碼使用 ES6 默認參數語法將 state 的值初始化爲 `5` 如果你不熟悉默認參數,可以參考 <a href="https://chinese.freecodecamp.org/learn/javascript-algorithms-and-data-structures/es6/set-default-parameters-for-your-functions" target="_blank" rel="noopener noreferrer nofollow">課程中的 ES6 部分</a>,其中涵蓋了這個主題
# --hints--

View File

@@ -12,7 +12,7 @@ dashedName: access-the-json-data-from-an-api
現在,你將進一步觀察返回的數據,以更好地瞭解 JSON 格式。 回憶一下 JavaScript 中的一些符號:
<blockquote>[ ] -> 方括號表示數組<br>{ } -> 大括號表示對象<br>" " -> 雙引號表示字符串 它們還用於表示 JSON 中的鍵名</blockquote>
<blockquote>[ ] -> 方括號表示數組<br>{ } -> 大括號表示對象<br>" " -> 雙引號表示字符串 它們還用於表示 JSON 中的鍵名</blockquote>
理解 API 返回數據的結構是必需的,它將影響你如何獲取你所需的值。

View File

@@ -8,10 +8,10 @@ dashedName: exercise-tracker
# --description--
構建一個 JavaScript 的全棧應用,在功能上與這個應用相似: <https://exercise-tracker.freecodecamp.rocks/>。 在這個項目中,你將使用以下方法之一編寫你的代碼:
構建一個功能類似於此的全棧 JavaScript 應用:<a href="https://exercise-tracker.freecodecamp.rocks" target="_blank" rel="noopener noreferrer nofollow">https://exercise-tracker.freecodecamp.rocks</a>。 在這個項目中,你將使用以下方法之一編寫你的代碼:
- 克隆 [GitHub 倉庫](https://github.com/freeCodeCamp/boilerplate-project-exercisetracker/) 並在本地完成你的項目。
- 使用[我們的 Replit 初始化項目](https://replit.com/github/freeCodeCamp/boilerplate-project-exercisetracker)來完成你的項目。
- 克隆<a href="https://github.com/freeCodeCamp/boilerplate-project-exercisetracker/" target="_blank" rel="noopener noreferrer nofollow">這個 GitHub 倉庫</a>並在本地完成你的項目。
- 使用<a href="https://replit.com/github/freeCodeCamp/boilerplate-project-exercisetracker" target="_blank" rel="noopener noreferrer nofollow">我們在 Replit 上的初始化項目</a>來完成你的項目。
- 使用你選擇的網站生成器來完成項目。 需要包含我們 GitHub 倉庫的所有文件。
完成本項目後,請將一個正常運行的 demo項目演示託管在可以公開訪問的平臺。 然後在 `Solution Link` 字段中提交它的 URL。 此外,還可以將項目的源碼提交到 `GitHub Link` 中。
@@ -79,7 +79,7 @@ async (getUserInput) => {
const res = await fetch(url + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
body: `username=fcc_test_${Date.now()}`.substring(0, 29)
});
assert.isTrue(res.ok);
if(!res.ok) {
@@ -96,7 +96,7 @@ async (getUserInput) => {
const res = await fetch(url + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
body: `username=fcc_test_${Date.now()}`.substring(0, 29)
});
if (res.ok) {
const { _id, username } = await res.json();
@@ -164,7 +164,7 @@ async (getUserInput) => {
const res = await fetch(url + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
body: `username=fcc_test_${Date.now()}`.substring(0, 29)
});
if (res.ok) {
const { _id, username } = await res.json();
@@ -198,7 +198,7 @@ async (getUserInput) => {
const res = await fetch(url + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
body: `username=fcc_test_${Date.now()}`.substring(0, 29)
});
if (res.ok) {
const { _id, username } = await res.json();
@@ -237,7 +237,7 @@ async (getUserInput) => {
const res = await fetch(url + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
body: `username=fcc_test_${Date.now()}`.substring(0, 29)
});
if (res.ok) {
const { _id, username } = await res.json();
@@ -276,7 +276,7 @@ async (getUserInput) => {
const res = await fetch(url + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
body: `username=fcc_test_${Date.now()}`.substring(0, 29)
});
if (res.ok) {
const { _id, username } = await res.json();
@@ -309,7 +309,7 @@ async (getUserInput) => {
};
```
`/api/users/:id/logs``GET` 請求將返回用戶對象,其中包含添加的所有練習的 `log` 數組。
`/api/users/:_id/logs``GET` 請求將返回用戶對象,其中包含添加的所有練習的 `log` 數組。
```js
async(getUserInput) => {
@@ -319,7 +319,7 @@ async(getUserInput) => {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
body: `username=fcc_test_${Date.now()}`.substring(0, 29)
})
if(res.ok){
const {_id, username} = await res.json();
@@ -353,7 +353,7 @@ async(getUserInput) => {
};
```
`GET /api/users/:id/logs` 返回的 `log` 數組中的每一項都是一個應該具有 `description` 的對象, `duration``date` 屬性。
`GET /api/users/:_id/logs` 返回的 `log` 數組中的每個項目都是一個應該具有 `description``duration``date` 屬性的對象
```js
async(getUserInput) => {
@@ -363,7 +363,7 @@ async(getUserInput) => {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
body: `username=fcc_test_${Date.now()}`.substring(0, 29)
});
if(res.ok) {
const {_id, username} = await res.json();
@@ -400,7 +400,7 @@ async(getUserInput) => {
};
```
`GET /api/users/:id/logs` 返回的 `log` 數組中任何對象的 `description` 屬性都應該是一個字符串。
`GET /api/users/:_id/logs` 返回的 `log` 數組中任何對象的 `description` 屬性都應該是一個字符串。
```js
async(getUserInput) => {
@@ -410,7 +410,7 @@ async(getUserInput) => {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `username=fcc_test_${Date.now()}`.substr(0,29)
body: `username=fcc_test_${Date.now()}`.substring(0,29)
});
if(res.ok) {
const {_id, username} = await res.json();
@@ -447,7 +447,7 @@ async(getUserInput) => {
};
```
`GET /api/users/:id/logs` 返回的 `log` 數組中任何對象的 `duration` 屬性應該是一個數字。
`GET /api/users/:_id/logs` 返回的 `log` 數組中任何對象的 `duration` 屬性應該是一個數字。
```js
async(getUserInput) => {
@@ -457,7 +457,7 @@ async(getUserInput) => {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `username=fcc_test_${Date.now()}`.substr(0,29)
body: `username=fcc_test_${Date.now()}`.substring(0,29)
});
if(res.ok) {
const {_id, username} = await res.json();
@@ -494,7 +494,7 @@ async(getUserInput) => {
};
```
`GET /api/users/:id/logs` 返回的 `log` 數組中任何對象的 `date` 屬性應該是一個字符串。 使用 `Date` API 的 `dateString` 格式。
`GET /api/users/:_id/logs` 返回的 `log` 數組中任何對象的 `date` 屬性應該是一個字符串。 使用 `Date` API 的 `dateString` 格式。
```js
async(getUserInput) => {
@@ -504,7 +504,7 @@ async(getUserInput) => {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `username=fcc_test_${Date.now()}`.substr(0,29)
body: `username=fcc_test_${Date.now()}`.substring(0,29)
});
if(res.ok) {
const {_id, username} = await res.json();
@@ -549,7 +549,7 @@ async (getUserInput) => {
const res = await fetch(url + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
body: `username=fcc_test_${Date.now()}`.substring(0, 29)
});
if (res.ok) {
const { _id, username } = await res.json();

View File

@@ -8,10 +8,10 @@ dashedName: file-metadata-microservice
# --description--
構建一個 JavaScript 的全棧應用,在功能上與這個應用相似:<https://file-metadata-microservice.freecodecamp.rocks/>。 在這個項目中,你將使用以下方法之一編寫你的代碼:
構建一個功能類似於此的全棧 JavaScript 應用程序:<a href="https://file-metadata-microservice.freecodecamp.rocks" target="_blank" rel="noopener noreferrer nofollow">https://file-metadata-microservice.freecodecamp.rocks</a>。 在這個項目中,你將使用以下方法之一編寫你的代碼:
- 克隆 [this GitHub repo](https://github.com/freeCodeCamp/boilerplate-project-filemetadata/) 並在本地完成項目。
- 使用[我們的 Replit 初始化項目](https://replit.com/github/freeCodeCamp/boilerplate-project-filemetadata)來完成你的項目。
- 克隆<a href="https://github.com/freeCodeCamp/boilerplate-project-filemetadata/" target="_blank" rel="noopener noreferrer nofollow">這個 GitHub 倉庫</a>並在本地完成你的項目。
- 使用<a href="https://replit.com/github/freeCodeCamp/boilerplate-project-filemetadata" target="_blank" rel="noopener noreferrer nofollow">我們在 Replit 上的初始化項目</a>來完成你的項目。
- 使用你選擇的網站生成器來完成項目。 需要包含我們 GitHub 倉庫的所有文件。
完成本項目後,請將一個正常運行的 demo項目演示託管在可以公開訪問的平臺。 然後在 `Solution Link` 字段中提交它的 URL。 此外,還可以將項目的源碼提交到 `GitHub Link` 中。

View File

@@ -8,10 +8,10 @@ dashedName: request-header-parser-microservice
# --description--
構建一個 JavaScript 的全棧應用,在功能上與這個應用相似:<https://request-header-parser-microservice.freecodecamp.rocks/>。 在這個項目中,你將使用以下方法之一編寫你的代碼:
構建一個 JavaScript 的全棧應用,在功能上與這個應用相似:<a href="https://request-header-parser-microservice.freecodecamp.rocks/" target="_blank" rel="noopener noreferrer nofollow">https://request-header-parser-microservice.freecodecamp.rocks/</a>。 在這個項目中,你將使用以下方法之一編寫你的代碼:
- 克隆 [this GitHub repo](https://github.com/freeCodeCamp/boilerplate-project-headerparser/) 並在本地完成項目。
- 使用[我們的 Replit 初始化項目](https://replit.com/github/freeCodeCamp/boilerplate-project-headerparser)來完成你的項目。
- 克隆<a href="https://github.com/freeCodeCamp/boilerplate-project-headerparser/" target="_blank" rel="noopener noreferrer nofollow">這個 GitHub 倉庫</a>並在本地完成你的項目。
- 使用<a href="https://replit.com/github/freeCodeCamp/boilerplate-project-headerparser" target="_blank" rel="noopener noreferrer nofollow">我們在 Replit 上的初始化項目</a>來完成你的項目。
- 使用你選擇的網站生成器來完成項目。 需要包含我們 GitHub 倉庫的所有文件。
完成本項目後,請將一個正常運行的 demo項目演示託管在可以公開訪問的平臺。 然後在 `Solution Link` 字段中提交它的 URL。 此外,還可以將項目的源碼提交到 `GitHub Link` 中。

View File

@@ -8,10 +8,10 @@ dashedName: timestamp-microservice
# --description--
構建一個 JavaScript 的全棧應用,在功能上與這個應用相似:<https://timestamp-microservice.freecodecamp.rocks/>。 在這個項目中,你將使用以下方法之一編寫你的代碼:
構建一個功能類似於此的全棧 JavaScript 應用程序:<a href="https://timestamp-microservice.freecodecamp.rocks" target="_blank" rel="noopener noreferrer nofollow">https://timestamp-microservice.freecodecamp.rocks</a>。 在這個項目中,你將使用以下方法之一編寫你的代碼:
- 克隆 [這個 GitHub 倉庫](https://github.com/freeCodeCamp/boilerplate-project-timestamp/) 並在本地完成項目。
- 使用[我們的 Replit 初始化項目](https://replit.com/github/freeCodeCamp/boilerplate-project-timestamp)來完成你的項目。
- 克隆<a href="https://github.com/freeCodeCamp/boilerplate-project-timestamp/" target="_blank" rel="noopener noreferrer nofollow">這個 GitHub 倉庫</a>並在本地完成你的項目。
- 使用<a href="https://replit.com/github/freeCodeCamp/boilerplate-project-timestamp" target="_blank" rel="noopener noreferrer nofollow">我們在 Replit 上的初始化項目</a>來完成你的項目。
- 使用你選擇的網站生成器來完成項目。 需要包含我們 GitHub 倉庫的所有文件。
完成本項目後,請將一個正常運行的 demo項目演示託管在可以公開訪問的平臺。 然後在 `Solution Link` 字段中提交它的 URL。 此外,還可以將項目的源碼提交到 `GitHub Link` 中。

View File

@@ -8,10 +8,10 @@ dashedName: url-shortener-microservice
# --description--
構建一個 JavaScript 的全棧應用,在功能上與這個應用相似:<https://url-shortener-microservice.freecodecamp.rocks/>。 在這個項目中,你將使用以下方法之一編寫你的代碼:
構建一個功能類似於此的全棧 JavaScript 應用程序:<a href="https://url-shortener-microservice.freecodecamp.rocks" target="_blank" rel="noopener noreferrer nofollow">https://url-shortener-microservice.freecodecamp.rocks</a>。 在這個項目中,你將使用以下方法之一編寫你的代碼:
- 克隆 [this GitHub repo](https://github.com/freeCodeCamp/boilerplate-project-filemetadata/) 並在本地完成項目。
- 使用[我們的 Replit 初始化項目](https://replit.com/github/freeCodeCamp/boilerplate-project-urlshortener)來完成你的項目。
- 克隆<a href="https://github.com/freeCodeCamp/boilerplate-project-urlshortener/" target="_blank" rel="noopener noreferrer nofollow">這個 GitHub 倉庫</a>並在本地完成你的項目。
- 使用<a href="https://replit.com/github/freeCodeCamp/boilerplate-project-urlshortener" target="_blank" rel="noopener noreferrer nofollow">我們在 Replit 上的初始化項目</a>來完成你的項目。
- 使用你選擇的網站生成器來完成項目。 需要包含我們 GitHub 倉庫的所有文件。
完成本項目後,請將一個正常運行的 demo項目演示託管在可以公開訪問的平臺。 然後在 `Solution Link` 字段中提交它的 URL。 此外,還可以將項目的源碼提交到 `GitHub Link` 中。

View File

@@ -8,7 +8,7 @@ dashedName: chain-middleware-to-create-a-time-server
# --description--
使用 `app.METHOD(path, middlewareFunction)` 可以在指定的路由掛載中間件, 也可以在路由定義中鏈式調用中間件
使用 `app.METHOD(path, middlewareFunction)` 可以在指定的路由掛載中間件, 中間件也可以鏈接在路由定義中。
請看以下示例:
@@ -49,7 +49,7 @@ app.get('/user', function(req, res, next) {
);
```
/now 接口應該返回一個現在時間 +/-20 秒的時間
`/now` 端點應該返回當前時間
```js
(getUserInput) =>

View File

@@ -10,8 +10,8 @@ dashedName: meet-the-node-console
你可以採用下面的任意一種編寫代碼的方式來完成這些挑戰:
- 克隆 [這個 GitHub 倉庫](https://github.com/freeCodeCamp/boilerplate-express/) 並在本地完成項目
- 使用[我們的 Repl.it 上的初始化項目](https://replit.com/github/freeCodeCamp/boilerplate-express)來完成項目
- 克隆<a href="https://github.com/freeCodeCamp/boilerplate-express/" target="_blank" rel="noopener noreferrer nofollow">這個 GitHub 倉庫</a>並在本地完成這些挑戰
- 使用<a href="https://replit.com/github/freeCodeCamp/boilerplate-express" target="_blank" rel="noopener noreferrer nofollow">我們在 Replit 上的初始化項目</a>來完成這些挑戰
- 使用你選擇的網站生成器來完成項目。 需要包含我們 GitHub 倉庫的所有文件。
完成本項目後,請將一個正常運行的 demo項目演示託管在可以公開訪問的平臺。 然後在 `Solution Link` 字段中提交它的 URL。

View File

@@ -22,11 +22,11 @@ Content-Length: 20
name=John+Doe&age=25
```
正如你所看到的,正文被編碼成類似查詢字符串的形式, 這是 HTML 表單使用的默認格式。 我們還可以通過 Ajax 使用 JSON 來處理具有更復雜結構的數據。 還有另一種類型的編碼multipart/form-data 它被用來上傳二進制文件。 在本練習中,我們將使用 URL 編碼請求正文。 要解析來自 POST 請求的數據,你必須安裝 `body-parser` 這個包包含一套可以解碼不同格式數據的中間件。
正如你所看到的,正文被編碼成類似查詢字符串的形式, 這是 HTML 表單使用的默認格式。 我們還可以通過 Ajax 使用 JSON 來處理具有更復雜結構的數據。 還有另一種類型的編碼multipart/form-data 它被用來上傳二進制文件。 在本練習中,將使用 URL 編碼正文。 要解析來自 POST 請求的數據,你必須使用 `body-parser` 這個包包含一套可以解碼不同格式數據的中間件。
# --instructions--
`package.json` 中安裝 `body-parser` 模塊, 然後在文件頂部 `require` 進來, 用變量 `bodyParser` 保存它。 通過中間件`bodyParser.urlencoded({extended: false})` 方法處理 URL 編碼數據 將通過先前的方法調用返回的函數傳遞 `app.use()`中間件通常掛載在所有需要它的路由之前。
`body-parser` 已經安裝並且在你項目的 `package.json` 文件中。 在 `myApp.js` 文件頂部包含(`require`)它,並將其存儲在名爲 `bodyParser`變量中。 `bodyParser.urlencoded({extended: false})` 返回處理 URL 編碼數據的中間件。 將上一個方法調用返回的函數傳遞 `app.use()`像往常一樣,中間件必須在所有依賴它的路由之前安裝
**注意:** `extended` 是一個配置選項, 告訴 `body-parser` 需要使用哪個解析。 當 `extended=false` 時,它使用經典編碼 `querystring` 庫。 當 `extended=true`時,它使用 `qs` 庫進行解析。

View File

@@ -18,11 +18,11 @@ dashedName: use-the--env-file
在項目根目錄創建一個 `.env` 文件,並存儲變量 `MESSAGE_STYLE=uppercase`
當向 `/json` GET 請求時,如果 `process.env.MESSAGE_STYLE` 的值爲 `uppercase`那麼上一次挑戰中的路由處理程序返回的對象的消息則應該大寫。 響應對象應該是 `{"message": "Hello json"}` or `{"message": "HELLO JSON"}`,取決於 `MESSAGE_STYLE` 的值。
然後,在你在上個挑戰中創建的 `/json` GET 路由處理程序中訪問 `process.env.MESSAGE_STYLE`,並且如果變量等於 `uppercase`將響應對象的 `message` 轉換爲大寫。 響應對象應該是 `{"message": "Hello json"}` or `{"message": "HELLO JSON"}`,取決於 `MESSAGE_STYLE` 的值。
**注意:** 如果你正在使用 Replit你無法創建一個 `.env` 文件。 相反,使用內置的 <dfn>SECRETS</dfn> 標籤添加變量。
如果你在本地工作,你將需要 `dotenv` 包。 它將環境變量從你的 `.env` 文件加載到 `process.env` 中。 使用 `npm install dotenv` 安裝它。 然後,`myApp.js` 文件的頂部,使用 `require('dotenv').config()` 導入加載變量。
如果你在本地工作,你將需要 `dotenv` 包。 它將環境變量從你的 `.env` 文件加載到 `process.env` 中。 `dotenv` 包已經安裝,並且在你項目的 `package.json` 文件中。 `myApp.js` 文件的頂部,使用 `require('dotenv').config()` 導入加載變量。
# --hints--

View File

@@ -22,13 +22,13 @@ dashedName: expand-your-project-with-external-packages-from-npm
# --instructions--
package.json 文件的 `dependencies` 字段中添加一個版本號爲“2.14.0”的“moment”包
`@freecodecamp/example` 包的版本 “1.1.0” 添加到 `package.json` 文件的 `dependencies` 字段。
**注意:** Moment 是一個非常方便地用來處理時間和日期的庫
**注意:** `@freecodecamp/example` 是一個用作學習工具的仿包
# --hints--
dependencies”字段應該包含“moment”
`"dependencies"` 應包括 `"@freecodecamp/example"`
```js
(getUserInput) =>
@@ -37,8 +37,8 @@ dashedName: expand-your-project-with-external-packages-from-npm
var packJson = JSON.parse(data);
assert.property(
packJson.dependencies,
'moment',
'"dependencies" does not include "moment"'
'@freecodecamp/example',
'"dependencies" does not include "@freecodecamp/example"'
);
},
(xhr) => {
@@ -47,7 +47,7 @@ dashedName: expand-your-project-with-external-packages-from-npm
);
```
“moment”的版本應該是“2.14.0
`"@freecodecamp/example"` 版本應爲 `"1.1.0"`
```js
(getUserInput) =>
@@ -55,9 +55,9 @@ dashedName: expand-your-project-with-external-packages-from-npm
(data) => {
var packJson = JSON.parse(data);
assert.match(
packJson.dependencies.moment,
/^[\^\~]?2\.14\.0/,
'Wrong version of "moment" installed. It should be 2.14.0'
packJson.dependencies["@freecodecamp/example"],
/^[\^\~]?1\.1\.0/,
'Wrong version of "@freecodecamp/example" installed. It should be 1.1.0'
);
},
(xhr) => {

View File

@@ -10,11 +10,11 @@ dashedName: how-to-use-package-json-the-core-of-any-node-js-project-or-npm-packa
你可以採用下面的任意一種編寫代碼的方式來完成這些挑戰:
- 克隆 [GitHub repo](https://github.com/freeCodeCamp/boilerplate-npm/) 並在本地完成項目
- 使用[我們的 Replit 上的初始化項目](https://replit.com/github/freeCodeCamp/boilerplate-npm)來完成項目
- 克隆<a href="https://github.com/freeCodeCamp/boilerplate-npm/" target="_blank" rel="noopener noreferrer nofollow">這個 GitHub 倉庫</a>並在本地完成這些挑戰
- 使用<a href="https://replit.com/github/freeCodeCamp/boilerplate-npm" target="_blank" rel="noopener noreferrer nofollow">我們在 Replit 上的初始化項目</a>來完成這些挑戰
- 使用你選擇的網站生成器來完成項目。 需要包含我們 GitHub 倉庫的所有文件。
完成本項目後,請將一個正常運行的 demo項目演示託管在可以公開訪問的平臺。 然後在 `Solution Link` 字段中提交它的 URL。 此外,還可以將項目的源碼提交到 `GitHub Link` 中。
完成本項目後,請將一個正常運行的 demo項目演示託管在可以公開訪問的平臺。 然後在 `Solution Link` 字段中提交它的 URL。
`package.json` 文件是所有 Node.js 項目和 npm 包的樞紐, 和 HTML 文檔中的 &lt;head> 區域用來描述網頁的配置信息(元數據)一樣,它存儲項目的相關信息。 它由單個 JSON 對象組成,並以鍵值對的形式存儲項目信息, 且至少包含兩個必填字段“name”和“version”——但是最好提供有關項目的其他信息這將對用戶或者維護者有所幫助。

View File

@@ -20,11 +20,11 @@ dashedName: manage-npm-dependencies-by-understanding-semantic-versioning
# --instructions--
在 package.json 文件的依賴項中,修改 moment 的`version`,讓它的主版本是 2次版本號是 10修訂號是 2。
`package.json` 文件的依賴項部分,更改 `@freecodecamp/example` 的版本以匹配 MAJOR 版本爲 1、MINOR 版本爲 2 和 PATCH 版本爲 13
# --hints--
dependencies”字段應該包含“moment”
`"dependencies"` 應包括 `"@freecodecamp/example"`
```js
(getUserInput) =>
@@ -33,8 +33,8 @@ dashedName: manage-npm-dependencies-by-understanding-semantic-versioning
var packJson = JSON.parse(data);
assert.property(
packJson.dependencies,
'moment',
'"dependencies" does not include "moment"'
'@freecodecamp/example',
'"dependencies" does not include "@freecodecamp/example"'
);
},
(xhr) => {
@@ -43,7 +43,7 @@ dashedName: manage-npm-dependencies-by-understanding-semantic-versioning
);
```
“moment”的版本號應該是“2.10.2”
`"@freecodecamp/example"` 版本應爲 `"1.2.13"`
```js
(getUserInput) =>
@@ -51,9 +51,9 @@ dashedName: manage-npm-dependencies-by-understanding-semantic-versioning
(data) => {
var packJson = JSON.parse(data);
assert.equal(
packJson.dependencies.moment,
'2.10.2',
'Wrong version of "moment". It should be 2.10.2'
packJson.dependencies["@freecodecamp/example"],
'1.2.13',
'Wrong version of "@freecodecamp/example". It should be 1.2.13'
);
},
(xhr) => {

View File

@@ -12,17 +12,17 @@ dashedName: remove-a-package-from-your-dependencies
但是,如果想要刪除不再需要的依賴包,該怎麼辦呢? 可能已經猜到了——只需要從依賴項中刪除相應的鍵值對就行了。
同樣的方法也適用於刪除 package.json 中的其字段。
同樣的方法也適用於刪除 package.json 中的其字段。
# --instructions--
從依賴項中刪除 moment 依賴包。
從依賴項中刪除 `@freecodecamp/example` 包。
**注意:**刪除依賴包後,確保逗號數量正確。
# --hints--
dependencies”字段不包含“moment”
`"dependencies"` 不應包含 `"@freecodecamp/example"`
```js
(getUserInput) =>
@@ -31,8 +31,8 @@ dashedName: remove-a-package-from-your-dependencies
var packJson = JSON.parse(data);
assert.notProperty(
packJson.dependencies,
'moment',
'"dependencies" still includes "moment"'
'@freecodecamp/example',
'"dependencies" still includes "@freecodecamp/example"'
);
},
(xhr) => {

View File

@@ -10,7 +10,7 @@ dashedName: use-the-caret-character-to-use-the-latest-minor-version-of-a-depende
和上一個挑戰中我們學到的用波浪號來安裝最新的修訂版依賴一樣,脫字符(`^`)也允許 npm 來安裝功能更新。 它們的不同之處在於:脫字符允許次版本和修訂版更新。
現在項目中的 moment 依賴包的版本應該是“~2.10.2”,這意味着 npm 可以安裝最新的 2.10.x 版的 moment 如果使用脫字符(^)來替換版本號的前綴,那麼 npm 可以將 moment 升級安裝到任何 2.x.x 版本。
你當前的 `@freecodecamp/example` 版本應該是“~1.2.13”,它允許 npm 安裝最新的 1.2.x 版本。 如果使用插入符號(^作爲版本前綴npm 將被允許更新到任何 1.x.x 版本。
```json
"package": "^1.3.8"
@@ -20,13 +20,13 @@ dashedName: use-the-caret-character-to-use-the-latest-minor-version-of-a-depende
# --instructions--
在依賴項中,使用脫字符(`^`)爲 moment 的版本添加前綴,允許 npm 更新依賴包到任新的版本。
使用插入符號(`^`)爲依賴項中的 `@freecodecamp/example` 版本添加前綴,允許 npm 將其更新到任新的 MINOR 版本。
**注意:** 原來的版本號不用更改。
# --hints--
dependencies”字段中應包含“moment”
`"dependencies"` 應包括 `"@freecodecamp/example"`
```js
(getUserInput) =>
@@ -35,8 +35,8 @@ dashedName: use-the-caret-character-to-use-the-latest-minor-version-of-a-depende
var packJson = JSON.parse(data);
assert.property(
packJson.dependencies,
'moment',
'"dependencies" does not include "moment"'
'@freecodecamp/example',
'"dependencies" does not include "@freecodecamp/example"'
);
},
(xhr) => {
@@ -45,7 +45,7 @@ dashedName: use-the-caret-character-to-use-the-latest-minor-version-of-a-depende
);
```
“moment”的版本應是“^2.x.x”
`"@freecodecamp/example"` 版本應匹配 `"^1.x.x"`
```js
(getUserInput) =>
@@ -53,9 +53,9 @@ dashedName: use-the-caret-character-to-use-the-latest-minor-version-of-a-depende
(data) => {
var packJson = JSON.parse(data);
assert.match(
packJson.dependencies.moment,
/^\^2\./,
'Wrong version of "moment". It should be ^2.10.2'
packJson.dependencies["@freecodecamp/example"],
/^\^1\./,
'Wrong version of "@freecodecamp/example". It should be ^1.2.13'
);
},
(xhr) => {

View File

@@ -18,15 +18,15 @@ dashedName: use-the-tilde-character-to-always-use-the-latest-patch-version-of-a-
# --instructions--
在 package.json 文件中,當前規則是 npm 將 moment 升級到特定版本2.10.2)。 但現在,要允許使用最新的 2.10.x 版本。
在 package.json 文件中,當前關於 npm 如何升級 `@freecodecamp/example` 的規則是使用特定版本(1.2.13)。 但現在,你想允許最新的 1.2.x 版本。
在依賴項中,給 moment 的版本號添加波浪號(`~`前綴,允許 npm 將其更新爲最新的修訂版
在依賴項中使用波浪號(`~`)字符作爲 `@freecodecamp/example` 版本的前綴,允許 npm 將其更新爲任何新的*補丁*發佈
**注意:**原來的版本號不用更改。
# --hints--
dependencies”字段中應包含“moment”
`"dependencies"` 應包括 `"@freecodecamp/example"`
```js
(getUserInput) =>
@@ -35,8 +35,8 @@ dashedName: use-the-tilde-character-to-always-use-the-latest-patch-version-of-a-
var packJson = JSON.parse(data);
assert.property(
packJson.dependencies,
'moment',
'"dependencies" does not include "moment"'
'@freecodecamp/example',
'"dependencies" does not include "@freecodecamp/example"'
);
},
(xhr) => {
@@ -45,7 +45,7 @@ dashedName: use-the-tilde-character-to-always-use-the-latest-patch-version-of-a-
);
```
“moment”的版本號應該是“~2.10.2”
`"@freecodecamp/example"` 版本應匹配 `"~1.2.13"`
```js
(getUserInput) =>
@@ -53,9 +53,9 @@ dashedName: use-the-tilde-character-to-always-use-the-latest-patch-version-of-a-
(data) => {
var packJson = JSON.parse(data);
assert.match(
packJson.dependencies.moment,
/^\~2\.10\.2/,
'Wrong version of "moment". It should be ~2.10.2'
packJson.dependencies["@freecodecamp/example"],
/^\~1\.2\.13/,
'Wrong version of "@freecodecamp/example". It should be ~1.2.13'
);
},
(xhr) => {

View File

@@ -10,19 +10,23 @@ dashedName: install-and-set-up-mongoose
你可以採用下面的任意一種編寫代碼的方式來完成這些挑戰:
- 克隆 [這個 GitHub 倉庫](https://github.com/freeCodeCamp/boilerplate-mongomongoose/) 並在本地完成項目
- 使用[我們的 Replit 上的初始化項目](https://replit.com/github/freeCodeCamp/boilerplate-mongomongoose)來完成項目
- 克隆<a href="https://github.com/freeCodeCamp/boilerplate-mongomongoose/" target="_blank" rel="noopener noreferrer nofollow">這個 GitHub 倉庫</a>並在本地完成這些挑戰
- 使用<a href="https://replit.com/github/freeCodeCamp/boilerplate-mongomongoose" target="_blank" rel="noopener noreferrer nofollow">我們在 Replit 上的初始化項目</a>來完成這些挑戰
- 使用你選擇的網站生成器來完成項目。 需要包含我們 GitHub 倉庫的所有文件。
完成本項目後,請將一個正常運行的 demo項目演示託管在可以公開訪問的平臺。 然後在 `Solution Link` 字段中提交它的 URL。
在這個挑戰中,你將建立一個 MongoDB Atlas 數據庫並導入連接到它所需的軟件包。
按照<a href='https://www.freecodecamp.org/news/get-started-with-mongodb-atlas/' rel='noopener noreferrer' target='_blank'>這篇教程</a>在 MongoDB Atlas 創建一個託管數據庫。
按照<a href='https://chinese.freecodecamp.org/news/get-started-with-mongodb-atlas/' target="_blank" rel="noopener noreferrer nofollow">這篇教程</a>在 MongoDB Atlas 創建一個託管數據庫。
# --instructions--
`mongodb@~3.6.0``mongoose@~5.4.0` 添加到項目的 `package.json` 中。 然後,在 `myApp.js` 文件中請求 `mongoose`。 創建一個 `.env` 文件,給它添加一個 `MONGO_URI` 變量。 變量的值爲你的 MongoDB Atlas 數據庫 URI。 應用單引號或雙引號包裹 URI。請記住環境變量 `=` 兩邊不能有空格。 例如,`MONGO_URI='VALUE'` 完成後,使用下面的代碼來連接數據庫。
`mongoose@^5.11.15` 添加到項目的 `package.json` 文件中。 首先,在 `myApp.js` 中請求 mongoose 爲 `mongoose`接下來,創建一個 `.env` 文件並向其中添加一個 `MONGO_URI` 變量。 變量的值爲你的 MongoDB Atlas 數據庫 URI。 應用單引號或雙引號包裹 URI。請記住環境變量 `=` 兩邊不能有空格。 例如,`MONGO_URI='VALUE'`
**注意:** 如果你使用的是 Replit則無法創建 `.env` 文件。 相反,使用內置的 <dfn>SECRETS</dfn> 選項卡來添加變量。 在使用 <em>SECRETS</em> 選項卡時,<em>不要</em>將值括在引號中。
完成後,使用以下語法連接到數據庫:
```js
mongoose.connect(<Your URI>, { useNewUrlParser: true, useUnifiedTopology: true });
@@ -30,22 +34,7 @@ mongoose.connect(<Your URI>, { useNewUrlParser: true, useUnifiedTopology: true }
# --hints--
“mongodb” 應在 package.json 中作爲依賴項定義。
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/file/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert.property(packJson.dependencies, 'mongodb');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
“mongoose” 應在 package.json 中作爲依賴項定義。
“mongoose version ^5.11.15” 依賴項應該在 package.json
```js
(getUserInput) =>
@@ -53,6 +42,11 @@ mongoose.connect(<Your URI>, { useNewUrlParser: true, useUnifiedTopology: true }
(data) => {
var packJson = JSON.parse(data);
assert.property(packJson.dependencies, 'mongoose');
assert.match(
packJson.dependencies.mongoose,
/^\^5\.11\.15/,
'Wrong version of "mongoose". It should be ^5.11.15'
);
},
(xhr) => {
throw new Error(xhr.responseText);

View File

@@ -14,7 +14,7 @@ dashedName: perform-classic-updates-by-running-find-edit-then-save
在這個挑戰中,請使用參數 `personId` 作爲字段,修改 `findEditThenSave` 方法,以在數據庫中通過 `_id` 找到相應的 person你可以使用之前挑戰中的任何一種方法。 將 `"hamburger"` 添加到它的 `favoriteFoods` 清單中(你可以使用 `Array.push()`)。 然後,在查詢數據庫的方法的回調裏通過 `save()` 方法更新 `Person` 的數據。
**提示:** 如果你在 Schema 中將 `favoriteFoods` 聲明爲一個 Array數組並且沒有指定數組的類型(如 `[String]`) 那麼此時,`favoriteFoods` 就會是默認的 Mixed 類型。如果想編輯它,就必須執行 `document.markModified('edited-field')`詳情請參閱 [Mongoose 文檔](https://mongoosejs.com/docs/schematypes.html#Mixed)
**提示:** 如果你在 Schema 中將 `favoriteFoods` 聲明爲一個 Array數組並且沒有指定數組的類型(如 `[String]`) 那麼此時,`favoriteFoods` 就會是默認的 Mixed 類型。如果想編輯它,就必須執行 `document.markModified('edited-field')`查看我們的 <a href="https://www.freecodecamp.org/news/introduction-to-mongoose-for-mongodb-d2a7aa593c57/" target="_blank" rel="noopener noreferrer nofollow">Mongoose 文章</a>。
# --hints--

View File

@@ -34,7 +34,7 @@ socket.on('user', data => {
});
```
完成上述要求後,你可以在下方提交你的頁面鏈接。 如果你遇到了問題,可以參考 [這裏](https://gist.github.com/camperbot/bf95a0f74b756cf0771cd62c087b8286) 的答案
完成上述要求後,你可以在下方提交你的頁面鏈接。 如果你在運行時遇到錯誤,可以點擊此處查看 <a href="https://gist.github.com/camperbot/bf95a0f74b756cf0771cd62c087b8286" target="_blank" rel="noopener noreferrer nofollow">已執行項目的當前進度</a>
# --hints--

View File

@@ -8,7 +8,7 @@ dashedName: test-if-a-value-is-an-array
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
請注意,本項目是在 <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a> 上的初始化項目的基礎上進行開發你也可以從 <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a> 上克隆。
# --instructions--

View File

@@ -0,0 +1,88 @@
---
id: 56533eb9ac21ba0edf2244e2
title: 構建一個凱撒密碼
challengeType: 5
forumTopicId: 16003
dashedName: build-a-caesars-cipher
---
# --description--
凱撒密碼( <dfn>Caesar cipher</dfn>)是最簡單且最廣爲人知的密碼(<dfn>ciphers</dfn>),也被稱爲移位密碼(<dfn>shift cipher</dfn>)。 在移位密碼中,明文中的字母通過按照一個固定數目進行偏移後被替換成新的字母。
現代最常被應用到的一個變種就是 <a href="https://www.freecodecamp.org/news/how-to-code-the-caesar-cipher-an-introduction-to-basic-encryption-3bf77b4e19f7/" target="_blank" rel="noopener noreferrer nofollow">ROT13</a> 加密,也就是明文中的字母向後移 13 位。 也就是, `A ↔ N``B ↔ O` 等等。
編寫一個函數,它將把使用 <a href="https://www.freecodecamp.org/news/how-to-code-the-caesar-cipher-an-introduction-to-basic-encryption-3bf77b4e19f7/" target="_blank" rel="noopener noreferrer nofollow">ROT13</a> 加密編碼的字符串作爲輸入並返回解碼字符串。
所有解碼後的字母都必須爲字母大寫。 請不要解碼非字母的字符(例如,空格、標點符號),但你需要在結果中保留它們。
# --hints--
`rot13("SERR PBQR PNZC")` 應解碼爲 `FREE CODE CAMP`
```js
assert(rot13('SERR PBQR PNZC') === 'FREE CODE CAMP');
```
`rot13("SERR CVMMN!")` 應解碼爲 `FREE PIZZA!`
```js
assert(rot13('SERR CVMMN!') === 'FREE PIZZA!');
```
`rot13("SERR YBIR?")` 應解碼爲 `FREE LOVE?`
```js
assert(rot13('SERR YBIR?') === 'FREE LOVE?');
```
`rot13("GUR DHVPX OEBJA SBK WHZCF BIRE GUR YNML QBT.")` 應解碼爲 `THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.`
```js
assert(
rot13('GUR DHVPX OEBJA SBK WHZCF BIRE GUR YNML QBT.') ===
'THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.'
);
```
# --seed--
## --seed-contents--
```js
function rot13(str) {
return str;
}
rot13("SERR PBQR PNZC");
```
# --solutions--
```js
var lookup = {
'A': 'N','B': 'O','C': 'P','D': 'Q',
'E': 'R','F': 'S','G': 'T','H': 'U',
'I': 'V','J': 'W','K': 'X','L': 'Y',
'M': 'Z','N': 'A','O': 'B','P': 'C',
'Q': 'D','R': 'E','S': 'F','T': 'G',
'U': 'H','V': 'I','W': 'J','X': 'K',
'Y': 'L','Z': 'M'
};
function rot13(encodedStr) {
var codeArr = encodedStr.split(""); // String to Array
var decodedArr = []; // Your Result goes here
// Only change code below this line
decodedArr = codeArr.map(function(letter) {
if(lookup.hasOwnProperty(letter)) {
letter = lookup[letter];
}
return letter;
});
// Only change code above this line
return decodedArr.join(""); // Array to String
}
```

View File

@@ -0,0 +1,252 @@
---
id: aa2e6f85cab2ab736c9a9b24
title: 構建一個收銀機
challengeType: 5
forumTopicId: 16012
dashedName: build-a-cash-register
---
# --description--
設計一個收銀機抽屜函數 `checkCashRegister()`,它接受購買價格作爲第一個參數(`price`),付款作爲第二個參數(`cash`),和抽屜的現金(`cid`)作爲第三個參數。
`cid` 是包含貨幣面值的二維數組。
函數 `checkCashRegister()` 應返回含有 `status` 屬性和 `change` 屬性的對象。
如果收銀機內的金額少於應找回的零錢數,或者你無法返回確切的數目時,返回 `{status: "INSUFFICIENT_FUNDS", change: []}`
如果收銀機內的金額恰好等於應找回的零錢數,返回 `{status: "CLOSED", change: [...]}`,其中 `change` 的屬性值就是收銀機內的金額。
否則,返回 `{status: "OPEN", change: [...]}`,其中 `change` 鍵值是應找回的零錢數,並將找零的面值由高到低排序。
<table class='table table-striped'><tbody><tr><th>貨幣單位</th><th>面值</th></tr><tr><td>Penny</td><td>0.01 美元PENNY</td></tr><tr><td>Nickel</td><td>0.05 美元NICKEL</td></tr><tr><td>Dime</td><td>0.1 美元DIME</td></tr><tr><td>Quarter</td><td>0.25 美元QUARTER</td></tr><tr><td>Dollar</td><td>1 美元ONE</td></tr><tr><td>Five Dollars</td><td>5 美元FIVE</td></tr><tr><td>Ten Dollars</td><td>10 美元TEN</td></tr><tr><td>Twenty Dollars</td><td>20 美元TWENTY</td></tr><tr><td>One-hundred Dollars</td><td>100 美元ONE HUNDRED</td></tr></tbody></table>
下面的抽屜裏現金數組示例:
```js
[
["PENNY", 1.01],
["NICKEL", 2.05],
["DIME", 3.1],
["QUARTER", 4.25],
["ONE", 90],
["FIVE", 55],
["TEN", 20],
["TWENTY", 60],
["ONE HUNDRED", 100]
]
```
# --hints--
`checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]])` 應返回一個對象。
```js
assert.deepEqual(
Object.prototype.toString.call(
checkCashRegister(19.5, 20, [
['PENNY', 1.01],
['NICKEL', 2.05],
['DIME', 3.1],
['QUARTER', 4.25],
['ONE', 90],
['FIVE', 55],
['TEN', 20],
['TWENTY', 60],
['ONE HUNDRED', 100]
])
),
'[object Object]'
);
```
`checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]])` 應返回 `{status: "OPEN", change: [["QUARTER", 0.5]]}`
```js
assert.deepEqual(
checkCashRegister(19.5, 20, [
['PENNY', 1.01],
['NICKEL', 2.05],
['DIME', 3.1],
['QUARTER', 4.25],
['ONE', 90],
['FIVE', 55],
['TEN', 20],
['TWENTY', 60],
['ONE HUNDRED', 100]
]),
{ status: 'OPEN', change: [['QUARTER', 0.5]] }
);
```
`checkCashRegister(3.26, 100, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]])` 應返回 `{status: "OPEN", change: [["TWENTY", 60], ["TEN", 20], ["FIVE", 15], ["ONE", 1], ["QUARTER", 0.5], ["DIME", 0.2], ["PENNY", 0.04]]}`
```js
assert.deepEqual(
checkCashRegister(3.26, 100, [
['PENNY', 1.01],
['NICKEL', 2.05],
['DIME', 3.1],
['QUARTER', 4.25],
['ONE', 90],
['FIVE', 55],
['TEN', 20],
['TWENTY', 60],
['ONE HUNDRED', 100]
]),
{
status: 'OPEN',
change: [
['TWENTY', 60],
['TEN', 20],
['FIVE', 15],
['ONE', 1],
['QUARTER', 0.5],
['DIME', 0.2],
['PENNY', 0.04]
]
}
);
```
`checkCashRegister(19.5, 20, [["PENNY", 0.01], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]])` 應返回 `{status: "INSUFFICIENT_FUNDS", change: []}`
```js
assert.deepEqual(
checkCashRegister(19.5, 20, [
['PENNY', 0.01],
['NICKEL', 0],
['DIME', 0],
['QUARTER', 0],
['ONE', 0],
['FIVE', 0],
['TEN', 0],
['TWENTY', 0],
['ONE HUNDRED', 0]
]),
{ status: 'INSUFFICIENT_FUNDS', change: [] }
);
```
`checkCashRegister(19.5, 20, [["PENNY", 0.01], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 1], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]])` 應返回 `{status: "INSUFFICIENT_FUNDS", change: []}`
```js
assert.deepEqual(
checkCashRegister(19.5, 20, [
['PENNY', 0.01],
['NICKEL', 0],
['DIME', 0],
['QUARTER', 0],
['ONE', 1],
['FIVE', 0],
['TEN', 0],
['TWENTY', 0],
['ONE HUNDRED', 0]
]),
{ status: 'INSUFFICIENT_FUNDS', change: [] }
);
```
`checkCashRegister(19.5, 20, [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]])` 應返回 `{status: "CLOSED", change: [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]}`
```js
assert.deepEqual(
checkCashRegister(19.5, 20, [
['PENNY', 0.5],
['NICKEL', 0],
['DIME', 0],
['QUARTER', 0],
['ONE', 0],
['FIVE', 0],
['TEN', 0],
['TWENTY', 0],
['ONE HUNDRED', 0]
]),
{
status: 'CLOSED',
change: [
['PENNY', 0.5],
['NICKEL', 0],
['DIME', 0],
['QUARTER', 0],
['ONE', 0],
['FIVE', 0],
['TEN', 0],
['TWENTY', 0],
['ONE HUNDRED', 0]
]
}
);
```
# --seed--
## --seed-contents--
```js
function checkCashRegister(price, cash, cid) {
let change;
return change;
}
checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]);
```
# --solutions--
```js
const denom = [
{ name: "ONE HUNDRED", val: 100 },
{ name: "TWENTY", val: 20 },
{ name: "TEN", val: 10 },
{ name: "FIVE", val: 5 },
{ name: "ONE", val: 1 },
{ name: "QUARTER", val: 0.25 },
{ name: "DIME", val: 0.1 },
{ name: "NICKEL", val: 0.05 },
{ name: "PENNY", val: 0.01 },
];
function checkCashRegister(price, cash, cid) {
const output = { status: null, change: [] };
let change = cash - price;
const register = cid.reduce(
function (acc, curr) {
acc.total += curr[1];
acc[curr[0]] = curr[1];
return acc;
},
{ total: 0 }
);
if (register.total === change) {
output.status = "CLOSED";
output.change = cid;
return output;
}
if (register.total < change) {
output.status = "INSUFFICIENT_FUNDS";
return output;
}
const change_arr = denom.reduce(function (acc, curr) {
let value = 0;
while (register[curr.name] > 0 && change >= curr.val) {
change -= curr.val;
register[curr.name] -= curr.val;
value += curr.val;
change = Math.round(change * 100) / 100;
}
if (value > 0) {
acc.push([curr.name, value]);
}
return acc;
}, []);
if (change_arr.length < 1 || change > 0) {
output.status = "INSUFFICIENT_FUNDS";
return output;
}
output.status = "OPEN";
output.change = change_arr;
return output;
}
```

View File

@@ -0,0 +1,125 @@
---
id: aaa48de84e1ecc7c742e1124
title: 構建一個迴文檢測器
challengeType: 5
forumTopicId: 16004
dashedName: build-a-palindrome-checker
---
# --description--
如果傳入的字符串是迴文字符串,則返回 `true`。 否則,返回 `false`
迴文(<dfn>palindrome</dfn>),指在忽略標點符號、大小寫和空格的前提下,正着讀和反着讀一模一樣。
**注意:** 檢查迴文時,你需要先去除 **所有非字母數字的字符**(標點、空格和符號),並將所有字母都轉換成大寫或都轉換成小寫。
我們會傳入具有不同格式的字符串,如 `racecar``RaceCar``race CAR` 等等。
我們也會傳入一些包含特殊符號的字符串,例如 `2A3*3a2``2A3 3a2``2_A3*3#A2`
# --hints--
`palindrome("eye")` 應返回一個布爾值。
```js
assert(typeof palindrome('eye') === 'boolean');
```
`palindrome("eye")` 應返回 `true`
```js
assert(palindrome('eye') === true);
```
`palindrome("_eye")` 應返回 `true`
```js
assert(palindrome('_eye') === true);
```
`palindrome("race car")` 應返回 `true`
```js
assert(palindrome('race car') === true);
```
`palindrome("not a palindrome")` 應返回 `false`
```js
assert(palindrome('not a palindrome') === false);
```
`palindrome("A man, a plan, a canal. Panama")` 應返回 `true`
```js
assert(palindrome('A man, a plan, a canal. Panama') === true);
```
`palindrome("never odd or even")` 應返回 `true`
```js
assert(palindrome('never odd or even') === true);
```
`palindrome("nope")` 應返回 `false`
```js
assert(palindrome('nope') === false);
```
`palindrome("almostomla")` 應返回 `false`
```js
assert(palindrome('almostomla') === false);
```
`palindrome("My age is 0, 0 si ega ym.")` 應返回 `true`
```js
assert(palindrome('My age is 0, 0 si ega ym.') === true);
```
`palindrome("1 eye for of 1 eye.")` 應返回 `false`
```js
assert(palindrome('1 eye for of 1 eye.') === false);
```
`palindrome("0_0 (: /-\ :) 0-0")` 應返回 `true`
```js
assert(palindrome('0_0 (: /- :) 0-0') === true);
```
`palindrome("five|\_/|four")` 應返回 `false`
```js
assert(palindrome('five|_/|four') === false);
```
# --seed--
## --seed-contents--
```js
function palindrome(str) {
return true;
}
palindrome("eye");
```
# --solutions--
```js
function palindrome(str) {
var string = str.toLowerCase().split(/[^A-Za-z0-9]/gi).join('');
var aux = string.split('');
if (aux.join('') === aux.reverse().join('')){
return true;
}
return false;
}
```

View File

@@ -0,0 +1,215 @@
---
id: a7f4d8f2483413a6ce226cac
title: 構建羅馬數字轉換器
challengeType: 5
forumTopicId: 16044
dashedName: build-a-roman-numeral-converter
---
# --description--
把傳入的數字轉爲羅馬數字。
| 羅馬數字 | 阿拉伯數字 |
| ---- | ----- |
| M | 1000 |
| CM | 900 |
| D | 500 |
| CD | 400 |
| C | 100 |
| XC | 90 |
| L | 50 |
| XL | 40 |
| X | 10 |
| IX | 9 |
| V | 5 |
| IV | 4 |
| I | 1 |
所有羅馬數字答案都應該大寫。
# --hints--
`convertToRoman(2)` 應該返回字符串 `II`
```js
assert.deepEqual(convertToRoman(2), 'II');
```
`convertToRoman(3)` 應該返回字符串 `III`
```js
assert.deepEqual(convertToRoman(3), 'III');
```
`convertToRoman(4)` 應該返回字符串 `IV`
```js
assert.deepEqual(convertToRoman(4), 'IV');
```
`convertToRoman(5)` 應該返回字符串 `V`
```js
assert.deepEqual(convertToRoman(5), 'V');
```
`convertToRoman(9)` 應該返回字符串 `IX`
```js
assert.deepEqual(convertToRoman(9), 'IX');
```
`convertToRoman(12)` 應該返回字符串 `XII`
```js
assert.deepEqual(convertToRoman(12), 'XII');
```
`convertToRoman(16)` 應該返回字符串 `XVI`
```js
assert.deepEqual(convertToRoman(16), 'XVI');
```
`convertToRoman(29)` 應該返回字符串 `XXIX`
```js
assert.deepEqual(convertToRoman(29), 'XXIX');
```
`convertToRoman(44)` 應該返回字符串 `XLIV`.
```js
assert.deepEqual(convertToRoman(44), 'XLIV');
```
`convertToRoman(45)` 應該返回字符串 `XLV`
```js
assert.deepEqual(convertToRoman(45), 'XLV');
```
`convertToRoman(68)` 應該返回字符串 `LXVIII`
```js
assert.deepEqual(convertToRoman(68), 'LXVIII');
```
`convertToRoman(83)` 應該返回字符串 `LXXXIII`
```js
assert.deepEqual(convertToRoman(83), 'LXXXIII');
```
`convertToRoman(97)` 應該返回字符串 `XCVII`
```js
assert.deepEqual(convertToRoman(97), 'XCVII');
```
`convertToRoman(99)` 應該返回字符串 `XCIX`
```js
assert.deepEqual(convertToRoman(99), 'XCIX');
```
`convertToRoman(400)` 應該返回字符串 `CD`
```js
assert.deepEqual(convertToRoman(400), 'CD');
```
`convertToRoman(500)` 應該返回字符串 `D`
```js
assert.deepEqual(convertToRoman(500), 'D');
```
`convertToRoman(501)` 應該返回字符串 `DI`
```js
assert.deepEqual(convertToRoman(501), 'DI');
```
`convertToRoman(649)` 應該返回字符串 `DCXLIX`
```js
assert.deepEqual(convertToRoman(649), 'DCXLIX');
```
`convertToRoman(798)` 應該返回字符串 `DCCXCVIII`
```js
assert.deepEqual(convertToRoman(798), 'DCCXCVIII');
```
`convertToRoman(891)` 應該返回字符串 `DCCCXCI`
```js
assert.deepEqual(convertToRoman(891), 'DCCCXCI');
```
`convertToRoman(1000)` 應該返回字符串 `M`
```js
assert.deepEqual(convertToRoman(1000), 'M');
```
`convertToRoman(1004)` 應該返回字符串 `MIV`
```js
assert.deepEqual(convertToRoman(1004), 'MIV');
```
`convertToRoman(1006)` 應該返回字符串 `MVI`
```js
assert.deepEqual(convertToRoman(1006), 'MVI');
```
`convertToRoman(1023)` 應該返回字符串 `MXXIII`
```js
assert.deepEqual(convertToRoman(1023), 'MXXIII');
```
`convertToRoman(2014)` 應該返回字符串 `MMXIV`
```js
assert.deepEqual(convertToRoman(2014), 'MMXIV');
```
`convertToRoman(3999)` 應該返回字符串 `MMMCMXCIX`
```js
assert.deepEqual(convertToRoman(3999), 'MMMCMXCIX');
```
# --seed--
## --seed-contents--
```js
function convertToRoman(num) {
return num;
}
convertToRoman(36);
```
# --solutions--
```js
function convertToRoman(num) {
var ref = [['M', 1000], ['CM', 900], ['D', 500], ['CD', 400], ['C', 100], ['XC', 90], ['L', 50], ['XL', 40], ['X', 10], ['IX', 9], ['V', 5], ['IV', 4], ['I', 1]];
var res = [];
ref.forEach(function(p) {
while (num >= p[1]) {
res.push(p[0]);
num -= p[1];
}
});
return res.join('');
}
```

View File

@@ -0,0 +1,217 @@
---
id: aff0395860f5d3034dc0bfc9
title: 構建電話號碼驗證器
challengeType: 5
forumTopicId: 16090
dashedName: build-a-telephone-number-validator
---
# --description--
如果傳入的字符串是一個有效的美國電話號碼,則返回 `true`
用戶可以按照他們選擇的方式填寫表單字段,只要它是有效美國號碼的格式即可。 以下是美國電話號碼的有效格式示例(其他格式變化,請參考下面的測試):
<blockquote>555-555-5555<br>(555)555-5555<br>(555) 555-5555<br>555 555 5555<br>5555555555<br>1 555 555 5555</blockquote>
在這個挑戰中,傳入的字符串可能是例如 `800-692-7753` 或者 `8oo-six427676;laskdjf` 的號碼。 你的任務是根據上面不同的格式組合,判斷它是否爲有效的電話號碼。 地區代碼是必需的。 如果提供了國家/地區代碼,則必須確認國家/地區代碼爲`1` 。 如果傳入的字符串是有效的美國電話號碼,則返回 `true`,否則返回 `false`
# --hints--
`telephoneCheck("555-555-5555")` 應返回一個布爾值。
```js
assert(typeof telephoneCheck('555-555-5555') === 'boolean');
```
`telephoneCheck("1 555-555-5555")` 應返回 `true`
```js
assert(telephoneCheck('1 555-555-5555') === true);
```
`telephoneCheck("1 (555) 555-5555")` 應返回 `true`
```js
assert(telephoneCheck('1 (555) 555-5555') === true);
```
`telephoneCheck("5555555555")` 應返回 `true`
```js
assert(telephoneCheck('5555555555') === true);
```
`telephoneCheck("555-555-5555")` 應返回 `true`
```js
assert(telephoneCheck('555-555-5555') === true);
```
`telephoneCheck("(555)555-5555")` 應返回 `true`
```js
assert(telephoneCheck('(555)555-5555') === true);
```
`telephoneCheck("1(555)555-5555")` 應返回 `true`
```js
assert(telephoneCheck('1(555)555-5555') === true);
```
`telephoneCheck("555-5555")` 應返回 `false`
```js
assert(telephoneCheck('555-5555') === false);
```
`telephoneCheck("5555555")` 應返回 `false`
```js
assert(telephoneCheck('5555555') === false);
```
`telephoneCheck("1 555)555-5555")` 應返回 `false`
```js
assert(telephoneCheck('1 555)555-5555') === false);
```
`telephoneCheck("1 555 555 5555")` 應返回 `true`
```js
assert(telephoneCheck('1 555 555 5555') === true);
```
`telephoneCheck("1 456 789 4444")` 應返回 `true`
```js
assert(telephoneCheck('1 456 789 4444') === true);
```
`telephoneCheck("123**&!!asdf#")` 應返回 `false`
```js
assert(telephoneCheck('123**&!!asdf#') === false);
```
`telephoneCheck("55555555")` 應返回 `false`
```js
assert(telephoneCheck('55555555') === false);
```
`telephoneCheck("(6054756961)")` 應返回 `false`
```js
assert(telephoneCheck('(6054756961)') === false);
```
`telephoneCheck("2 (757) 622-7382")` 應返回 `false`
```js
assert(telephoneCheck('2 (757) 622-7382') === false);
```
`telephoneCheck("0 (757) 622-7382")` 應返回 `false`
```js
assert(telephoneCheck('0 (757) 622-7382') === false);
```
`telephoneCheck("-1 (757) 622-7382")` 應返回 `false`
```js
assert(telephoneCheck('-1 (757) 622-7382') === false);
```
`telephoneCheck("2 757 622-7382")` 應返回 `false`
```js
assert(telephoneCheck('2 757 622-7382') === false);
```
`telephoneCheck("10 (757) 622-7382")` 應返回 `false`
```js
assert(telephoneCheck('10 (757) 622-7382') === false);
```
`telephoneCheck("27576227382")` 應返回 `false`
```js
assert(telephoneCheck('27576227382') === false);
```
`telephoneCheck("(275)76227382")` 應返回 `false`
```js
assert(telephoneCheck('(275)76227382') === false);
```
`telephoneCheck("2(757)6227382")` 應返回 `false`
```js
assert(telephoneCheck('2(757)6227382') === false);
```
`telephoneCheck("2(757)622-7382")` 應返回 `false`
```js
assert(telephoneCheck('2(757)622-7382') === false);
```
`telephoneCheck("555)-555-5555")` 應返回 `false`
```js
assert(telephoneCheck('555)-555-5555') === false);
```
`telephoneCheck("(555-555-5555")` 應返回 `false`
```js
assert(telephoneCheck('(555-555-5555') === false);
```
`telephoneCheck("(555)5(55?)-5555")` 應返回 `false`
```js
assert(telephoneCheck('(555)5(55?)-5555') === false);
```
`telephoneCheck("55 55-55-555-5")` 應返回 `false`
```js
assert(telephoneCheck('55 55-55-555-5') === false);
```
`telephoneCheck("11 555-555-5555")` 應返回 `false`
```js
assert(telephoneCheck('11 555-555-5555') === false);
```
# --seed--
## --seed-contents--
```js
function telephoneCheck(str) {
return true;
}
telephoneCheck("555-555-5555");
```
# --solutions--
```js
var re = /^([+]?1[\s]?)?((?:[(](?:[2-9]1[02-9]|[2-9][02-8][0-9])[)][\s]?)|(?:(?:[2-9]1[02-9]|[2-9][02-8][0-9])[\s.-]?)){1}([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2}[\s.-]?){1}([0-9]{4}){1}$/;
function telephoneCheck(str) {
return re.test(str);
}
telephoneCheck("555-555-5555");
```

View File

@@ -0,0 +1,154 @@
---
id: 5d5a813321b9e3db6c106a46
title: 步驟 1
challengeType: 0
dashedName: step-1
---
# --description--
JavaScript 是一種強大的語言,它允許你構建交互式網站。 首先,使用 `DOCTYPE``html``head``body` 創建你的標準 HTML 樣板。 包括一個 `title` 元素和一個 `link` 用於樣式表,以及 `meta` 標記用於 `charset`。 然後,在 `body` 中創建一個 ID 爲 `game``div` 元素。 給你的 `title` 元素添加文本 `RPG - Dragon Repeller`
# --hints--
代碼應包含 `DOCTYPE` 聲明。
```js
assert(code.match(/<!DOCTYPE/gi));
```
應該在 `DOCTYPE` 聲明之後包含一個空格。
```js
assert(code.match(/<!DOCTYPE\s+/gi));
```
應該將文檔類型定義爲 `html`
```js
assert(code.match(/<!DOCTYPE\s+html/gi));
```
應該在類型之後使用 `>` 關閉 `DOCTYPE` 聲明。
```js
assert(code.match(/<!DOCTYPE\s+html\s*>/gi));
```
`html` 元素應該有一個開始標籤。 不要忘記 `lang` 屬性。
```js
assert(code.match(/<html\s+lang\s*=\s*('|")en\1\s*>/gi));
```
`html` 元素應該有一個結束標籤。
```js
assert(code.match(/<\/html\s*>/));
```
`DOCTYPE` 聲明應位於 HTML 的開頭。
```js
assert(__helpers.removeHtmlComments(code).match(/^\s*<!DOCTYPE\s+html\s*>/i));
```
應該有一個 `head` 開始標籤。
```js
assert(code.match(/<head\s*>/i));
```
應該有一個 `head` 結束標籤。
```js
assert(code.match(/<\/head\s*>/i));
```
應該有一個 `body` 開始標籤。
```js
assert(code.match(/<body\s*>/i));
```
應該有一個 `body` 結束標籤。
```js
assert(code.match(/<\/body\s*>/i));
```
`head``body` 元素應該是兄弟元素。
```js
assert(document.querySelector('head')?.nextElementSibling?.localName === 'body');
```
`head` 元素應該在 `html` 元素內。
```js
assert([...document.querySelector('html')?.children].some(x => x?.localName === 'head'));
```
`body` 元素應該在 `html` 元素內。
```js
assert([...document.querySelector('html')?.children].some(x => x?.localName === 'body'));
```
代碼應該有一個 `meta` 元素。
```js
const meta = document.querySelector('meta');
assert.exists(meta);
```
`meta` 元素應該有一個 `charset` 屬性,其值爲 `UTF-8`
```js
assert.match(code, /<meta[\s\S]+?charset=('|"|`)UTF-8\1/i)
```
代碼應該有一個 `title` 元素。
```js
const title = document.querySelector('title');
assert.exists(title);
```
代碼應該有一個 `link` 元素。
```js
const link = document.querySelector('head > link');
assert.exists(link);
```
代碼應該有一個 `div` 元素。
```js
const div = document.querySelector('div');
assert.exists(div);
```
`div` 元素應該有一個 `id` 屬性,其值爲 `game`
```js
const div = document.querySelector('div');
assert.equal(div?.id, 'game');
```
`div` 元素應該在 `body` 元素內。
```js
const div = document.querySelector('div');
assert.equal(div?.parentElement?.localName, 'body');
```
# --seed--
## --seed-contents--
```html
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,78 @@
---
id: 62a115879a6d51422652cbfc
title: 步驟 2
challengeType: 0
dashedName: step-2
---
# --description--
`#game` 元素中創建四個 `div` 元素。 按順序爲它們提供以下相應的 `id` 值:`stats``controls``monsterStats``text`
# --hints--
應該創建四個新的 `div` 元素。
```js
assert.equal(document.querySelectorAll('div')?.length, 5);
```
應該爲新的 `div` 元素之一提供 `id` 設爲 `stats`
```js
assert.exists(document.querySelector('div#stats'));
```
應該爲新的 `div` 元素之一提供 `id` 設爲 `controls`
```js
assert.exists(document.querySelector('div#controls'));
```
應該爲新的 `div` 元素之一提供 `id` 設爲 `monsterStats`
```js
assert.exists(document.querySelector('div#monsterStats'));
```
應該爲新的 `div` 元素之一提供 `id` 設爲 `text`
```js
assert.exists(document.querySelector('div#text'));
```
應該以正確的順序放置新的 `div` 元素。
```js
function __t(a, b) {
return document.querySelector(a)?.nextElementSibling?.getAttribute('id') === b;
}
assert(__t('div#stats','controls') && __t('div#controls','monsterStats') && __t('div#monsterStats','text'));
```
應該將新的 `div` 元素放在 `#game` 元素中。
```js
assert.equal(document.querySelector('#game')?.children?.length, 4);
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="./styles.css">
<title>RPG - Dragon Repeller</title>
</head>
--fcc-editable-region--
<body>
<div id="game">
</div>
</body>
--fcc-editable-region--
</html>
```

View File

@@ -0,0 +1,70 @@
---
id: 62a1166ed9a56d439c0770e7
title: 步驟 3
challengeType: 0
dashedName: step-3
---
# --description--
`#stats` 元素中創建三個 `span` 元素。 給每個元素一個類 `stat`。 然後給第一個元素設置文本 `XP: 0`,給第二個元素設置文本 `Health: 100`,給第三個元素設置文本 `Gold: 50`
# --hints--
`#stats` 元素中應該有三個 `span` 元素。
```js
const spans = document.querySelectorAll('#stats > span');
assert.equal(spans?.length, 3);
```
應該給新的三個 `span` 元素一個 `stat` 類。
```js
assert.exists(document.querySelectorAll('#stats > .stat')?.length, 3);
```
第一個 `.stat` 元素應具有提供的文本 `XP: 0`
```js
assert(document.querySelectorAll('#stats > .stat')?.[0]?.innerText === 'XP: 0');
```
第二個 `.stat` 元素應具有提供的文本 `Health: 100`
```js
assert(document.querySelectorAll('#stats > .stat')?.[1]?.innerText === 'Health: 100');
```
第三個 `.stat` 元素應具有提供的文本 `Gold: 50`
```js
assert(document.querySelectorAll('#stats > .stat')?.[2]?.innerText === 'Gold: 50');
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="./styles.css">
<title>RPG - Dragon Repeller</title>
</head>
--fcc-editable-region--
<body>
<div id="game">
<div id="stats">
</div>
<div id="controls"></div>
<div id="monsterStats"></div>
<div id="text"></div>
</div>
</body>
--fcc-editable-region--
</html>
```

View File

@@ -0,0 +1,167 @@
---
id: 62a23c1d505bfa13747c8a9b
title: 步驟 4
challengeType: 0
dashedName: step-4
---
# --description--
將數字 `0``100``50` 包含在 `span` 元素中,並將這些新的 `span` 元素包含在 `strong` 元素中。 然後分別爲新的 `span` 元素設置 `id` 值爲 `xpText``healthText``goldText`
# --hints--
應該在第一個 `.stat` 元素中添加一個 `strong` 元素。
```js
const stat = document.querySelectorAll('.stat')[0];
const strong = stat?.querySelector('strong');
assert.exists(strong);
```
第一個新的 `strong` 元素應該有一個 `span` 元素。
```js
const stat = document.querySelectorAll('.stat')[0];
const strong = stat?.querySelector('strong');
const span = strong?.querySelector('span');
assert.exists(span);
```
第一個嵌套的 `span` 元素應具有 `id` 值爲 `xpText`
```js
const stat = document.querySelectorAll('.stat')[0];
const strong = stat?.querySelector('strong');
const span = strong?.querySelector('span');
assert.equal(span?.id, 'xpText');
```
第一個 `span` 元素應該包裹在文本 `0` 周圍。
```js
const stat = document.querySelectorAll('.stat')[0];
const strong = stat?.querySelector('strong');
const span = strong?.querySelector('span');
assert.equal(span.innerText, '0');
```
第一個 `.stat` 元素的文本仍應爲 `XP: 0`
```js
const stat = document.querySelectorAll('.stat')[0];
assert.equal(stat.innerText, 'XP: 0');
```
應該在第二個 `.stat` 元素中添加一個 `strong` 元素。
```js
const stat = document.querySelectorAll('.stat')[1];
const strong = stat?.querySelector('strong');
assert.exists(strong);
```
第二個新 `strong` 元素應該有一個 `span` 元素。
```js
const stat = document.querySelectorAll('.stat')[1];
const strong = stat?.querySelector('strong');
const span = strong?.querySelector('span');
assert.exists(span);
```
第二個嵌套的 `span` 元素應具有 `id` 值爲 `healthText`
```js
const stat = document.querySelectorAll('.stat')[1];
const strong = stat?.querySelector('strong');
const span = strong?.querySelector('span');
assert.equal(span?.id, 'healthText');
```
第二個 `span` 元素應包裹在文本 `100` 周圍。
```js
const stat = document.querySelectorAll('.stat')[1];
const strong = stat?.querySelector('strong');
const span = strong?.querySelector('span');
assert.equal(span.innerText, '100');
```
第二個 `.stat` 元素的文本仍應爲 `Health: 100`
```js
const stat = document.querySelectorAll('.stat')[1];
assert.equal(stat.innerText, 'Health: 100');
```
應該在第三個 `.stat` 元素中添加一個 `strong` 元素。
```js
const stat = document.querySelectorAll('.stat')[2];
const strong = stat?.querySelector('strong');
assert.exists(strong);
```
第三個新 `strong` 元素應該有一個 `span` 元素。
```js
const stat = document.querySelectorAll('.stat')[2];
const strong = stat?.querySelector('strong');
const span = strong?.querySelector('span');
assert.exists(span);
```
第三個嵌套的 `span` 元素應具有 `id` 值爲 `goldText`
```js
const stat = document.querySelectorAll('.stat')[2];
const strong = stat?.querySelector('strong');
const span = strong?.querySelector('span');
assert.equal(span?.id, 'goldText');
```
第三個 `span` 元素應包裹在文本 `50` 周圍。
```js
const stat = document.querySelectorAll('.stat')[2];
const strong = stat?.querySelector('strong');
const span = strong?.querySelector('span');
assert.equal(span.innerText, '50');
```
第三個 `.stat` 元素的文本仍應爲 `Gold: 50`
```js
const stat = document.querySelectorAll('.stat')[2];
assert.equal(stat.innerText, 'Gold: 50');
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="./styles.css">
<title>RPG - Dragon Repeller</title>
</head>
<body>
<div id="game">
<div id="stats">
--fcc-editable-region--
<span class="stat">XP: 0</span>
<span class="stat">Health: 100</span>
<span class="stat">Gold: 50</span>
--fcc-editable-region--
</div>
<div id="controls"></div>
<div id="monsterStats"></div>
<div id="text"></div>
</div>
</body>
</html>
```

View File

@@ -0,0 +1,99 @@
---
id: 62a23cb9bc467a147516b500
title: 步驟 5
challengeType: 0
dashedName: step-5
---
# --description--
`#controls` 元素中,創建三個 `button` 元素。 第一個應該將 `id` 設置爲 `button1`,以及文本設置爲 `Go to store`。 第二個應該將 `id` 設置爲 `button2`,以及文本設置爲 `Go to cave`。 第三個應該將 `id` 設置爲 `button3`,以及文本設置爲 `Fight dragon`
# --hints--
應該將三個 `button` 元素添加到 `#controls` 元素中。
```js
const buttons = document.querySelectorAll('#controls > button');
assert.exists(buttons);
assert.equal(buttons.length, 3);
```
第一個按鈕應該將 `id` 設置爲 `button1`
```js
const buttons = document.querySelectorAll('#controls > button');
const button1 = buttons[0];
assert.equal(button1.id, 'button1');
```
第一個按鈕應該有文本 `Go to store`
```js
const buttons = document.querySelectorAll('#controls > button');
const button1 = buttons[0];
assert.equal(button1.innerText, 'Go to store');
```
第二個按鈕應該將 `id` 設置爲 `button2`
```js
const buttons = document.querySelectorAll('#controls > button');
const button2 = buttons[1];
assert.equal(button2.id, 'button2');
```
第二個按鈕應該有文本 `Go to cave`
```js
const buttons = document.querySelectorAll('#controls > button');
const button2 = buttons[1];
assert.equal(button2.innerText, 'Go to cave');
```
第三個按鈕應該將 `id` 設置爲 `button3`
```js
const buttons = document.querySelectorAll('#controls > button');
const button3 = buttons[2];
assert.equal(button3.id, 'button3');
```
第三個按鈕應該有文本 `Fight dragon`
```js
const buttons = document.querySelectorAll('#controls > button');
const button3 = buttons[2];
assert.equal(button3.innerText, 'Fight dragon');
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="./styles.css">
<title>RPG - Dragon Repeller</title>
</head>
<body>
<div id="game">
<div id="stats">
<span class="stat">XP: <strong><span id="xpText">0</span></strong></span>
<span class="stat">Health: <strong><span id="healthText">100</span></strong></span>
<span class="stat">Gold: <strong><span id="goldText">50</span></strong></span>
</div>
--fcc-editable-region--
<div id="controls">
</div>
--fcc-editable-region--
<div id="monsterStats"></div>
<div id="text"></div>
</div>
</body>
</html>
```

View File

@@ -0,0 +1,104 @@
---
id: 62a23d1c5f1c93161f3582ae
title: 步驟 6
challengeType: 0
dashedName: step-6
---
# --description--
`#stats` 元素類似,`#monsterStats` 元素需要兩個 `span` 元素。 給它們類 `stat`,並給第一個元素文本 `Monster Name:`,給第二個元素文本 `Health:`。 在每個文本之後,添加一個 `strong` 元素和一個空的嵌套 `span` 元素。
# --hints--
`monsterStats` 元素應該有兩個 `span` 元素。
```js
const spans = document.querySelectorAll(`#monsterStats > span`);
assert.equal(spans.length, 2);
```
新的 `span` 元素都應該具有 `stat``class` 值。
```js
const spans = document.querySelectorAll(`#monsterStats > span`);
assert.equal(spans[0].className, 'stat');
assert.equal(spans[1].className, 'stat');
```
第一個 `span` 元素應該包含文本 `Monster Name:`。 請確保間隔正確。
```js
const spans = document.querySelectorAll(`#monsterStats > span`);
assert.equal(spans[0].innerText, 'Monster Name: ');
```
第二個 `span` 元素應包含文本 `Health:`。 請確保間隔正確。
```js
const spans = document.querySelectorAll(`#monsterStats > span`);
assert.equal(spans[1].textContent, 'Health: ');
```
第一個 `span` 元素應該有一個 `strong` 元素和一個空的嵌套 `span` 元素。
```js
const spans = document.querySelectorAll(`#monsterStats > span`);
const strong = spans[0]?.querySelector('strong');
const span = strong?.querySelector('span');
assert.exists(strong);
assert.exists(span);
```
第二個 `span` 元素應該有一個 `strong` 元素和一個空的嵌套 `span` 元素。
```js
const spans = document.querySelectorAll(`#monsterStats > span`);
const strong = spans[1]?.querySelector('strong');
const span = strong?.querySelector('span');
assert.exists(strong);
assert.exists(span);
```
`strong``span` 元素應該在文本之後。
```js
const spans = document.querySelectorAll(`#monsterStats > span`);
assert.match(spans[0].innerHTML, /Monster Name: <strong>/);
assert.match(spans[1].innerHTML, /Health: <strong>/);
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="./styles.css">
<title>RPG - Dragon Repeller</title>
</head>
<body>
<div id="game">
<div id="stats">
<span class="stat">XP: <strong><span id="xpText">0</span></strong></span>
<span class="stat">Health: <strong><span id="healthText">100</span></strong></span>
<span class="stat">Gold: <strong><span id="goldText">50</span></strong></span>
</div>
<div id="controls">
<button id="button1">Go to store</button>
<button id="button2">Go to cave</button>
<button id="button3">Fight dragon</button>
</div>
--fcc-editable-region--
<div id="monsterStats">
</div>
--fcc-editable-region--
<div id="text"></div>
</div>
</body>
</html>
```

View File

@@ -0,0 +1,62 @@
---
id: 62a2401b9842721796b72850
title: 步驟 7
challengeType: 0
dashedName: step-7
---
# --description--
爲你的 `#text` 元素提供以下文本:
```markup
Welcome to Dragon Repeller. You must defeat the dragon that is preventing people from leaving the town.
You are in the town square. Where do you want to go? Use the buttons above.
```
# --hints--
`#text` 元素應該有上面引用的文本。
```js
const text = document.querySelector('#text');
assert.equal(text.innerText, "Welcome to Dragon Repeller. You must defeat the dragon that is preventing people from leaving the town. You are in the town square. Where do you want to go? Use the buttons above.");
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="./styles.css">
<title>RPG - Dragon Repeller</title>
</head>
<body>
<div id="game">
<div id="stats">
<span class="stat">XP: <strong><span id="xpText">0</span></strong></span>
<span class="stat">Health: <strong><span id="healthText">100</span></strong></span>
<span class="stat">Gold: <strong><span id="goldText">50</span></strong></span>
</div>
<div id="controls">
<button id="button1">Go to store</button>
<button id="button2">Go to cave</button>
<button id="button3">Fight dragon</button>
</div>
<div id="monsterStats">
<span class="stat">Monster Name: <strong><span id="monsterName"></span></strong></span>
<span class="stat">Health: <strong><span id="monsterHealth"></span></strong></span>
</div>
--fcc-editable-region--
<div id="text">
</div>
--fcc-editable-region--
</div>
</body>
</html>
```

View File

@@ -0,0 +1,68 @@
---
id: 62a24068d60b671847d1d4e2
title: 步驟 8
challengeType: 0
dashedName: step-8
---
# --description--
現在我們需要快速設置一些樣式。 首先將 `body``background-color` 設置爲 `darkblue`
# --hints--
應該有一個 `body` 選擇器。
```js
const body = new __helpers.CSSHelp(document).getStyle('body');
assert.exists(body);
```
`body` 選擇器應該將 `background-color` 屬性設置爲 `darkblue`
```js
const background = new __helpers.CSSHelp(document).getStyle('body')?.getPropertyValue('background-color');
assert.equal(background, 'darkblue');
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="./styles.css">
<title>RPG - Dragon Repeller</title>
</head>
<body>
<div id="game">
<div id="stats">
<span class="stat">XP: <strong><span id="xpText">0</span></strong></span>
<span class="stat">Health: <strong><span id="healthText">100</span></strong></span>
<span class="stat">Gold: <strong><span id="goldText">50</span></strong></span>
</div>
<div id="controls">
<button id="button1">Go to store</button>
<button id="button2">Go to cave</button>
<button id="button3">Fight dragon</button>
</div>
<div id="monsterStats">
<span class="stat">Monster Name: <strong><span id="monsterName"></span></strong></span>
<span class="stat">Health: <strong><span id="monsterHealth"></span></strong></span>
</div>
<div id="text">
Welcome to Dragon Repeller. You must defeat the dragon that is preventing people from leaving the town. You are in the town square. Where do you want to go? Use the buttons above.
</div>
</div>
</body>
</html>
```
```css
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,86 @@
---
id: 62a2409897ec621942234cf6
title: 步驟 9
challengeType: 0
dashedName: step-9
---
# --description--
`#text` 元素一個 `black``background-color`,一個 `white``color` 和一個 `10px` 的邊距。
# --hints--
應該有一個 `#text` 選擇器。
```js
const text = new __helpers.CSSHelp(document).getStyle('#text');
assert.exists(text);
```
`#text` 元素應該有一個 `black``background-color`
```js
const background = new __helpers.CSSHelp(document).getStyle('#text')?.getPropertyValue('background-color');
assert.equal(background, 'black');
```
`#text` 元素應該具有 `white``color`
```js
const color = new __helpers.CSSHelp(document).getStyle('#text')?.getPropertyValue('color');
assert.equal(color, 'white');
```
`#text` 元素應該有 `10px` 的邊距。
```js
const padding = new __helpers.CSSHelp(document).getStyle('#text')?.getPropertyValue('padding');
assert.equal(padding, '10px');
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="./styles.css">
<title>RPG - Dragon Repeller</title>
</head>
<body>
<div id="game">
<div id="stats">
<span class="stat">XP: <strong><span id="xpText">0</span></strong></span>
<span class="stat">Health: <strong><span id="healthText">100</span></strong></span>
<span class="stat">Gold: <strong><span id="goldText">50</span></strong></span>
</div>
<div id="controls">
<button id="button1">Go to store</button>
<button id="button2">Go to cave</button>
<button id="button3">Fight dragon</button>
</div>
<div id="monsterStats">
<span class="stat">Monster Name: <strong><span id="monsterName"></span></strong></span>
<span class="stat">Health: <strong><span id="monsterHealth"></span></strong></span>
</div>
<div id="text">
Welcome to Dragon Repeller. You must defeat the dragon that is preventing people from leaving the town. You are in the town square. Where do you want to go? Use the buttons above.
</div>
</div>
</body>
</html>
```
```css
body {
background-color: darkblue;
}
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,113 @@
---
id: 62a240c67f3dbb1a1e6d95ee
title: 步驟 10
challengeType: 0
dashedName: step-10
---
# --description--
`#game` 提供 `500px` 的最大寬度和 `400px` 的最大高度。 將 `background-color` 設置爲 `lightgray`,並將 `color` 設置爲 `white`。 最後,使用邊距使其居中,並在所有四個邊上給它 `10px` 的填充。
# --hints--
應該有一個 `#game` 選擇器。
```js
const game = new __helpers.CSSHelp(document).getStyle('#game');
assert.exists(game);
```
`#game` 選擇器的 `max-width` 應該是 `500px`
```js
const maxWidth = new __helpers.CSSHelp(document).getStyle('#game')?.getPropertyValue('max-width');
assert.equal(maxWidth, '500px');
```
`#game` 選擇器的 `max-height` 應該是 `400px`
```js
const maxHeight = new __helpers.CSSHelp(document).getStyle('#game')?.getPropertyValue('max-height');
assert.equal(maxHeight, '400px');
```
`#game` 選擇器應該具有 `lightgray``background-color`
```js
const background = new __helpers.CSSHelp(document).getStyle('#game')?.getPropertyValue('background-color');
assert.equal(background, 'lightgray');
```
`#game` 選擇器應該有一個 `color` `white`
```js
const color = new __helpers.CSSHelp(document).getStyle('#game')?.getPropertyValue('color');
assert.equal(color, 'white');
```
`#game` 選擇器應該將 `margin` 設置爲 `0 auto`
```js
const margin = new __helpers.CSSHelp(document).getStyle('#game')?.getPropertyValue('margin');
assert.equal(margin, '0px auto');
```
`#game` 選擇器應該有 `10px` 的邊距。
```js
const padding = new __helpers.CSSHelp(document).getStyle('#game')?.getPropertyValue('padding');
assert.equal(padding, '10px');
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="./styles.css">
<title>RPG - Dragon Repeller</title>
</head>
<body>
<div id="game">
<div id="stats">
<span class="stat">XP: <strong><span id="xpText">0</span></strong></span>
<span class="stat">Health: <strong><span id="healthText">100</span></strong></span>
<span class="stat">Gold: <strong><span id="goldText">50</span></strong></span>
</div>
<div id="controls">
<button id="button1">Go to store</button>
<button id="button2">Go to cave</button>
<button id="button3">Fight dragon</button>
</div>
<div id="monsterStats">
<span class="stat">Monster Name: <strong><span id="monsterName"></span></strong></span>
<span class="stat">Health: <strong><span id="monsterHealth"></span></strong></span>
</div>
<div id="text">
Welcome to Dragon Repeller. You must defeat the dragon that is preventing people from leaving the town. You are in the town square. Where do you want to go? Use the buttons above.
</div>
</div>
</body>
</html>
```
```css
body {
background-color: darkblue;
}
#text {
background-color: black;
color: white;
padding: 10px;
}
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,101 @@
---
id: 62a24128d5e8af1b47ad1aab
title: 步驟 11
challengeType: 0
dashedName: step-11
---
# --description--
`#controls``#stats` 元素一個 `border``1px solid black`,一個 `black` 的文本顏色和 `5px` 的填充padding
# --hints--
應該有一個 `#controls, #stats` 選擇器。
```js
const selector = new __helpers.CSSHelp(document).getStyle('#controls, #stats');
assert.exists(selector);
```
`#controls, #stats` 選擇器的 `border` 應該是 `1px solid black`
```js
const border = new __helpers.CSSHelp(document).getStyle('#controls, #stats')?.getPropertyValue('border');
assert.equal(border, '1px solid black');
```
`#controls, #stats` 選擇器的 `color` 應該是 `black`
```js
const color = new __helpers.CSSHelp(document).getStyle('#controls, #stats')?.getPropertyValue('color');
assert.equal(color, 'black');
```
`#controls, #stats` 選擇器應該有 `5px` 的填充。
```js
const padding = new __helpers.CSSHelp(document).getStyle('#controls, #stats')?.getPropertyValue('padding');
assert.equal(padding, '5px');
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="./styles.css">
<title>RPG - Dragon Repeller</title>
</head>
<body>
<div id="game">
<div id="stats">
<span class="stat">XP: <strong><span id="xpText">0</span></strong></span>
<span class="stat">Health: <strong><span id="healthText">100</span></strong></span>
<span class="stat">Gold: <strong><span id="goldText">50</span></strong></span>
</div>
<div id="controls">
<button id="button1">Go to store</button>
<button id="button2">Go to cave</button>
<button id="button3">Fight dragon</button>
</div>
<div id="monsterStats">
<span class="stat">Monster Name: <strong><span id="monsterName"></span></strong></span>
<span class="stat">Health: <strong><span id="monsterHealth"></span></strong></span>
</div>
<div id="text">
Welcome to Dragon Repeller. You must defeat the dragon that is preventing people from leaving the town. You are in the town square. Where do you want to go? Use the buttons above.
</div>
</div>
</body>
</html>
```
```css
body {
background-color: darkblue;
}
#text {
background-color: black;
color: white;
padding: 10px;
}
#game {
max-width: 500px;
max-height: 400px;
background-color: lightgray;
color: white;
margin: 0 auto;
padding: 10px;
}
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,127 @@
---
id: 62a24190868ca51c0b6e83c7
title: 步驟 13
challengeType: 0
dashedName: step-13
---
# --description--
暫時隱藏 `#monsterStats` 元素。 不要更改任何其他樣式。
# --hints--
應該有一個 `#monsterStats` 選擇器。
```js
const monsterStats = new __helpers.CSSHelp(document).getStyle('#monsterStats');
assert.exists(monsterStats);
```
`#monsterStats` 選擇器應具有 `none``display` 屬性。
```js
const display = new __helpers.CSSHelp(document).getStyle('#monsterStats')?.getPropertyValue('display');
assert.equal(display, 'none');
```
`#monsterStats` 選擇器應該有一個 `1px solid black``border`
```js
const border = new __helpers.CSSHelp(document).getStyle('#monsterStats')?.getPropertyValue('border');
assert.equal(border, '1px solid black');
```
`#monsterStats` 選擇器應該有 `5px` 的填充padding
```js
const padding = new __helpers.CSSHelp(document).getStyle('#monsterStats')?.getPropertyValue('padding');
assert.equal(padding, '5px');
```
`#monsterStats` 選擇器應具有 `white``color`
```js
const color = new __helpers.CSSHelp(document).getStyle('#monsterStats')?.getPropertyValue('color');
assert.equal(color, 'white');
```
`#monsterStats` 選擇器應具有 `red``background-color`
```js
const background = new __helpers.CSSHelp(document).getStyle('#monsterStats')?.getPropertyValue('background-color');
assert.equal(background, 'red');
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="./styles.css">
<title>RPG - Dragon Repeller</title>
</head>
<body>
<div id="game">
<div id="stats">
<span class="stat">XP: <strong><span id="xpText">0</span></strong></span>
<span class="stat">Health: <strong><span id="healthText">100</span></strong></span>
<span class="stat">Gold: <strong><span id="goldText">50</span></strong></span>
</div>
<div id="controls">
<button id="button1">Go to store</button>
<button id="button2">Go to cave</button>
<button id="button3">Fight dragon</button>
</div>
<div id="monsterStats">
<span class="stat">Monster Name: <strong><span id="monsterName"></span></strong></span>
<span class="stat">Health: <strong><span id="monsterHealth"></span></strong></span>
</div>
<div id="text">
Welcome to Dragon Repeller. You must defeat the dragon that is preventing people from leaving the town. You are in the town square. Where do you want to go? Use the buttons above.
</div>
</div>
</body>
</html>
```
```css
body {
background-color: darkblue;
}
#text {
background-color: black;
color: white;
padding: 10px;
}
#game {
max-width: 500px;
max-height: 400px;
background-color: lightgray;
color: white;
margin: 0 auto;
padding: 10px;
}
#controls, #stats {
border: 1px solid black;
padding: 5px;
color: black;
}
--fcc-editable-region--
#monsterStats {
border: 1px solid black;
padding: 5px;
color: white;
background-color: red;
}
--fcc-editable-region--
```

View File

@@ -0,0 +1,101 @@
---
id: 62a241df03c1f61ce936f5d9
title: 步驟 14
challengeType: 0
dashedName: step-14
---
# --description--
最後,給 `.stat` 元素一個 `10px``padding-right`
# --hints--
應該有一個 `.stat` 選擇器。
```js
const stat = new __helpers.CSSHelp(document).getStyle('.stat');
assert.exists(stat);
```
`.stat` 選擇器應該有一個 `10px``padding-right`
```js
const paddingRight = new __helpers.CSSHelp(document).getStyle('.stat')?.getPropertyValue('padding-right');
assert.equal(paddingRight, '10px');
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="./styles.css">
<title>RPG - Dragon Repeller</title>
</head>
<body>
<div id="game">
<div id="stats">
<span class="stat">XP: <strong><span id="xpText">0</span></strong></span>
<span class="stat">Health: <strong><span id="healthText">100</span></strong></span>
<span class="stat">Gold: <strong><span id="goldText">50</span></strong></span>
</div>
<div id="controls">
<button id="button1">Go to store</button>
<button id="button2">Go to cave</button>
<button id="button3">Fight dragon</button>
</div>
<div id="monsterStats">
<span class="stat">Monster Name: <strong><span id="monsterName"></span></strong></span>
<span class="stat">Health: <strong><span id="monsterHealth"></span></strong></span>
</div>
<div id="text">
Welcome to Dragon Repeller. You must defeat the dragon that is preventing people from leaving the town. You are in the town square. Where do you want to go? Use the buttons above.
</div>
</div>
</body>
</html>
```
```css
body {
background-color: darkblue;
}
#text {
background-color: black;
color: white;
padding: 10px;
}
#game {
max-width: 500px;
max-height: 400px;
background-color: lightgray;
color: white;
margin: 0 auto;
padding: 10px;
}
#controls, #stats {
border: 1px solid black;
padding: 5px;
color: black;
}
#monsterStats {
display: none;
border: 1px solid black;
padding: 5px;
color: white;
background-color: red;
}
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,108 @@
---
id: 62a2509ba163e020bb9d84ea
title: 步驟 15
challengeType: 0
dashedName: step-15
---
# --description--
現在可以開始編寫 JavaScript。 首先創建一個 `script` 元素。 此元素用於將 JavaScript 加載到 HTML 文件中。 應該使用開始 `<script>` 和結束 `</script>` 標記。
# --hints--
應該有一個 `script` 元素。
```js
assert.isAtLeast(document.querySelectorAll('script').length, 2);
```
`script` 元素應該有一個開始標記。
```js
assert.match(code, /<script\s*>/i);
```
`script` 元素應該有一個結束標記。
```js
assert.match(code, /<\/script\s*>/i);
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="./styles.css">
<title>RPG - Dragon Repeller</title>
--fcc-editable-region--
--fcc-editable-region--
</head>
<body>
<div id="game">
<div id="stats">
<span class="stat">XP: <strong><span id="xpText">0</span></strong></span>
<span class="stat">Health: <strong><span id="healthText">100</span></strong></span>
<span class="stat">Gold: <strong><span id="goldText">50</span></strong></span>
</div>
<div id="controls">
<button id="button1">Go to store</button>
<button id="button2">Go to cave</button>
<button id="button3">Fight dragon</button>
</div>
<div id="monsterStats">
<span class="stat">Monster Name: <strong><span id="monsterName"></span></strong></span>
<span class="stat">Health: <strong><span id="monsterHealth"></span></strong></span>
</div>
<div id="text">
Welcome to Dragon Repeller. You must defeat the dragon that is preventing people from leaving the town. You are in the town square. Where do you want to go? Use the buttons above.
</div>
</div>
</body>
</html>
```
```css
body {
background-color: darkblue;
}
#text {
background-color: black;
color: white;
padding: 10px;
}
#game {
max-width: 500px;
max-height: 400px;
background-color: lightgray;
color: white;
margin: 0 auto;
padding: 10px;
}
#controls, #stats {
border: 1px solid black;
padding: 5px;
color: black;
}
#monsterStats {
display: none;
border: 1px solid black;
padding: 5px;
color: white;
background-color: red;
}
.stat {
padding-right: 10px;
}
```

View File

@@ -0,0 +1,108 @@
---
id: 62a255dae245b52317da824a
title: 步驟 16
challengeType: 0
dashedName: step-16
---
# --description--
你的開發者控制檯是最強大的工具之一。 根據你的瀏覽器不同,可能需要通過按 `F12``Ctrl+Shift+I` 來打開它。 也可以點擊預覽窗口上方的“控制檯”按鈕來查看我們的內置控制檯。 開發者控制檯將包含你的代碼產生的錯誤,但你也可以使用它來查看代碼中變量的值,這有助於調試。
`script` 標籤之間添加 `console.log("Hello World");` 行,然後單擊 “Console” 按鈕打開我們的控制檯,你應該會看到文本 `Hello World` 在你的控制檯中。
請注意該行如何以分號結尾。 JavaScript 中的常見做法是用分號結束代碼行。
# --hints--
應該在代碼中添加 `console.log("Hello World");` 行。 不要忘記分號。
```js
assert.match(code, /console\.log\("Hello World"\);/);
```
`console.log("Hello World");` 行應該在 `script` 標記之間。
```js
assert.match(code, /<script>\s*console\.log\("Hello World"\);\s*<\/script>/);
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="./styles.css">
<title>RPG - Dragon Repeller</title>
--fcc-editable-region--
<script>
</script>
--fcc-editable-region--
</head>
<body>
<div id="game">
<div id="stats">
<span class="stat">XP: <strong><span id="xpText">0</span></strong></span>
<span class="stat">Health: <strong><span id="healthText">100</span></strong></span>
<span class="stat">Gold: <strong><span id="goldText">50</span></strong></span>
</div>
<div id="controls">
<button id="button1">Go to store</button>
<button id="button2">Go to cave</button>
<button id="button3">Fight dragon</button>
</div>
<div id="monsterStats">
<span class="stat">Monster Name: <strong><span id="monsterName"></span></strong></span>
<span class="stat">Health: <strong><span id="monsterHealth"></span></strong></span>
</div>
<div id="text">
Welcome to Dragon Repeller. You must defeat the dragon that is preventing people from leaving the town. You are in the town square. Where do you want to go? Use the buttons above.
</div>
</div>
</body>
</html>
```
```css
body {
background-color: darkblue;
}
#text {
background-color: black;
color: white;
padding: 10px;
}
#game {
max-width: 500px;
max-height: 400px;
background-color: lightgray;
color: white;
margin: 0 auto;
padding: 10px;
}
#controls, #stats {
border: 1px solid black;
padding: 5px;
color: black;
}
#monsterStats {
display: none;
border: 1px solid black;
padding: 5px;
color: white;
background-color: red;
}
.stat {
padding-right: 10px;
}
```

View File

@@ -15,7 +15,7 @@ dashedName: practice-comparing-different-values
**示例**
`3 == '3'` 返回 `true` ,因为 JavaScript 执行了从字符串到数字类型的转换。 `3 === '3'` 返回 false因为类型不同且类型转换没有执行
`3 == '3'` 返回 `true` ,因为 JavaScript 执行了从字符串到数字类型的转换。 `3 === '3'` 返回 `false`,因为类型不同,没有进行类型转换
**提示** 在 JavaScript 中,你可以使用 `typeof` 运算符确定变量或值的类型,如下所示:

View File

@@ -11,14 +11,14 @@ dashedName: understand-string-immutability
在 JavaScript 中,字符串(`String`)的值是不可变的(<dfn>immutable</dfn>),这意味着一旦字符串被创建就不能被改变。
例如,下面的代码
例如,以下代码将产生错误,因为字符串 `Bob` 中的字母 `B` 不能更改为字母 `J`
```js
let myStr = "Bob";
myStr[0] = "J";
```
是不会把变量 `myStr` 的值改变成 `Job` 的,因为变量 `myStr` 是不可变的。 注意,这*不*意味着 `myStr` 永远不能被改变,只是字符串字面量 <dfn>string literal</dfn> 的各个字符不能被改变。 改变 `myStr` 的唯一方法是重新给它赋一个值,如:
注意,这*不*意味着无法重新分配 `myStr`。 更改 `myStr` 的唯一方法是为其分配一个值,如下所示
```js
let myStr = "Bob";

View File

@@ -8,7 +8,7 @@ dashedName: mutate-an-array-declared-with-const
# --description--
如果你不熟悉 `const`,请查看[这个挑战](/learn/javascript-algorithms-and-data-structures/basic-javascript/declare-a-read-only-variable-with-the-const-keyword)
如果你不熟悉 `const`,请查看 <a href="/learn/javascript-algorithms-and-data-structures/basic-javascript/declare-a-read-only-variable-with-the-const-keyword" target="_blank" rel="noopener noreferrer nofollow">这个 <code>const</code> 关键词的挑战</a>
`const` 声明在现代 JavaScript 中有很多用例。
@@ -23,7 +23,7 @@ s[2] = 45;
console.log(s);
```
`s = [1, 2, 3]` 将导致错误。 `console.log` 将显示值 `[5, 6, 45]`
`s = [1, 2, 3]` 将导致错误。 注释掉该行后,`console.log` 将显示值 `[5, 6, 45]`
如你所见,你可以改变对象 `[5, 6, 7]` 本身,变量 `s` 仍将指向更改后的数组 `[5, 6, 45]`。 像所有数组一样,`s` 中的数组元素是可变的,但是因为使用了 `const`,所以不能使用变量标识符 `s` 来指向一个使用赋值运算符的不同数组。

View File

@@ -8,9 +8,9 @@ dashedName: build-a-25--5-clock
# --description--
**目标:** 在 [CodePen.io](https://codepen.io) 上实现一个功能类似 <https://codepen.io/freeCodeCamp/full/XpKrrW> 的 App
**目标:** 构建一个应用,功能和 <a href="https://codepen.io/freeCodeCamp/full/XpKrrW" target="_blank" rel="noopener noreferrer nofollow">https://codepen.io/freeCodeCamp/full/XpKrrW</a> 类似
在满足以下 [需求](https://en.wikipedia.org/wiki/User_story) 并能通过所有测试的前提下, 赋予它你自己的个人风格。
完成以下需求,并且通过所有测试。 可以使用你需要的任何库或 API。 赋予它你自己的个人风格。
可以使用 HTML、JavaScript、CSS、Bootstrap、SASS、React、Redux、jQuery 来完成这个挑战。 但鉴于这个章节的学习内容与前端框架相关,推荐使用一款前端框架(比如 React来完成这个挑战不推荐使用前面没有提到的技术否则风险自负。 不推荐使用前面没有提到的技术,否则风险自担。 我们有计划新增其他前端框架课程,例如 Angular 和 Vue不过目前还没有这些内容。 我们会接受并尝试修复你在使用推荐技术栈创建项目时报告的问题。 编码愉快!
@@ -70,7 +70,7 @@ dashedName: build-a-25--5-clock
**需求 28** 当点击 id 属性为 `reset` 的元素时id 属性为 `beep` 的音频元素必须停止播放并回到开头。
你可以<a href='https://codepen.io/pen?template=MJjpwO' target='_blank' rel='nofollow'>使用这个 CodePen 模</a>,点击 `Save` 即可创建你自己的项目。 或者你可以在任何你喜欢的环境中使用以下 CDN 链接来运行测试:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
你可以<a href='https://codepen.io/pen?template=MJjpwO' target='_blank' rel="noopener noreferrer nofollow">使用 CodePen 模</a>创建你的新项目,点击 `Save` 即可创建你的项目。 或者你可以在任何你喜欢的环境中使用以下 CDN 链接来运行测试:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
当你完成了本项目,并且该项目所有测试运行通过, 请提交项目的 URL。

View File

@@ -8,9 +8,9 @@ dashedName: build-a-drum-machine
# --description--
**目标:** 在 [CodePen.io](https://codepen.io) 上实现一个功能类似 <https://codepen.io/freeCodeCamp/full/MJyNMd> 的 App
**目标:** 构建一个应用,功能和 <a href="https://codepen.io/freeCodeCamp/full/MJyNMd" target="_blank" rel="noopener noreferrer nofollow">https://codepen.io/freeCodeCamp/full/MJyNMd</a> 类似
在满足以下 [需求](https://en.wikipedia.org/wiki/User_story) 并能通过所有测试的前提下, 赋予它你自己的个人风格。
完成以下需求,并且通过所有测试。 可以使用你需要的任何库或 API。 赋予它你自己的个人风格。
可以使用 HTML、JavaScript、CSS、Bootstrap、SASS、React、Redux、jQuery 来完成这个挑战。 但鉴于这个章节的学习内容与前端框架相关,推荐使用一款前端框架(比如 React来完成这个挑战。 不推荐使用前面没有提到的技术,否则风险自担。 我们有计划新增其他前端框架课程,例如 Angular 和 Vue不过目前还没有这些内容。 我们会接受并尝试修复你在使用推荐技术栈创建项目时报告的问题。 编码愉快!
@@ -28,9 +28,21 @@ dashedName: build-a-drum-machine
**需求 7** 当触发一个具有 `.drum-pad` 属性的元素时,`#display` 元素内应该展示这个触发元素关联音频片段的描述字符串(每一个字符串都应该是独一无二的)。
你可以<a href='https://codepen.io/pen?template=MJjpwO' target='_blank' rel='nofollow'>使用这个 CodePen 模板</a>,点击 `Save` 即可创建你自己的项目。 或者可以在任何喜欢的环境中使用以下 CDN 链接来运行测试:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
以下是一些可用于鼓机的音频样本:
当你完成了本项目,并且该项目所有测试运行通过,请提交项目的 URL。
- [Heater 1](https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3)
- [Heater 2](https://s3.amazonaws.com/freecodecamp/drums/Heater-2.mp3)
- [Heater 3](https://s3.amazonaws.com/freecodecamp/drums/Heater-3.mp3)
- [Heater 4](https://s3.amazonaws.com/freecodecamp/drums/Heater-4_1.mp3)
- [Clap](https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3)
- [Open-HH](https://s3.amazonaws.com/freecodecamp/drums/Dsc_Oh.mp3)
- [Kick-n'-Hat](https://s3.amazonaws.com/freecodecamp/drums/Kick_n_Hat.mp3)
- [Kick](https://s3.amazonaws.com/freecodecamp/drums/RP4_KICK_1.mp3)
- [Closed-HH](https://s3.amazonaws.com/freecodecamp/drums/Cev_H2.mp3)
你可以<a href='https://codepen.io/pen?template=MJjpwO' target='_blank' rel="noopener noreferrer nofollow">使用 CodePen 模版</a>创建你的新项目,点击 `Save` 即可创建你的新项目。 或者你可以在任何你喜欢的环境中使用以下 CDN 链接来运行测试:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
当你完成了本项目,并且项目通过所有测试,请提交项目的 URL。
# --solutions--

View File

@@ -8,9 +8,9 @@ dashedName: build-a-javascript-calculator
# --description--
**目标:** 在 [CodePen.io](https://codepen.io) 上实现一个功能类似 <https://codepen.io/freeCodeCamp/full/wgGVVX> 的 App
**目标:** 构建一个应用,功能和 <a href="https://codepen.io/freeCodeCamp/full/wgGVVX" target="_blank" rel="noopener noreferrer nofollow">https://codepen.io/freeCodeCamp/full/wgGVVX</a> 类似
在满足以下 [需求](https://en.wikipedia.org/wiki/User_story) 并能通过所有测试的前提下, 赋予它你自己的个人风格。
完成以下需求,并且通过所有测试。 可以使用你需要的任何库或 API。 赋予它你自己的个人风格。
可以使用 HTML、JavaScript、CSS、Bootstrap、SASS、React、Redux、jQuery 来完成这个挑战。 但鉴于这个章节的学习内容与前端框架相关,推荐使用一款前端框架(比如 React来完成这个挑战不推荐使用前面没有提到的技术否则风险自负。 不推荐使用前面没有提到的技术,否则风险自担。 我们有计划新增其他前端框架课程,例如 Angular 和 Vue不过目前还没有这些内容。 我们会接受并尝试修复你在使用推荐技术栈创建项目时报告的问题。 编码愉快!
@@ -51,7 +51,7 @@ dashedName: build-a-javascript-calculator
- **立即执行逻辑:** `11.5`
- **公式/表达式逻辑:** `32.5`
你可以<a href='https://codepen.io/pen?template=MJjpwO' target='_blank' rel='nofollow'>使用这个 CodePen 模</a>,点击 `Save` 即可创建你自己的项目。 或者可以在任何喜欢的环境中使用以下 CDN 链接来运行测试:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
你可以<a href='https://codepen.io/pen?template=MJjpwO' target="_blank" rel="noopener noreferrer nofollow">使用 CodePen 模</a>创建你的新项目,点击 `Save` 即可创建你的项目。 或者可以在任何喜欢的环境中使用以下 CDN 链接来运行测试:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
当你完成了本项目,并且该项目所有测试运行通过,请提交项目的 URL。

View File

@@ -8,9 +8,9 @@ dashedName: build-a-markdown-previewer
# --description--
**目标:** 在 [CodePen.io](https://codepen.io) 上实现一个功能类似 <https://codepen.io/freeCodeCamp/full/GrZVVO> 的 App
**目标:** 构建一个应用,功能和 <a href="https://codepen.io/freeCodeCamp/full/GrZVVO" target="_blank" rel="noopener noreferrer nofollow">https://codepen.io/freeCodeCamp/full/GrZVVO</a> 类似
在满足以下 [需求](https://en.wikipedia.org/wiki/User_story) 并能通过所有测试的前提下, 赋予它你自己的个人风格。
完成以下需求,并且通过所有测试。 可以使用你需要的任何库或 API。 赋予它你自己的个人风格。
可以使用 HTML、JavaScript、CSS、Bootstrap、SASS、React、Redux、jQuery 来完成这个挑战。 但鉴于这个章节的学习内容与前端框架相关,推荐使用一款前端框架(比如 React来完成这个挑战不推荐使用前面没有提到的技术否则风险自负。 不推荐使用前面没有提到的技术,否则风险自担。 我们有计划新增其他前端框架课程,例如 Angular 和 Vue不过目前还没有这些内容。 我们会接受并尝试修复你在使用推荐技术栈创建项目时报告的问题。 编码愉快!
@@ -28,7 +28,7 @@ dashedName: build-a-markdown-previewer
**可选需求(你无需通过这项测试):** Markdown 预览器能够解析回车符并且将他们以 `br`(换行)元素的形式渲染出来。
你可以<a href='https://codepen.io/pen?template=MJjpwO' target='_blank' rel='nofollow'>使用这个 CodePen 模</a>,点击 `Save` 即可创建你自己的项目。 或者可以在任何喜欢的环境中使用以下 CDN 链接来运行测试:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
你可以<a href='https://codepen.io/pen?template=MJjpwO' target="_blank" rel="noopener noreferrer nofollow">使用 CodePen 模</a>创建你的新项目,点击 `Save` 即可创建你的项目。 或者可以在任何喜欢的环境中使用以下 CDN 链接来运行测试:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
当你完成了本项目,并且该项目所有测试运行通过,请提交项目的 URL。

View File

@@ -8,9 +8,9 @@ dashedName: build-a-random-quote-machine
# --description--
**目标:** 在 [CodePen.io](https://codepen.io) 上实现一个功能类似 <https://codepen.io/freeCodeCamp/full/qRZeGZ> 的 App
**目标:** 构建一个应用,功能和 <a href="https://codepen.io/freeCodeCamp/full/qRZeGZ" target="_blank" rel="noopener noreferrer nofollow">https://codepen.io/freeCodeCamp/full/qRZeGZ</a> 类似
在满足以下 [需求](https://en.wikipedia.org/wiki/User_story) 并能通过所有测试的前提下, 赋予它你自己的个人风格。
完成以下需求,并且通过所有测试。 可以使用你需要的任何库或 API。 赋予它你自己的个人风格。
可以使用 HTML、JavaScript、CSS、Bootstrap、SASS、React、Redux、jQuery 来完成这个挑战。 但鉴于这个章节的学习内容与前端框架相关,推荐使用一款前端框架(比如 React来完成这个挑战不推荐使用前面没有提到的技术否则风险自负。 不推荐使用前面没有提到的技术,否则风险自担。 我们有计划新增其他前端框架课程,例如 Angular 和 Vue不过目前还没有这些内容。 我们会接受并尝试修复你在使用推荐技术栈创建项目时报告的问题。 编码愉快!
@@ -36,7 +36,7 @@ dashedName: build-a-random-quote-machine
**需求 11** 具有 `#quote-box` 属性的包裹元素应该水平居中。 请在浏览器缩放尺寸为 100% 且页面窗口最大化时运行测试。
你可以<a href='https://codepen.io/pen?template=MJjpwO' target='_blank' rel='nofollow'>使用这个 CodePen 模</a>,点击 `Save` 创建即可你自己的项目 或者可以在任何喜欢的环境中使用以下 CDN 链接来运行测试:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
你可以<a href='https://codepen.io/pen?template=MJjpwO' target="_blank" rel="noopener noreferrer nofollow">使用 CodePen 模</a>创建你的新项目,点击 `Save` 即可创建你的新项目 或者可以在任何喜欢的环境中使用以下 CDN 链接来运行测试:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`
一旦完成了本项目并且该项目所有测试运行通过,请提交项目的 URL。

View File

@@ -22,7 +22,7 @@ jQuery 还有一个类似的函数 `.text()`,可以在不添加标签的前提
给 id 为 `target4` 的按钮的文本添加强调效果。
查看这篇[关于 &lt;em> 的文章](https://www.freecodecamp.org/news/html-elements-explained-what-are-html-tags/#em-element)来了解更多 `<i>``<em>` 的区别和用法
<a href="https://www.freecodecamp.org/news/html-elements-explained-what-are-html-tags/#em-element" target="_blank" rel="noopener noreferrer nofollow">查看我们的专栏文章 &lt;em&gt;</a>来了解 `<i>``<em>` 及其用途之间的差异
注意,`<i>` 标签虽然传统上用来强调文本,但此后常用作图标的标签。 `<em>` 标签作为强调标签现在已被广泛接受。 可以使用任意一种完成这个挑战。

View File

@@ -10,7 +10,7 @@ dashedName: moving-forward-from-here
恭喜! 你完成了 React 和 Redux 的所有课程! 结束之前,还要再提一点。 通常,我们不会在这样的编辑器中编写 React 应用代码。 如果你在自己的计算机上使用 npm 和文件系统,这个挑战可让你一瞥 React 应用的语法之貌。 除了使用 `import` 语句(这些语句引入了各挑战中提供的所有依赖关系),其代码看起来类似。 “管理包(含 npm”这一节更详细地介绍了 npm。
最后,写 React 和 Redux 的代码通常需要一些配置, 且很快会变得复杂起来。 如果你有兴趣在自己的电脑上尝试<a href="https://github.com/facebookincubator/create-react-app" target="_blank" rel="nofollow">Create React App</a> 已配置好并准备就绪。
最后,写 React 和 Redux 的代码通常需要一些配置, 且很快会变得复杂起来。 如果你有兴趣在自己的机器上进行实验<a href="https: www.freecodecamp.org/news/install-react-with-create-react-app/" target="_blank" rel="noopener noreferrer nofollow">Create React App</a> 已配置好并准备就绪。
或者,你可以在 CodePen 中启用 Babel 作为 JavaScript 预处理器,将 React 和 ReactDOM 添加为外部 JavaScript 资源,这样编写应用。

View File

@@ -22,7 +22,7 @@ this.state = {
# --instructions--
代码编辑器有一个组件试图从其 `state`渲染一个 `name` 属性 但是 `state` 还没有定义。 在 `constructor` 中使用 `state` 初始化组件,并将你的名字赋给 `name` 属性。
代码编辑器里,有一个组件尝试渲染 `state``firstName` 属性 但是 `state` 还没有定义。 在 `constructor` 中使用 `state` 初始化这个组件,并将你的名字赋`firstName` 属性。
# --hints--
@@ -55,7 +55,7 @@ assert(
);
```
应使用被设置为字符串的 `name` 属性来初始化 `StatefulComponent` 的 state。
`StatefulComponent` 的 state 应该初始化为被设置成字符串的 `firstName` 属性
```js
assert(
@@ -65,13 +65,13 @@ assert(
);
const initialState = mockedComponent.state();
return (
typeof initialState === 'object' && typeof initialState.name === 'string'
typeof initialState === 'object' && typeof initialState.firstName === 'string'
);
})()
);
```
`StatefulComponent` 中 state 的 `name` 属性应该渲染`h1` 元素
`StatefulComponent` 状态中的属性 `firstName` 应该呈现`h1` 元素
```js
assert(
@@ -80,7 +80,7 @@ assert(
React.createElement(StatefulComponent)
);
const initialState = mockedComponent.state();
return mockedComponent.find('h1').text() === initialState.name;
return mockedComponent.find('h1').text() === initialState.firstName;
})()
);
```
@@ -106,7 +106,7 @@ class StatefulComponent extends React.Component {
render() {
return (
<div>
<h1>{this.state.name}</h1>
<h1>{this.state.firstName}</h1>
</div>
);
}
@@ -120,13 +120,13 @@ class StatefulComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'freeCodeCamp!'
firstName: 'freeCodeCamp!'
}
}
render() {
return (
<div>
<h1>{this.state.name}</h1>
<h1>{this.state.firstName}</h1>
</div>
);
}

View File

@@ -8,7 +8,7 @@ dashedName: introducing-inline-styles
# --description--
还有其他复杂的概念可以为 React 代码增加强大的功能。 但是,你可能会想知道更简单的问题,比如:如何对在 React 中创建的 JSX 元素添加样式。 你可能知道,由于[将 class 应用于 JSX 元素的方式](/learn/front-end-development-libraries/react/define-an-html-class-in-jsx)与 HTML 中的使用并不完全相同。
还有其他复杂的概念可以为 React 代码增加强大的功能。 但是,你可能会想知道更简单的问题,比如:如何对在 React 中创建的 JSX 元素添加样式。 你可能知道,鉴于<a href="/learn/front-end-development-libraries/react/define-an-html-class-in-jsx" target="_blank" rel="noopener noreferrer nofollow">将 class 应用于 JSX 元素的方式</a>,它与使用 HTML 并不完全相同。
如果从样式表导入样式,它就没有太大的不同。 使用 `className` 属性将 class 应用于 JSX 元素,并将样式应用于样式表中的 class。 另一种选择是使用内联样式,这在 ReactJS 开发中非常常见。

View File

@@ -123,7 +123,7 @@ assert.strictEqual(
})();
```
`GameOfChance` 组件第一次挂载到 DOM 上时,每次按钮被点击,都应该返回一个 `h1` 元素,元素中随机渲染 `You Win!` 或者 `You Lose!`
`GameOfChance` 组件第一次挂载到 DOM 上时,每次按钮被点击,都应该返回一个 `h1` 元素,元素中随机渲染 `You Win!` 或者 `You Lose!` 注意:这有时可能会失败。 如果发生这种情况,请再试一次。
```js
(() => {
@@ -265,6 +265,11 @@ class GameOfChance extends React.Component {
# --solutions--
```jsx
// We want this to be deterministic for testing purposes.
const randomSequence = [true, false, false, true, true, false, false, true, true, false];
let index = 0;
const fiftyFifty = () => randomSequence[index++ % randomSequence.length];
class Results extends React.Component {
constructor(props) {
super(props);
@@ -290,11 +295,10 @@ class GameOfChance extends React.Component {
});
}
render() {
const expression = Math.random() >= 0.5;
return (
<div>
<button onClick={this.handleClick}>Play Again</button>
<Results fiftyFifty={expression} />
<Results fiftyFifty={fiftyFifty()} />
<p>{'Turn: ' + this.state.counter}</p>
</div>
);

View File

@@ -16,7 +16,7 @@ this.setState({
});
```
React 要求永远不要直接修改 `state`,而是在 state 发生改变时始终使用 `this.setState()`。 此外应该注意React 可以批量处理多个 state 更新以提高性能。 这意味着通过 `setState` 方法进行的 state 更新可以是异步的。 `setState` 方法有一种替代语法可以解决异步问题, 虽然这很少用到,但是最好还是记住它! 有关详细信息,请参阅[React 文档](https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous)
React 要求永远不要直接修改 `state`,而是在 state 发生改变时始终使用 `this.setState()`。 此外应该注意React 可以批量处理多个 state 更新以提高性能。 这意味着通过 `setState` 方法进行的 state 更新可以是异步的。 `setState` 方法有一种替代语法可以解决异步问题, 虽然这很少用到,但是最好还是记住它! 请查阅我们的 <a href="https://www.freecodecamp.org/news/what-is-state-in-react-explained-with-examples/" target="_blank" rel="noopener noreferrer nofollow">React 文章</a>了解更多详情
# --instructions--

View File

@@ -16,7 +16,7 @@ dashedName: use-array-map-to-dynamically-render-elements
代码编辑器完成了 `MyToDoList` 组件的大部分设置。 如果完成了受控表单挑战,这些代码中的一些应该看起来很熟悉。 你会注意到一个 `textarea` 和一个 `button`,以及一些跟踪它们状态的方法,但是页面当前还没有任何东西被渲染。
`constructor` 中,创建一个 `this.state` 对象并定义两个 state`userInput` 应该初始化为空字符串,`toDoList` 应该初始化为空数组。 接下来,删除 `items` 变量旁边 `render()` 方法中的注释。 取而代之的是,将存储在组件内部 state 中的 `toDoList` 数组一一遍历并相应的动态呈现 `li` 元素中。 尝试在 `textarea` 中输入 `eat, code, sleep, repeat`,然后点击按钮,看看会发生什么。
`constructor` 中,创建一个 `this.state` 对象并定义两个 state`userInput` 应该初始化为空字符串,`toDoList` 应该初始化为空数组。 接下来,`render()` 方法中删除 `items` 变量 `null`。 取而代之的是,将存储在组件内部 state 中的 `toDoList` 数组一一遍历并相应的动态呈现 `li` 元素中。 尝试在 `textarea` 中输入 `eat, code, sleep, repeat`,然后点击按钮,看看会发生什么。
**注意:** 像这样的映射操作创建的所有兄弟子元素都需要提供唯一的 `key` 属性。 别担心,这是下一个挑战的主题。

View File

@@ -16,7 +16,7 @@ React 提供了有用的类型检查特性,以验证组件是否接收了正
MyComponent.propTypes = { handleClick: PropTypes.func.isRequired }
```
在上面的示例中,`PropTypes.func` 部分检查 `handleClick` 是否为函数。 添加 `isRequired`,告诉 React `handleClick` 是该组件的必需属性。 如果没有那个属性,将出现警告。 还要注意 `func` 代表 `function` 。 在 7 种 JavaScript 原语类型中, `function``boolean` (写为 `bool` )是唯一使用异常拼写的两种类型。 除了原始类型,还有其他类型可用。 例如,你可以检查 prop 是否为 React 元素。 请参阅[文档](https://reactjs.org/docs/typechecking-with-proptypes.html#proptypes)以获取所有选项。
在上面的示例中,`PropTypes.func` 部分检查 `handleClick` 是否为函数。 添加 `isRequired`,告诉 React `handleClick` 是该组件的必需属性。 如果没有那个属性,将出现警告。 还要注意 `func` 代表 `function` 。 在 7 种 JavaScript 原语类型中, `function``boolean` (写为 `bool` )是唯一使用异常拼写的两种类型。 除了原始类型,还有其他类型可用。 例如,你可以检查 prop 是否为 React 元素。 请查看<a href="https://reactjs.org/docs/typechecking-with-proptypes.html#proptypes" target="_blank" rel="noopener noreferrer nofollow">文档</a>以获取所有选项。
**注意:**在 React v15.5.0 中, `PropTypes` 可以从 React 中单独引入,例如:`import PropTypes from 'prop-types';`

View File

@@ -10,7 +10,7 @@ dashedName: use-the-lifecycle-method-componentwillmount
React 组件有几种特殊方法,可以在组件生命周期的特定点执行操作。 这些称为生命周期方法或生命周期钩子,允许在特定时间点捕获组件。 这可以在渲染之前、更新之前、接收 props 之前、卸载之前等等。 以下是一些主要生命周期方法的列表: `componentWillMount()` `componentDidMount()` `shouldComponentUpdate()` `componentDidUpdate()` `componentWillUnmount()` 接下来的几节课将讲述这些生命周期方法的一些基本用例。
**注意:** `componentWillMount` 生命周期方法会在版本 16.X 废弃在版本 17 移除。 [(来源)](https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html)
**注意:** `componentWillMount` 生命周期方法会在版本 16.X 废弃在版本 17 移除。 在这篇<a href="https://www.freecodecamp.org/news/how-to-safely-use-reacts-life-cycles-with-fiber-s-async-rendering-fd4469ebbd8f/" target="_blank" rel="noopener noreferrer nofollow">文章</a>中了解更多。
# --instructions--

View File

@@ -20,7 +20,7 @@ Redux `store` 是一个保存和管理应用程序状态的`state` 可以使
声明一个 `store` 变量并把它分配给 `createStore()` 方法,然后把 `reducer` 作为一个参数传入即可。
**注意**: 编辑器中的代码使用 ES6 默认参数语法将 state 的值初始化为 `5` 如果你不熟悉默认参数,可以参考[ES6 全部课程](https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/es6/set-default-parameters-for-your-functions),它里面涵盖了这个内容
**注意**: 编辑器中的代码使用 ES6 默认参数语法将 state 的值初始化为 `5` 如果你不熟悉默认参数,可以参考 <a href="https://chinese.freecodecamp.org/learn/javascript-algorithms-and-data-structures/es6/set-default-parameters-for-your-functions" target="_blank" rel="noopener noreferrer nofollow">课程中的 ES6 部分</a>,其中涵盖了这个主题
# --hints--

View File

@@ -12,7 +12,7 @@ dashedName: access-the-json-data-from-an-api
现在,你将进一步观察返回的数据,以更好地了解 JSON 格式。 回忆一下 JavaScript 中的一些符号:
<blockquote>[ ] -> 方括号表示数组<br>{ } -> 大括号表示对象<br>" " -> 双引号表示字符串 它们还用于表示 JSON 中的键名</blockquote>
<blockquote>[ ] -> 方括号表示数组<br>{ } -> 大括号表示对象<br>" " -> 双引号表示字符串 它们还用于表示 JSON 中的键名</blockquote>
理解 API 返回数据的结构是必需的,它将影响你如何获取你所需的值。

View File

@@ -8,10 +8,10 @@ dashedName: exercise-tracker
# --description--
构建一个 JavaScript 的全栈应用,在功能上与这个应用相似: <https://exercise-tracker.freecodecamp.rocks/>。 在这个项目中,你将使用以下方法之一编写你的代码:
构建一个功能类似于此的全栈 JavaScript 应用:<a href="https://exercise-tracker.freecodecamp.rocks" target="_blank" rel="noopener noreferrer nofollow">https://exercise-tracker.freecodecamp.rocks</a>。 在这个项目中,你将使用以下方法之一编写你的代码:
- 克隆 [GitHub 仓库](https://github.com/freeCodeCamp/boilerplate-project-exercisetracker/) 并在本地完成你的项目。
- 使用[我们的 Replit 初始化项目](https://replit.com/github/freeCodeCamp/boilerplate-project-exercisetracker)来完成你的项目。
- 克隆<a href="https://github.com/freeCodeCamp/boilerplate-project-exercisetracker/" target="_blank" rel="noopener noreferrer nofollow">这个 GitHub 仓库</a>并在本地完成你的项目。
- 使用<a href="https://replit.com/github/freeCodeCamp/boilerplate-project-exercisetracker" target="_blank" rel="noopener noreferrer nofollow">我们在 Replit 上的初始化项目</a>来完成你的项目。
- 使用你选择的网站生成器来完成项目。 需要包含我们 GitHub 仓库的所有文件。
完成本项目后,请将一个正常运行的 demo项目演示托管在可以公开访问的平台。 然后在 `Solution Link` 字段中提交它的 URL。 此外,还可以将项目的源码提交到 `GitHub Link` 中。
@@ -79,7 +79,7 @@ async (getUserInput) => {
const res = await fetch(url + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
body: `username=fcc_test_${Date.now()}`.substring(0, 29)
});
assert.isTrue(res.ok);
if(!res.ok) {
@@ -96,7 +96,7 @@ async (getUserInput) => {
const res = await fetch(url + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
body: `username=fcc_test_${Date.now()}`.substring(0, 29)
});
if (res.ok) {
const { _id, username } = await res.json();
@@ -164,7 +164,7 @@ async (getUserInput) => {
const res = await fetch(url + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
body: `username=fcc_test_${Date.now()}`.substring(0, 29)
});
if (res.ok) {
const { _id, username } = await res.json();
@@ -198,7 +198,7 @@ async (getUserInput) => {
const res = await fetch(url + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
body: `username=fcc_test_${Date.now()}`.substring(0, 29)
});
if (res.ok) {
const { _id, username } = await res.json();
@@ -237,7 +237,7 @@ async (getUserInput) => {
const res = await fetch(url + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
body: `username=fcc_test_${Date.now()}`.substring(0, 29)
});
if (res.ok) {
const { _id, username } = await res.json();
@@ -276,7 +276,7 @@ async (getUserInput) => {
const res = await fetch(url + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
body: `username=fcc_test_${Date.now()}`.substring(0, 29)
});
if (res.ok) {
const { _id, username } = await res.json();
@@ -309,7 +309,7 @@ async (getUserInput) => {
};
```
`/api/users/:id/logs``GET` 请求将返回用户对象,其中包含添加的所有练习的 `log` 数组。
`/api/users/:_id/logs``GET` 请求将返回用户对象,其中包含添加的所有练习的 `log` 数组。
```js
async(getUserInput) => {
@@ -319,7 +319,7 @@ async(getUserInput) => {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
body: `username=fcc_test_${Date.now()}`.substring(0, 29)
})
if(res.ok){
const {_id, username} = await res.json();
@@ -353,7 +353,7 @@ async(getUserInput) => {
};
```
`GET /api/users/:id/logs` 返回的 `log` 数组中的每一项都是一个应该具有 `description` 的对象, `duration``date` 属性。
`GET /api/users/:_id/logs` 返回的 `log` 数组中的每个项目都是一个应该具有 `description``duration``date` 属性的对象
```js
async(getUserInput) => {
@@ -363,7 +363,7 @@ async(getUserInput) => {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
body: `username=fcc_test_${Date.now()}`.substring(0, 29)
});
if(res.ok) {
const {_id, username} = await res.json();
@@ -400,7 +400,7 @@ async(getUserInput) => {
};
```
`GET /api/users/:id/logs` 返回的 `log` 数组中任何对象的 `description` 属性都应该是一个字符串。
`GET /api/users/:_id/logs` 返回的 `log` 数组中任何对象的 `description` 属性都应该是一个字符串。
```js
async(getUserInput) => {
@@ -410,7 +410,7 @@ async(getUserInput) => {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `username=fcc_test_${Date.now()}`.substr(0,29)
body: `username=fcc_test_${Date.now()}`.substring(0,29)
});
if(res.ok) {
const {_id, username} = await res.json();
@@ -447,7 +447,7 @@ async(getUserInput) => {
};
```
`GET /api/users/:id/logs` 返回的 `log` 数组中任何对象的 `duration` 属性应该是一个数字。
`GET /api/users/:_id/logs` 返回的 `log` 数组中任何对象的 `duration` 属性应该是一个数字。
```js
async(getUserInput) => {
@@ -457,7 +457,7 @@ async(getUserInput) => {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `username=fcc_test_${Date.now()}`.substr(0,29)
body: `username=fcc_test_${Date.now()}`.substring(0,29)
});
if(res.ok) {
const {_id, username} = await res.json();
@@ -494,7 +494,7 @@ async(getUserInput) => {
};
```
`GET /api/users/:id/logs` 返回的 `log` 数组中任何对象的 `date` 属性应该是一个字符串。 使用 `Date` API 的 `dateString` 格式。
`GET /api/users/:_id/logs` 返回的 `log` 数组中任何对象的 `date` 属性应该是一个字符串。 使用 `Date` API 的 `dateString` 格式。
```js
async(getUserInput) => {
@@ -504,7 +504,7 @@ async(getUserInput) => {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `username=fcc_test_${Date.now()}`.substr(0,29)
body: `username=fcc_test_${Date.now()}`.substring(0,29)
});
if(res.ok) {
const {_id, username} = await res.json();
@@ -549,7 +549,7 @@ async (getUserInput) => {
const res = await fetch(url + '/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=fcc_test_${Date.now()}`.substr(0, 29)
body: `username=fcc_test_${Date.now()}`.substring(0, 29)
});
if (res.ok) {
const { _id, username } = await res.json();

View File

@@ -8,10 +8,10 @@ dashedName: file-metadata-microservice
# --description--
构建一个 JavaScript 的全栈应用,在功能上与这个应用相似:<https://file-metadata-microservice.freecodecamp.rocks/>。 在这个项目中,你将使用以下方法之一编写你的代码:
构建一个功能类似于此的全栈 JavaScript 应用程序:<a href="https://file-metadata-microservice.freecodecamp.rocks" target="_blank" rel="noopener noreferrer nofollow">https://file-metadata-microservice.freecodecamp.rocks</a>。 在这个项目中,你将使用以下方法之一编写你的代码:
- 克隆 [this GitHub repo](https://github.com/freeCodeCamp/boilerplate-project-filemetadata/) 并在本地完成项目。
- 使用[我们的 Replit 初始化项目](https://replit.com/github/freeCodeCamp/boilerplate-project-filemetadata)来完成你的项目。
- 克隆<a href="https://github.com/freeCodeCamp/boilerplate-project-filemetadata/" target="_blank" rel="noopener noreferrer nofollow">这个 GitHub 仓库</a>并在本地完成你的项目。
- 使用<a href="https://replit.com/github/freeCodeCamp/boilerplate-project-filemetadata" target="_blank" rel="noopener noreferrer nofollow">我们在 Replit 上的初始化项目</a>来完成你的项目。
- 使用你选择的网站生成器来完成项目。 需要包含我们 GitHub 仓库的所有文件。
完成本项目后,请将一个正常运行的 demo项目演示托管在可以公开访问的平台。 然后在 `Solution Link` 字段中提交它的 URL。 此外,还可以将项目的源码提交到 `GitHub Link` 中。

View File

@@ -8,10 +8,10 @@ dashedName: request-header-parser-microservice
# --description--
构建一个 JavaScript 的全栈应用,在功能上与这个应用相似:<https://request-header-parser-microservice.freecodecamp.rocks/>。 在这个项目中,你将使用以下方法之一编写你的代码:
构建一个 JavaScript 的全栈应用,在功能上与这个应用相似:<a href="https://request-header-parser-microservice.freecodecamp.rocks/" target="_blank" rel="noopener noreferrer nofollow">https://request-header-parser-microservice.freecodecamp.rocks/</a>。 在这个项目中,你将使用以下方法之一编写你的代码:
- 克隆 [this GitHub repo](https://github.com/freeCodeCamp/boilerplate-project-headerparser/) 并在本地完成项目。
- 使用[我们的 Replit 初始化项目](https://replit.com/github/freeCodeCamp/boilerplate-project-headerparser)来完成你的项目。
- 克隆<a href="https://github.com/freeCodeCamp/boilerplate-project-headerparser/" target="_blank" rel="noopener noreferrer nofollow">这个 GitHub 仓库</a>并在本地完成你的项目。
- 使用<a href="https://replit.com/github/freeCodeCamp/boilerplate-project-headerparser" target="_blank" rel="noopener noreferrer nofollow">我们在 Replit 上的初始化项目</a>来完成你的项目。
- 使用你选择的网站生成器来完成项目。 需要包含我们 GitHub 仓库的所有文件。
完成本项目后,请将一个正常运行的 demo项目演示托管在可以公开访问的平台。 然后在 `Solution Link` 字段中提交它的 URL。 此外,还可以将项目的源码提交到 `GitHub Link` 中。

View File

@@ -8,10 +8,10 @@ dashedName: timestamp-microservice
# --description--
构建一个 JavaScript 的全栈应用,在功能上与这个应用相似:<https://timestamp-microservice.freecodecamp.rocks/>。 在这个项目中,你将使用以下方法之一编写你的代码:
构建一个功能类似于此的全栈 JavaScript 应用程序:<a href="https://timestamp-microservice.freecodecamp.rocks" target="_blank" rel="noopener noreferrer nofollow">https://timestamp-microservice.freecodecamp.rocks</a>。 在这个项目中,你将使用以下方法之一编写你的代码:
- 克隆 [这个 GitHub 仓库](https://github.com/freeCodeCamp/boilerplate-project-timestamp/) 并在本地完成项目。
- 使用[我们的 Replit 初始化项目](https://replit.com/github/freeCodeCamp/boilerplate-project-timestamp)来完成你的项目。
- 克隆<a href="https://github.com/freeCodeCamp/boilerplate-project-timestamp/" target="_blank" rel="noopener noreferrer nofollow">这个 GitHub 仓库</a>并在本地完成你的项目。
- 使用<a href="https://replit.com/github/freeCodeCamp/boilerplate-project-timestamp" target="_blank" rel="noopener noreferrer nofollow">我们在 Replit 上的初始化项目</a>来完成你的项目。
- 使用你选择的网站生成器来完成项目。 需要包含我们 GitHub 仓库的所有文件。
完成本项目后,请将一个正常运行的 demo项目演示托管在可以公开访问的平台。 然后在 `Solution Link` 字段中提交它的 URL。 此外,还可以将项目的源码提交到 `GitHub Link` 中。

View File

@@ -8,10 +8,10 @@ dashedName: url-shortener-microservice
# --description--
构建一个 JavaScript 的全栈应用,在功能上与这个应用相似:<https://url-shortener-microservice.freecodecamp.rocks/>。 在这个项目中,你将使用以下方法之一编写你的代码:
构建一个功能类似于此的全栈 JavaScript 应用程序:<a href="https://url-shortener-microservice.freecodecamp.rocks" target="_blank" rel="noopener noreferrer nofollow">https://url-shortener-microservice.freecodecamp.rocks</a>。 在这个项目中,你将使用以下方法之一编写你的代码:
- 克隆 [this GitHub repo](https://github.com/freeCodeCamp/boilerplate-project-filemetadata/) 并在本地完成项目。
- 使用[我们的 Replit 初始化项目](https://replit.com/github/freeCodeCamp/boilerplate-project-urlshortener)来完成你的项目。
- 克隆<a href="https://github.com/freeCodeCamp/boilerplate-project-urlshortener/" target="_blank" rel="noopener noreferrer nofollow">这个 GitHub 仓库</a>并在本地完成你的项目。
- 使用<a href="https://replit.com/github/freeCodeCamp/boilerplate-project-urlshortener" target="_blank" rel="noopener noreferrer nofollow">我们在 Replit 上的初始化项目</a>来完成你的项目。
- 使用你选择的网站生成器来完成项目。 需要包含我们 GitHub 仓库的所有文件。
完成本项目后,请将一个正常运行的 demo项目演示托管在可以公开访问的平台。 然后在 `Solution Link` 字段中提交它的 URL。 此外,还可以将项目的源码提交到 `GitHub Link` 中。

View File

@@ -8,7 +8,7 @@ dashedName: chain-middleware-to-create-a-time-server
# --description--
使用 `app.METHOD(path, middlewareFunction)` 可以在指定的路由挂载中间件, 也可以在路由定义中链式调用中间件
使用 `app.METHOD(path, middlewareFunction)` 可以在指定的路由挂载中间件, 中间件也可以链接在路由定义中。
请看以下示例:
@@ -49,7 +49,7 @@ app.get('/user', function(req, res, next) {
);
```
/now 接口应该返回一个现在时间 +/-20 秒的时间
`/now` 端点应该返回当前时间
```js
(getUserInput) =>

View File

@@ -10,8 +10,8 @@ dashedName: meet-the-node-console
你可以采用下面的任意一种编写代码的方式来完成这些挑战:
- 克隆 [这个 GitHub 仓库](https://github.com/freeCodeCamp/boilerplate-express/) 并在本地完成项目
- 使用[我们的 Repl.it 上的初始化项目](https://replit.com/github/freeCodeCamp/boilerplate-express)来完成项目
- 克隆<a href="https://github.com/freeCodeCamp/boilerplate-express/" target="_blank" rel="noopener noreferrer nofollow">这个 GitHub 仓库</a>并在本地完成这些挑战
- 使用<a href="https://replit.com/github/freeCodeCamp/boilerplate-express" target="_blank" rel="noopener noreferrer nofollow">我们在 Replit 上的初始化项目</a>来完成这些挑战
- 使用你选择的网站生成器来完成项目。 需要包含我们 GitHub 仓库的所有文件。
完成本项目后,请将一个正常运行的 demo项目演示托管在可以公开访问的平台。 然后在 `Solution Link` 字段中提交它的 URL。

View File

@@ -22,11 +22,11 @@ Content-Length: 20
name=John+Doe&age=25
```
正如你所看到的,正文被编码成类似查询字符串的形式, 这是 HTML 表单使用的默认格式。 我们还可以通过 Ajax 使用 JSON 来处理具有更复杂结构的数据。 还有另一种类型的编码multipart/form-data 它被用来上传二进制文件。 在本练习中,我们将使用 URL 编码请求正文。 要解析来自 POST 请求的数据,你必须安装 `body-parser` 这个包包含一套可以解码不同格式数据的中间件。
正如你所看到的,正文被编码成类似查询字符串的形式, 这是 HTML 表单使用的默认格式。 我们还可以通过 Ajax 使用 JSON 来处理具有更复杂结构的数据。 还有另一种类型的编码multipart/form-data 它被用来上传二进制文件。 在本练习中,将使用 URL 编码正文。 要解析来自 POST 请求的数据,你必须使用 `body-parser` 这个包包含一套可以解码不同格式数据的中间件。
# --instructions--
`package.json` 中安装 `body-parser` 模块, 然后在文件顶部 `require` 进来, 用变量 `bodyParser` 保存它。 通过中间件`bodyParser.urlencoded({extended: false})` 方法处理 URL 编码数据 将通过先前的方法调用返回的函数传递 `app.use()`中间件通常挂载在所有需要它的路由之前。
`body-parser` 已经安装并且在你项目的 `package.json` 文件中。 在 `myApp.js` 文件顶部包含(`require`)它,并将其存储在名为 `bodyParser`变量中。 `bodyParser.urlencoded({extended: false})` 返回处理 URL 编码数据的中间件。 将上一个方法调用返回的函数传递 `app.use()`像往常一样,中间件必须在所有依赖它的路由之前安装
**注意:** `extended` 是一个配置选项, 告诉 `body-parser` 需要使用哪个解析。 当 `extended=false` 时,它使用经典编码 `querystring` 库。 当 `extended=true`时,它使用 `qs` 库进行解析。

View File

@@ -18,11 +18,11 @@ dashedName: use-the--env-file
在项目根目录创建一个 `.env` 文件,并存储变量 `MESSAGE_STYLE=uppercase`
当向 `/json` GET 请求时,如果 `process.env.MESSAGE_STYLE` 的值为 `uppercase`那么上一次挑战中的路由处理程序返回的对象的消息则应该大写。 响应对象应该是 `{"message": "Hello json"}` or `{"message": "HELLO JSON"}`,取决于 `MESSAGE_STYLE` 的值。
然后,在你在上个挑战中创建的 `/json` GET 路由处理程序中访问 `process.env.MESSAGE_STYLE`,并且如果变量等于 `uppercase`将响应对象的 `message` 转换为大写。 响应对象应该是 `{"message": "Hello json"}` or `{"message": "HELLO JSON"}`,取决于 `MESSAGE_STYLE` 的值。
**注意:** 如果你正在使用 Replit你无法创建一个 `.env` 文件。 相反,使用内置的 <dfn>SECRETS</dfn> 标签添加变量。
如果你在本地工作,你将需要 `dotenv` 包。 它将环境变量从你的 `.env` 文件加载到 `process.env` 中。 使用 `npm install dotenv` 安装它。 然后,`myApp.js` 文件的顶部,使用 `require('dotenv').config()` 导入加载变量。
如果你在本地工作,你将需要 `dotenv` 包。 它将环境变量从你的 `.env` 文件加载到 `process.env` 中。 `dotenv` 包已经安装,并且在你项目的 `package.json` 文件中。 `myApp.js` 文件的顶部,使用 `require('dotenv').config()` 导入加载变量。
# --hints--

View File

@@ -22,13 +22,13 @@ dashedName: expand-your-project-with-external-packages-from-npm
# --instructions--
package.json 文件的 `dependencies` 字段中添加一个版本号为“2.14.0”的“moment”包
`@freecodecamp/example` 包的版本 “1.1.0” 添加到 `package.json` 文件的 `dependencies` 字段。
**注意:** Moment 是一个非常方便地用来处理时间和日期的库
**注意:** `@freecodecamp/example` 是一个用作学习工具的仿包
# --hints--
dependencies”字段应该包含“moment”
`"dependencies"` 应包括 `"@freecodecamp/example"`
```js
(getUserInput) =>
@@ -37,8 +37,8 @@ dashedName: expand-your-project-with-external-packages-from-npm
var packJson = JSON.parse(data);
assert.property(
packJson.dependencies,
'moment',
'"dependencies" does not include "moment"'
'@freecodecamp/example',
'"dependencies" does not include "@freecodecamp/example"'
);
},
(xhr) => {
@@ -47,7 +47,7 @@ dashedName: expand-your-project-with-external-packages-from-npm
);
```
“moment”的版本应该是“2.14.0
`"@freecodecamp/example"` 版本应为 `"1.1.0"`
```js
(getUserInput) =>
@@ -55,9 +55,9 @@ dashedName: expand-your-project-with-external-packages-from-npm
(data) => {
var packJson = JSON.parse(data);
assert.match(
packJson.dependencies.moment,
/^[\^\~]?2\.14\.0/,
'Wrong version of "moment" installed. It should be 2.14.0'
packJson.dependencies["@freecodecamp/example"],
/^[\^\~]?1\.1\.0/,
'Wrong version of "@freecodecamp/example" installed. It should be 1.1.0'
);
},
(xhr) => {

View File

@@ -10,11 +10,11 @@ dashedName: how-to-use-package-json-the-core-of-any-node-js-project-or-npm-packa
你可以采用下面的任意一种编写代码的方式来完成这些挑战:
- 克隆 [GitHub repo](https://github.com/freeCodeCamp/boilerplate-npm/) 并在本地完成项目
- 使用[我们的 Replit 上的初始化项目](https://replit.com/github/freeCodeCamp/boilerplate-npm)来完成项目
- 克隆<a href="https://github.com/freeCodeCamp/boilerplate-npm/" target="_blank" rel="noopener noreferrer nofollow">这个 GitHub 仓库</a>并在本地完成这些挑战
- 使用<a href="https://replit.com/github/freeCodeCamp/boilerplate-npm" target="_blank" rel="noopener noreferrer nofollow">我们在 Replit 上的初始化项目</a>来完成这些挑战
- 使用你选择的网站生成器来完成项目。 需要包含我们 GitHub 仓库的所有文件。
完成本项目后,请将一个正常运行的 demo项目演示托管在可以公开访问的平台。 然后在 `Solution Link` 字段中提交它的 URL。 此外,还可以将项目的源码提交到 `GitHub Link` 中。
完成本项目后,请将一个正常运行的 demo项目演示托管在可以公开访问的平台。 然后在 `Solution Link` 字段中提交它的 URL。
`package.json` 文件是所有 Node.js 项目和 npm 包的枢纽, 和 HTML 文档中的 &lt;head> 区域用来描述网页的配置信息(元数据)一样,它存储项目的相关信息。 它由单个 JSON 对象组成,并以键值对的形式存储项目信息, 且至少包含两个必填字段“name”和“version”——但是最好提供有关项目的其他信息这将对用户或者维护者有所帮助。

View File

@@ -20,11 +20,11 @@ dashedName: manage-npm-dependencies-by-understanding-semantic-versioning
# --instructions--
在 package.json 文件的依赖项中,修改 moment 的`version`,让它的主版本是 2次版本号是 10修订号是 2。
`package.json` 文件的依赖项部分,更改 `@freecodecamp/example` 的版本以匹配 MAJOR 版本为 1、MINOR 版本为 2 和 PATCH 版本为 13
# --hints--
dependencies”字段应该包含“moment”
`"dependencies"` 应包括 `"@freecodecamp/example"`
```js
(getUserInput) =>
@@ -33,8 +33,8 @@ dashedName: manage-npm-dependencies-by-understanding-semantic-versioning
var packJson = JSON.parse(data);
assert.property(
packJson.dependencies,
'moment',
'"dependencies" does not include "moment"'
'@freecodecamp/example',
'"dependencies" does not include "@freecodecamp/example"'
);
},
(xhr) => {
@@ -43,7 +43,7 @@ dashedName: manage-npm-dependencies-by-understanding-semantic-versioning
);
```
“moment”的版本号应该是“2.10.2”
`"@freecodecamp/example"` 版本应为 `"1.2.13"`
```js
(getUserInput) =>
@@ -51,9 +51,9 @@ dashedName: manage-npm-dependencies-by-understanding-semantic-versioning
(data) => {
var packJson = JSON.parse(data);
assert.equal(
packJson.dependencies.moment,
'2.10.2',
'Wrong version of "moment". It should be 2.10.2'
packJson.dependencies["@freecodecamp/example"],
'1.2.13',
'Wrong version of "@freecodecamp/example". It should be 1.2.13'
);
},
(xhr) => {

View File

@@ -12,17 +12,17 @@ dashedName: remove-a-package-from-your-dependencies
但是,如果想要删除不再需要的依赖包,该怎么办呢? 可能已经猜到了——只需要从依赖项中删除相应的键值对就行了。
同样的方法也适用于删除 package.json 中的其字段。
同样的方法也适用于删除 package.json 中的其字段。
# --instructions--
从依赖项中删除 moment 依赖包。
从依赖项中删除 `@freecodecamp/example` 包。
**注意:**删除依赖包后,确保逗号数量正确。
# --hints--
dependencies”字段不包含“moment”
`"dependencies"` 不应包含 `"@freecodecamp/example"`
```js
(getUserInput) =>
@@ -31,8 +31,8 @@ dashedName: remove-a-package-from-your-dependencies
var packJson = JSON.parse(data);
assert.notProperty(
packJson.dependencies,
'moment',
'"dependencies" still includes "moment"'
'@freecodecamp/example',
'"dependencies" still includes "@freecodecamp/example"'
);
},
(xhr) => {

View File

@@ -10,7 +10,7 @@ dashedName: use-the-caret-character-to-use-the-latest-minor-version-of-a-depende
和上一个挑战中我们学到的用波浪号来安装最新的修订版依赖一样,脱字符(`^`)也允许 npm 来安装功能更新。 它们的不同之处在于:脱字符允许次版本和修订版更新。
现在项目中的 moment 依赖包的版本应该是“~2.10.2”,这意味着 npm 可以安装最新的 2.10.x 版的 moment 如果使用脱字符(^)来替换版本号的前缀,那么 npm 可以将 moment 升级安装到任何 2.x.x 版本。
你当前的 `@freecodecamp/example` 版本应该是“~1.2.13”,它允许 npm 安装最新的 1.2.x 版本。 如果使用插入符号(^作为版本前缀npm 将被允许更新到任何 1.x.x 版本。
```json
"package": "^1.3.8"
@@ -20,13 +20,13 @@ dashedName: use-the-caret-character-to-use-the-latest-minor-version-of-a-depende
# --instructions--
在依赖项中,使用脱字符(`^`)为 moment 的版本添加前缀,允许 npm 更新依赖包到任新的版本。
使用插入符号(`^`)为依赖项中的 `@freecodecamp/example` 版本添加前缀,允许 npm 将其更新到任新的 MINOR 版本。
**注意:** 原来的版本号不用更改。
# --hints--
dependencies”字段中应包含“moment”
`"dependencies"` 应包括 `"@freecodecamp/example"`
```js
(getUserInput) =>
@@ -35,8 +35,8 @@ dashedName: use-the-caret-character-to-use-the-latest-minor-version-of-a-depende
var packJson = JSON.parse(data);
assert.property(
packJson.dependencies,
'moment',
'"dependencies" does not include "moment"'
'@freecodecamp/example',
'"dependencies" does not include "@freecodecamp/example"'
);
},
(xhr) => {
@@ -45,7 +45,7 @@ dashedName: use-the-caret-character-to-use-the-latest-minor-version-of-a-depende
);
```
“moment”的版本应是“^2.x.x”
`"@freecodecamp/example"` 版本应匹配 `"^1.x.x"`
```js
(getUserInput) =>
@@ -53,9 +53,9 @@ dashedName: use-the-caret-character-to-use-the-latest-minor-version-of-a-depende
(data) => {
var packJson = JSON.parse(data);
assert.match(
packJson.dependencies.moment,
/^\^2\./,
'Wrong version of "moment". It should be ^2.10.2'
packJson.dependencies["@freecodecamp/example"],
/^\^1\./,
'Wrong version of "@freecodecamp/example". It should be ^1.2.13'
);
},
(xhr) => {

View File

@@ -18,15 +18,15 @@ dashedName: use-the-tilde-character-to-always-use-the-latest-patch-version-of-a-
# --instructions--
在 package.json 文件中,当前规则是 npm 将 moment 升级到特定版本2.10.2)。 但现在,要允许使用最新的 2.10.x 版本。
在 package.json 文件中,当前关于 npm 如何升级 `@freecodecamp/example` 的规则是使用特定版本(1.2.13)。 但现在,你想允许最新的 1.2.x 版本。
在依赖项中,给 moment 的版本号添加波浪号(`~`前缀,允许 npm 将其更新为最新的修订版
在依赖项中使用波浪号(`~`)字符作为 `@freecodecamp/example` 版本的前缀,允许 npm 将其更新为任何新的*补丁*发布
**注意:**原来的版本号不用更改。
# --hints--
dependencies”字段中应包含“moment”
`"dependencies"` 应包括 `"@freecodecamp/example"`
```js
(getUserInput) =>
@@ -35,8 +35,8 @@ dashedName: use-the-tilde-character-to-always-use-the-latest-patch-version-of-a-
var packJson = JSON.parse(data);
assert.property(
packJson.dependencies,
'moment',
'"dependencies" does not include "moment"'
'@freecodecamp/example',
'"dependencies" does not include "@freecodecamp/example"'
);
},
(xhr) => {
@@ -45,7 +45,7 @@ dashedName: use-the-tilde-character-to-always-use-the-latest-patch-version-of-a-
);
```
“moment”的版本号应该是“~2.10.2”
`"@freecodecamp/example"` 版本应匹配 `"~1.2.13"`
```js
(getUserInput) =>
@@ -53,9 +53,9 @@ dashedName: use-the-tilde-character-to-always-use-the-latest-patch-version-of-a-
(data) => {
var packJson = JSON.parse(data);
assert.match(
packJson.dependencies.moment,
/^\~2\.10\.2/,
'Wrong version of "moment". It should be ~2.10.2'
packJson.dependencies["@freecodecamp/example"],
/^\~1\.2\.13/,
'Wrong version of "@freecodecamp/example". It should be ~1.2.13'
);
},
(xhr) => {

View File

@@ -10,19 +10,23 @@ dashedName: install-and-set-up-mongoose
你可以采用下面的任意一种编写代码的方式来完成这些挑战:
- 克隆 [这个 GitHub 仓库](https://github.com/freeCodeCamp/boilerplate-mongomongoose/) 并在本地完成项目
- 使用[我们的 Replit 上的初始化项目](https://replit.com/github/freeCodeCamp/boilerplate-mongomongoose)来完成项目
- 克隆<a href="https://github.com/freeCodeCamp/boilerplate-mongomongoose/" target="_blank" rel="noopener noreferrer nofollow">这个 GitHub 仓库</a>并在本地完成这些挑战
- 使用<a href="https://replit.com/github/freeCodeCamp/boilerplate-mongomongoose" target="_blank" rel="noopener noreferrer nofollow">我们在 Replit 上的初始化项目</a>来完成这些挑战
- 使用你选择的网站生成器来完成项目。 需要包含我们 GitHub 仓库的所有文件。
完成本项目后,请将一个正常运行的 demo项目演示托管在可以公开访问的平台。 然后在 `Solution Link` 字段中提交它的 URL。
在这个挑战中,你将建立一个 MongoDB Atlas 数据库并导入连接到它所需的软件包。
按照<a href='https://www.freecodecamp.org/news/get-started-with-mongodb-atlas/' rel='noopener noreferrer' target='_blank'>这篇教程</a>在 MongoDB Atlas 创建一个托管数据库。
按照<a href='https://chinese.freecodecamp.org/news/get-started-with-mongodb-atlas/' target="_blank" rel="noopener noreferrer nofollow">这篇教程</a>在 MongoDB Atlas 创建一个托管数据库。
# --instructions--
`mongodb@~3.6.0``mongoose@~5.4.0` 添加到项目的 `package.json` 中。 然后,在 `myApp.js` 文件中请求 `mongoose`。 创建一个 `.env` 文件,给它添加一个 `MONGO_URI` 变量。 变量的值为你的 MongoDB Atlas 数据库 URI。 应用单引号或双引号包裹 URI。请记住环境变量 `=` 两边不能有空格。 例如,`MONGO_URI='VALUE'` 完成后,使用下面的代码来连接数据库。
`mongoose@^5.11.15` 添加到项目的 `package.json` 文件中。 首先,在 `myApp.js` 中请求 mongoose 为 `mongoose`接下来,创建一个 `.env` 文件并向其中添加一个 `MONGO_URI` 变量。 变量的值为你的 MongoDB Atlas 数据库 URI。 应用单引号或双引号包裹 URI。请记住环境变量 `=` 两边不能有空格。 例如,`MONGO_URI='VALUE'`
**注意:** 如果你使用的是 Replit则无法创建 `.env` 文件。 相反,使用内置的 <dfn>SECRETS</dfn> 选项卡来添加变量。 在使用 <em>SECRETS</em> 选项卡时,<em>不要</em>将值括在引号中。
完成后,使用以下语法连接到数据库:
```js
mongoose.connect(<Your URI>, { useNewUrlParser: true, useUnifiedTopology: true });
@@ -30,22 +34,7 @@ mongoose.connect(<Your URI>, { useNewUrlParser: true, useUnifiedTopology: true }
# --hints--
“mongodb” 应在 package.json 中作为依赖项定义。
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/file/package.json').then(
(data) => {
var packJson = JSON.parse(data);
assert.property(packJson.dependencies, 'mongodb');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
“mongoose” 应在 package.json 中作为依赖项定义。
“mongoose version ^5.11.15” 依赖项应该在 package.json
```js
(getUserInput) =>
@@ -53,6 +42,11 @@ mongoose.connect(<Your URI>, { useNewUrlParser: true, useUnifiedTopology: true }
(data) => {
var packJson = JSON.parse(data);
assert.property(packJson.dependencies, 'mongoose');
assert.match(
packJson.dependencies.mongoose,
/^\^5\.11\.15/,
'Wrong version of "mongoose". It should be ^5.11.15'
);
},
(xhr) => {
throw new Error(xhr.responseText);

View File

@@ -14,7 +14,7 @@ dashedName: perform-classic-updates-by-running-find-edit-then-save
在这个挑战中,请使用参数 `personId` 作为字段,修改 `findEditThenSave` 方法,以在数据库中通过 `_id` 找到相应的 person你可以使用之前挑战中的任何一种方法。 将 `"hamburger"` 添加到它的 `favoriteFoods` 清单中(你可以使用 `Array.push()`)。 然后,在查询数据库的方法的回调里通过 `save()` 方法更新 `Person` 的数据。
**提示:** 如果你在 Schema 中将 `favoriteFoods` 声明为一个 Array数组并且没有指定数组的类型(如 `[String]`) 那么此时,`favoriteFoods` 就会是默认的 Mixed 类型。如果想编辑它,就必须执行 `document.markModified('edited-field')`详情请参阅 [Mongoose 文档](https://mongoosejs.com/docs/schematypes.html#Mixed)
**提示:** 如果你在 Schema 中将 `favoriteFoods` 声明为一个 Array数组并且没有指定数组的类型(如 `[String]`) 那么此时,`favoriteFoods` 就会是默认的 Mixed 类型。如果想编辑它,就必须执行 `document.markModified('edited-field')`查看我们的 <a href="https://www.freecodecamp.org/news/introduction-to-mongoose-for-mongodb-d2a7aa593c57/" target="_blank" rel="noopener noreferrer nofollow">Mongoose 文章</a>。
# --hints--

View File

@@ -34,7 +34,7 @@ socket.on('user', data => {
});
```
完成上述要求后,你可以在下方提交你的页面链接。 如果你遇到了问题,可以参考 [这里](https://gist.github.com/camperbot/bf95a0f74b756cf0771cd62c087b8286) 的答案
完成上述要求后,你可以在下方提交你的页面链接。 如果你在运行时遇到错误,可以点击此处查看 <a href="https://gist.github.com/camperbot/bf95a0f74b756cf0771cd62c087b8286" target="_blank" rel="noopener noreferrer nofollow">已执行项目的当前进度</a>
# --hints--

View File

@@ -8,7 +8,7 @@ dashedName: test-if-a-value-is-an-array
# --description--
请注意,本项目在[这个 Replit 项目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基础上进行开发你也可以从 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
请注意,本项目是在 <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a> 上的初始化项目的基础上进行开发你也可以从 <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a> 上克隆。
# --instructions--

View File

@@ -0,0 +1,88 @@
---
id: 56533eb9ac21ba0edf2244e2
title: 构建一个凯撒密码
challengeType: 5
forumTopicId: 16003
dashedName: build-a-caesars-cipher
---
# --description--
凯撒密码( <dfn>Caesar cipher</dfn>)是最简单且最广为人知的密码(<dfn>ciphers</dfn>),也被称为移位密码(<dfn>shift cipher</dfn>)。 在移位密码中,明文中的字母通过按照一个固定数目进行偏移后被替换成新的字母。
现代最常被应用到的一个变种就是 <a href="https://www.freecodecamp.org/news/how-to-code-the-caesar-cipher-an-introduction-to-basic-encryption-3bf77b4e19f7/" target="_blank" rel="noopener noreferrer nofollow">ROT13</a> 加密,也就是明文中的字母向后移 13 位。 也就是, `A ↔ N``B ↔ O` 等等。
编写一个函数,它将把使用 <a href="https://www.freecodecamp.org/news/how-to-code-the-caesar-cipher-an-introduction-to-basic-encryption-3bf77b4e19f7/" target="_blank" rel="noopener noreferrer nofollow">ROT13</a> 加密编码的字符串作为输入并返回解码字符串。
所有解码后的字母都必须为字母大写。 请不要解码非字母的字符(例如,空格、标点符号),但你需要在结果中保留它们。
# --hints--
`rot13("SERR PBQR PNZC")` 应解码为 `FREE CODE CAMP`
```js
assert(rot13('SERR PBQR PNZC') === 'FREE CODE CAMP');
```
`rot13("SERR CVMMN!")` 应解码为 `FREE PIZZA!`
```js
assert(rot13('SERR CVMMN!') === 'FREE PIZZA!');
```
`rot13("SERR YBIR?")` 应解码为 `FREE LOVE?`
```js
assert(rot13('SERR YBIR?') === 'FREE LOVE?');
```
`rot13("GUR DHVPX OEBJA SBK WHZCF BIRE GUR YNML QBT.")` 应解码为 `THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.`
```js
assert(
rot13('GUR DHVPX OEBJA SBK WHZCF BIRE GUR YNML QBT.') ===
'THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.'
);
```
# --seed--
## --seed-contents--
```js
function rot13(str) {
return str;
}
rot13("SERR PBQR PNZC");
```
# --solutions--
```js
var lookup = {
'A': 'N','B': 'O','C': 'P','D': 'Q',
'E': 'R','F': 'S','G': 'T','H': 'U',
'I': 'V','J': 'W','K': 'X','L': 'Y',
'M': 'Z','N': 'A','O': 'B','P': 'C',
'Q': 'D','R': 'E','S': 'F','T': 'G',
'U': 'H','V': 'I','W': 'J','X': 'K',
'Y': 'L','Z': 'M'
};
function rot13(encodedStr) {
var codeArr = encodedStr.split(""); // String to Array
var decodedArr = []; // Your Result goes here
// Only change code below this line
decodedArr = codeArr.map(function(letter) {
if(lookup.hasOwnProperty(letter)) {
letter = lookup[letter];
}
return letter;
});
// Only change code above this line
return decodedArr.join(""); // Array to String
}
```

View File

@@ -0,0 +1,252 @@
---
id: aa2e6f85cab2ab736c9a9b24
title: 构建一个收银机
challengeType: 5
forumTopicId: 16012
dashedName: build-a-cash-register
---
# --description--
设计一个收银机抽屉函数 `checkCashRegister()`,它接受购买价格作为第一个参数(`price`),付款作为第二个参数(`cash`),和抽屉的现金(`cid`)作为第三个参数。
`cid` 是包含货币面值的二维数组。
函数 `checkCashRegister()` 应返回含有 `status` 属性和 `change` 属性的对象。
如果收银机內的金额少于应找回的零钱数,或者你无法返回确切的数目时,返回 `{status: "INSUFFICIENT_FUNDS", change: []}`
如果收银机內的金额恰好等于应找回的零钱数,返回 `{status: "CLOSED", change: [...]}`,其中 `change` 的属性值就是收银机內的金额。
否则,返回 `{status: "OPEN", change: [...]}`,其中 `change` 键值是应找回的零钱数,并将找零的面值由高到低排序。
<table class='table table-striped'><tbody><tr><th>货币单位</th><th>面值</th></tr><tr><td>Penny</td><td>0.01 美元PENNY</td></tr><tr><td>Nickel</td><td>0.05 美元NICKEL</td></tr><tr><td>Dime</td><td>0.1 美元DIME</td></tr><tr><td>Quarter</td><td>0.25 美元QUARTER</td></tr><tr><td>Dollar</td><td>1 美元ONE</td></tr><tr><td>Five Dollars</td><td>5 美元FIVE</td></tr><tr><td>Ten Dollars</td><td>10 美元TEN</td></tr><tr><td>Twenty Dollars</td><td>20 美元TWENTY</td></tr><tr><td>One-hundred Dollars</td><td>100 美元ONE HUNDRED</td></tr></tbody></table>
下面的抽屉里现金数组示例:
```js
[
["PENNY", 1.01],
["NICKEL", 2.05],
["DIME", 3.1],
["QUARTER", 4.25],
["ONE", 90],
["FIVE", 55],
["TEN", 20],
["TWENTY", 60],
["ONE HUNDRED", 100]
]
```
# --hints--
`checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]])` 应返回一个对象。
```js
assert.deepEqual(
Object.prototype.toString.call(
checkCashRegister(19.5, 20, [
['PENNY', 1.01],
['NICKEL', 2.05],
['DIME', 3.1],
['QUARTER', 4.25],
['ONE', 90],
['FIVE', 55],
['TEN', 20],
['TWENTY', 60],
['ONE HUNDRED', 100]
])
),
'[object Object]'
);
```
`checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]])` 应返回 `{status: "OPEN", change: [["QUARTER", 0.5]]}`
```js
assert.deepEqual(
checkCashRegister(19.5, 20, [
['PENNY', 1.01],
['NICKEL', 2.05],
['DIME', 3.1],
['QUARTER', 4.25],
['ONE', 90],
['FIVE', 55],
['TEN', 20],
['TWENTY', 60],
['ONE HUNDRED', 100]
]),
{ status: 'OPEN', change: [['QUARTER', 0.5]] }
);
```
`checkCashRegister(3.26, 100, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]])` 应返回 `{status: "OPEN", change: [["TWENTY", 60], ["TEN", 20], ["FIVE", 15], ["ONE", 1], ["QUARTER", 0.5], ["DIME", 0.2], ["PENNY", 0.04]]}`
```js
assert.deepEqual(
checkCashRegister(3.26, 100, [
['PENNY', 1.01],
['NICKEL', 2.05],
['DIME', 3.1],
['QUARTER', 4.25],
['ONE', 90],
['FIVE', 55],
['TEN', 20],
['TWENTY', 60],
['ONE HUNDRED', 100]
]),
{
status: 'OPEN',
change: [
['TWENTY', 60],
['TEN', 20],
['FIVE', 15],
['ONE', 1],
['QUARTER', 0.5],
['DIME', 0.2],
['PENNY', 0.04]
]
}
);
```
`checkCashRegister(19.5, 20, [["PENNY", 0.01], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]])` 应返回 `{status: "INSUFFICIENT_FUNDS", change: []}`
```js
assert.deepEqual(
checkCashRegister(19.5, 20, [
['PENNY', 0.01],
['NICKEL', 0],
['DIME', 0],
['QUARTER', 0],
['ONE', 0],
['FIVE', 0],
['TEN', 0],
['TWENTY', 0],
['ONE HUNDRED', 0]
]),
{ status: 'INSUFFICIENT_FUNDS', change: [] }
);
```
`checkCashRegister(19.5, 20, [["PENNY", 0.01], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 1], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]])` 应返回 `{status: "INSUFFICIENT_FUNDS", change: []}`
```js
assert.deepEqual(
checkCashRegister(19.5, 20, [
['PENNY', 0.01],
['NICKEL', 0],
['DIME', 0],
['QUARTER', 0],
['ONE', 1],
['FIVE', 0],
['TEN', 0],
['TWENTY', 0],
['ONE HUNDRED', 0]
]),
{ status: 'INSUFFICIENT_FUNDS', change: [] }
);
```
`checkCashRegister(19.5, 20, [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]])` 应返回 `{status: "CLOSED", change: [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]}`
```js
assert.deepEqual(
checkCashRegister(19.5, 20, [
['PENNY', 0.5],
['NICKEL', 0],
['DIME', 0],
['QUARTER', 0],
['ONE', 0],
['FIVE', 0],
['TEN', 0],
['TWENTY', 0],
['ONE HUNDRED', 0]
]),
{
status: 'CLOSED',
change: [
['PENNY', 0.5],
['NICKEL', 0],
['DIME', 0],
['QUARTER', 0],
['ONE', 0],
['FIVE', 0],
['TEN', 0],
['TWENTY', 0],
['ONE HUNDRED', 0]
]
}
);
```
# --seed--
## --seed-contents--
```js
function checkCashRegister(price, cash, cid) {
let change;
return change;
}
checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]);
```
# --solutions--
```js
const denom = [
{ name: "ONE HUNDRED", val: 100 },
{ name: "TWENTY", val: 20 },
{ name: "TEN", val: 10 },
{ name: "FIVE", val: 5 },
{ name: "ONE", val: 1 },
{ name: "QUARTER", val: 0.25 },
{ name: "DIME", val: 0.1 },
{ name: "NICKEL", val: 0.05 },
{ name: "PENNY", val: 0.01 },
];
function checkCashRegister(price, cash, cid) {
const output = { status: null, change: [] };
let change = cash - price;
const register = cid.reduce(
function (acc, curr) {
acc.total += curr[1];
acc[curr[0]] = curr[1];
return acc;
},
{ total: 0 }
);
if (register.total === change) {
output.status = "CLOSED";
output.change = cid;
return output;
}
if (register.total < change) {
output.status = "INSUFFICIENT_FUNDS";
return output;
}
const change_arr = denom.reduce(function (acc, curr) {
let value = 0;
while (register[curr.name] > 0 && change >= curr.val) {
change -= curr.val;
register[curr.name] -= curr.val;
value += curr.val;
change = Math.round(change * 100) / 100;
}
if (value > 0) {
acc.push([curr.name, value]);
}
return acc;
}, []);
if (change_arr.length < 1 || change > 0) {
output.status = "INSUFFICIENT_FUNDS";
return output;
}
output.status = "OPEN";
output.change = change_arr;
return output;
}
```

View File

@@ -0,0 +1,125 @@
---
id: aaa48de84e1ecc7c742e1124
title: 构建一个回文检测器
challengeType: 5
forumTopicId: 16004
dashedName: build-a-palindrome-checker
---
# --description--
如果传入的字符串是回文字符串,则返回 `true`。 否则,返回 `false`
回文(<dfn>palindrome</dfn>),指在忽略标点符号、大小写和空格的前提下,正着读和反着读一模一样。
**注意:** 检查回文时,你需要先去除 **所有非字母数字的字符**(标点、空格和符号),并将所有字母都转换成大写或都转换成小写。
我们会传入具有不同格式的字符串,如 `racecar``RaceCar``race CAR` 等等。
我们也会传入一些包含特殊符号的字符串,例如 `2A3*3a2``2A3 3a2``2_A3*3#A2`
# --hints--
`palindrome("eye")` 应返回一个布尔值。
```js
assert(typeof palindrome('eye') === 'boolean');
```
`palindrome("eye")` 应返回 `true`
```js
assert(palindrome('eye') === true);
```
`palindrome("_eye")` 应返回 `true`
```js
assert(palindrome('_eye') === true);
```
`palindrome("race car")` 应返回 `true`
```js
assert(palindrome('race car') === true);
```
`palindrome("not a palindrome")` 应返回 `false`
```js
assert(palindrome('not a palindrome') === false);
```
`palindrome("A man, a plan, a canal. Panama")` 应返回 `true`
```js
assert(palindrome('A man, a plan, a canal. Panama') === true);
```
`palindrome("never odd or even")` 应返回 `true`
```js
assert(palindrome('never odd or even') === true);
```
`palindrome("nope")` 应返回 `false`
```js
assert(palindrome('nope') === false);
```
`palindrome("almostomla")` 应返回 `false`
```js
assert(palindrome('almostomla') === false);
```
`palindrome("My age is 0, 0 si ega ym.")` 应返回 `true`
```js
assert(palindrome('My age is 0, 0 si ega ym.') === true);
```
`palindrome("1 eye for of 1 eye.")` 应返回 `false`
```js
assert(palindrome('1 eye for of 1 eye.') === false);
```
`palindrome("0_0 (: /-\ :) 0-0")` 应返回 `true`
```js
assert(palindrome('0_0 (: /- :) 0-0') === true);
```
`palindrome("five|\_/|four")` 应返回 `false`
```js
assert(palindrome('five|_/|four') === false);
```
# --seed--
## --seed-contents--
```js
function palindrome(str) {
return true;
}
palindrome("eye");
```
# --solutions--
```js
function palindrome(str) {
var string = str.toLowerCase().split(/[^A-Za-z0-9]/gi).join('');
var aux = string.split('');
if (aux.join('') === aux.reverse().join('')){
return true;
}
return false;
}
```

View File

@@ -0,0 +1,215 @@
---
id: a7f4d8f2483413a6ce226cac
title: 构建罗马数字转换器
challengeType: 5
forumTopicId: 16044
dashedName: build-a-roman-numeral-converter
---
# --description--
把传入的数字转为罗马数字。
| 罗马数字 | 阿拉伯数字 |
| ---- | ----- |
| M | 1000 |
| CM | 900 |
| D | 500 |
| CD | 400 |
| C | 100 |
| XC | 90 |
| L | 50 |
| XL | 40 |
| X | 10 |
| IX | 9 |
| V | 5 |
| IV | 4 |
| I | 1 |
所有罗马数字答案都应该大写。
# --hints--
`convertToRoman(2)` 应该返回字符串 `II`
```js
assert.deepEqual(convertToRoman(2), 'II');
```
`convertToRoman(3)` 应该返回字符串 `III`
```js
assert.deepEqual(convertToRoman(3), 'III');
```
`convertToRoman(4)` 应该返回字符串 `IV`
```js
assert.deepEqual(convertToRoman(4), 'IV');
```
`convertToRoman(5)` 应该返回字符串 `V`
```js
assert.deepEqual(convertToRoman(5), 'V');
```
`convertToRoman(9)` 应该返回字符串 `IX`
```js
assert.deepEqual(convertToRoman(9), 'IX');
```
`convertToRoman(12)` 应该返回字符串 `XII`
```js
assert.deepEqual(convertToRoman(12), 'XII');
```
`convertToRoman(16)` 应该返回字符串 `XVI`
```js
assert.deepEqual(convertToRoman(16), 'XVI');
```
`convertToRoman(29)` 应该返回字符串 `XXIX`
```js
assert.deepEqual(convertToRoman(29), 'XXIX');
```
`convertToRoman(44)` 应该返回字符串 `XLIV`.
```js
assert.deepEqual(convertToRoman(44), 'XLIV');
```
`convertToRoman(45)` 应该返回字符串 `XLV`
```js
assert.deepEqual(convertToRoman(45), 'XLV');
```
`convertToRoman(68)` 应该返回字符串 `LXVIII`
```js
assert.deepEqual(convertToRoman(68), 'LXVIII');
```
`convertToRoman(83)` 应该返回字符串 `LXXXIII`
```js
assert.deepEqual(convertToRoman(83), 'LXXXIII');
```
`convertToRoman(97)` 应该返回字符串 `XCVII`
```js
assert.deepEqual(convertToRoman(97), 'XCVII');
```
`convertToRoman(99)` 应该返回字符串 `XCIX`
```js
assert.deepEqual(convertToRoman(99), 'XCIX');
```
`convertToRoman(400)` 应该返回字符串 `CD`
```js
assert.deepEqual(convertToRoman(400), 'CD');
```
`convertToRoman(500)` 应该返回字符串 `D`
```js
assert.deepEqual(convertToRoman(500), 'D');
```
`convertToRoman(501)` 应该返回字符串 `DI`
```js
assert.deepEqual(convertToRoman(501), 'DI');
```
`convertToRoman(649)` 应该返回字符串 `DCXLIX`
```js
assert.deepEqual(convertToRoman(649), 'DCXLIX');
```
`convertToRoman(798)` 应该返回字符串 `DCCXCVIII`
```js
assert.deepEqual(convertToRoman(798), 'DCCXCVIII');
```
`convertToRoman(891)` 应该返回字符串 `DCCCXCI`
```js
assert.deepEqual(convertToRoman(891), 'DCCCXCI');
```
`convertToRoman(1000)` 应该返回字符串 `M`
```js
assert.deepEqual(convertToRoman(1000), 'M');
```
`convertToRoman(1004)` 应该返回字符串 `MIV`
```js
assert.deepEqual(convertToRoman(1004), 'MIV');
```
`convertToRoman(1006)` 应该返回字符串 `MVI`
```js
assert.deepEqual(convertToRoman(1006), 'MVI');
```
`convertToRoman(1023)` 应该返回字符串 `MXXIII`
```js
assert.deepEqual(convertToRoman(1023), 'MXXIII');
```
`convertToRoman(2014)` 应该返回字符串 `MMXIV`
```js
assert.deepEqual(convertToRoman(2014), 'MMXIV');
```
`convertToRoman(3999)` 应该返回字符串 `MMMCMXCIX`
```js
assert.deepEqual(convertToRoman(3999), 'MMMCMXCIX');
```
# --seed--
## --seed-contents--
```js
function convertToRoman(num) {
return num;
}
convertToRoman(36);
```
# --solutions--
```js
function convertToRoman(num) {
var ref = [['M', 1000], ['CM', 900], ['D', 500], ['CD', 400], ['C', 100], ['XC', 90], ['L', 50], ['XL', 40], ['X', 10], ['IX', 9], ['V', 5], ['IV', 4], ['I', 1]];
var res = [];
ref.forEach(function(p) {
while (num >= p[1]) {
res.push(p[0]);
num -= p[1];
}
});
return res.join('');
}
```

Some files were not shown because too many files have changed in this diff Show More