こんにちは、ライターのマサトです!
今回は、新規のインスタンスを作成する際に使う演算子「new」について学習していきましょう!この記事では、
- 「new」とは?
- newの使い方
という基本的な内容から、
- newの実践例
- コンストラクタの作り方
- new演算子の注意点
などの応用的な使い方に関しても解説していきます。この記事で、new演算子について楽しく学習していきましょう!
「new」とは?
まず最初に、みなさんはJavaScriptで「new」をどんな時に使うかご存知でしょうか?簡単に言ってしまえば「インスタンスを作成する時」にnew演算子は使われる…、ということなのですが、そもそも「インスタンス」とは何でしょうか?
JavaScriptに限らずオブジェクト指向のプログラムは、あらかじめ用意されている「オブジェクト」をそのまま扱うことはありません。
例えば、目的が違う「A」「B」という2つのプログラムがあったとします。両方のプログラムがまったく同じ「オブジェクト」に対してデータを読み書きしてしまうとお互いに干渉してしまって正しく動作しません!
このような場合、通常は「オブジェクト」の本体からコピーしたものを利用するのです!
こうすれば、両方のプログラムが干渉することは無くなりますよね?
この「コピーをする」という行為がインスタンス化であり、コピーされた「オブジェクト」をインスタンスと呼ぶわけです。JavaScriptでは、このインスタンスを作成する役割を担っているのが「new演算子」ということになります!
newの使い方
ここからは、実際に「new」を使ったプログラミング手法について学んでいきましょう!JavaScriptの標準で用意されているオブジェクトから、よく使われるものを見ていきます。
組み込みオブジェクトの種類について
まずは、標準で提供されているJavaScriptの組み込みオブジェクトについて確認してみましょう!一般的には、以下のような種類があります。
オブジェクト | 内容 |
---|---|
Array | 配列を扱うための機能を提供する |
String | 文字列を扱うための機能を提供する |
Boolean | 真偽値を扱うための機能を提供する |
Number | 数値を扱うための機能を提供する |
Function | 関数を扱うための機能を提供する |
Date | 日付を扱うための機能を提供する |
RegExp | 正規表現を扱うための機能を提供する |
Object | オブジェクトを扱うための機能を提供する |
配列や日付など、いずれも「new」を使うことでインスタンスを作成して利用することができるわけです。そして、そのインスタンスを活用することでJavaScriptはさまざまな表現やプログラムを組み立てることが出来るようになっています。
「new date」で日付を生成する方法
試しに「Dateオブジェクト」を使って「new」演算子の使い方を見ていきましょう!一般的な使い方としては、【 new オブジェクト 】のようにオブジェクトの前にnewを記述するだけでOKです。
次のサンプル例を見てください!
var today = new Date();
この例では、「new Date()」と記述することでDateオブジェクトのインスタンス(コピー)を作成しています。
そして、そのインスタンスを変数「today」に代入することで、それ以降は「today」がインスタンスとしての役割を持つわけです。例えば、Dateオブジェクトが標準で提供しているいくつかのメソッドは以下のように利用できます!
var today = new Date(); var year = today.getFullYear(); var day = today.getDate(); var time = today.getHours(); console.log( '今日の西暦:' + year ); console.log( '今日は' + day+ '日です' ); console.log( '今は' + time + '時です');
実行結果
今日の西暦:2018 今日は23日です 今は16時です
インスタンス「today」に続けて「today.getFullYear()」と記述すれば西暦を取得できるメソッドが利用できるわけです。このように、「new」はオブジェクトをコピーする役割があり、一般的にはインスタンス化するという表現でよく言われています。
ちなみに、Dateオブジェクトのさまざまなメソッドを活用する方法は次の記事で詳しくまとめているのでぜひ参考にしてみてください!
「new array」で配列を生成する方法
今度は「Arrayオブジェクト」を使った「new」演算子の使い方を見てみましょう!「Arrayオブジェクト」って聞くと難しいイメージがするのですが、これは単純に「配列」のことだと考えてください。
つまり、配列データを作成したい時に利用できるオブジェクトになります。次のサンプル例を見てください!
var arr = new Array('イチゴ', 'メロン', 'バナナ', 'スイカ');
この例では、Arrayオブジェクトの引数に配列へ格納したい文字列を指定しています。これにより、インスタンス化と同時に配列データを作成しているわけですね。
もちろんメソッドも利用可能で、例えば並び替えができる「sort()」メソッドを使うと次のようになります。
var arr = new Array('イチゴ', 'メロン', 'バナナ', 'スイカ'); arr.sort(); //あいうえお順に並び替え console.log( arr );
実行結果
イチゴ,スイカ,バナナ,メロン
このように、「sort()」を実行するだけで配列に格納されていた文字列が「あいうえお順」に並び替えられるわけです。その他、Arrayオブジェクトが持っている多彩なメソッドやその活用技については次の記事でまとめているので参考にしてみてください!
newの実践例
ここからは、その他の組み込みオブジェクトによる「new」の使い方について学んでいきましょう!主に「オブジェクト」「関数」「画像」について、それぞれのパターンでインスタンスを生成してみます。
オブジェクト(Object)を生成して利用する方法
まずは「オブジェクト(Object)」をnewで生成してみましょう!一般的な記述方法は以下のとおりです。
var myObj = new Object();
この例では「オブジェクト(Object)」のインスタンスを作成して変数「myObj」に代入しています。ここで言う「オブジェクト(Object)」というのは、これまで出てきたDateやArrayオブジェクトのベースになるものと考えると良いでしょう。
つまり、何もデータが入っていない「空っぽ」のオブジェクトを作成したということです。また、やろうと思えば自分でDateオブジェクトなどと同じものが作れる可能性も秘めていると言えるでしょう。
作成したオブジェクトは、「プロパティ」に「値」を代入することでデータを追加していくことができます。次のサンプル例を見てください!
myObj.name = '太郎'; myObj.age = 30; console.log( myObj );
実行結果
{"name":"太郎","age":30}
この例では、「myObj.name = ‘太郎’」のように記述することで「name」というプロパティに「太郎」という値を代入しています。これにより、インスタンス「myObj」にどんどんデータが追加されていき実行結果のようにオブジェクトが作られるわけです。
関数(Function)を生成して利用する方法
今度は「Functionオブジェクト」をnewで生成してみましょう!
「Functionオブジェクト」は、一般的な関数を作るようなイメージで考えると分かりやすいです。記述方法としては、【new Function( 処理の内容 )】のように引数へ実行したい処理を文字列で記述します。次のサンプル例を見てください!
var myFunc = new Function('console.log("Hello")'); myFunc();
実行結果
Hello
この例では、Functionオブジェクトの引数にコンソールログの出力を記述していますよね?そのため、インスタンスを「myFunc()」と記述することで処理が実行されてコンソールログに「Hello」と出力されるわけです。
また、仮引数の設定も次のように記述することができます。
var myFunc = new Function('name', 'console.log("こんにちは、" + name)'); myFunc('太郎');
実行結果
こんにちは、太郎
Functionオブジェクトの第1引数に仮引数「name」を設定することで、インスタンスを実行する際に「太郎」と指定することができます。
さらに、Functionオブジェクトの活用方法やnewを使わない手法について次の記事でまとめているのでぜひ参考にしてみてください!
画像(Image)を生成して利用する方法
最後に「Imageオブジェクト」をnewで生成してみましょう!「Imageオブジェクト」は、画像を表示・操作するためのもので一般的な「imgタグ」に相当します。
次のサンプル例を見てください!
var image = new Image();
このように、「new Image()」と記述するだけでインスタンスを作成することが可能です。ただし、インスタンスを作成したあとに「画像ファイルの指定」と「HTMLへの組み込み処理」が次のように必要です!
var image = new Image(); image.src = "sample.jpg"; document.body.appendChild(image);
「image.src」に画像ファイルを指定することで、画面に表示させる画像を設定することができます。あとは、「appendChild()」を使って任意のHTML要素へ組み込めば画面に表示させることができます。
上記の例だと、HTMLのbody要素内に指定した画像を表示するという意味になるわけです。ちなみに、インスタンスを作成する際に画像のサイズをあらかじめ設定することも可能です!
一般的な記述としては、【 new Image( 幅, 高さ ) 】のように引数へ幅と高さを設定すればOKです。
var image = new Image( 150, 100 );
このように記述することで、設定したサイズの画像が生成されて表示させることができるわけです!
コンストラクタの作り方
ここまで、組み込みオブジェクトについて見てきましたが、もちろん独自に「クラス」を作成してインスタンスを作ることも可能です。
ただし、他のオブジェクト指向言語と違って、JavaScriptにはクラスという概念が無いので、クラスによく似た構造を持つ関数「コンストラクタ」を作ることで実現します。具体的なコード例を見てみましょう!
function Member(name, age) { this.name = name; this.age = age; } var member = new Member('太郎', 30); console.log( member );
出力結果
Member {name: "太郎", age: 30}
このサンプルのように、「Member」というコンストラクタを作成する場合は、functionを使って関数を作る感覚で構築していきます。
ポイントは関数内に「this」と記述している部分で、これを書くことでインスタンスのプロパティを設定することが可能で、この例では「名前(name)」と「年齢(age)」の2種類のプロパティを持っていることが分かります。
あとはこれまでと同じ方法で、newのあとに引数を代入した「Member」を指定すればOKです。ちなみにコンストラクタは、通常の関数名と区別するために「大文字」で始めるのが慣習となっている点も忘れないようにしましょう。
new演算子の注意点
実を言うとコンストラクタは間違った使い方をすると危険な状況になる問題を秘めています。それは、ズバリ言うと「newの付け忘れ」によるものです!
これを確認するために、先ほど「Member」を作成したコードを使って、newを付けない場合にどうなるかを見てみましょう!
function Member(name, age) { this.name = name; this.age = age; } //newを付けない場合の処理 var myMember = Member('太郎', 30); console.log(myMember); console.log(this.name); console.log(this.age);
出力結果
undefined 太郎 30
この例を見ると、newを付け忘れたら単純に「関数」が変数へ代入されただけのように見えます。出力結果を見ると、変数「myMember」は「undefined」となっているのですが、注目すべきは「this.name」と「this.age」でそれぞれ値が取得できている点です!
これは言い換えると、「window.name」「window.age」と同じ意味であり、なんとグローバル変数を作ってしまっているわけです。
グローバル変数はプログラム全体に影響を与えるため、予期せぬバグやトラブルを引き起こす可能性が非常に高くなるので注意が必要になるわけです。そこで、念のため「Strictモード」を適用しておくという方法があります。
function Member(name, age) { 'use strict'; this.name = name; this.age = age; }
このようにしておけば、newを付け忘れたとしても「グローバル変数」を作成する前にエラーになるだけなので、重大なバグを未然に防ぐことができるでしょう。
まとめ
今回は、インスタンスを作成する時に使う演算子「new」について学習しました!学習した内容について、もう一度おさらいをしておきましょう。
- オブジェクトのコピー(インスタンス)を作る時にnew演算子を使う!
- 組み込みオブジェクトは、new演算子を使ってインスタンス化できる!
- 独自に作成したコンストラクタもnew演算子でインスタンス化できる!
- newの付け忘れについては危険なので注意が必要!
これらのポイントを踏まえたうえで、ぜひ自分でもプログラムを実際に書いてどのような出力結果になるかを確認するようにしておきましょう!