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

This commit is contained in:
camperbot
2022-01-21 01:00:18 +05:30
committed by GitHub
parent f866718a3d
commit 5c868af2b8
1696 changed files with 159426 additions and 69 deletions

View File

@@ -0,0 +1,134 @@
---
id: 587d7b87367417b2b2512b40
title: var キーワードと let キーワードのスコープを比較する
challengeType: 1
forumTopicId: 301195
dashedName: compare-scopes-of-the-var-and-let-keywords
---
# --description--
`let` に慣れていない方は、[こちらのチャレンジ](/learn/javascript-algorithms-and-data-structures/basic-javascript/explore-differences-between-the-var-and-let-keywords)をご覧ください。
`var` キーワードを付けて変数を宣言すると、グローバルに宣言されるか、または関数内で宣言された場合はローカルに宣言されます。
`let` キーワードの動作も似ていますが、いくつか追加の機能があります。 ブロック、ステートメント、または式の中で `let` キーワードを付けて変数を宣言すると、変数のスコープがそのブロック、ステートメント、または式に限定されます。
例:
```js
var numArray = [];
for (var i = 0; i < 3; i++) {
numArray.push(i);
}
console.log(numArray);
console.log(i);
```
ここでは、コンソールに値 `[0, 1, 2]``3` が表示されます。
`var` キーワードでは、`i` はグローバルに宣言されます。 そのため、`i++` を実行するとグローバル変数が更新されます。 このコードは次のコードと同様です。
```js
var numArray = [];
var i;
for (i = 0; i < 3; i++) {
numArray.push(i);
}
console.log(numArray);
console.log(i);
```
ここでも、コンソールに値 `[0, 1, 2]``3` が表示されます。
`i` 変数を使用している `for` ループの中で関数を作成し、後で使用できるように保存した場合には、この動作が問題を起こします。 これは、変数を保存した関数からは、更新されたグローバルの `i` 変数の値が常に参照されるためです。
```js
var printNumTwo;
for (var i = 0; i < 3; i++) {
if (i === 2) {
printNumTwo = function() {
return i;
};
}
}
console.log(printNumTwo());
```
ここでは、コンソールに値 `3` が表示されます。
ご覧のように、`printNumTwo()` は 2 ではなく 3 を出力します。 これは、`i` に代入された値が更新されて、`printNumTwo()` が、for ループで関数を作成したときに与えられた値 `i` ではなく、グローバルの `i` を返すからです。 `let` キーワードの場合はこうした動作に従いません。
```js
let printNumTwo;
for (let i = 0; i < 3; i++) {
if (i === 2) {
printNumTwo = function() {
return i;
};
}
}
console.log(printNumTwo());
console.log(i);
```
ここでは、コンソールに値 `2` が表示され、エラー `i is not defined` が表示されます。
`i` はグローバルスコープで宣言されていないため、定義されていません。 `for` ループステートメントの中で宣言されているだけです。 `printNumTwo()`は正しい値を返しました。これは、ループステートメント内で `let` キーワードによって、独自の値 (0、1、および 2) を持つ 3 つの異なる `i` 変数が作成されたからです。
# --instructions--
`if` ステートメント内で宣言された `i` が、関数の最初の行で宣言された `i` とは別の変数になるように、コードを修正してください。 コードではどの場所でもキーワード `var` を使用しないでください。
この練習の目的は、`var` キーワードと `let` キーワードで、宣言された変数に割り当てられるスコープの違いを理解することです。 この練習で使用しているような関数をプログラミングする場合は、通常は混同を避けるために異なる変数名を使用することをお勧めします。
# --hints--
`var` をコードに入れてはいけません。
```js
assert(!code.match(/var/g));
```
`if` ステートメント内で宣言された変数 `i` は、文字列 `block scope` になる必要があります。
```js
assert(code.match(/(i\s*=\s*).*\s*.*\s*.*\1('|")block\s*scope\2/g));
```
`checkScope()` は、文字列 `function scope` を返す必要があります。
```js
assert(checkScope() === 'function scope');
```
# --seed--
## --seed-contents--
```js
function checkScope() {
var i = 'function scope';
if (true) {
i = 'block scope';
console.log('Block scope i is: ', i);
}
console.log('Function scope i is: ', i);
return i;
}
```
# --solutions--
```js
function checkScope() {
let i = 'function scope';
if (true) {
let i = 'block scope';
console.log('Block scope i is: ', i);
}
console.log('Function scope i is: ', i);
return i;
}
```

View File

@@ -0,0 +1,77 @@
---
id: 5cdafbc32913098997531680
title: resolve と reject を使用してプロミスを完了する
challengeType: 1
forumTopicId: 301196
dashedName: complete-a-promise-with-resolve-and-reject
---
# --description--
プロミスには、`pending` (保留)、`fulfilled` (成功)、`rejected` (拒否) の 3 つの状態があります。 前のチャレンジで作成したプロミスは、プロミスの完了方法を追加していなかったために、永久に `pending` 状態のままになります。 プロミスを完了するには、プロミスの引数に与えられた `resolve` および `reject` パラメーターを使用します。 プロミスを成功としたい場合は `resolve` を使用し、失敗としたい場合は `reject` を使用します。 これらは、次に示すように引数を取るメソッドです。
```js
const myPromise = new Promise((resolve, reject) => {
if(condition here) {
resolve("Promise was fulfilled");
} else {
reject("Promise was rejected");
}
});
```
上記の例では、これらの関数の引数として文字列を使用していますが、実際には何でも使用できます。 多くの場合はオブジェクトで、そこからウェブサイトなどに設定するデータを取得して使用します。
# --instructions--
プロミスを使用して成功と失敗を処理してください。 `responseFromServer``true` の場合は、`resolve` メソッドを呼び出してプロミスを成功として完了してください。 `resolve`には、`We got the data` という値の文字列を渡します。 `responseFromServer``false` の場合は、代わりに `reject` メソッドを使用して文字列 `Data not received` を渡してください。
# --hints--
`if` 条件が `true` の場合は、必要な文字列とともに `resolve` を呼び出す必要があります。
```js
assert(
code.match(/if\s*\(\s*responseFromServer\s*\)\s*{\s*resolve\s*\(\s*('|"|`)We got the data\1\s*\)(\s*|\s*;\s*)}/g)
);
```
`if` 条件が `false` の場合は、必要な文字列とともに `reject` を呼び出す必要があります。
```js
assert(
code.match(/}\s*else\s*{\s*reject\s*\(\s*('|"|`)Data not received\1\s*\)(\s*|\s*;\s*)}/g)
);
```
# --seed--
## --seed-contents--
```js
const makeServerRequest = new Promise((resolve, reject) => {
// responseFromServer represents a response from a server
let responseFromServer;
if(responseFromServer) {
// Change this line
} else {
// Change this line
}
});
```
# --solutions--
```js
const makeServerRequest = new Promise((resolve, reject) => {
// responseFromServer represents a response from a server
let responseFromServer;
if(responseFromServer) {
resolve("We got the data");
} else {
reject("Data not received");
}
});
```

View File

@@ -0,0 +1,55 @@
---
id: 5cdafbb0291309899753167f
title: JavaScript のプロミスを作成する
challengeType: 1
forumTopicId: 301197
dashedName: create-a-javascript-promise
---
# --description--
JavaScript におけるプロミスとは、その言葉が示すように、何らかの処理を (通常は非同期に) 実行することを「約束する」場合に使用するものです。 タスクを完了するとき、そのタスクは約束を果たしたか果たせなかったかのいずれかになります。 プロミス (`Promise`) はコンストラクター関数なので、`new` キーワードを使用して作成する必要があります。 引数として、2 つのパラメーター (`resolve``reject`) を持つ関数を受け取ります。 これらのメソッドは、プロミスの結果を判定するのに使用します。 構文は次のようになります。
```js
const myPromise = new Promise((resolve, reject) => {
});
```
# --instructions--
`makeServerRequest` という新しいプロミスを作成してください。 `resolve``reject` のパラメーターを持つ関数をコンストラクターに渡してください。
# --hints--
`makeServerRequest` という名前の宣言された変数に、プロミスを割り当てる必要があります。
```js
assert(makeServerRequest instanceof Promise);
```
プロミスには、`resolve``reject` をパラメーターとして持つ関数を渡す必要があります。
```js
assert(
code.match(
/Promise\(\s*(function\s*\(\s*resolve\s*,\s*reject\s*\)\s*{|\(\s*resolve\s*,\s*reject\s*\)\s*=>\s*{)[^}]*}/g
)
);
```
# --seed--
## --seed-contents--
```js
```
# --solutions--
```js
const makeServerRequest = new Promise((resolve, reject) => {
});
```

View File

@@ -0,0 +1,73 @@
---
id: 5cddbfd622f1a59093ec611d
title: モジュールスクリプトを作成する
challengeType: 6
forumTopicId: 301198
dashedName: create-a-module-script
---
# --description--
JavaScript は、当初の用途はほとんどが HTML ウェブであり、それ以外の用途にはあまり役に立ちませんでした。 現在ではその役割は非常に大きく、ウェブサイト全体がほとんど JavaScript で構築されることもあります。 JavaScript のモジュール化を進め、コードをより明解にしてメンテナンスできるように、ES6 では JavaScript ファイル間でコードを簡単に共有する方法が導入されました。 そのためには、他の 1 つまたは複数のファイルで使用できるように、ファイルの一部分をエクスポートし、必要になったときに対象の部分をインポートする必要があります。 この機能を利用するには、`type``module` のスクリプトを HTML ドキュメントに作成する必要があります。 例を次に示します。
```html
<script type="module" src="filename.js"></script>
```
これで、この `module` タイプを使用するスクリプトで `import``export` の機能を使用できるようになりました。これらについてはこのあとのチャレンジで説明します。
# --instructions--
type が `module` のスクリプトを HTML ドキュメントに追加し、`index.js` というソースファイルを指定してください。
# --hints--
`script` タグを作成する必要があります。
```js
assert(code.match(/<\s*script[^>]*>\s*<\/\s*script\s*>/g));
```
`script` タグに、`module` という値を設定した `type` 属性を持たせる必要があります。
```js
assert(
code.match(
/<\s*script\s+[^t]*type\s*=\s*('|")module\1[^>]*>\s*<\/\s*script\s*>/g
)
);
```
`script` タグに、`index.js` という `src` 属性を付ける必要があります。
```js
assert(
code.match(
/<\s*script\s+[^s]*src\s*=\s*('|")index\.js\1[^>]*>\s*<\/\s*script\s*>/g
)
);
```
# --seed--
## --seed-contents--
```html
<html>
<body>
<!-- Only change code below this line -->
<!-- Only change code above this line -->
</body>
</html>
```
# --solutions--
```html
<html>
<body>
<script type="module" src="index.js"></script>
</body>
</html>
```

View File

@@ -0,0 +1,63 @@
---
id: 587d7b8c367417b2b2512b58
title: export default を使用してエクスポートのフォールバック (代替) を作成する
challengeType: 1
forumTopicId: 301199
dashedName: create-an-export-fallback-with-export-default
---
# --description--
`export` のレッスンでは、<dfn>名前付きエクスポート</dfn>と呼ばれる構文について学びました。 これにより、複数の関数や変数を他のファイルで使用できるようになります。
もう一つ覚えておく必要がある `export` 構文として、<dfn>export default</dfn> というものがあります。 通常は、ファイルから 1 つの値だけをエクスポートする場合にこの構文を使用します。 また、ファイルやモジュールのフォールバック (代替) 値を作成する場合にも使用します。
`export default` を使用した例を次に示します。
```js
export default function add(x, y) {
return x + y;
}
export default function(x, y) {
return x + y;
}
```
1 つ目は名前付き関数、2 つ目は匿名関数です。
`export default` は、モジュールまたはファイルのフォールバック値を宣言するために使用します。そのため、各モジュールまたはファイルでデフォルトのエクスポートにすることができるのは 1 つの値だけです。 また、`var``let`、または `const` を持つ `export default` は使用できません。
# --instructions--
次の関数をモジュールのフォールバック値にする必要があります。 そのために必要なコードを追加してください。
# --hints--
コードで `export` のフォールバックを使用する必要があります。
```js
assert(
code.match(
/export\s+default\s+function(\s+subtract\s*|\s*)\(\s*x,\s*y\s*\)\s*{/g
)
);
```
# --seed--
## --seed-contents--
```js
function subtract(x, y) {
return x - y;
}
```
# --solutions--
```js
export default function subtract(x, y) {
return x - y;
}
```

View File

@@ -0,0 +1,116 @@
---
id: 587d7b8a367417b2b2512b4e
title: テンプレートリテラルを使用して文字列を作成する
challengeType: 1
forumTopicId: 301200
dashedName: create-strings-using-template-literals
---
# --description--
ES6 の新機能に<dfn>テンプレートリテラル</dfn>があります。 これは複雑な文字列を簡単に作成できる特殊な型の文字列です。
テンプレートリテラルを使用すると、複数行の文字列を作成したり、文字列の補完機能を使用して文字列を作成したりできます。
次のコードを考えてみましょう。
```js
const person = {
name: "Zodiac Hasbro",
age: 56
};
const greeting = `Hello, my name is ${person.name}!
I am ${person.age} years old.`;
console.log(greeting);
```
コンソールには、`Hello, my name is Zodiac Hasbro!``I am 56 years old.` の文字列が表示されます。
ここではいろいろな処理を行っています。 まず、文字列を囲むのに引用符 (`'` または `"`) ではなくバッククォート (`` ` ``) を使用しています。 次に、コードと出力の両方で文字列が複数行になっています。 このため文字列内に `\n` を挿入せずに済みます。 上記で使用している `${variable}` の構文はプレイスホルダーです。 基本的には `+` 演算子で連結する必要がなくなります。 文字列に変数を追加するには、変数をテンプレート文字列に入れて `${` と `}` で囲むだけです。 同様にして、文字列リテラルに `${a + b}` などの他の式を含めることもできます。 この新しい方法で文字列を作成することで、より柔軟に堅牢な文字列を作成できます。
# --instructions--
テンプレートリテラル構文でバッククォートを使用して、リスト要素 (`li`) 文字列の配列を作成してください。 各リスト要素のテキストは、`result` オブジェクトの `failure` プロパティの配列要素の 1 つであり、`text-warning` の値を持つ `class` 属性を持たせます。 `makeList` 関数からは、リスト項目の文字列の配列を返してください。
イテレーターメソッド (任意の種類のループ) を使用して、次のような目的の出力を実現してください。
```js
[
'<li class="text-warning">no-var</li>',
'<li class="text-warning">var-on-top</li>',
'<li class="text-warning">linebreak</li>'
]
```
# --hints--
`failuresList` は、`result.failure` のメッセージを含む配列にする必要があります。
```js
assert(
typeof makeList(result.failure) === 'object' && failuresList.length === 3
);
```
`failuresList` は、指定された出力と等しい必要があります。
```js
assert(
makeList(result.failure).every(
(v, i) =>
v === `<li class="text-warning">${result.failure[i]}</li>` ||
v === `<li class='text-warning'>${result.failure[i]}</li>`
)
);
```
テンプレート文字列と式の補間機能を使用する必要があります。
```js
(getUserInput) => assert(getUserInput('index').match(/(`.*\${.*}.*`)/));
```
イテレーターを使用する必要があります。
```js
(getUserInput) =>
assert(getUserInput('index').match(/for|map|reduce|forEach|while/));
```
# --seed--
## --seed-contents--
```js
const result = {
success: ["max-length", "no-amd", "prefer-arrow-functions"],
failure: ["no-var", "var-on-top", "linebreak"],
skipped: ["no-extra-semi", "no-dup-keys"]
};
function makeList(arr) {
// Only change code below this line
const failureItems = [];
// Only change code above this line
return failureItems;
}
const failuresList = makeList(result.failure);
```
# --solutions--
```js
const result = {
success: ["max-length", "no-amd", "prefer-arrow-functions"],
failure: ["no-var", "var-on-top", "linebreak"],
skipped: ["no-extra-semi", "no-dup-keys"]
};
function makeList(arr) {
return arr.map(val => `<li class="text-warning">${val}</li>`);
}
const failuresList = makeList(result.failure);
```

View File

@@ -0,0 +1,92 @@
---
id: 5cdafbd72913098997531681
title: 成功したプロミスを then メソッドで処理する
challengeType: 1
forumTopicId: 301203
dashedName: handle-a-fulfilled-promise-with-then
---
# --description--
プロミスは、サーバーリクエストなど、処理にどの程度の時間がかかるかわからないプロセス (たとえば、非同期的なもの) がコードにある場合に最も役立ちます。 サーバーリクエストを行う場合、処理には時間がかかり、通常は処理の完了後にサーバーからの応答を受けて何らかの処理を行う必要があります。 `then` メソッドを使用するとこうした処理を実現できます。 `then` メソッドは、`resolve` によってプロミスが成功した直後に実行されます。 例を次に示します。
```js
myPromise.then(result => {
});
```
`result` は、`resolve` メソッドに渡された引数からの結果です。
# --instructions--
`then` メソッドをプロミスに追加してください。 `result` をコールバック関数のパラメーターとして使用し、コンソールに `result` を出力してください。
# --hints--
プロミスで `then` メソッドを呼び出す必要があります。
```js
assert(
__helpers.removeWhiteSpace(code).match(/(makeServerRequest|\))\.then\(/g)
);
```
`then` メソッドでは、`result` をパラメーターとするコールバック関数を記述する必要があります。
```js
assert(resultIsParameter);
```
コンソールに `result` を出力する必要があります。
```js
assert(
resultIsParameter &&
__helpers
.removeWhiteSpace(code)
.match(/\.then\(.*?result.*?console.log\(result\).*?\)/)
);
```
# --seed--
## --after-user-code--
```js
const resultIsParameter = /\.then\((function\(result\){|result|\(result\)=>)/.test(__helpers.removeWhiteSpace(code));
```
## --seed-contents--
```js
const makeServerRequest = new Promise((resolve, reject) => {
// responseFromServer is set to true to represent a successful response from a server
let responseFromServer = true;
if(responseFromServer) {
resolve("We got the data");
} else {
reject("Data not received");
}
});
```
# --solutions--
```js
const makeServerRequest = new Promise((resolve, reject) => {
// responseFromServer is set to true to represent a successful response from a server
let responseFromServer = true;
if(responseFromServer) {
resolve("We got the data");
} else {
reject("Data not received");
}
});
makeServerRequest.then(result => {
console.log(result);
});
```

View File

@@ -0,0 +1,100 @@
---
id: 5cdafbe72913098997531682
title: 拒否されたプロミスを catch で処理する
challengeType: 1
forumTopicId: 301204
dashedName: handle-a-rejected-promise-with-catch
---
# --description--
`catch` は、プロミスが拒否されたときに使用するメソッドで、 プロミスの `reject` メソッドが呼び出された直後に実行されます。 構文は次のとおりです。
```js
myPromise.catch(error => {
});
```
`error``reject` メソッドに渡される引数です。
# --instructions--
`catch` メソッドをプロミスに追加してください。 `error` をコールバック関数のパラメーターとして使用し、コンソールに `error` を出力してください。
# --hints--
プロミスで `catch` メソッドを呼び出す必要があります。
```js
assert(
__helpers.removeWhiteSpace(code).match(/(makeServerRequest|\))\.catch\(/g)
);
```
`catch` メソッドでは、`error` をパラメーターとするコールバック関数を記述する必要があります。
```js
assert(errorIsParameter);
```
コンソールに `error` を出力する必要があります。
```js
assert(
errorIsParameter &&
__helpers
.removeWhiteSpace(code)
.match(/\.catch\(.*?error.*?console.log\(error\).*?\)/)
);
```
# --seed--
## --after-user-code--
```js
const errorIsParameter = /\.catch\((function\(error\){|error|\(error\)=>)/.test(__helpers.removeWhiteSpace(code));
```
## --seed-contents--
```js
const makeServerRequest = new Promise((resolve, reject) => {
// responseFromServer is set to false to represent an unsuccessful response from a server
let responseFromServer = false;
if(responseFromServer) {
resolve("We got the data");
} else {
reject("Data not received");
}
});
makeServerRequest.then(result => {
console.log(result);
});
```
# --solutions--
```js
const makeServerRequest = new Promise((resolve, reject) => {
// responseFromServer is set to false to represent an unsuccessful response from a server
let responseFromServer = false;
if(responseFromServer) {
resolve("We got the data");
} else {
reject("Data not received");
}
});
makeServerRequest.then(result => {
console.log(result);
});
makeServerRequest.catch(error => {
console.log(error);
});
```

View File

@@ -0,0 +1,48 @@
---
id: 587d7b8d367417b2b2512b59
title: デフォルトのエクスポートをインポートする
challengeType: 1
forumTopicId: 301205
dashedName: import-a-default-export
---
# --description--
前回のチャレンジでは `export default` とその用法について学びました。 デフォルトのエクスポートをインポートするには、別の `import` 構文を使用する必要があります。 次の例では、`add``math_functions.js` ファイルのデフォルトのエクスポートです。 インポートする方法は次のとおりです。
```js
import add from "./math_functions.js";
```
構文は 1 か所重要な部分が異なっています。 インポートする値 `add` が波括弧 (`{}`) で囲まれていません。 ここでの `add` は、`math_functions.js` ファイルのデフォルトのエクスポートが何であっても、単なる変数名になります。 デフォルトをインポートするときは、ここで任意の名前を使用できます。
# --instructions--
次のコードで、このファイルと同じディレクトリにある `math_functions.js` ファイルからデフォルトのエクスポートをインポートしてください。 インポートしたものに `subtract` という名前を付けてください。
# --hints--
`math_functions.js` から `subtract` を適切にインポートする必要があります。
```js
assert(code.match(/import\s+subtract\s+from\s+('|")\.\/math_functions\.js\1/g));
```
# --seed--
## --seed-contents--
```js
// Only change code above this line
subtract(7,4);
```
# --solutions--
```js
import subtract from "./math_functions.js";
subtract(7,4);
```

View File

@@ -0,0 +1,91 @@
---
id: 587d7b87367417b2b2512b42
title: const で宣言された配列をミューテートする
challengeType: 1
forumTopicId: 301206
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` 宣言は、現在の JavaScript では多くの用法があります。
デフォルトですべての変数を `const` を使用して割り当てることを好む開発者もいますが、値の再割り当てを必要としないことがわかっている場合に限られます。 そうした開発者は、変数を再割り当てする場合にのみ `let` を使用しています。
しかし、`const` を使用して変数に割り当てたオブジェクト (列や関数を含む) であってもミュータブル (変更可能) であることを理解しておくことが重要です。 `const` 宣言を使用しても、変数識別子の再割り当てを防げるだけです。
```js
const s = [5, 6, 7];
s = [1, 2, 3];
s[2] = 45;
console.log(s);
```
`s = [1, 2, 3]` はエラーになります。 `console.log` には値 `[5, 6, 45]` が表示されます。
ご覧のように、オブジェクト `[5, 6, 7]` それ自体をミューテートさせることができ、その場合も変数 `s` は変更された配列 `[5, 6, 45]` を指し示します。 あらゆる配列と同様に、`s` 内の配列要素はミュータブルですが、`const` を使用したため、代入演算子を使用して異なる配列を指し示すように変数識別子 `s` を使用することはできません。
# --instructions--
配列が `const s = [5, 7, 2]` として宣言されています。 さまざまな要素割り当てを使用して、配列を `[2, 5, 7]` に変更してください。
# --hints--
`const` キーワードを置き換えないでください。
```js
(getUserInput) => assert(getUserInput('index').match(/const/g));
```
`s` は (`const` を使用して宣言した) 定数変数である必要があります。
```js
(getUserInput) => assert(getUserInput('index').match(/const\s+s/g));
```
元の配列宣言を変更しないでください。
```js
(getUserInput) =>
assert(
getUserInput('index').match(
/const\s+s\s*=\s*\[\s*5\s*,\s*7\s*,\s*2\s*\]\s*;?/g
)
);
```
`s``[2, 5, 7]` と等しくなるようにする必要があります。
```js
assert.deepEqual(s, [2, 5, 7]);
```
# --seed--
## --seed-contents--
```js
const s = [5, 7, 2];
function editInPlace() {
// Only change code below this line
// Using s = [2, 5, 7] would be invalid
// Only change code above this line
}
editInPlace();
```
# --solutions--
```js
const s = [5, 7, 2];
function editInPlace() {
s[0] = 2;
s[1] = 5;
s[2] = 7;
}
editInPlace();
```

View File

@@ -0,0 +1,104 @@
---
id: 598f48a36c8c40764b4e52b3
title: オブジェクトのミューテーションを防ぐ
challengeType: 1
forumTopicId: 301207
dashedName: prevent-object-mutation
---
# --description--
前のチャレンジで説明したように、`const` 宣言だけではデータのミューテーションを防ぐことはできません。 データが変更されないことを保証するため、JavaScript ではデータの変更を防ぐための `Object.freeze` という関数が用意されています。
スクリプトを strict モードで実行している場合は、オブジェクトを変更しようとしても拒否され、エラーがスローされます。
```js
let obj = {
name:"FreeCodeCamp",
review:"Awesome"
};
Object.freeze(obj);
obj.review = "bad";
obj.newProp = "Test";
console.log(obj);
```
エディターが strict モードで実行されているため、`obj.review``obj.newProp` に代入しようとするとエラーになり、コンソールに値 `{ name: "FreeCodeCamp", review: "Awesome" }` が表示されます。
# --instructions--
このチャレンジでは、`Object.freeze` を使用して、算術定数が変化しないようにします。 `PI` の値の変更、またはプロパティの追加や削除ができないように、`MATH_CONSTANTS` オブジェクトをフリーズする必要があります。
# --hints--
`const` キーワードを置き換えないでください。
```js
(getUserInput) => assert(getUserInput('index').match(/const/g));
```
`MATH_CONSTANTS` は (`const` を使用して宣言した) 定数変数である必要があります。
```js
(getUserInput) =>
assert(getUserInput('index').match(/const\s+MATH_CONSTANTS/g));
```
`MATH_CONSTANTS` の元の宣言を変更しないでください。
```js
(getUserInput) =>
assert(
getUserInput('index').match(
/const\s+MATH_CONSTANTS\s+=\s+{\s+PI:\s+3.14\s+};/g
)
);
```
`PI``3.14` と等しくなるようにしてください。
```js
assert(PI === 3.14);
```
# --seed--
## --seed-contents--
```js
function freezeObj() {
const MATH_CONSTANTS = {
PI: 3.14
};
// Only change code below this line
// Only change code above this line
try {
MATH_CONSTANTS.PI = 99;
} catch(ex) {
console.log(ex);
}
return MATH_CONSTANTS.PI;
}
const PI = freezeObj();
```
# --solutions--
```js
function freezeObj() {
const MATH_CONSTANTS = {
PI: 3.14
};
Object.freeze(MATH_CONSTANTS);
try {
MATH_CONSTANTS.PI = 99;
} catch(ex) {
console.log(ex);
}
return MATH_CONSTANTS.PI;
}
const PI = freezeObj();
```

View File

@@ -0,0 +1,70 @@
---
id: 587d7b8c367417b2b2512b55
title: インポートを使用して JavaScript コードを再利用する
challengeType: 1
forumTopicId: 301208
dashedName: reuse-javascript-code-using-import
---
# --description--
`import` を使用すると、ファイルまたはモジュールのどの部分を読み込むかを選択できます。 前のレッスンの例では、`math_functions.js` ファイルから `add` をエクスポートしました。 次の方法で、別のファイルでインポートして使用することができます。
```js
import { add } from './math_functions.js';
```
ここでは、`import``math_functions.js` 内の `add` を見つけ、その関数だけをインポートして利用できるようにし、残りは無視します。 `./` は、現在のファイルと同じフォルダ内の `math_functions.js` ファイルを探すようにインポートに指示します。 この方法でインポートする場合は、相対ファイルパス (`./`) とファイル拡張子 (`.js`) が必要です。
ファイルから複数のアイテムをインポートするには、次のように `import` ステートメントにアイテムを追加します。
```js
import { add, subtract } from './math_functions.js';
```
# --instructions--
以前のレッスンでエクスポートした `uppercaseString` および `lowercaseString` 関数を現在のファイルで使用できるようにする、適切な `import` ステートメントを追加してください。 これらの関数は、現在のファイルと同じディレクトリにある `string_functions.js`というファイルに含まれています。
# --hints--
`uppercaseString` を正しくインポートする必要があります。
```js
assert(
code.match(
/import\s*{\s*(uppercaseString[^}]*|[^,]*,\s*uppercaseString\s*)}\s+from\s+('|")\.\/string_functions\.js\2/g
)
);
```
`lowercaseString` を正しくインポートする必要があります。
```js
assert(
code.match(
/import\s*{\s*(lowercaseString[^}]*|[^,]*,\s*lowercaseString\s*)}\s+from\s+('|")\.\/string_functions\.js\2/g
)
);
```
# --seed--
## --seed-contents--
```js
// Only change code above this line
uppercaseString("hello");
lowercaseString("WORLD!");
```
# --solutions--
```js
import { uppercaseString, lowercaseString } from './string_functions.js';
uppercaseString("hello");
lowercaseString("WORLD!");
```

View File

@@ -0,0 +1,64 @@
---
id: 587d7b88367417b2b2512b46
title: 関数のデフォルトパラメーターを設定する
challengeType: 1
forumTopicId: 301209
dashedName: set-default-parameters-for-your-functions
---
# --description--
より柔軟な関数を作成できるように、ES6 では関数の<dfn>デフォルトパラメーター</dfn>が導入されています。
次のコードをご覧ください。
```js
const greeting = (name = "Anonymous") => "Hello " + name;
console.log(greeting("John"));
console.log(greeting());
```
コンソールには文字列 `Hello John``Hello Anonymous` が表示されます。
デフォルトパラメーターは、引数が指定されていない場合 (定義されていない場合) に適用されます。 上記の例でわかるように、パラメーター `name` には、パラメーターの値を指定しなければデフォルト値の `Anonymous` が渡されます。 デフォルト値は必要なパラメーターの数だけいくつでも追加できます。
# --instructions--
関数 `increment` を変更してデフォルトパラメーターを追加し、`value` が指定されていない場合に `number` に 1 を加えるようにしてください。
# --hints--
`increment(5, 2)` の結果は `7` になる必要があります。
```js
assert(increment(5, 2) === 7);
```
`increment(5)` の結果は `6` になる必要があります。
```js
assert(increment(5) === 6);
```
`value` に対して デフォルトパラメーター値 `1` を使用する必要があります。
```js
assert(code.match(/value\s*=\s*1/g));
```
# --seed--
## --seed-contents--
```js
// Only change code below this line
const increment = (number, value) => number + value;
// Only change code above this line
```
# --solutions--
```js
const increment = (number, value = 1) => number + value;
```

View File

@@ -0,0 +1,60 @@
---
id: 587d7b8c367417b2b2512b57
title: '* を使用してファイルからすべてのものをインポートする'
challengeType: 1
forumTopicId: 301210
dashedName: use--to-import-everything-from-a-file
---
# --description--
ファイルがあり、現在のファイルにそのすべての内容をインポートしたいとします。 これは `import * as` 構文を使用すれば可能です。 次の例では、`math_functions.js` という名前のファイルの内容を同じディレクトリ内のファイルにインポートします。
```js
import * as myMathModule from "./math_functions.js";
```
上記の `import` ステートメントでは、`myMathModule` というオブジェクトが作成されます。 これは変数名にすぎないため、好きな名前を付けることができます。 このオブジェクトには、`math_functions.js` からエクスポートされたすべてのものが格納されるため、他のオブジェクトプロパティと同じように関数にアクセスできます。 たとえば、インポートした `add` 関数と `subtract` 関数を次のように使用できます。
```js
myMathModule.add(2,3);
myMathModule.subtract(5,3);
```
# --instructions--
このファイル内のコードでは、ファイル `string_functions.js` の内容を必要としています。このファイルは現在のファイルと同じディレクトリにあります。 `import * as` 構文を使用してファイルのすべての内容を `stringFunctions` というオブジェクトにインポートしてください。
# --hints--
`import * as` 構文を正しく使用する必要があります。
```js
assert(
code.match(
/import\s*\*\s*as\s+stringFunctions\s+from\s*('|")\.\/string_functions\.js\1/g
)
);
```
# --seed--
## --seed-contents--
```js
// Only change code above this line
stringFunctions.uppercaseString("hello");
stringFunctions.lowercaseString("WORLD!");
```
# --solutions--
```js
import * as stringFunctions from "./string_functions.js";
// add code above this line
stringFunctions.uppercaseString("hello");
stringFunctions.lowercaseString("WORLD!");
```

View File

@@ -0,0 +1,91 @@
---
id: 587d7b87367417b2b2512b43
title: アロー関数を使用して簡潔な匿名関数を記述する
challengeType: 1
forumTopicId: 301211
dashedName: use-arrow-functions-to-write-concise-anonymous-functions
---
# --description--
JavaScript では多くの場合、特に他の関数に引数として関数を渡す場合に、関数に名前を付ける必要がありません。 代わりに、インライン関数を作成します。 これらの関数は他の場所で再利用することがないため、名前を付ける必要はありません。
これを実現するため、次のような構文をよく使用します。
```js
const myFunc = function() {
const myVar = "value";
return myVar;
}
```
ES6 では、こうした方法で匿名関数を記述する必要がないように、構文糖が用意されています。 代わりに**アロー関数の構文**を使用できます。
```js
const myFunc = () => {
const myVar = "value";
return myVar;
}
```
関数本体がなく戻り値のみが存在する場合は、アロー関数の構文を使用して、コードを囲む中括弧やキーワード `return` を省略できます。 比較的小さな関数であれば、この方法で 1 行のステートメントにまとめることができます。
```js
const myFunc = () => "value";
```
このコードもまた、デフォルトで文字列 `value` を返します。
# --instructions--
`new Date()` を返す関数が変数 `magic` に割り当てられています。この関数を、アロー関数の構文を使用するように書き換えてください。 また、キーワード `var` による定義を使用しないでください。
# --hints--
`var` キーワードを置き換える必要があります。
```js
(getUserInput) => assert(!getUserInput('index').match(/var/g));
```
`magic` は (`const` を使用して宣言した) 定数変数である必要があります。
```js
(getUserInput) => assert(getUserInput('index').match(/const\s+magic/g));
```
`magic``function` である必要があります。
```js
assert(typeof magic === 'function');
```
`magic()` は正しい日付を返す必要があります。
```js
assert(magic().setHours(0, 0, 0, 0) === new Date().setHours(0, 0, 0, 0));
```
`function` キーワードは使用しないでください。
```js
(getUserInput) => assert(!getUserInput('index').match(/function/g));
```
# --seed--
## --seed-contents--
```js
var magic = function() {
return new Date();
};
```
# --solutions--
```js
const magic = () => {
return new Date();
};
```

View File

@@ -0,0 +1,100 @@
---
id: 587d7b8b367417b2b2512b53
title: class 構文を使用してコンストラクター関数を定義する
challengeType: 1
forumTopicId: 301212
dashedName: use-class-syntax-to-define-a-constructor-function
---
# --description--
ES6 では、<dfn>class</dfn> キーワードを使用してオブジェクトを作成する新しい構文が提供されています。
`class` 構文は単なる構文にすぎません。Java、Python、Ruby などの言語とは異なり、オブジェクト指向のパラダイムをクラスベースで本格的に実装するものではないことに注意してください。
ES5 では、通常は `constructor` 関数を定義し、`new` キーワードを使用してオブジェクトをインスタンス化します。
```js
var SpaceShuttle = function(targetPlanet){
this.targetPlanet = targetPlanet;
}
var zeus = new SpaceShuttle('Jupiter');
```
`class` 構文は、こうした `constructor` 関数による作成の代わりとなるだけです。
```js
class SpaceShuttle {
constructor(targetPlanet) {
this.targetPlanet = targetPlanet;
}
}
const zeus = new SpaceShuttle('Jupiter');
```
`class` キーワードによって、コンストラクターの追加先となる新しい関数を宣言していることに注意してください。 このコンストラクターは、新しいオブジェクトを作成するために `new` が呼び出されるときに呼び出されます。
**注:** ES6 のクラス名には、上記の `SpaceShuttle` のように「アッパーキャメルケース」を使用するのが慣例になっています。
`constructor` メソッドは、class を使用して作成されたオブジェクトを生成して初期化するための特別なメソッドです。 詳細については、「JavaScript アルゴリズムとデータ構造」認定講座の「オブジェクト指向プログラミング」のセクションを参照してください。
# --instructions--
`class` キーワードを使用して `constructor` を記述し、`Vegetable` クラスを作成してください。
`Vegetable` クラスを使用すると、`constructor` に渡されたプロパティ `name` を持つ野菜オブジェクトを作成できます。
# --hints--
`Vegetable` は、`constructor` メソッドが定義された `class` である必要があります。
```js
assert(
typeof Vegetable === 'function' && typeof Vegetable.constructor === 'function'
);
```
`class` キーワードを使用する必要があります。
```js
assert(code.match(/class/g));
```
`Vegetable` をインスタンス化できる必要があります。
```js
assert(() => {
const a = new Vegetable('apple');
return typeof a === 'object';
});
```
`carrot.name``carrot` を返す必要があります。
```js
assert(carrot.name == 'carrot');
```
# --seed--
## --seed-contents--
```js
// Only change code below this line
// Only change code above this line
const carrot = new Vegetable('carrot');
console.log(carrot.name); // Should display 'carrot'
```
# --solutions--
```js
class Vegetable {
constructor(name) {
this.name = name;
}
}
const carrot = new Vegetable('carrot');
```

View File

@@ -0,0 +1,71 @@
---
id: 587d7b89367417b2b2512b4b
title: 分割代入を使用して配列から変数を代入する
challengeType: 1
forumTopicId: 301213
dashedName: use-destructuring-assignment-to-assign-variables-from-arrays
---
# --description--
ES6 では、配列の分割はオブジェクトの分割と同じくらい簡単になります。
スプレッド演算子と配列分割の重要な違いは、スプレッド演算子は配列のすべての内容をカンマ区切りのリストに展開することです。 したがって、どの要素をどの変数に代入するかを選ぶことはできません。
配列の分割では、まさにそれを行うことができます。
```js
const [a, b] = [1, 2, 3, 4, 5, 6];
console.log(a, b);
```
コンソールは `a``b` の値を `1, 2` と表示します。
変数 `a` には配列の最初の値が代入され、 `b` には配列の 2 番目の値が代入されます。 目的のインデックスに到達するためにカンマを利用して分割することにより、配列内の任意のインデックスの値にアクセスすることもできます。
```js
const [a, b,,, c] = [1, 2, 3, 4, 5, 6];
console.log(a, b, c);
```
コンソールは `a``b``c` の値を `1, 2, 5` と表示します。
# --instructions--
分割代入を使用して `a``b` の値を入れ替え、`b` に保存されている値を `a` が受け取り、`a` に保存されている値を `b` が受け取るようにしてください。
# --hints--
`a` の値は入れ替え後に `6` となります。
```js
assert(a === 6);
```
`b` の値は入れ替え後に `8` となります。
```js
assert(b === 8);
```
配列の分割を使用して `a``b` を入れ替える必要があります。
```js
assert(/\[\s*(\w)\s*,\s*(\w)\s*\]\s*=\s*\[\s*\2\s*,\s*\1\s*\]/g.test(code));
```
# --seed--
## --seed-contents--
```js
let a = 8, b = 6;
// Only change code below this line
```
# --solutions--
```js
let a = 8, b = 6;
[a, b] = [b, a];
```

View File

@@ -0,0 +1,106 @@
---
id: 587d7b89367417b2b2512b4a
title: 分割代入を使用してネストされたオブジェクトから変数を代入する
challengeType: 1
forumTopicId: 301214
dashedName: use-destructuring-assignment-to-assign-variables-from-nested-objects
---
# --description--
前の 2 つのレッスンと同じ原則を使用して、ネストされたオブジェクトから値を分割することができます。
前の例と同様のオブジェクトを使用します。
```js
const user = {
johnDoe: {
age: 34,
email: 'johnDoe@freeCodeCamp.com'
}
};
```
オブジェクトのプロパティの値を抽出し、同じ名前の変数に代入する方法を次に示します。
```js
const { johnDoe: { age, email }} = user;
```
オブジェクトのプロパティの値を異なる名前の変数に代入する方法を次に示します。
```js
const { johnDoe: { age: userAge, email: userEmail }} = user;
```
# --instructions--
2 つの代入を同等の分割代入に置き換えてください。 ここでも、`LOCAL_FORECAST` オブジェクトの `today.low``today.high` の値を変数 `lowToday``highToday` に代入します。
# --hints--
ES5 の代入構文を削除する必要があります。
```js
assert(
!code.match(/lowToday = LOCAL_FORECAST\.today\.low/g) &&
!code.match(/highToday = LOCAL_FORECAST\.today.high/g)
);
```
分割を使用して `lowToday` 変数を作成する必要があります。
```js
assert(
code.match(
/(var|const|let)\s*{\s*today\s*:\s*{\s*(low\s*:\s*lowToday[^}]*|[^,]*,\s*low\s*:\s*lowToday\s*)}\s*}\s*=\s*LOCAL_FORECAST(;|\s+|\/\/)/g
)
);
```
分割を使用して `highToday` 変数を作成する必要があります。
```js
assert(
code.match(
/(var|const|let)\s*{\s*today\s*:\s*{\s*(high\s*:\s*highToday[^}]*|[^,]*,\s*high\s*:\s*highToday\s*)}\s*}\s*=\s*LOCAL_FORECAST(;|\s+|\/\/)/g
)
);
```
`lowToday``64` に等しくなり、`highToday``77` に等しくなる必要があります。
```js
assert(lowToday === 64 && highToday === 77);
```
# --seed--
## --seed-contents--
```js
const LOCAL_FORECAST = {
yesterday: { low: 61, high: 75 },
today: { low: 64, high: 77 },
tomorrow: { low: 68, high: 80 }
};
// Only change code below this line
const lowToday = LOCAL_FORECAST.today.low;
const highToday = LOCAL_FORECAST.today.high;
// Only change code above this line
```
# --solutions--
```js
const LOCAL_FORECAST = {
yesterday: { low: 61, high: 75 },
today: { low: 64, high: 77 },
tomorrow: { low: 68, high: 80 }
};
const { today: { low: lowToday, high: highToday }} = LOCAL_FORECAST;
```

View File

@@ -0,0 +1,97 @@
---
id: 587d7b89367417b2b2512b49
title: 分割代入を使用してオブジェクトから変数を代入する
challengeType: 1
forumTopicId: 301215
dashedName: use-destructuring-assignment-to-assign-variables-from-objects
---
# --description--
分割を使用すると、値を抽出する際に新しい変数名を割り当てることができます。 これを行うには、値を代入する際にコロンの後に新しい名前を指定します。
前の例と同じオブジェクトを使用します。
```js
const user = { name: 'John Doe', age: 34 };
```
代入で新しい変数名を指定する方法を次に示します。
```js
const { name: userName, age: userAge } = user;
```
`user.name` の値を抽出し、その値を `userName` という名前の新しい変数に代入する」と解釈することもできます。 `userName` の値は文字列 `John Doe` になり、`userAge`の値は `34` になります。
# --instructions--
2 つの代入を同等の分割代入に置き換えてください。 ここでも、`HIGH_TEMPERATURES` オブジェクトの `today``tomorrow` の値を変数 `highToday``highTomorrow` に代入する必要があります。
# --hints--
ES5 の代入構文を削除する必要があります。
```js
assert(
!code.match(/highToday = HIGH_TEMPERATURES\.today/g) &&
!code.match(/highTomorrow = HIGH_TEMPERATURES\.tomorrow/g)
);
```
分割を使用して `highToday` 変数を作成する必要があります。
```js
assert(
code.match(
/(var|const|let)\s*{\s*(today\s*:\s*highToday[^}]*|[^,]*,\s*today\s*:\s*highToday\s*)}\s*=\s*HIGH_TEMPERATURES(;|\s+|\/\/)/g
)
);
```
分割を使用して `highTomorrow` 変数を作成する必要があります。
```js
assert(
code.match(
/(var|const|let)\s*{\s*(tomorrow\s*:\s*highTomorrow[^}]*|[^,]*,\s*tomorrow\s*:\s*highTomorrow\s*)}\s*=\s*HIGH_TEMPERATURES(;|\s+|\/\/)/g
)
);
```
`highToday``77` に等しくなり、`highTomorrow``80` に等しくなる必要があります。
```js
assert(highToday === 77 && highTomorrow === 80);
```
# --seed--
## --seed-contents--
```js
const HIGH_TEMPERATURES = {
yesterday: 75,
today: 77,
tomorrow: 80
};
// Only change code below this line
const highToday = HIGH_TEMPERATURES.today;
const highTomorrow = HIGH_TEMPERATURES.tomorrow;
// Only change code above this line
```
# --solutions--
```js
const HIGH_TEMPERATURES = {
yesterday: 75,
today: 77,
tomorrow: 80
};
const { today: highToday, tomorrow: highTomorrow } = HIGH_TEMPERATURES;
```

View File

@@ -0,0 +1,101 @@
---
id: 5cfa550e84205a357704ccb6
title: 分割代入を使用してオブジェクトから値を抽出する
challengeType: 1
forumTopicId: 301216
dashedName: use-destructuring-assignment-to-extract-values-from-objects
---
# --description--
<dfn>分割代入</dfn>は ES6 で導入された特別な構文で、オブジェクトから値を直接抽出して適切に代入することができます。
次の ES5 コードを考えてみましょう。
```js
const user = { name: 'John Doe', age: 34 };
const name = user.name;
const age = user.age;
```
`name` は文字列の値 `John Doe` になり、`age` は数値 `34` になります。
ES6 の分割構文を使用すると同等の分割ステートメントは次のようになります。
```js
const { name, age } = user;
```
ここでも、`name` は文字列の値 `John Doe` になり、`age` は数値 `34` になります。
ここでは、`name``age` という変数が作成され、 `user` オブジェクトからそれぞれの値が代入されます。 ご覧のようにコードをすっきりと記述できます。
必要に応じてオブジェクトから値をいくつでも抽出できます。
# --instructions--
2 つの代入を同等の分割代入に置き換えてください。 ここでも、`HIGH_TEMPERATURES` オブジェクトの `today``tomorrow` の値を変数 `today``tomorrow` に代入する必要があります。
# --hints--
ES5 の代入構文を削除する必要があります。
```js
assert(
!code.match(/today\s*=\s*HIGH_TEMPERATURES\.(today|tomorrow)/g)
);
```
分割を使用して `today` 変数を作成する必要があります。
```js
assert(
code.match(/(var|let|const)\s*{\s*(today[^}]*|[^,]*,\s*today)\s*}\s*=\s*HIGH_TEMPERATURES(;|\s+|\/\/)/g)
);
```
分割を使用して `tomorrow` 変数を作成する必要があります。
```js
assert(
code.match(/(var|let|const)\s*{\s*(tomorrow[^}]*|[^,]*,\s*tomorrow)\s*}\s*=\s*HIGH_TEMPERATURES(;|\s+|\/\/)/g)
);
```
`today``77` に等しくなり、`tomorrow``80` に等しくなる必要があります。
```js
assert(today === 77 && tomorrow === 80);
```
# --seed--
## --seed-contents--
```js
const HIGH_TEMPERATURES = {
yesterday: 75,
today: 77,
tomorrow: 80
};
// Only change code below this line
const today = HIGH_TEMPERATURES.today;
const tomorrow = HIGH_TEMPERATURES.tomorrow;
// Only change code above this line
```
# --solutions--
```js
const HIGH_TEMPERATURES = {
yesterday: 75,
today: 77,
tomorrow: 80
};
const { today, tomorrow } = HIGH_TEMPERATURES;
```

View File

@@ -0,0 +1,94 @@
---
id: 587d7b8a367417b2b2512b4d
title: 分割代入を使用してオブジェクトを関数のパラメーターとして渡す
challengeType: 1
forumTopicId: 301217
dashedName: use-destructuring-assignment-to-pass-an-object-as-a-functions-parameters
---
# --description--
場合によっては関数の引数自体にオブジェクトを分割することもできます。
次のコードを考えてみましょう。
```js
const profileUpdate = (profileData) => {
const { name, age, nationality, location } = profileData;
}
```
このように、オブジェクトを分割して関数に渡す効果を得ることができます。 中に記述することもできます。
```js
const profileUpdate = ({ name, age, nationality, location }) => {
}
```
`profileData` が上記の関数に渡されると、関数のパラメーターから値が分割されて、関数内で使用されます。
# --instructions--
`half` 関数の引数内で分割代入を使用して、関数内で `max``min` だけを渡してください。
# --hints--
`stats``object` である必要があります。
```js
assert(typeof stats === 'object');
```
`half(stats)``28.015` である必要があります。
```js
assert(half(stats) === 28.015);
```
分割を使用する必要があります。
```js
assert(__helpers.removeWhiteSpace(code).match(/half=\({\w+,\w+}\)/));
```
分割されたパラメーターを使用する必要があります。
```js
assert(!code.match(/stats\.max|stats\.min/));
```
# --seed--
## --seed-contents--
```js
const stats = {
max: 56.78,
standard_deviation: 4.34,
median: 34.54,
mode: 23.87,
min: -0.75,
average: 35.85
};
// Only change code below this line
const half = (stats) => (stats.max + stats.min) / 2.0;
// Only change code above this line
```
# --solutions--
```js
const stats = {
max: 56.78,
standard_deviation: 4.34,
median: 34.54,
mode: 23.87,
min: -0.75,
average: 35.85
};
const half = ( {max, min} ) => (max + min) / 2.0;
```

View File

@@ -0,0 +1,85 @@
---
id: 587d7b8a367417b2b2512b4c
title: >-
分割代入で残余引数を使用して配列要素を割り当て直す
challengeType: 1
forumTopicId: 301218
dashedName: >-
use-destructuring-assignment-with-the-rest-parameter-to-reassign-array-elements
---
# --description--
配列の分割において、残りの要素を別の配列にまとめたいことがあります。
次に示すように、`Array.prototype.slice()` に似た結果になります。
```js
const [a, b, ...arr] = [1, 2, 3, 4, 5, 7];
console.log(a, b);
console.log(arr);
```
コンソールには、値 `1, 2``[3, 4, 5, 7]` が表示されます。
変数 `a``b` は配列の最初と 2 番目の値を受け取ります。 その後は残余引数になっているため、`arr` は残りの値を配列の形で受け取ります。 残余引数は、リスト内の最後の変数としてのみ正しく動作します。 したがって、残余引数を使用して元の配列の最後の要素を取り除いた部分配列を取得することはできません。
# --instructions--
分割代入と残余変数を使用して、`Array.prototype.slice()` の効果を実現してください。`arr` が、元の配列 `source` から最初の 2 つの要素を省いた部分配列となるようにします。
# --hints--
`arr``[3,4,5,6,7,8,9,10]` である必要があります。
```js
assert(arr.every((v, i) => v === i + 3) && arr.length === 8);
```
`source``[1,2,3,4,5,6,7,8,9,10]` である必要があります。
```js
assert(source.every((v, i) => v === i + 1) && source.length === 10);
```
`Array.slice()` は使用しないでください。
```js
(getUserInput) => assert(!getUserInput('index').match(/slice/g));
```
`list` の分割を使用する必要があります。
```js
assert(
__helpers
.removeWhiteSpace(code)
.match(/\[(([_$a-z]\w*)?,){1,}\.\.\.arr\]=list/i)
);
```
# --seed--
## --seed-contents--
```js
const source = [1,2,3,4,5,6,7,8,9,10];
function removeFirstTwo(list) {
// Only change code below this line
const arr = list; // Change this line
// Only change code above this line
return arr;
}
const arr = removeFirstTwo(source);
```
# --solutions--
```js
const source = [1,2,3,4,5,6,7,8,9,10];
function removeFirstTwo(list) {
const [, , ...arr] = list;
return arr;
}
const arr = removeFirstTwo(source);
```

View File

@@ -0,0 +1,85 @@
---
id: 587d7b8c367417b2b2512b56
title: export を使用してコードブロックを共有する
challengeType: 1
forumTopicId: 301219
dashedName: use-export-to-share-a-code-block
---
# --description--
算術演算に関わる関数をいくつか含む `math_functions.js` というファイルがあるとします。 それらの関数の 1 つは変数 `add` に格納されています。この関数は、2 つの数字を受け取り、その和を返します。 この関数を、複数の別の JavaScript ファイルで使用したいとします。 関数をそれらの他のファイルと共有するには、まず `export` (エクスポート) する必要があります。
```js
export const add = (x, y) => {
return x + y;
}
```
上記は単一の関数をエクスポートする一般的な方法ですが、次のようにしても同じことができます。
```js
const add = (x, y) => {
return x + y;
}
export { add };
```
変数や関数をエクスポートすると、それを別のファイルに import (インポート) して使用でき、コードを記述し直す必要がなくなります。 複数をエクスポートする場合は、次のように、エクスポートしたいものそれぞれについて 1 番目の例と同じことを繰り返すか、または 2 番目の例の export ステートメントにそれらを記述します。
```js
export { add, subtract };
```
# --instructions--
エディターに、 文字列に関連した関数が 2 つあります。 好きなメソッドを使用してこれら 2 つの関数の両方をエクスポートしてください。
# --hints--
`uppercaseString` を正しくエクスポートする必要があります。
```js
assert(
code.match(
/(export\s+const\s+uppercaseString|export\s*{\s*(uppercaseString[^}]*|[^,]*,\s*uppercaseString\s*)})/g
)
);
```
`lowercaseString` を正しくエクスポートする必要があります。
```js
assert(
code.match(
/(export\s+const\s+lowercaseString|export\s*{\s*(lowercaseString[^}]*|[^,]*,\s*lowercaseString\s*)})/g
)
);
```
# --seed--
## --seed-contents--
```js
const uppercaseString = (string) => {
return string.toUpperCase();
}
const lowercaseString = (string) => {
return string.toLowerCase()
}
```
# --solutions--
```js
export const uppercaseString = (string) => {
return string.toUpperCase();
}
export const lowercaseString = (string) => {
return string.toLowerCase()
}
```

View File

@@ -0,0 +1,174 @@
---
id: 587d7b8c367417b2b2512b54
title: getter や setter を使用してオブジェクトへのアクセスを管理する
challengeType: 1
forumTopicId: 301220
dashedName: use-getters-and-setters-to-control-access-to-an-object
---
# --description--
オブジェクトから値を取得したり、オブジェクト内のプロパティの値を設定したりできます。
これらは従来から <dfn>getters</dfn> および <dfn>setters</dfn> と呼ばれています。
getter 関数は、ユーザーがプライベート変数に直接アクセスしなくても、単にオブジェクトのプライベート変数の値をユーザーに返す (値を取得する) ことを目的としたものです。
setter 関数の目的は、setter 関数に渡された値に基づいて、オブジェクトのプライベート変数の値を変更 (設定) することです。 この変更には計算を含めることができ、以前の値を完全に上書きすることも可能です。
```js
class Book {
constructor(author) {
this._author = author;
}
// getter
get writer() {
return this._author;
}
// setter
set writer(updatedAuthor) {
this._author = updatedAuthor;
}
}
const novel = new Book('anonymous');
console.log(novel.writer);
novel.writer = 'newAuthor';
console.log(novel.writer);
```
この例では、コンソールに文字列 `anonymous``newAuthor` が表示されます。
getter と setter の呼び出しに使用している構文に注目してください。 関数とは違う形式のようにも見えます。 getter と setter が重要なのは、内部の実装の詳細を隠してくれるからです。
**注:** プライベート変数の名前には前にアンダースコア (`_`) を付けることが慣例になっています。 しかし、変数をプライベート変数として扱うのが慣例になっているわけではありません。
# --instructions--
`class` キーワードを使用して `Thermostat` クラスを作成してください。 `constructor` は華氏温度を受け取ります。
クラスでは、温度を摂氏で取得する `getter` と、温度を摂氏で設定する `setter` を作成してください。
関係式は `C = 5/9 * (F - 32)` および `F = C * 9.0 / 5 + 32` です。`F` は華氏温度の値で、`C` は摂氏での同じ温度です。
**注:** このクラスを実装する場合、クラスでは華氏または摂氏のいずれか 1 つの尺度で温度を追跡することになります。
getter と setter を使用することで、 プログラマーが API の作成でどちらの尺度を追跡しているかに関係なく、別のユーザーはその API を使用して正しい結果を得られるようになります。
つまり、実装の詳細が抽象化され、ユーザーからは見えなくなります。
# --hints--
`Thermostat` は、`constructor` メソッドを定義した `class` である必要があります。
```js
assert(
typeof Thermostat === 'function' &&
typeof Thermostat.constructor === 'function'
);
```
`class` キーワードを使用する必要があります。
```js
assert(code.match(/class/g));
```
`Thermostat` をインスタンス化できるようにする必要があります。
```js
assert(
(() => {
const t = new Thermostat(122);
return typeof t === 'object';
})()
);
```
華氏値でインスタンス化された場合、`Thermostat` は正しい `temperature` を設定する必要があります。
```js
assert(
(() => {
const t = new Thermostat(122);
return t.temperature === 50;
})()
);
```
`getter` を定義する必要があります。
```js
assert(
(() => {
const desc = Object.getOwnPropertyDescriptor(
Thermostat.prototype,
'temperature'
);
return !!desc && typeof desc.get === 'function';
})()
);
```
`setter` を定義する必要があります。
```js
assert(
(() => {
const desc = Object.getOwnPropertyDescriptor(
Thermostat.prototype,
'temperature'
);
return !!desc && typeof desc.set === 'function';
})()
);
```
`setter` が摂氏値で呼び出されたとき、`temperature` を設定する必要があります。
```js
assert(
(() => {
const t = new Thermostat(32);
t.temperature = 26;
const u = new Thermostat(32);
u.temperature = 50;
return t.temperature === 26 && u.temperature === 50;
})()
);
```
# --seed--
## --seed-contents--
```js
// Only change code below this line
// Only change code above this line
const thermos = new Thermostat(76); // Setting in Fahrenheit scale
let temp = thermos.temperature; // 24.44 in Celsius
thermos.temperature = 26;
temp = thermos.temperature; // 26 in Celsius
```
# --solutions--
```js
class Thermostat {
constructor(fahrenheit) {
this._tempInCelsius = 5/9 * (fahrenheit - 32);
}
get temperature(){
return this._tempInCelsius;
}
set temperature(newTemp){
this._tempInCelsius = newTemp;
}
}
const thermos = new Thermostat(76); // Setting in Fahrenheit scale
let temp = thermos.temperature; // 24.44 in Celsius
thermos.temperature = 26;
temp = thermos.temperature; // 26 in Celsius
```

View File

@@ -0,0 +1,80 @@
---
id: 587d7b88367417b2b2512b47
title: 関数パラメーターで残余引数を使用する
challengeType: 1
forumTopicId: 301221
dashedName: use-the-rest-parameter-with-function-parameters
---
# --description--
より柔軟な関数を作成できるように、ES6 では関数パラメーターに<dfn>残余引数</dfn>が導入されています。 残余引数を使用すると、可変個の引数を取る関数を作成できます。 これらの引数は配列に格納され、後で関数内からアクセスできます。
次のコードをご覧ください。
```js
function howMany(...args) {
return "You have passed " + args.length + " arguments.";
}
console.log(howMany(0, 1, 2));
console.log(howMany("string", null, [1, 2, 3], { }));
```
コンソールには、文字列 `You have passed 3 arguments.``You have passed 4 arguments.` が表示されます。
残余引数を使用すると、`args` 配列を調べる必要がなくなり、パラメーターの配列に `map()``filter()``reduce()` を適用できるようになります。
# --instructions--
残余引数を使用して関数 `sum` を変更し、関数 `sum` が任意の数の引数を受け取ってその和を返せるようにしてください。
# --hints--
`sum(0,1,2)` の結果は 3 になる必要があります。
```js
assert(sum(0, 1, 2) === 3);
```
`sum(1,2,3,4)`の結果 は 10 になる必要があります。
```js
assert(sum(1, 2, 3, 4) === 10);
```
`sum(5)` の結果は 5 になる必要があります。
```js
assert(sum(5) === 5);
```
`sum()` の結果は 0 になる必要があります。
```js
assert(sum() === 0);
```
`sum` は、`args` パラメーターで残余引数の構文 (`...`) を使用するアロー関数にする必要があります。
```js
assert(__helpers.removeWhiteSpace(code).match(/sum=\(\.\.\.args\)=>/));
```
# --seed--
## --seed-contents--
```js
const sum = (x, y, z) => {
const args = [x, y, z];
return args.reduce((a, b) => a + b, 0);
}
```
# --solutions--
```js
const sum = (...args) => {
return args.reduce((a, b) => a + b, 0);
}
```

View File

@@ -0,0 +1,84 @@
---
id: 587d7b89367417b2b2512b48
title: スプレッド演算子を使用して配列をインプレースで評価する
challengeType: 1
forumTopicId: 301222
dashedName: use-the-spread-operator-to-evaluate-arrays-in-place
---
# --description--
ES6 では<dfn>スプレッド演算子</dfn>が導入されています。この演算子を使用すると、複数のパラメーターまたは要素が要求される場所の中で配列やその他の式を展開することができます。
次の ES5 コードでは、配列の最大値を計算するために `apply()` を使用しています。
```js
var arr = [6, 89, 3, 45];
var maximus = Math.max.apply(null, arr);
```
`maximus` の値は `89` になります。
`Math.max(arr)``NaN` を返すため、`Math.max.apply(null, arr)` を使用する必要がありました。 `Math.max()` は、配列ではなくコンマ区切りの引数を要求します。 スプレッド演算子を使用すれば、この構文が読みやすくなり、管理しやすくなります。
```js
const arr = [6, 89, 3, 45];
const maximus = Math.max(...arr);
```
`maximus` の値は `89` になります。
`...arr` は、分割された配列を返します。 つまり、スプレッド演算子によって配列が*展開*されます。 ただし、スプレッド演算子が有効なのは「インプレース」のみです。つまり、関数の引数や配列リテラルなどの中でのみ動作します。 次のコードは有効ではありません。
```js
const spreaded = ...arr;
```
# --instructions--
スプレッド演算子を使用して、 `arr1` のすべての内容を別の配列 `arr2` にコピーしてください。
# --hints--
`arr2``arr1` の正確なコピーである必要があります。
```js
assert(arr2.every((v, i) => v === arr1[i]) && arr2.length);
```
`...` スプレッド演算子を使用して `arr1` を複製する必要があります。
```js
assert(code.match(/Array\(\s*\.\.\.arr1\s*\)|\[\s*\.\.\.arr1\s*\]/));
```
`arr1` が変更されても `arr2` は変わりません。
```js
assert((arr1, arr2) => {
arr1.push('JUN');
return arr2.length < arr1.length;
});
```
# --seed--
## --seed-contents--
```js
const arr1 = ['JAN', 'FEB', 'MAR', 'APR', 'MAY'];
let arr2;
arr2 = []; // Change this line
console.log(arr2);
```
# --solutions--
```js
const arr1 = ['JAN', 'FEB', 'MAR', 'APR', 'MAY'];
let arr2;
arr2 = [...arr1];
```

View File

@@ -0,0 +1,94 @@
---
id: 587d7b88367417b2b2512b44
title: パラメーターのあるアロー関数を記述する
challengeType: 1
forumTopicId: 301223
dashedName: write-arrow-functions-with-parameters
---
# --description--
通常の関数と同様に、アロー関数にも引数を渡すことができます。
```js
const doubler = (item) => item * 2;
doubler(4);
```
`doubler(4)` は値 `8` を返します。
アロー関数のパラメーターが 1 つしかない場合は、パラメーターを囲む丸括弧を省略してもかまいません。
```js
const doubler = item => item * 2;
```
複数の引数をアロー関数に渡すこともできます。
```js
const multiplier = (item, multi) => item * multi;
multiplier(4, 2);
```
`multiplier(4, 2)` は値 `8` を返します。
# --instructions--
`arr2` の内容を `arr1` の末尾に追加する `myConcat` 関数を書き換えて、アロー関数の構文を使用してください。
# --hints--
`var` キーワードを置き換える必要があります。
```js
(getUserInput) => assert(!getUserInput('index').match(/var/g));
```
`myConcat` は (`const` を使用して宣言した) 定数変数である必要があります。
```js
(getUserInput) => assert(getUserInput('index').match(/const\s+myConcat/g));
```
`myConcat` は、2 つのパラメーターを持つアロー関数にする必要があります。
```js
assert(
/myConcat=\(\w+,\w+\)=>/.test(code.replace(/\s/g, '')) &&
typeof myConcat === 'function'
);
```
`myConcat()``[1, 2, 3, 4, 5]` を返す必要があります。
```js
assert.deepEqual(myConcat([1, 2], [3, 4, 5]), [1, 2, 3, 4, 5]);
```
`function` キーワードは使用しないでください。
```js
(getUserInput) => assert(!getUserInput('index').match(/function/g));
```
# --seed--
## --seed-contents--
```js
var myConcat = function(arr1, arr2) {
return arr1.concat(arr2);
};
console.log(myConcat([1, 2], [3, 4, 5]));
```
# --solutions--
```js
const myConcat = (arr1, arr2) => {
return arr1.concat(arr2);
};
console.log(myConcat([1, 2], [3, 4, 5]));
```

View File

@@ -0,0 +1,86 @@
---
id: 587d7b8b367417b2b2512b50
title: ES6 を使用して簡潔な宣言的関数を記述する
challengeType: 1
forumTopicId: 301224
dashedName: write-concise-declarative-functions-with-es6
---
# --description--
ES5 では、オブジェクト内で関数を定義する場合、次のようにキーワード `function` を使用する必要があります。
```js
const person = {
name: "Taylor",
sayHello: function() {
return `Hello! My name is ${this.name}.`;
}
};
```
ES6 では、オブジェクト内で関数を定義する場合、`function` キーワードとコロンを完全に省略できます。 この構文の例を次に示します。
```js
const person = {
name: "Taylor",
sayHello() {
return `Hello! My name is ${this.name}.`;
}
};
```
# --instructions--
オブジェクト `bicycle` 内の関数 `setGear` を、上記で説明した簡潔な構文を使用してリファクタリングしてください。
# --hints--
従来の関数式は使用しないでください。
```js
(getUserInput) => assert(!code.match(/function/));
```
`setGear` は宣言的な関数にする必要があります。
```js
assert(
typeof bicycle.setGear === 'function' && code.match(/setGear\s*\(.+\)\s*\{/)
);
```
`bicycle.setGear(48)` は、`gear` の値を 48 に変更する必要があります。
```js
assert(new bicycle.setGear(48).gear === 48);
```
# --seed--
## --seed-contents--
```js
// Only change code below this line
const bicycle = {
gear: 2,
setGear: function(newGear) {
this.gear = newGear;
}
};
// Only change code above this line
bicycle.setGear(3);
console.log(bicycle.gear);
```
# --solutions--
```js
const bicycle = {
gear: 2,
setGear(newGear) {
this.gear = newGear;
}
};
bicycle.setGear(3);
```

View File

@@ -0,0 +1,75 @@
---
id: 587d7b8a367417b2b2512b4f
title: オブジェクトプロパティの省略形を使用して簡潔なオブジェクトリテラル宣言を記述する
challengeType: 1
forumTopicId: 301225
dashedName: write-concise-object-literal-declarations-using-object-property-shorthand
---
# --description--
ES6 では、オブジェクトリテラルを簡単に定義できるように、便利なサポートが提供されるようになりました。
次のコードを考えてみましょう。
```js
const getMousePosition = (x, y) => ({
x: x,
y: y
});
```
`getMousePosition` は、2 つのプロパティを含むオブジェクトを返すシンプルな関数です。 ES6 では、`x: x` を記述するという冗長さをなくすために、構文糖が導入されました。 `x` を一度書けば、あとは自動的に `x: x` (または同等のコード) に変換されます。 新しい構文を使用して書き換えた上記と同じ関数は次のようになります。
```js
const getMousePosition = (x, y) => ({ x, y });
```
# --instructions--
オブジェクトプロパティの省略形とオブジェクトリテラルを使用して、`name``age``gender` の各プロパティを持つオブジェクトを作成して返してください。
# --hints--
`createPerson("Zodiac Hasbro", 56, "male")``{name: "Zodiac Hasbro", age: 56, gender: "male"}` を返す必要があります。
```js
assert.deepEqual(
{ name: 'Zodiac Hasbro', age: 56, gender: 'male' },
createPerson('Zodiac Hasbro', 56, 'male')
);
```
コードでは `key:value` の形式を使用しないでください。
```js
(getUserInput) => assert(!getUserInput('index').match(/:/g));
```
# --seed--
## --seed-contents--
```js
const createPerson = (name, age, gender) => {
// Only change code below this line
return {
name: name,
age: age,
gender: gender
};
// Only change code above this line
};
```
# --solutions--
```js
const createPerson = (name, age, gender) => {
return {
name,
age,
gender
};
};
```