Edited at

JavaScriptのnew(インスタンス生成)は何をしているのか?について調べてみた

More than 1 year has passed since last update.


はじめに

「JavaScriptでオブジェクトを生成する場合は、new演算子を使用します。」

これはnewの説明で用いられる説明文であり、その例として以下のようなコードもよく見ると思う。

var Person = function(name, age) {

this.name = name;
this.age = age;
};

var taro = new Person('太郎', 20);

僕はこのコードを見て、「なぜthisが必要なのか?」「コンストラクタはなに?」「そもそもインスタンス化して何になるの?」と色々と疑問が湧いてきたわけである。

この記事では、これらの疑問に対して調べて分かったことをメモに残していく。


JavaScriptにはクラスはない(※ES6からクラスは導入された)

現在はJavaScriptでもクラスが利用できるようになったが、ECMAScript6(ES6)以前はクラス構文が無かったため、クラスではなくコンストラクタからインスタンスを生成していた。


コンストラクタとは何か

古いコードを理解することは大切だと思うので、コンストラクタでインスタンスを生成する仕様も学びたいと思う。

コンストラクタを一言で説明すると、new(インスタンス生成)した瞬間に実行される関数のことと言える。

さきほどのコードで見ると、functionに当たる部分がコンストラクタである。

var Person = function(name, age) {

this.name = name;
this.age = age;
};

var taro = new Person('太郎', 20);


なぜthisを付ける必要があるのか

まずは、this付きの場合とthis無しの場合における違いを見てみる。


this付きの場合

var Person = function(name, age) {

this.name = name;
this.age = age;
};

var taro = new Person('太郎', 20);
console.log(taro.name + '' + taro.age + '歳です。');
//=>太郎は20歳です。


this無しの場合

//thisなし

var Person = function(name, age) {
name = name;
age = age;
};

var taro = new Person('太郎', 20);
console.log(taro.name + '' + taro.age + '歳です。');
//=>undefinedはundefined歳です。

this無しの場合は、undefinedとなり値を取得できなくなった。最初は理由がわからなかったが、newについて調べていくうちにあることが分かった。


newの挙動

var Person = function(name, age) {

// var this = {};
this.name = name;
this.age = age;
// return this;
};

var taro = new Person('太郎', 20);


  1. 実はnewと一緒に関数を呼び出すと、まず新しい空のオブジェクト (つまり {}) が生成される。

  2. 次に関数が呼び出されるが、その際に関数内の this が生成されたオブジェクトを指すようになる。

  3. 関数が実行された後、生成されたオブジェクトが new の実行結果として返される。

ということで、空のオブジェクトを生成しているのが理由だったみたい。

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


これでES6で導入されたクラス構文が理解しやすくなる

class Figure {

constructor(height, width) {
this.height = height;
this.width = width;
}
}

var rectangle = new Figure(20, 40);
console.log(rectangle.width);
//=>40

従来の関数宣言ではなく、クラス構文が使えるようになったことで可読性が上がる。

constructorという名前のメソッドは、クラスに1つしか定義できず、2回以上定義されている場合は、SyntaxErrorになるので注意。

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


参考記事


  1. http://www.yunabe.jp/docs/javascript_class_in_google.html#function

  2. https://html5experts.jp/takazudo/17355/