【俺的理解】JavaScriptのnew演算子
公開日:
参考記事
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/new
https://ja.javascript.info/constructor-new
はじめに
JavaScript
の new
演算子とはなんですか?と自分で自分に問いかけて、説明できなかったので調べてまとめました。
通常のオブジェクト
const user = {
name: 'Jack',
isAdmin: false,
};
通常のオブジェクトは上のように作成できます。しかし、複数のユーザーやメニューのアイテムなど似たようなオブジェクトを複数作成する必要がある場合があったとしましょう。その場合、上のような記法で繰り返しオブジェクトを作成しようとするとめんどくさいし、どうしてもミスが発生しやすくなってしまいます。そこで登場するのが
- new 演算子
- コンストラクタ関数
です。こいつらを利用することで似たようなオブジェクトを簡単に作成することができるようになります。
new 演算子・コンストラクタ関数とは
まずはコンストラクタ関数から
コンストラクタ関数とは
コンストラクタ関数と呼ばれる関数は基本的には通常の関数と全く同じです。しかし以下の慣習があります。
- 最初の文字は大文字
- new 演算子のみで実行されるべき
慣習というのはコードを読みやすくするための暗黙の了解的なものだと自分は理解していて、
boolean 型の変数名は isHoge みたいな形にした方がわかりやすい
みたいな感じだと思ってます。
new 演算子とは
// コンストラクタ関数
function User(name) {
this.name = name;
this.isAdmin = false;
}
// new演算子を用いてコンストラクタ関数を実行
let user = new User('Jack');
alert(user.name); // Jack
alert(user.isAdmin); // false
new
演算子を用いてコンストラクタ関数が実行された場合、以下の処理が行われます。
- 新しい空のオブジェクトが作成され、
this
に割り当てられる。 - 関数本体を実行します。通常は新しいプロパティを追加することで
this
に変更を加えます。 this
の値が返されます。
つまり上の例で見ると、new 演算子で関数を実行したことにより、以下の処理が行われていることになります。
function User(name) {
// this = {}; (暗黙)
// this へプロパティを追加
this.name = name;
this.isAdmin = false;
// return this; (暗黙)
}
したがって上の例の
let user = new User('Jack');
は
let user = {
name: 'Jack',
isAdmin: false,
};
と同じ意味になります。似たオブジェクトを複数作成するときに new
演算子とコンストラクタ関数が便利という意味がわかったような気がします。
ここまで new
演算子とコンストラクタ関数について調べましたが、まとめると
new
演算子で実行されることを期待されている関数のことをコンストラクタ関数とよび、慣習的に最初の文字は大文字であるべき
ってことになるでしょうか
メソッドも this に追加可能
余談ですが、new
演算子を使った時にメソッドもプロパティとして追加できます。
// コンストラクタ関数
function User(name) {
this.name = name;
this.sayHi = function () {
alert('My name is: ' + this.name);
};
}
let john = new User('John');
john.sayHi(); // My name is: John
コンストラクタ関数の戻り値
コンストラクタ関数の役割は必要なものを this の中に書き込み、this を return することなので、コンストラクタ関数は通常 return 文を持ちません。
だた、return が定義されていた場合は以下のルールに従って値を返します
- オブジェクトが return された場合はそのオブジェクトを返す
- プリミティブ値が return されたときは無視する
これは最後に試してみます。
new 演算子を使ってみる
普通のコンストラクタ関数
function Hoge() {
this.hoge = 'hoge';
this.fuga = 2;
}
const piyo = new Hoge();
console.log(piyo.hoge); // 'hoge'
console.log(piyo.fuga); // 2
よし。
小文字で始まっていても new 演算子使える
function hoge() {
this.hoge = 'hoge';
this.fuga = 2;
}
const piyo = new hoge();
console.log(piyo.hoge); // 'hoge'
console.log(piyo.fuga); // 2
小文字はじまりでも全然使えるが、わかりにくいので暗黙的に NG
メソッド追加してみる
function Hoge() {
this.hoge = 'hoge';
this.fuga = 2;
this.sayPiyo = function () {
return 'piyopiyo' + this.hoge;
};
}
const piyo = new Hoge();
console.log(piyo.hoge); // 'hoge'
console.log(piyo.fuga); // 2
console.log(piyo.sayPiyo()); // piyopiyohoge
メソッド追加できる。
特殊な return をつけてみる
function Hoge() {
this.hoge = 'hoge';
this.fuga = 2;
return { hoge: 'hogehoge' };
}
const piyo = new Hoge();
console.log(piyo.hoge); // 'hogehoge'
console.log(piyo.fuga); // undefined
オブジェクトを返したらそのオブジェクトが返ってきた。
function Hoge() {
this.hoge = 'hoge';
this.fuga = 2;
return 7;
}
const piyo = new Hoge();
console.log(piyo.hoge); // 'hoge'
console.log(piyo.fuga); // 2
プリミティブ値を返したらガン無視で this が返ってきた。
最後に
new ってクラスをインスタンス化するときのアレでしょ的な感じだったのを理解できたのが嬉しい。実際調べてみたらちょっと違ったし。
では
Bye