JavaScriptコードの「?」をまとめたページはこちら⬆︎。
function Person(「「5name」」) { 「「2this」」.name = 「「5name」」; } const person1 = 「「2new」」 Person(「「5taro」」);
こんにちは、「ふ」です。
今回はJavaScriptのコンストラクタとインスタンスについて紹介します。
const person1 = { name:"taro", age:20 };
今回もいきなりコード。
人物のプロフィールを登録するための、person1オブジェクトを作りました。
プロパティには名前と年齢を入れてあります。
const person2 = { name:"jiro", age:19 }
人物をもう1人追加します。
person2を作り、名前と年齢を追加....さらに3人目も....
あれ?
これだと人物を追加するたびに、nameプロパティとageプロパティを記述していくことになります。長いコードになりそうだ💧
ならば、「オブジェクトのテンプレート」のようなものを最初につくっておき、
このテンプレをもとにオブジェクトを生成・初期化し、値だけを入れていくようにすれば.... はるかに効率的ですよね。
JavaScriptにはその仕組みがちゃんとあります。
オブジェクトのテンプレートにあたるものがコンストラクタ、そのテンプレをもとに作ったオブジェクトがインスタンスと呼ばれるものです。
コンストラクタとインスタンス、2つの性質と使い方をじっくりと見ていきましょう。またこれらを理解する際に障壁となる「this」を使った構文についても、根こそぎ分析していきます。
現在のJavaScriptにおいては、コンストラクタの記述は2通り存在します。
class A = { constructor() { 〜内容〜 } }
ES2015以降のJavaScriptでは、class構文が使えるようになっています。classも同じくオブジェクトのテンプレートとなるものですが、その構造はやや複雑です。
1つ目の方法は⬆︎のように、classの中でconstructorメソッドを使って記述するやり方です。
function A() { 〜内容〜 }
もう1つは従来からある、関数形式で定義する方法。
見た目はフツーの関数と変わりません。
現在コンストラクタの定義方法はこのように2つ存在するのですが、今回は純粋にコンストラクタとインスタンスについて理解を深めていただくのが目的です。そのため、より単純な「関数形式」を使ってお話を進めていきます。
双方において機能的な違いはありません。class形式については記事の後半ですこしだけ触れるようにしますね。
const person1 = { name:"taro", age:20 };
それではperson1,2,3...とオブジェクトを作っていくための、テンプレートを作成しましょう。
function Person() { }
Personというコンストラクタを作りました。頭文字の「P」は大文字にしています。
関数タイプのコンストラクタは、フツーの関数と同じ形式で記述します。そのため「これはフツーの関数なのか、それともコンストラクタなのか」の区別がつきにくいですよね。そこでフツーの関数は名前を小文字に、コンストラクタについては大文字から始まる名前にする、というのが慣例です。
そしてオブジェクトを生成・初期化したときに、自動的にプロパティ名と値がセットされるようにしましょう。
function Person(name,age) { this.name = name; this.age = age; }
引数と処理を⬆︎のように記述します....
this.name = name;
意味のわからない処理が登場しました。ここがコンストラクタを理解するための1番の障壁です💧
大丈夫です。じっくりと解説していきます。
「「1this」」.name = name;
はじめに1番左にある「this」について。
thisキーワードは、現在置かれているオブジェクト自身を指すものでした。
const obj = { a:5, b:function() { console.log(this.a); } } obj.b(); 「「3//▶︎ 5」」
objというオブジェクト。
プロパティbはメソッドで、「this.a」を出力する処理になっています。thisは「現在置かれているオブジェクト」なので、「this.a」は「obj.a」ということになります。
実行するちゃんと、obj.aの値「5」が出力されます。
コンストラクタ内の表記に戻ります。
ここでの「this」はこのテンプレを使って、将来生成されるオブジェクトにおいてのthisです。
コンストラクタは「定義」なので、定義段階でのthisは特別な何かを指しているわけではありません。「将来オブジェクトを生成・初期化するとき用のthis」という位置づけです。
このthisを言語化するとすれば、「生成・初期化されたときのオブジェクト自身」ということです。
もしこのコンストラクタをつかって「person5」を作ったときのthisは「person5」を指し示し、「person10」を作ったときはこのthisは「person10」を指すことになります。
this「「1.name」」 = name;
ではその後に続く「name」はというと。
thisに対してドット「 . 」でつながっているので、「thisのnameプロパティ」ということになります。
言語化したものをつなげると、「生成・初期化されたときのオブジェクト自身の、nameプロパティ」ということに成増。
this.name = 「「1name」」;
そしてそのnameプロパティに代入されているのが「name」。
これはコンストラクタの引数です。
function Person(「「5name」」,age) { this.name = 「「5name」」; this.age = age; }
this.nameに対し、引数の「name」に指定したものを代入しているのです。
またまた言語化したものをつなげると、
「生成・初期化されたときのオブジェクトの、nameプロパティには、○番目の引数に指定したものを入れてくださいよ〜」
〜ということに。
やっとこの「this.name = name;」の一文が解明できました。
function Person(name,「「2age」」) { this.name = name; this.age = 「「2age」」; }
同様にageプロパティの値は、第2引数に入力できるようにしています。
このようにしてコンストラクタは、オブジェクト初期化と同時に「プロパティ: 値」をセットできる仕組みになっているのです。
function Person(「「4abc」」,age) { this.name = 「「4abc」」; this.age = age; }
ちなみに引数なので定義時の名前は任意です。⬆︎のように記述しても同じように動作します。
ただし、わざわざ別のものを命名しても識別するのがめんどくさいので、プロパティ名と同じものを使ったほうがわかりやすいでしょう。
お待たせしました。テンプレであるコンストラクタを使って、オブジェクトを生成しましょう。
冒頭でもお話ししましたが、コンストラクタやクラスを元に生成したオブジェクトのことをインスタンスと呼びます。
const obj = 「「1new」」 Obj(セットしたい値);
インスタンス生成にはnew演算子を使ってコンストラクタを呼び出し、プロパティにセットしたい値については、引数の部分に指定します。
Personコンストラクタのインスタンスを作ってみます。
function Person(name,age) { this.name = name; this.age = age; } const person3 = 「「1new Person("saburo",25)」」;
person3を作り、nameとageプロパティの値を指定しました。
console.log(person3); 「「3▶︎ Person {name:'saburo', age: 25}」」
person3を出力してみると、プロパティと引数に指定した値がちゃんと入っていました。
似たような構造のオブジェクトをたくさん作る際には、コンストラクタがあるととても楽ですね ♪ new演算子を使えば、基本セットを持ったオブジェクトをすぐに作成することができます。
ここで登場した「new演算子」。
JavaScriptを学習してきたみなさんであれば、すでに目にしたことがあるかと思います。
const arr = 「「1new」」 Array(); const date = 「「1new」」 Date();
配列を作るとき、時刻を取得するときなどにも、new演算子を使って記述していました。
これらの記述は、インスタンスを生成していたのですね。
console.log(Array); 「「3▶︎ ƒ Array() { }」」 console.log(Date); 「「3▶︎ ƒ Date() { }」」
試しにArrayやDateをconsole.logしてみると「f Array( )」「f Date( )」と、関数形式で出力されます。
これらはコンストラクタだった、ということがわかります。
person3.age = 26; person3.sports = "soccer"; console.log(person3); 「「3▶︎ Person {name: 'saburo', age: '26', sports: 'soccer'}」」
生成したインスタンスは独立したオブジェクトとなるので、もちろん編集が可能です。
⬆︎ではプロパティの値を変更したり新たなプロパティを追加していますが、ちゃんと反映されています。
インスタンスを編集したとしても、元となっているコンストラクタの内容には影響しません。これも「テンプレ」の良いところです。
では最後にclass構文においてのコンストラクタの表記を紹介します。
classもまた、オブジェクトのテンプレートとなるものです。関数型のコンストラクタよりも複雑な形式になりますが、それだけに幅広い用途を持っています。
class Cls_person { 「「1constructor」」(name,age) { this.name = name; this.age = age; } };
class内でコンストラクタを使う際には、constructorメソッドという形で記述していきます。以降に続く引数や処理の記述は関数型と同様です。
const person4 = new Cls_person("siro",33);
classからオブジェクトを生成するときも、関数型と同じくnew演算子を使用します。
JavaScriptのclass構文についてお話しはじめると、この記事がとてつもなく長くなってしまうので、今回は記述方法の紹介に留めさせていただきます。なお次のJavaScriptのバージョンであるES2022では、現状のものからさらに、class構文でのコンストラクタ記述も変更があるとか..そのへんも含め、次の機会に紹介させていただきますね。
ここまでお読みくださり、ありがとうございました。今回の記事が「コンストラクタ」「インスタンス」を理解する上での助けになれれば幸いです。
ではまた〜 ♬
JavaScriptの矢印「=>」〜これはアロー関数というものです。
2022.01.09
使い方とメリットについて解説。
JavaScriptのforEachとは? 〜配列のループメソッドについて。
2022.03.24
HTML要素の一括編集にも。
JavaScriptのドルマーク$に中括弧{ }、テンプレートリテラルについて。
2022.02.09
クオテーション祭り、さようなら。
swift、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。