Skip to content

Commit f37e998

Browse files
committed
2022-04-17 修正分
1 parent 20ca54e commit f37e998

File tree

38 files changed

+1637
-6
lines changed

38 files changed

+1637
-6
lines changed

docs/1-trial-session/03-javascript/index.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,13 @@ document.write("Hello World3");
6666

6767
## コメント
6868

69-
`//` から行末までは**コメント**とみなされ、プログラムの実行に影響を与えません。この講座内でもプログラムの意味を説明するのに利用していきます。
69+
`//` から行末までの部分や、`/*` から `*/` で囲まれた部分は**コメント**とみなされ、プログラムの実行に影響を与えません。この講座内でもプログラムの意味を説明するのに利用していきます。
7070

7171
```javascript title="script.js"
7272
// この部分はコメントです
7373
document.write("Hello World"); // この部分もコメントです
74+
/* この部分も
75+
やはりコメントです。 */
7476
```
7577

7678
:::tip

docs/1-trial-session/05-variables/samples/compound-assignment/script.js

Lines changed: 0 additions & 3 deletions
This file was deleted.

docs/1-trial-session/08-functions/index.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ title: 関数
33
---
44

55
import Term from "@site/src/components/Term";
6+
import returnValueVideo from "./return-value.mp4";
67

78
## 処理の共通化
89

@@ -57,6 +58,8 @@ document.write(add(3, 4));
5758

5859
上の例の 4 行目で、<Term type="javascriptExpression">式</Term> `add(3, 4)` が<Term type="javascriptEvaluation">評価</Term>されると、 `a = 3, b = 4` として `add` <Term type="javascriptFunction">関数</Term>が実行されます。`add`<Term type="javascript">関数</Term>の中で<Term type="javascriptStatement">文</Term> `return a + b;` が実行されると、<Term type="javascriptExpression">式</Term> `a + b` が<Term type="javascriptEvaluation">評価</Term>され、`7` になります。これにより、 `add` <Term type="javascriptFunction">関数</Term>は `7` を<Term type="javascriptReturn">返し</Term>、<Term type="javascriptExpression">式</Term> `add(3, 4)` の<Term type="javascriptEvaluation">評価</Term>結果は `7` となります。
5960

61+
<video src={returnValueVideo} controls autoPlay muted loop />
62+
6063
## <Term type="javascriptVariable">変数</Term>の<Term type="javascriptScope">スコープ</Term>
6164

6265
<p><Term type="javascriptFunction">関数</Term>内で<Term type="javascriptDeclaration">宣言</Term>された<Term type="javascriptVariable">変数</Term>は、<Term type="javascriptFunction">関数</Term>内でのみ有効です。<Term type="javascriptVariable">変数</Term>が有効な範囲のことを、その<Term type="javascriptVariable">変数</Term>の<Term type="javascriptScope" strong>スコープ</Term>と呼んでいます。</p>
@@ -95,7 +98,6 @@ function increment() {
9598
increment();
9699
increment();
97100
```
98-
99101
:::
100102

101103
## 演習
96.8 KB
Binary file not shown.
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
---
2+
title: 定数とオブジェクトの参照
3+
---
4+
5+
import CodeBlock from '@theme/CodeBlock';
6+
import Term from "@site/src/components/Term";
7+
import OpenInCodeSandbox from "@site/src/components/OpenInCodeSandbox";
8+
9+
## 定数
10+
11+
これまで、変数の宣言には `let` キーワードを使用してきました。ところが、JavaScript の変数は、大抵初回代入以降は再代入が行われません。
12+
13+
再代入が行われない変数は `const` を用いて宣言することができます。このようにして宣言された変数を定数と呼び、定数への代入は宣言時にしか行えません。
14+
15+
```javascript
16+
// let で宣言した変数は再代入できる
17+
let variable = 1;
18+
variable = 2;
19+
20+
const constant = 1;
21+
// const で宣言した変数に再代入しようとするとエラー
22+
// constant = 2;
23+
```
24+
25+
:::tip `let``const`
26+
ほとんどの場合、`const` が用いられたプログラムは `let` 書き換えても動作します。それでは、あえて `const` を用いる理由は何なのでしょうか。
27+
28+
JavaScript において、それはコードを読んだ際に読みやすいからです。`const` で定義されている変数なら、宣言文さえ見れば変数の中に入っている値を知ることができます。`const` が使用できる場所では、基本的に全て `const` を用いるようにしましょう。
29+
:::
30+
31+
:::info オブジェクトと `const`
32+
`const` による宣言で禁止されるのはその変数への代入だけであり、オブジェクトのプロパティへの代入はこれにあたりません。
33+
34+
```javascript
35+
const person = { name: "田中", age: 18 };
36+
person.name = "佐藤"; // OK
37+
```
38+
39+
:::
40+
41+
## 参照
42+
43+
[オブジェクト](../../1-trial-session/10-object/index.md)で扱ったように、JavaScript の値はオブジェクトとプリミティブに分けられます。前回は、プリミティブを「それ以上分解できない値」のように説明しました。もう少し詳しくみてみましょう。
44+
45+
![オブジェクトとプリミティブ](../../1-trial-session/10-object/value-types-with-object.drawio.svg)
46+
47+
次のコードを実行してみてください。
48+
49+
```javascript
50+
const object1 = { name: "田中", age: 18 };
51+
const object2 = object1;
52+
object2.age = 19;
53+
document.write(object1.age);
54+
```
55+
56+
<OpenInCodeSandbox path="/docs/2-javascript-training/01-constant/samples/reference" />
57+
58+
このプログラムの実行結果は `19` になります。なぜでしょうか。
59+
60+
実は、オブジェクトを生成する式 `{ name: "田中", age: 18 }` は、オブジェクトを生成こそするものの、**式自体の評価結果は、オブジェクトそのものでなく、コンピューターのメモリ上のどこかに存在するオブジェクトの本体の場所を指し示す値になります**
61+
62+
言い換えれば、JavaScript において、**オブジェクトそのものは値ではありません**。JavaScript の**値として有効なのは、オブジェクトへの参照**なのです。
63+
64+
![参照](./reference.drawio.svg)
65+
66+
これを踏まえて先ほどのコードを見直してみましょう。JavaScript で値として扱えるのは参照のみなので、1 行目で `object1` に代入されるのは、その本体への参照です。
67+
68+
2 行目では、変数 `object1` に代入されている参照が `object2` にコピーされます。これにより、同じオブジェクトを参照する変数が 2 つできます。よって、`object1.age``object2.age` は同じものになるのです。
69+
70+
## ネストされたオブジェクト
71+
72+
オブジェクトの中に別のオブジェクトが格納されている場合を考えてみましょう。
73+
74+
```javascript
75+
const person = {
76+
name: "田中",
77+
scores: { math: 80, science: 90 },
78+
};
79+
```
80+
81+
[以前](../../1-trial-session/10-object/index.md)にも記載した通り、オブジェクトのプロパティ名として使用可能なのは文字列のみですが、プロパティの値としては任意の JavaScript の値が使用できるのでした。
82+
83+
オブジェクトがネストされている場合、次のようにプロパティの値として別のオブジェクトへの参照が格納されていると考えることができます。
84+
85+
![ネストされた参照](./nested-reference.drawio.svg)
86+
87+
## 課題
88+
89+
参照の仕組みが特に問題になってくる場合として、オブジェクトの参照先が別の関数によって書き換えられる場合があります。次のコードを実行してみましょう。
90+
91+
```javascript
92+
function incrementAge(person) {
93+
person.age = person.age + 1;
94+
}
95+
96+
const tanaka = { name: "田中", age: 18 };
97+
const nextYearTanaka = incrementAge(tanaka);
98+
document.write(nextYearTanaka.age);
99+
100+
// 19 と表示されてしまう
101+
document.write(tanaka.age);
102+
```
103+
104+
<OpenInCodeSandbox path="/docs/2-javascript-training/01-constant/samples/object-mutated-by-function" />
105+
106+
このコードは、[オブジェクト](../../1-trial-session/10-object/index.md)の項で扱った課題でした。実はこのコードには問題があり、`tanaka` に対して `incrementAge` を適用すると、関数が適用された `tanaka` にも影響が及んでしまいます。これは、関数に渡される値はオブジェクトへの参照で、このオブジェクトは呼び出し元の変数が参照するものと同一のものだからです。
107+
108+
`incrementAge` 関数の実装を変更し、関数に渡したオブジェクトが書き換えられないようにしてください。
109+
110+
:::tip
111+
オブジェクトが書き換えられないようにするためには、オブジェクトを新しく作り直す必要があります。
112+
:::
113+
114+
<details>
115+
<summary>解答</summary>
116+
<div>
117+
<p>オブジェクトを新しく生成して、生成したオブジェクトを返しましょう。</p>
118+
<CodeBlock language="javascript">{`
119+
function incrementAge(person) {
120+
return { name: person.name, age: person.age + 1 };
121+
};\n
122+
const tanaka = { name: "田中", age: 18 };
123+
const nextYearTanaka = incrementAge(tanaka);
124+
document.write(nextYearTanaka.age);\n
125+
// 18
126+
document.write(tanaka.age);
127+
`.trim()}</CodeBlock>
128+
<OpenInCodeSandbox path="/docs/2-javascript-training/01-constant/samples/answer" />
129+
</div>
130+
</details>

0 commit comments

Comments
 (0)