56453


いつもお世話になっています。  
下記の質問についてご存知の方がいらっしゃいましたら、ご教示を願います

* * *

## 【質問の主旨】

下記のコードにおいて、`var Person = function() {};`はどのような役割を指定のでしょうか？

[code]

    var Person = function() {};
    
    Person.prototype = {
        eat: function() {
            console.log('もぐもぐと食べる');
        }
    };
    
    var  BusinessPerson = function() {
        Person.call(this);
    };
    
    BusinessPerson.prototype = new Person();
    
    BusinessPerson.prototype.work = function() {
        console.log('せっせ、せっせと働く');
    };
    
    var bp = new BusinessPerson();
    bp.eat(); // もぐもぐと食べる
    bp.work(); // せっせ、せっせと働く
    
[/code]

## 【質問の補足】

### 1.

`var Person = function()
{};`はプロパティもメソッドも定義されていません。Personがクラスであることを示すためだけに、空の関数を定義しているだけであると解釈しても差し支えはないでしょうか？

### 2.

`var Person = function() {};`をコメントアウトすると、

[code]

    Uncaught ReferenceError: Person is not defined es5_proto_chain.js:3
    
[/code]

というエラーが表示されます。

* * *

以上、ご確認よろしくお願いします。


CC BY-SA 4.0
2019-07-06T08:17:59.190
56448
2019-07-07T06:17:31.040
32232
question
javascript
クラスを定義するために使用している空の関数の役割を教えてください。


> 下記のコードにおいて、`var Person = function() {};` はどのような役割をしているのでしょうか？

コンストラクタです。若干の差異はありますが、以下と同等のものと考えて良いと思います。

[code]

    function Person() {}
    
    Person.prototype = {
        eat: function() {
            console.log('もぐもぐと食べる');
        }
    };
    
    function BusinessPerson() {
        Person.call(this);
    }
    
    BusinessPerson.prototype = new Person();
    
    BusinessPerson.prototype.work = function() {
        console.log('せっせ、せっせと働く');
    };
    
    var bp = new BusinessPerson();
    bp.eat(); //=> もぐもぐと食べる
    bp.work(); //=> せっせ、せっせと働く
    
[/code]

* * *

> `var Person = function() {};`
> はプロパティもメソッドも定義されていません。Personがクラスであることを示すためだけに、空の関数を定義しているだけであると解釈しても差し支えはないでしょうか？

確かに、Person 関数は `new` 演算子を用いてコンストラクタとして呼び出すことが可能です[[1]](https://www.ecma-
international.org/ecma-262/8.0/index.html#sec-
functionallocate)。しかし、この関数は通常の関数呼び出しも可能であるため[[1]](https://www.ecma-
international.org/ecma-262/8.0/index.html#sec-functionallocate)、
**この関数が定義された時点では用途が明らかになりません** 。

そのため、当該関数定義のみを見た場合には「何の処理も行わない(normal な)関数 Person が定義された」と解釈するほうが適当ではないかと思います。


CC BY-SA 4.0
2019-07-06T09:47:25.447
56453
2019-07-06T09:59:18.563
2019-07-06T09:59:18.563
32986
32986
56448
answer


## prototype プロパティ

> var Person = function() {};はプロパティもメソッドも定義されていません。

ここに誤解があるように読めます。  
関数式や関数宣言は、 **`prototype` プロパティを既に持っています**。

[code]

    'use strict';
    function functionDeclaration () {}        // 関数宣言
    var functionExpression = function () {};  // 関数式
    
    console.log('prototype' in functionExpression);   // true
    console.log('prototype' in functionDeclaration);  // true
    
[/code]

アロー関数は `this` 値の性質上、コンストラクタになれないので、`prototype` を持っていません。  
`class` は勿論、持っています。

[code]

    var arrowFunction = () => {}; // アロー関数
    class Foo {}                  // class
    console.log('prototype' in arrowFunction);  // false
    console.log('prototype' in Foo);            // true
    
[/code]

## new 演算子

`prototype` プロパティを持っている関数は、`new` 演算子による呼び出しが可能です。

[code]

    function functionDeclaration () {}        // 関数宣言
    var functionExpression = function () {};  // 関数式
    var arrowFunction = () => {};             // アロー関数
    class Foo {constructor(){}}               // class
    
    new functionDeclaration;
    new functionExpression;
    new Foo;
    new arrowFunction;  // TypeError: arrowFunction is not a constructor
    
[/code]

## 関数呼び出し

`class` は関数ではない為、関数呼び出し出来ませんが、関数式や関数宣言は可能です。

[code]

    function functionDeclaration () {}
    var functionExpression = function () {};
    class Foo {constructor(){}}
    
    functionDeclaration(); // 呼び出せる(エラーなし)
    functionExpression(); // 呼び出せる(エラーなし)
    Foo();  // TypeError: Class constructor Foo cannot be invoked without 'new'
    
[/code]

この性質上の違いから、「関数式」を「class」の性質に近づけたコードが前回、echizenya_yota さんが質問されたコードです。

  * [javascript - "this instanceof Animal" と "this === instanceof Animal" の差を教えてください - スタック・オーバーフロー](https://ja.stackoverflow.com/questions/56247/this-instanceof-animal-%e3%81%a8-this-instanceof-animal-%e3%81%ae%e5%b7%ae%e3%82%92%e6%95%99%e3%81%88%e3%81%a6%e3%81%8f%e3%81%a0%e3%81%95%e3%81%84)

[code]

    var Animal = function(name) {
      if (!(this === instanceof Animal)) {
          return new Animal(name);
      }
    };
    
    Animal(); // new Animal と等価
    
[/code]

関数呼び出しされた際に、`new` 演算子呼び出しとして扱うのでアプローチは異なりますが、「コンストラクタとしてのみ扱う」という点においては同じです。

Re: echizenya_yota さん


CC BY-SA 4.0
2019-07-07T06:17:31.040
56470
2019-07-07T06:17:31.040
20262
56448
answer