回答編集履歴

3 プロトタイプベースに関して追記

miyabi-sun

miyabi-sun score 18951

2017/09/05 10:57  投稿

> 1行目で宣言した変数personの型はオブジェクトですか?
いいえ、これは関数です※
ただし、`new`を使ってインスタンスを作ることを想定した関数です。
 
> 1行目で宣言したpersonがオブジェクトだとすると、下部で new person(); とオブジェクトを生成する意味は何でしょうか?  
オブジェクトではない場合、person の型は何でしょうか?  
`new`が何やってんねんってのいうのがわかれば自ずと理解出来ます。
newを使って関数を叩くと、まず空のオブジェクトを作ります。
関数内部で`this.hoge = 123;`という風に`this`に向かってプロパティを詰めていくと、
newで作られた空のオブジェクトのプロパティに値が詰め込まれていきます。
そして、ここが重要!
newを使って関数が実行されると、最初に作ったオブジェクトだったものが戻り値として帰ってきます。
関数内の`return`じゃないよ!
要するに変数`me`は`new person()`と指定するから、必ずオブジェクトが代入されるってわけ。
なので、thisのプロパティに値を突っ込む事が目的の変な関数が出てきたら、
それは他の言語で言うクラスに相当する雛形的な関数と解釈してください。
ちょっとだけ変な書き方になりますが、クラスベースのオブジェクト指向言語と同じ事は可能です。
(ES2015ではClass構文がサポートされ、他の言語のようなクラス宣言が出来るようになりました)
```Bash
var person = function() {
 this.name = "hogehoge";
}
var me = new person();
console.log(me);
// person {name: "hogehoge"}
```
---
newを使って作られたオブジェクトはただのオブジェクトではなく、
関数である`person`のインスタンスとして動作するオブジェクトになります。
`console.log`で中身を表示するとちゃんと`person`のインスタンスって表示されることが確認出来ます。
ついでに定義しておいたpersonのメソッド(プロトタイプのプロパティ)にアクセスできます。
```JavaScript
var person = function() {
 this.name = "hogehoge";
}
// これがメソッド定義
person.prototype.hello = function() {
 return "hello. my name is " + this.name;
}
var me = new person();
console.log(me);
// person {name: "hogehoge"}
console.log(me.hello());
// "hello. my name is hogehoge"
```
---
※因みにRubyは完全なオブジェクト指向言語なので数値や文字列も全てオブジェクトですが、
> 1行目で宣言したpersonがオブジェクトだとすると、下部で new person(); とオブジェクトを生成する意味は何でしょうか?
オブジェクトではない場合、person の型は何でしょうか?
JavaScriptはプロトタイプベースのオブジェクト指向言語という話を聞いたことありませんか?
(その気になれば)全ての関数をnewして新しいインスタンスを生成することが可能です。
現実的にはthisに値を突っ込むコンストラクタメソッド的な関数しかプロトタイプの元には成りえないので、
雛形に相当する関数を予め作っておく(プロトタイプ)、それを元に新しいインスタンスを生成する(new)
正にコピーを作りながら量産するという考え方になります。
継承の代わりになるのがプロトタイプのコピー及び改良。
ちょっとしたコードを買いて見せたかったけど、ちゃんとした書き方は大変なので参考サイト張っておきます。
参考サイト:[継承とプロトタイプチェーン - MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain)
---
※Rubyは完全なオブジェクト指向言語なので数値や文字列も全てオブジェクトですが、
JavaScriptも不完全ながら似たようなアプローチで、`Number, String, Boolean`等のプリミティブなもの以外はオブジェクトから派生して作られたものです。
JavaScriptの関数はFunctionというオブジェクトを使って生成されたものです。
「変数personの型はオブジェクトですか?」という問いに関しては、
その通りと回答するのが正解なのですが、
今回の質問に限ってはそういう分類に対する質問とは異なると考え、否定しています。
2 ただのオブジェクトではないよと追記

miyabi-sun

miyabi-sun score 18951

2017/09/05 10:33  投稿

> 1行目で宣言した変数personの型はオブジェクトですか?
いいえ、これは関数です※
ただし、`new`を使ってインスタンスを作ることを想定した関数です。
> 1行目で宣言したpersonがオブジェクトだとすると、下部で new person(); とオブジェクトを生成する意味は何でしょうか?
オブジェクトではない場合、person の型は何でしょうか?
`new`が何やってんねんってのいうのがわかれば自ずと理解出来ます。
newを使って関数を叩くと、まず空のオブジェクトを作ります。
関数内部で`this.hoge = 123;`という風に`this`に向かってプロパティを詰めていくと、
newで作られた空のオブジェクトのプロパティに値が詰め込まれていきます。
そして、ここが重要!
newを使って関数が実行されると、最初に作ったオブジェクトだったものが戻り値として帰ってきます。
関数内の`return`じゃないよ!
要するに変数`me`は`new person()`と指定するから、必ずオブジェクトが代入されるってわけ。
なので、thisのプロパティに値を突っ込む事が目的の変な関数が出てきたら、
それは他の言語で言うクラスに相当する雛形的な関数と解釈してください。
ちょっとだけ変な書き方になりますが、クラスベースのオブジェクト指向言語と同じ事は可能です。
(ES2015ではClass構文がサポートされ、他の言語のようなクラス宣言が出来るようになりました)
```Bash
var person = function() {
 this.name = "hogehoge";
}
 
var me = new person();  
 
console.log(me);  
// person {name: "hogehoge"}  
```  
 
---  
 
newを使って作られたオブジェクトはただのオブジェクトではなく、  
関数である`person`のインスタンスとして動作するオブジェクトになります。  
 
`console.log`で中身を表示するとちゃんと`person`のインスタンスって表示されることが確認出来ます。  
ついでに定義しておいたpersonのメソッド(プロトタイプのプロパティ)にアクセスできます。  
 
```JavaScript  
var person = function() {  
 this.name = "hogehoge";  
}  
// これがメソッド定義  
person.prototype.hello = function() {
 return "hello. my name is " + this.name;
}
var me = new person();
console.log(me);
// person {name: "hogehoge"}
console.log(me.hello());
// "hello. my name is hogehoge"
```
---
※因みにRubyは完全なオブジェクト指向言語なので数値や文字列も全てオブジェクトですが、
JavaScriptも不完全ながら似たようなアプローチで、`Number, String, Boolean`等のプリミティブなもの以外はオブジェクトから派生して作られたものです。
JavaScriptの関数はFunctionというオブジェクトを使って生成されたものです。
「変数personの型はオブジェクトですか?」という問いに関しては、
その通りと回答するのが正解なのですが、
今回の質問に限ってはそういう分類に対する質問とは異なると考え、否定しています。
1 meに何が代入されるか追記

miyabi-sun

miyabi-sun score 18951

2017/09/05 10:26  投稿

> 1行目で宣言した変数personの型はオブジェクトですか?
いいえ、これは関数です※
ただし、`new`を使ってインスタンスを作ることを想定した関数です。
> 1行目で宣言したpersonがオブジェクトだとすると、下部で new person(); とオブジェクトを生成する意味は何でしょうか?
オブジェクトではない場合、person の型は何でしょうか?
`new`が何やってんねんってのいうのがわかれば自ずと理解出来ます。
newを使って関数を叩くと、まず空のオブジェクトを作ります。
関数内部で`this.hoge = 123;`という風に`this`に向かってプロパティを詰めていくと、
newで作られた空のオブジェクトのプロパティに値が詰め込まれていきます。
 
そして、ここが重要!  
newを使って関数が実行されると、最初に作ったオブジェクトだったものが戻り値として帰ってきます。  
関数内の`return`じゃないよ!  
要するに変数`me`は`new person()`と指定するから、必ずオブジェクトが代入されるってわけ。  
なので、thisのプロパティに値を突っ込む事が目的の変な関数が出てきたら、
それは他の言語で言うクラスに相当する雛形的な関数と解釈してください。
ちょっとだけ変な書き方になりますが、クラスベースのオブジェクト指向言語と同じ事は可能です。
(ES2015ではClass構文がサポートされ、他の言語のようなクラス宣言が出来るようになりました)
```Bash
var person = function() {
 this.name = "hogehoge";
}
person.prototype.hello = function() {
 return "hello. my name is " + this.name;
}
var me = new person();
console.log(me);
// person {name: "hogehoge"}
console.log(me.hello());
// "hello. my name is hogehoge"
```
---
※因みにRubyは完全なオブジェクト指向言語なので数値や文字列も全てオブジェクトですが、
JavaScriptも不完全ながら似たようなアプローチで、`Number, String, Boolean`等のプリミティブなもの以外はオブジェクトから派生して作られたものです。
JavaScriptの関数はFunctionというオブジェクトを使って生成されたものです。
「変数personの型はオブジェクトですか?」という問いに関しては、
その通りと回答するのが正解なのですが、
今回の質問に限ってはそういう分類に対する質問とは異なると考え、否定しています。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る