JavaScriptまとめ



# 1. 概要

今まで業務で`JavaScript`は使用したことはないが、PFで使用する事にした
後で見返すときに簡単に理解出来るようにまとめる
りあクト！という書籍で勉強した

https://booth.pm/ja/items/2368045

# 2. 変数宣言について

JSでは昔から使用されている`var`がある
変数宣言では、`var`は使わず、**`let`**もしくは**`const`**で宣言する
以下で変数名と再代入、再宣言の可否をまとめた

| 変数名 | 再代入 | 再宣言 |
|:-:|:-:|:-:|
|var   |可能   |可能   |
|let   |可能   |不可   |
|const   |不可   |不可   |

`var`のさらなるデメリットとして
**変数スコープは関数単位**である
**他の大多数の言語ではブロックスコープである**ため、挙動が読みにくい

# 3. プリミティブ型について

## 3.1. プリミティブ型とは

オブジェクトではなく、メソッドをもたないデータの事
プリミティブ型のデータは、それ自体を変更することは出来ず、代入する事でしか新しい値にできない
又、**プリミティブ型を定義するときはリテラルを使用する必要がある**

https://developer.mozilla.org/ja/docs/Glossary/Primitive#javascript

## 3.2. プリミティブ型一覧

### 3.2.1. Boolean

TrueおよびFalseの二つの真偽値を扱うデータ型
`true`と`false`の**真偽値リテラル**で定義出来る

###3.2.2. Number型

数値を扱うためのデータ型
整数も小数も同じ`Number`型になる
数値リテラルで定義出来る(-9や36など)
先頭に`0x`をつけることで**16進数を表現できる**
`0o`をつけることで**8進数を表現できる**
`0b`をつけることで**2進数を表現できる**
`3.14`などの形式は**不動小数点リテラル**と呼ぶ

### 3.2.3. BigInt型

`Number`型では扱えない数値を扱うデータ型
`Number`型とは**互換性がない**ので代入や計算、等値比較はできない
`100n`のように**数字の後ろにnをつけて表現する数値リテラルで定義出来る**

### 3.2.4. String型

文字列を扱うためのデータ型
**`''`**、または`""`で囲む文字リテラル
`バッククウォート`を用いると**改行を含む複数行テキスト**や`${}`による**式展開が可能なテンプレートリテラルになる**

### 3.2.5. Symbol型

シンボル値という固有の識別子を表現する値
オブジェクトのプロパティキーとして使用可能

### 3.2.6. Null型

プリミティブ値Nullは何のデータも存在しない状態を明示的に表す際に使用する
nullリテラルである`null`はプリミティブ型`null`を返す
しかし、`typeof`演算子で`null`のデータ型を調べると`object`となるらしい

https://qiita.com/ta1fukumoto/items/effaa42cd296a2648d41#null型

### 3.2.7. Undefined型

宣言のみが行われた変数や、オブジェクト内の存在しないプロパティへのアクセスに割り当てられる
他の多くの言語と異なり、Nullと明確に区別される
`undefined`というのは**実際はグローバル変数**である

## 3.3. プリミティブ値のリテラルとラッパーオブジェクトについて

プリミティブ型ではインスタンスメソッドを持たないはずが、実際は使用できる
なぜか


#### ラッパーオブジェクトのおかげ である


本当ははラッパーオブジェクトは`new`演算子と対応するコンストラクタ関数を利用している作成する事になる
だが、明示的にラッパーオブジェクトを指定しなくてもプリミティブ型のデータに対してアクセスする時は**その対応するラッパーオブジェクトに自動変換するという仕組みがある**
この仕様によって、**明確に異なるプリミティブ型とオブジェクト型の間で同じインスタンスメソッドが利用できる**

## 3.4. オブジェクト型のリテラルについて

上記のプリミティブ型に対応するリテラル以外のリテラルを見ていく

### 3.4.1. 配列リテラル

```Js:sample.js
const Arr = [0, 1, 2]; //リテラルで定義
const Arr2 = new Array(1, 2, 3); //Arrayオブジェクトをコンストラクタで定義
```

当然だが、配列リテラルでは、配列の要素を直接指定する事になる
よって、`Array`オブジェクトとはこの様な差が生まれる

```Js:sample.js
const Arr = [3]; //Arr>>[3];
const Arr2 = new Array(3); //Arr2>>[empty,empty,empty];
```

https://www.javadrive.jp/javascript/array/index2.html

### 3.4.2. オブジェクトリテラル

```js:sample.js(オブジェクトリテラルの宣言)
const obj = {
  name: 'Islanders-Treasure',
  age: 26
```

定義したオブジェクトリテラルは`obj.key`または`obj[key]`で取得できる

```Js:sample.js
obj.name
>> 'Islanders-Treasure'
obj['age']
>>26
```

https://www.task-notes.com/entry/20160530/1464534038

###3.4.3. 正規表現リテラル

`/patern/frags`の形式で記述する
正規表現パターンでの特殊文字の使い方は他の言語と同じ
`RegExp`オブジェクトのインスタンスとして生成される

```Js:sample.js
let re = /ab+c/;
```

## 3.5. JavaScriptにおけるオブジェクト

**広義のオブジェクト**と**狭義のオブジェクト**という風に**コンテキストによって意味が変わる**

### 3.5.1. 狭義のオブジェクトの定義

一般的なクラスベースのオブジェクト指向言語では
`クラスインスタンス`のことを**「オブジェクト」**と呼称する

javascriptでのオブジェクトは
#### キーとそれに対応する値を持ったプロパティの集まり

- 一般的には連想配列と呼ばれる
- Rubyのハッシュに相当するもの

### 3.5.2. 広義のオブジェクトの定義

**プリミティブ値以外のすべてのものを包括して指す**

- 広義のオブジェクトはすべて`Object`という標準組み込みオブジェクトを最終的な継承元に持っている
- プリミティブ型はオブジェクトではない(`Object`オブジェクトを継承しているのではなく、**あくまでリテラル値で表現される値であるため**)

# 4. 関数の定義について

## 4.1. プログラムにおける文と式違い

### 4.1.1. 式  

- 値を生成し、変数に代入できる物
- 具体的には、リテラル(`sample`)、変数(`foo`)、関数呼び出しの事
- 指揮と演算子の組み合わせも式という

```Js:sample.js
const cnt = 'sample';
```

### 4.1.2. 文  

- 変数に代入できないもの
- 何らかの手続きを処理系に命令するもの

```Js:sample.js
const isTrue = true;
if (isTrue) {
}
```

### 4.3. セミコロンつける場所

#### 4.3.1. 文の場合

- 文の末尾にはセミコロンが必要
- `{}`の**ブロックで終わる場合にはつけないという例外規則がある**

#### 4.3.2. 式の場合

- 逆に関数式のほうは**最終的に変数への代入文になっているため**末尾にセミコロンをつける必要がある

https://jsprimer.net/basic/statement-expression/

# 5. 第一級オブジェクトとは

以下のような特徴を有するオブジェクトのこと

- 変数への代入

```Js:sample.js
let aaa = () => console.log('Hello');
aaa(); //>>Helo
```

- 配列の要素やオブジェクトのプロパティ値になれる

```Js:sample.js
let obj = {
  name: 'aaa',
  age: () => 10 * 3;
}
```

- 他の関数に引数として渡す事ができる
- 別の関数の戻り値として設定できる

JavaScriptでは、
#### 関数は第一級オブジェクトとして扱われる

# 6. アロー関数

JavaScriptの関数式

- 従来の関数の代替構文

```js:sample.js(従来の関数)
const addOne = function (n) {
  return n + 1;
};
```

- 従来の関数をアロー関数に書き換え

```js:sample.js(アロー関数)
const addOne = (n) => {
return n + 1;
};
```

- 本文が`return`文だけの時はreturn文をブロックごと省略できる

```js:sample.js(アロー関数：{}なし)
const addTwoArgs = (a, b) => return n + 1;
```

- 引数がひとつの時は引数の()も省略できる

```js:sample.js(アロー関数：()&{}なし)
const addOne = n =>  n + 1;
```

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions

# 7. 無名関数(匿名関数)

関数の名前は、関数式などで定義したものについては、**functionインスタンスとしてのnameプロパティに格納されている**
**定義時に名前を与えられない関数**を**無名関数**と呼ぶ
名前付き関数自体は、関数で閉じたローカル変数なので、外部から呼び出すことはできない
関数の中でのみ呼び出すことができる

```js
let x = 0;
const sampleFunc = function localFunc(){
  if(x === 0){
    ++x;
    console.log('Hello');
    localFunc();
  }
};
sampleFunc();
// >>Hello
localFunc();
// >>エラー
```

## 7.1. アロー関数でのnameプロパティ

(() => {}).name ではnameプロパティは無い
**名前が無いのでメモリに残らず、変数に代入されなければ定義しても参照できない**
無名関数は変数に代入することで、**nameプロパティに変数名が格納されるのでメモリに保存される**

```js
() => console.log('hello'); //このままではメモリに残らないので、どこからも参照できない
const sampleFunc = () => console.log('hello');
sampleFunc(); // >>hello
```

# 8. 引数の表現

## 8.1. デフォルト引数

関数の引数に対してデフォルト引数を設定できる
`VB`でいう引数の`Optional`での宣言みたいなもん

```js
const multiply(a, b) = (a, b=10) => a * b;
console.log(multiply(2,1); // >>2
console.log(multiply(2); // >>20
```

#### デフォルト引数を設定するとき

デフォルト値がある引数は引数の**後ろにまとめて**設定すること
**関数の設計として重要な値ほど前に持ってくるべきだから**

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Default_parameters

## 8.2. レストパラメーター

残りの引数を配列として受け取ることが出来るもの
関数の最後の引数の名前に「...」のプレフィックスをつけることで残りの引数を配列で受け取ることができる

```js
const sample = (a, b, ...c) => {
  let ans = a + b;
  c.map(element => ans += element);
  console.log(ans);
};
sample(1,2,3,4,5,6);
// >>21
```

#### レストパラメータにそれぞれ名前をつけたい場合

`const sum = (i, …[j, k, l]) => i + j + k + l;`
ただし、定義してある以上の引数が受け渡された場合は**切り捨てられる**

# 9. クラス構文

実態は特別な**関数**である
JSのクラスには**クラス式**と**クラス宣言**がある

## 9.1. クラス宣言

```js
class sample{
  constructor(name, age){
    this.name = name;
    this.age = age;
  }
}
```

## 9.2. クラス式

```js
const aaa = class {
  constructor(height,width) {
    this.height = height;
    this.width = width;
  }
  //ゲッター
  get area() {
    return this.calcArea();
  }
  //インスタンスメソッド
  calcArea () {
    return this.height * this.width;
  }
  //静的メソッド(クラスメソッド)
  static sayHello() {
    console.log('Hello');
  }
};

const sample = new aaa(10,20);
console.log(sample.area);
// >>200
aaa.sayHello();
// >>"Hello"
``` 

`extends`で親クラスを継承した子クラスを作ることができる(他のオブジェクト指向言語と同じ)
`super`で継承元のクラスにメンバー変数を渡すことができる

#### JavaScriptにおけるコンストラクタ関数とは

プロトタイプオブジェクトを継承してオブジェクトインスタンスを生成するための独立した関数のこと

# 10. プロトタイプベースのオブジェクト指向

プロトタイプベースでは**オブジェクトの抽象としてのクラス**が存在しない

## 10.1. 「オブジェクトの抽象としてのクラスがある」とは

クラスベースでは、オブジェクトの下になるクラスが存在する
これをもとにオブジェクトを作成する
これを「オブジェクトの抽象としてのクラスがある」と表現する

## 10.2. プロトタイプベースでのオブジェクト

プロトタイプベースでは、オブジェクトの抽象となるのはクラスではない
オブジェクトの抽象となるのはほかのオブジェクトを継承する

#### その時の継承元になったオブジェクトをオブジェクトプロトタイプと呼ぶ

## 10.3. コンストラクタ関数とは

**広義のオブジェクト**に設定されているプロトタイプオブジェクトを継承して新しくオブジェクトインスタンスを生成するための関数

```js:例
const arr = new Array(3); //arrというArrayオブジェクトを定義するためのコンストラクタ関数はArray
const str1 = new String('sample'); //str1というStringオブジェクトを定義するためのコンストラクタ関数はString
```
プリミティブ型のラッパーオブジェクト値がそれぞれ使えてるメソッドは**オブジェクトインスタンスの継承元であるプロトタイプが持ってるメソッドを継承したもの**
JavaScriptではあらゆるオブジェクトは何らかのプロトタイプを継承していて、その「プロトタイプチェーン」は最終的には{}(空オブジェクト)を経てnullに到達する

# 11. 配列やオブジェクトの便利な構文

## 11.1. オブジェクトのキー名と値をそれぞれ動的に設定する例(keyとbaz)

**オブジェクトのキーで変数を参照する際は[key]のように[]で囲む必要がある**

```js
const key = 'bar';
const baz = 65536;
const obj1 = { foo: 256, [key]: 4096, baz: baz };
console.log(obj1);   //{ foo: 256, bar: 4096, baz: 65536 }
```

## 11.2. プロパティのショートハンド

オブジェクトのキーと値を事前に変数で定義しているときに使用できる構文
オブジェクトの中で変数 baz の名前がプロパティのキー名に、値がそのプロパティ値になってる

```js
const baz = 100
const obj2 = { baz };
console.log(obj2);   // { baz: 100 }”
```

## 11.3. 分割代入

### 11.3.1. 通常の分割代入

**Rubyの多重代入に似たようなもの**

```js
const [n, m] = [1, 4];
console.log(n, m);     // 1 4
```

### 11.3.2. オブジェクトを分割代入するときの高度なテクニック

`Object`オブジェクトを定義するとき、`Object`のキーと同じキーで分割代入することができる

```js
const obj = { name: 'Kanae', age: 24 };
const { name, age } = obj;
console.log(name, age);     // Kanae 24”
```

## 11.4. スプレッド構文

コレクション型のオブジェクトを展開する際に使用する構文
**本質はレストパラメーターと同じ**
以下で使用用途を解説する

### 11.4.1. 配列の展開

任意の配列を展開する際に使用する
通常は、配列内の要素に配列変数を指定すると、1つの要素として配列が存在することになる
レストパラメーターを配列の要素に指定することで、配列変数内の要素を指定の配列に展開することができる
下記例では

- `arr2`でレストパラメーターを指定して配列展開をしている
- `arr3`では要素に直接配列を指定しているので、配列の要素に配列がそのまま入っている

```js
const arr1 = ['A', 'B', 'C'];
const arr2 = [...arr1, 'D', 'E'];
const arr3 = [arr1, 'D', 'E'];
console.log(arr2); // [ 'A', 'B', 'C', 'D', 'E' ]
console.log(arr3); // [ ['A', 'B', 'C'], 'D', 'E' ]
```

### 11.4.2. オブジェクトの展開

任意のオブジェクト内に展開する際に使用する
配列と同じで、変数をそのままオブジェクトのキーに指定すると、値にオブジェクトが入るだけになってしまう
レストパラメーターを指定することで、指定のオブジェクトの中にレストパラメーターで指定したオブジェクトを展開できる
下記例では

- `arr2`でレストパラメーターを指定してオブジェクトを展開をしている
- `arr3`では要素に直接オブジェクトを指定しているので、**キーに変数名**、**値にオブジェクト**がそのまま入っている

```js
const obj1 = { a: 1, b: 2, c: 3, d: 4 };
const obj2 = { ...obj1, d: 99, e: 5 };
const obj3 = { obj1, d: 99, e: 5 };
console.log(obj2);  // { a: 1, b: 2, c: 4, d: 99, e: 5 }
console.log(obj3);  // { obj1: { a: 1, b: 2, c: 3, d: 4 }, d: 99, e: 5 }
```

上記の**分割代入**と**スプレッド構文**を組み合わせることで
**分割代入で一部の値を受け取り、他の値をスプレッド構文で受け取る**といった高度なことが可能になる

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax

# 12. ショートサーキット評価(短絡評価)、他

他の言語と同様、複数の条件が存在する場合に左辺から評価し、真偽が決まった時点で残りを評価せずに値を返すことができる

## 12.1. Optional Chaining

プロパティアクセス修飾子の後に`?`をつけて、指定したキーが存在しなかった時にundefinedを返すための機能

### 12.1.0. なぜ必要か

オプショナルなオブジェクトに対してオブジェクトチェーンを使用してアクセスするソースを書いているときに
**通常であれば各階層の値が`undefined`かどうかをチェックする処理を各必要がある**
このチェックを行わずに下層のプロパティにアクセスするしたいから

### 12.1.1. 通常のオブジェクトチェーン

- 1階層目のプロパティが存在しない場合は`undefined`が返る
- 1階層目にないプロパティを指定して2階層目を指定するとエラーになってしまう

通常のオブジェクトチェーンでは1階層目で存在しなくても2階層目までアクセスしてしまうため、エラーとなってしまう
1階層目であるかどうかのチェックを入れてから2階層目にアクセスする処理を入れる必要があった

```js
const adventurer = {
  name: 'Alice',
  cat: {
    name: 'Dinah'
  }
};

console.log(adventurer.dog); //undefined
if (adventurer.dog != undefined) {
  console.log(adventurer.dog.name);
} //adventurer.dogがundefinedでない時だけadventurer.dog.nameにアクセスする
//console.log(adventurer.dog.name); //コメントアウトするとエラーが返る
```

### 12.1.2. オブジェクトチェーンに`?.`を使用する

`?.` を使うとチェーン内の各参照が正しいかどうかを明示的に確認せずにアクセスしていくことが出来る
プロパティアクセス修飾子の後に`?`をつけることでオブジェクトチェーンの各階層で短絡評価をするようにできる
途中のプロパティが存在していなかったらそこで式が短絡されて`undefined`が返る

```js
const adventurer = {
  name: 'Alice',
  cat: {
    name: 'Dinah'
  }
};

console.log(adventurer.dog?.name); //undefined
```

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Optional_chaining

## 12.2. Nullish Coalescing

左辺が`null`又は`undefined`の時に右辺が評価される機能

## 12.2.0. なぜ必要か

左辺が`空文字`や`0`の時に右辺を評価したい時がある
`""`や`0`は直感的には**明示的に指定している値かはわからない**
**これらを意図的に使用している場合に、`truthy`な値として評価させたいため**

### 12.2.1. 通常の処理

通常では、処理系が0や空文字を`falsy`な値と判断するため、その場合は右辺を評価して上書きされてしまう

- `fooo`はnullなのでこれはどちらでも`falsy`な値と判断できる
- `bazz`は左辺が`0`であり、明示的にそうなっているときでも処理系が`falsy`と判断して上書きされる

```js
const fooo = null || 'default string';
console.log(fooo); //'default string'
const bazz = 0 || 42;
console.log(bazz); //42
```

`??`を使えば、より厳密に`falsy`な値を判定できる
`0`や`""`を明示的に指定している場合は`??`を使うことで、左辺は`truthy`な値と判断して、上書きされない

- `foo`はnullなのでこれはどちらでも`falsy`な値と判断できる
- `baz`は左辺が`0`であり、`??`を使用することで`truthy`と判断させて、左辺のみで短絡させる

```js
const foo = null ?? 'default string';
console.log(foo); //'default string'
const baz = 0 ?? 42;
console.log(baz); //0
```

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator

## 12.x. Optional Chaining と Nullish Coalescing の組み合わせ

上記の二つの機能を使用することで

- `?.`でオブジェクトチェーンで下層のプロパティにアクセスするときに直感的にソースを書くことができる
- `??`でオブジェクトが`0`や`""`であり、且つそれを`truthy`に扱いたいときも直感的に書くことができる

オブジェクトに対する操作がより直感的になる
`null`と`undefined`との闘いが楽になる

https://sbfl.net/blog/2020/03/24/javascript-null-aware/

# 13. thisについて

## 13.1. thisとは

その関数が実行される**コンテキスト**であるオブジェクトの参照が格納されている引数のこと
以下のようなコンテキストがある

### 13.1.1. 関数・メソッド内での呼び出し

この時の`this`の参照は

##### その関数・メソッドをプロパティとして持つオブジェクトへの参照

#### 13.1.1.1. オブジェクトのメソッド内

以下では、`sample`オブジェクトが、`aaa`というキーでメソッド(プロパティ)を格納している
このメソッドの中での`this`のコンテキストはメソッドをプロパティとして持っている`sample`オブジェクトなので、`this=sample`となる

```js
var sample = {
  name: "user",
  aaa: function() {
    console.log(this.name);
  }
};
obj.aaa(); //user(this=sampleより、sample.nameとなる)
```

※JavaScriptにおけるプロパティとは
`Object`オブジェクトでいう、特定のキーをもとに公開するデータや値のこと
以下は、`sample`オブジェクトの中に、`name`キーで`user`というプロパティが格納されている

```js
const sample = { name = "user" };
```

https://javascript.keicode.com/lang/object-object-property.php

#### 13.1.1.2. 関数内

関数式を宣言しているスコープがグローバルスコープである場合
この時の`this`のコンテキストはグローバルオブジェクト(Window)[^1]になる

```
const aaa = 'user'
const samplefunc = function() {
  console.log(this.aaa);
};
samplefunc(); //user(this=Windowより、Window.aaaとなる)
```

### 13.1.2. コンストラクタ内での呼び出し

特定のインスタンスを生成するとき、`new`演算子に続けてコンストラクタ関数を使用する(`new Array`とか)
この時の`this`のコンテキストは新たに生成されるインスタンスを参照する
下の例では`sample`クラスに`name`キーと`age`キーで値を格納するようにしている
よって、インスタンス化するときに、コンストラクタ内の`this`が参照するのはインスタンスである`sample`となる

```js
const sample = class {
  constructor {
    this.name = name,
    this.age = age
  }
};

const sampleinstnce = new sample('user',30);
console.log(sampleinstance.name); //user(this=sampleinstanceより、sampleinstance.nameとなる)
```

### 13.1.3. apply,callでの呼び出し

`apply`、と`call`は特別なメソッドで、`this`のコンテキストを変更することができる
下の例では、`sample`の`samplefunc`メソッドのコンテキストは、メソッドのプロパティをもっているオブジェクトである`sample`になる
よって、`sample.samplefunc();`では`user`と出力される
それを、`apply`で`this`のコンテキストを`sample2`に変更することで`this.name`が`sample2.name`になるので`admin`と出力される

```js
const sample = {
    name: 'user',
    samplefunc: function(){
        console.log(this.name);
    }
};
 
const sample2 = {
    name: "admin",
};
 
sample.samplefunc(); //user
sample.samplefunc.apply(sample2); //admin
```

### 13.1.4. strictモードでのグローバルオブジェクト

`ES2015`で追加された機能である`strict`モードでは、それ以前のグローバルオブジェクトとコンテキストが異なる

#### 13.1.4.1. ES2015以前の仕様

メソッドでない関数(オブジェクトのプロパティではない関数)は
`this`のコンテキストにグローバルオブジェクトをとる
この仕様上、簡単にグローバル汚染を起こせてしまうことが問題であった

#### 13.1.4.2. ES2015以降の仕様(`strict`モード有効の時)

メソッドでない関数の`this`に`undefined`が入る仕様になった
関数のコンテキストがグローバルオブジェクトの場合は参照しないことになった


## 13.2. JavaScriptのthisの挙動による弊害

### 13.2.1. クラス構文で`strict`モードの時に困ること

メソッド内で関数を使用する時が困る
`strict`モードの時は、**メソッド内で使用する関数にはコンテキストがない**
通常のオブジェクト指向言語では、一つ外のスコープを参照することを期待するので、この挙動の違いは悩ましい
以下の`profile`で定義しているメソッドの中で`setTimeout`関数を使用している
この中の関数の`this`のコンテキストはグローバルオブジェクトとなり、通常は`strict`モードが有効なので、`undefined`となる

```js
const sample = {
  name: `user`,
  age: 30,
  profile: function(){	
    console.log(`Hi, My name is ${ this.name }.`);

    setTimeout(function(){
      console.log(`${ this.age } years old`)
      }
    , 1000);
  }
}
sample.profile();
//"Hi, My name is user."
//"undefined years old"
```

### 13.2.2. クラス内のメソッドでアロー関数を使用した時の`this`のコンテキスト

アロー関数の`this`のコンテキストは

#### 関数が定義された時点で確定される

よって、上記の`setTimeout()`内の関数をアロー関数で定義すると、その時点のコンテキストである`sample`となる

```js
const sample = {
  name: `user`,
  age: 30,
  profile: function(){	
    console.log(`Hi, My name is ${ this.name }.`);

    setTimeout(()=> console.log(`${ this.age } years old`)
    , 1000);
  }
}
sample.profile();
//"Hi, My name is user."
//"30 years old"
```

### 13.2.3. 教訓

- クラス式内で関数を使用する時は、挙動が直感的に理解しやすいアロー関数を使用すること


[^1]: ブラウザ実行の場合。`Node.js`の場合は`global`その他の環境ではまた別のグローバルオブジェクトがある　参考：[グローバルオブジェクト](https://ja.javascript.info/global-object)