本日は
JavaScriptのクラス、インスタンス、コンストラクタについて解説する記事です。
JavaScriptを勉強していて
クラスって何?オブジェクト?インスタンス?コンストラクタああああああああ????
と感じる初学者の方も多いのではないでしょうか。
何を隠そう私もそうでした。orz
なので今回は初学者の方にも一つ一つ分かりやすいように解説したいと思います。
こんな方にオススメの記事です
・JavaScriptの勉強を始められた方
・他の言語を勉強中でオブジェクトについて理解を深めたい方
・クラスとかインスタンスとかコンストラクタってなんなんだー!!?という方
この記事を書いている人
結論
まずはざっくりと結論からです。
クラス、インスタンス、コンストラクタは以下のように考えられます。
・クラス:設計図
・インスタンス:クラスを元に実際に作った物
・コンストラクタ:クラスを作るときに初期化するメソッド
となります。
ちなみにこれらはオブジェクト指向で使われる用語なのですが、オブジェクトは"モノ"のことを指します。物体であることもありますし、人であることもあります。
何かしら情報、つまりデータを持っているモノ、物体のことを指します。
例えば扇風機であれば
・扇風機の名前
・扇風機の色
・扇風機の機能
などのような"情報"が必ずありますよね。
弱のボタンを押すとこれくらいの強さで風が吹いて、とか。
名前は「爽快君」である、とか(例えばの話です)
そういったいろんな情報をまとめたものがオブジェクトです。
そういう意味では人間もオブジェクトとして捉える事が出来ますね。
(ここでは「人をモノと呼ぶとはどういうことだ!怒」といった倫理観的なものは一旦置いといての話になりますm(_ _)m)
繰り返しとはなりますが、オブジェクトはモノ自体であり、モノの情報をまとめたもののことを指します。
オブジェクトの構成
オブジェクトはプロパティと、メソッドの二つから構成されています。
プロパティとは、オブジェクトが持つ情報のことです。
メソッドとは、そのオブジェクトが取る行動のことを指します。
コードでは以下のように記述します。
class クラス名{
constructor(){
プロパティ名 =値
}
メソッド名()
}
//インスタンスの生成
const 変数名 = new クラス名();
//メソッドの呼び出し
変数名.メソッド名()
上記ではクラス名を付与し、その中にオブジェクトの情報となるプロパティと、オブジェクトの動作となるメソッドを入れ、インスタンス(オブジェクト)を生成、最後のコードで呼び出してます。
ではクラスはいつから導入されたものなのでしょうか。
クラスはECMAScirptから導入された
クラスやインスタンスはプログラミングのどの言語でも使える基本的な概念ですが、JavaScriptではECMAScript2015(ES6)から導入されました。
ECMAScriptとは
もともとJavaScriptはNetscape社のブラウザで使われる言語として誕生したので、他のブラウザは想定されておらず各ブラウザはJavaScriptを独自に拡張していたわけです。そのため、JavaScriptはまったく標準化がされていない言語だったわけです。
これではいろいろ問題があるとして、Netscape社は国際標準化団体のECMAに依頼してJavaScriptのコア部分を標準化しました。これがECMAScriptと呼ばれるものになります。
出典元:SAMURAI ENGINEER
つまりECMAScirptはJavaScriptがどのブラウザでも使えるようにした標準化規格、ということです。ここでは
ふーん、そうなんだ
くらいの認識で大丈夫です。
クラスは元々JavaScriptには無かった考え方で2015年から導入されたんだなとお考えください。
クラスとインスタンスとは
ではクラスとは一体なんでしょうか。
クラスはよく言われますが「設計図」であり「インスタンスの元となるもの」です。
インスタンスは「クラスという設計図から出来上がったモノ」です。
クラスは設計図とも言えますが、「大分類」とも言い換える事ができます。
クラスが「大分類」、インスタンスが「小分類」というイメージです。
例えばスマホであれば、クラスがスマートフォンで、インスタンスがiPhoneやAndroidといった感じです。
この場合スマートフォンが大分類、AndroidやiPhoneが小分類ですね。
他にもX(旧Twitter)の例で言うと、ツイートのテンプレートがあり、そこに当てはめてツイートをしていくわけですが、このこのテンプレートがクラス、実際のツイートがインスタンスという考え方もわかりやすいかと思います。
これらはオブジェクト指向ですがオブジェクト指向は、「それがどんなモノで、どういう動きをするのか」に着目した考え方と言えます。
なぜクラスやインスタンスを使うのか
っていうかそもそもなんでクラスやインスタンスを使うの?
と感じる方も多いと思います。
例えばですが、名前や形は同じでも挙動が少し違う場合などに毎回オブジェクトを作るのは面倒です。
そこで、クラスとインスタンスを使うことによって似たようなデータを効率よく生成する事ができます。
コードで見てみましょう。
{
name:'太郎',
text:'こんにちは'
}
show(){
console.log()
}
}
{
name:'二郎',
text:'こんばんは'
}
show(){
console.log()
}
}
上記のような二つのオブジェクト(インスタンス)は似ていますよね。
nameとtextの値が少し違うだけです。
このようなオブジェクトがあった場合、クラスを使うことで以下のようにテンプレート化できます。
class Person{
constructer(){
name:,
text:
}
show(){
console.log()
}
}
このテンプレート化されたものがクラスと言われるものです。
一度テンプレートを作って定義しておけば、後からいろんな種類のインスタンスを作る事ができてコードもシンプルに書く事ができ便利です。
例えばそうですね、ハンバーグカレーとチキンカツカレーを作りたい場合、二つは違う料理ですが、大きな分類としては「カレー」ですよね。
そしてカレーという大枠の料理を作るなら、ハンバーグカレーもチキンカツカレーも少し内容を変えるだけで作れてしまえた方が便利です。
また一からカレールーから作るよりも、ハンバーグを乗せたりチキンカツを乗せるだけ、の方がはるかに手間は省けるはずです。
このように一度「カレー」というクラスを作っておき、後からそのクラスを元に色々なインスタンス(チキンカツカレーやハンバーグカレーなど)を作る事が出来る。
これがクラスとインスタンスが存在する意義と使う目的です。
プログラミングにおいて「いかに楽に書くか」「いかに便利にするか」というのは根底にある考え方です。
なぜなら同じ結果なのであれば楽に効率的に書ける方が絶対いいですからね。
オブジェクトを生成する時に毎回「○○というプロパティがあり、○○というメ
ソッドがあって」と定義から作るのは面倒なわけです。
なのであらかじめクラスとして共通点をまとめて定義しておけば後々楽にプログラムを書く事ができるわけですね。
ちなみにクラスの作り方について改めて見ていきます。
ここではPersonというクラスを定義しています。
class Person{
constructor(name,text){
this.name = name,
this.text = text,
}
show(){
console.log()
}
}
const person = new Person();
constructor()という謎の文章が出てきましたが、後ほど解説します。
constructor()の引数にnameとtextを入れることで、インスタンスでも引数を入れることで使いまわす事ができます。
ポイントは以下です。
・「class ○○」という形でクラス名を定義する
・クラス名は原則最初の文字は大文字にする
・constructor()というメソッドを使って初期化する
・constructor()内のプロパティにはthisをつける
classを作るときは基本的には、「class クラス名」という形で定義するようにしましょう。
またその際にクラス名は原則大文字から始めるようにしましょう。
constructor()とは何か
constructor()メソッドは、 class で作成されたオブジェクトの生成と初期化のための特殊なメソッドです。コンストラクターを使用すると、インスタンス化されたオブジェクトに対して、他のメソッドを呼び出す前に行う必要のある独自の初期化を提供することができます。
出典元:MDN
少しわかりづらいのですが、constructor()とはメソッド(関数)のことで、クラスを新しく作った時に実行されるものです。
インスタンスを生成するためのメソッドとも言えます。
JavaScriptには元々クラスという概念がないため(ないってどういうことだよ!)、コンストラクタからインスタンスを生成する事になります。
コンストラクタの基本的な記述は以下となります。
class クラス名{
construcor(){
//ここに処理を書く
}
}
実際のコードで見てみましょう。
class Person{
constructor(){
console.log("ハロー!");
}
}
const person = new Person();
//結果
//ハロー!
ちなみにコンストラクタの中の処理はインスタンスが生成された直後に実行されます。
コンストラクタがあることによってインスタンスを生成する時に実行したい処理や設定を追加できるわけですね。
constructor()の「()」に引数名を記述することで、その引数をコンストラクタの処理内で使用する事ができます。
コンストラクタに引数として値を入れるには、「new クラス名()」の「()」 の中に値を入れてあげましょう。
また、constructor()は最初にやっておくべき処理、初期化などに使われます。
constructorのthis
次にconstructor()というメソッドを使って初期化をすると共に、プロパティにはthisをつけるようにしましょう。
コンストラクタの中で「this.プロパティ名=値」とすることで生成されたインスタンスにプロパティと値を追加する事ができます。
class Person{
constructor(){
this.name ="Taro";
this.age="22";
}
}
const person = new Person();
console.log(person.name);
console.log(person.age);
//結果
//Taro
//22
thisは呼び出される場所、呼び出し元によって挙動が変わる特殊な「変数」ですが、ここではPersonというクラスのことを指していることになります。
「this」=「Person」のnameになるということですね。
初期化とは何か
初期化はインスタンスを生成する際に行います。
インスタンスを生成する際には時にインスタンスの中に不要な要素が入っている事があり、期待通りの動きをしてくれない事があります。
そのような理由からエラーなどが起きないようにするためにインスタンス内を真っさらな状態にしておくのが初期化となります。
インスタンスを生成する方法
次にインスタンスを生成する方法ですが、インスタンスを生成するには必ず変数を指定してあげる必要があります。
そしてインスタンス名には必ず「new」という演算子をつけます。
new演算子はざっくり言うとインスタンスを生み出すためのものとお考えください。
実際にコードで見てみましょう。
const hoge = new Person();
これによってPerson()というインスタンスが生成され、hogeという変数に代入されました。
(hogeはプログラミングの世界で使われる「特に意味のない言葉」です。)
継承とは
クラスを理解する時に「継承」というキーワードが出てきます。
継承とはなんのことでしょうか。
継承とは、新しく作るクラスが、既存のクラスの一種であった場合、その既存のクラスのプロパティやメソッドを引き継げる方法のことです。
すでにあるクラス(親クラス)から新しいクラス(子クラス)を作るときに子クラスは親クラスの機能の全てを引き継ぐことができます。
継承するためには「extends」を用います。
extendsは直訳すると「拡張」という意味ですが、プログラミングの世界では継承する際に使われることを覚えておきましょう。
例を見てみましょう。
例えばFIsh(魚)というクラスからShark(サメ)というクラスを継承する場合は以下のように記載します。
class Shark extends Fish{
}
継承したクラス(Shark)は親クラス(Fish)のプロパティやメソッドを全て引き継ぐことができます。
class Fish {
constructor(color, size) {
this.color = silver;
this.size = 40;
}
bark() {
console.log("食べる");
}
}
class Shark extends Fish{
}
const shark = new Shark("blue",200);
//親クラスのbarkというメソッドをsharkでも呼び出せる
shark.bark();
//結果
食べる
上記で親クラスのFishのメソッドであるbark()を子クラスのsharkでも使えてることがわかりますね。
ただ、子クラスで定義したメソッドは親クラスでは使えないので、その点はご注意ください。
まとめ
はい、いかがでしたでしょうか。
・クラス=設計図
・インスタンス=クラスを元に作られるモノ(オブジェクト)
・コンストラクタ=クラスを新しく作った時に実行されるメソッド
でしたね。
オブジェクト指向は最初は中々慣れる事ができず覚えにくい概念だと思います。
カタカナも多いですしね。orz
オブジェクト指向に慣れるには、やはり書いてみるしかありません。
コードを書いていけばオブジェクト指向の便利さに気づきオブジェクト指向から離れられなく?なるはずです。笑
それではまた次の記事でお会いしましょう。