new 演算子とは
JavaScriptでは、new演算子を使用してオブジェクトを作成することができます。このとき、new演算子を使って呼び出される関数は、コンストラクター関数と呼ばれます。
コンストラクター関数内でreturn文が使用された場合、その返された値が新しいオブジェクトとして扱われます。具体的には、以下のような手順が実行されます。
- 新しい空のオブジェクトが作成されます。
- コンストラクター関数が呼び出されます。この時、thisキーワードは、新しく作成されたオブジェクトを参照します。
- コンストラクター関数内で、新しいオブジェクトに対してプロパティやメソッドを追加できます。
- 新しいオブジェクトがreturn文で返される場合、その値が返されます。そうでない場合、thisキーワードが自動的に返されます。
return文ない例(通常これ)
コンストラクター関数内でreturn文が使用されていない場合、thisキーワードが自動的に返されます。例えば、以下のコードは、新しいオブジェクトを作成してthisキーワードを返す例です。
function Person(name) {
this.name = name;
}
const person = new Person('Jane');
console.log(person.name); // 'Jane'
この場合、Personコンストラクター関数内でreturn文は使用されていません。そのため、新しいオブジェクトはthisキーワードによって参照され、person変数はそのオブジェクトを参照します。したがって、console.log(person.name)は'Jane'と出力されます。
return文がある例
以下のコードは、Personというコンストラクター関数を定義し、return文を使用してオブジェクトを返す例です。
function Person(name) {
this.name = name;
return {name: 'John'};
}
const person = new Person('Jane');
console.log(person.name); // 'John'
この場合、Personコンストラクター関数内でreturn {name: 'John'}が使用されています。そのため、新しいオブジェクトとして{name: 'John'}が返され、person変数はそのオブジェクトを参照します。したがって、console.log(person.name)は'John'と出力されます。
また、return文で返されるオブジェクトが、コンストラクター関数で定義されたプロパティやメソッドを上書きしてしまう場合もあります。例えば、以下のコードは、Personコンストラクター関数で定義されたgreetメソッドを上書きしてしまう例です。
function Person(name) {
this.name = name;
this.greet = function() {
console.log(`Hello, my name is ${this.name}`);
};
return {
name: 'John',
greet: function() {
console.log('Nice to meet you');
}
};
}
const person = new Person('Jane');
person.greet(); // 'Nice to meet you'
この場合、Personコンストラクター関数内でreturn文が使用され、greetメソッドも新しいオブジェクトに上書きされます。そのため、person.greet()は'Nice to meet you'と出力されます。
コンストラクター関数内でreturn文が使用されると、その返された値が新しいオブジェクトとして扱われるため、通常のnew演算子によるオブジェクトの作成とは異なる結果が得られます。new演算子を使用する際には、コンストラクター関数内でreturn文を使用することによる影響に注意しましょう。
return文でオブジェクト以外のプリミティブ値を返す場合
new演算子とreturn文の関係については、さまざまな観点から理解することができます。前述の通り、return文でオブジェクトが返された場合は、その返されたオブジェクトが新しいインスタンスとして扱われます。しかし、return文でプリミティブな値(string、number、boolean、null、undefined、symbol)が返された場合には、new演算子によって生成されたオブジェクトではなく、return文で返された値が返されます(そうじゃないJavaScriptエンジンもあるかも...)
以下は、return文でプリミティブな値を返すように定義されたコンストラクター関数の例です。
function Person(name) {
this.name = name;
return 123;
}
const person = new Person('John');
console.log(person); // Person { name: 'John' }
この例では、Personコンストラクター関数内でreturn文が使用され、123というプリミティブな値が返されます。しかし、new演算子によって生成されたpersonオブジェクトはPersonコンストラクター関数で定義されたthisのオブジェクトであり、nameプロパティを持っています。つまり、return文で返されたプリミティブな値ではなく、thisが返されていることがわかります。
あとがき
ChatGPTに大枠の文章とサンプルコードを書かせて修正しました。
嘘つくこともあるので検証は必要ですが、文章を0から作るより楽ですね。