[Day6] オブジェクト: 基本 part2

本記事は一人アドベントカレンダー企画の一つです。
[30代未経験エンジニアが25日後にJavaScriptをマスターするカレンダー](https://qiita.com/advent-calendar/2022)

[JAVASCRIPT.INFO](https://ja.javascript.info/)を元にJavaScriptを勉強していき、そこで学んだ知識をアウトプットしていきます。
２５日でJAVASCRIPT.INFOをやりきり、未経験エンジニアがJavaScriptをマスターする過程を投稿していきます。



## 4.5 コンストラクタ、 new 演算子
### 知らない単語
- コンストラクタとは
    - クラスからオブジェクトを作成した際に、クラスに中で1回だけ自動的に実行される特殊なメソッド

### 学んだこと

- コンストラクタ
コンストラクタはクラスの中に書ける
例えば
class hello {
constructor
}
などの書き方ができる

- コンストラクタ関数
コンストラクタ関数は2つのルール

1,名前は大文字で始める
2,「new」演算子を使ってのみ実行される
例えば
function User(name) {
  this.name = name;
  this.isAdmin = false;
}

let user = new User("Bill");
alert(user.name); // Bill
alert(user.isAdmin); // false
などと書く

new演算子を用いて関数が実行された場合に行われる処理は
新しい空のオブジェクトが作成され、「this」に割り当てられる
関数本体を実行し、新しいプロパティを追加して「this」に変更を加える
「this」の値が返される


- コンストラクタの呼び出しモードの確認: new.target
関数の中では、「new.target」という特別なプロパティを使うことで、「new」を使って呼び出されたのかそうでないのかを確認できる
例えば
function User() {
  alert(new.target);
}

// new なし:
User(); // undefined

// new あり:
new User(); // function User { ... }

のようになるのでわかりやすい


- コンストラクタからの返却
コンストラクタはreturn文を持たない
コンストラクタの仕事は、必要なものをすべて「this」の中に書き込むことであり、「this」が戻り値となる

return文がある場合のルールは
「return」がオブジェクトと一緒に呼ばれた場合、「this」の代わりにオブジェクトが返される
「return」がプリミティブと一緒に呼ばれた場合は無視される

これまでと同じくreturnで値が返る


### 感想
コンストラクタ関数やreturn文がある場合のルールは忘れないように覚えて正しく使いたいと思う。

## 4.6 オプショナルチェイニング(Optional chaining) '?.'
### 知らない単語
- オプショナルチェイニングとは
    - 接続されたオブジェクトチェーンの深くに位置するプロパティの値を、チェーン内の各参照が正しいかどうかを明示的に確認せずに読み込むことを可能にする

### 学んだこと

- オプショナルチェイニング
「オプショナルチェイニング ?.」は、「?.」の前の部分が「undefined」あるいは「null」であれば検査をストップし、「undefined」を返す

どのような事かと言うと
下記のコードのような場合
let user = {}; // ユーザは address を持たない
alert( user?.address?.street ); // undefined (エラーは起きません)

通常はエラーになるコードでも「?.」が付くことによって「undefined」を返し、エラーで処理が止まらない

- 他のケース: ?.(), ?.[]
「オプショナルチェイニング ?.」は演算子ではないので、関数や括弧と一緒でも機能する
例えば、「?.()」は存在しない可能性のある関数を呼び出すときに使用する
例えば下記のadminメソッドがある場合とない場合のコードでは

let userAdmin = {
  admin() {
    alert("I am admin");
  }
};

let userGuest = {};
userAdmin.admin?.(); // I am admin
userGuest.admin?.(); // なにもしない
のような違いがある

### 感想
通常はエラーになるコードでも「?.」が付くことによってエラーで処理が止まらないというのは便利だし、関数や括弧と一緒でも機能するのでうまく使っていきたい。


## 4.7 シンボル型
### 知らない単語
- シンボルとは
    - 変数や関数等の識別子をアドレスなどの情報と結びつけている目印の事

- サードパーティとは
    - ある事柄について、その直接の当事者ではない関係者のこと
### 学んだこと
- シンボル
シンボルはプリミティブ型で、ユニークな識別子のためのもの

// id は新しい symbol
let id = Symbol();

シンボルに説明を与えることもできる
// id は "id" という説明を持つsymbol
let id = Symbol("id");

- “隠れた” プロパティ
シンボルを使うと、オブジェクトの隠れたプロパティを作ることができる
他のコードがアクセスしたり上書きしたりすること無い

- リテラルのシンボル
オブジェクトリテラルの中でシンボルを使いたい場合は、角括弧で囲む必要がある

let id = Symbol("id");
let user = {
  name: "John",
  [id]: 123 // 単に "id: 123" ではない
};

- システムシンボル
システムシンボルを使うことでオブジェクトの様々な側面を微調整することができる
例えば、Symbol.toPrimitiveはオブジェクトからプリミティブへの変換を記述することができる

- 要するに
シンボルはキーのようなもの

let Sym1 = Symbol("Sym")
上記のコードであれば、「Sym」がシンボル

### 感想
リテラルのシンボルやシステムシンボルなどそれぞれのシンボルで書き方、役割などが違うので、間違えないように覚える


## 4.8 オブジェクトからプリミティブへの変換
### 知らない単語
- なし

### 学んだこと
- ToPrimitive
特別なオブジェクトメソッドを使って文字列や数値をを調整することができる
「hint(ヒント)」と呼ばれる、３つのバリエーションがある

「string」
操作がalertのように文字列を期待するとき、オブジェクトから文字列への変換をする

「number」
操作が数学のように数値を期待するとき、オブジェクトから数値への変換をする

「default」
操作がどんな型を期待しているか “よくわからない” ようなレアケースで起こる

- Symbol.toPrimitive
変換に応じて、文字列または金額になり、1つのメソッドがすべての変換ケースを扱っている

### 感想
オブジェクトからプリミティブへの変換、種類も多く、難しい。後日エンジニアの知人に教えてもらって理解を深めたい。

# 最後に
今後さらに難しくなると思うが、今回は特にオブジェクトからプリミティブへの変換がかなり難しい。「ToPrimitive」３つのバリエーションがあるので、場面によって使い分けたい。