

JSのクラスについての質問の続きとなります。

＞＞＞

[code]

    class Cat {
    constructor(name) {this.name = name}
    meow() {alert( this.name + 'はミャオと鳴きました' )}
    }
    
    //インスタンス作成
    var clsObj = new Cat("my cat");
    //インスタンス(オブジェクト)の中身を出力
    console.log(clsObj);
    
[/code]

初心者なのでこの中のどの記述が必須で、  
またnameはどれと対になっているかがわかりません。

インスタンスはnew クラス名 となっている所で作成されて変数に作られたインスタンスが代入されるというのは何となく分かったのですが、

[code]

    console.log(clsObj);
    VM793:9
    Cat {name: "my cat"}
    
[/code]

となるのがいまいちわかりません。

`new Cat("my cat");`は

[code]

    class Cat {
      constructor(name) {this.name = name}
      meow() {alert( this.name + 'はミャオと鳴きました' )}
    }
    
[/code]

を実行するという事で、  
引数は

[code]

    constructor(name)
    new Cat("my cat");
    
[/code]

が対になっているのでnameがmycatに代わるという事でしょうか？

`new Cat("my cat");`が実行された結果がインスタンスという事ですが、  
mycatがインスタンスなのですか？

大変恐縮ですが、簡単に一連の流れを教えていただければ幸いです。

[code]

    class Cat {
      constructor(name) {this.name = name}
      meow() {alert( this.name + 'はミャオと鳴きました' )}
    }
    
[/code]

にどう渡されてどのように処理され何がインスタンスとして吐き出されるのでしょうか？

[ES6でclassとは？](https://ja.stackoverflow.com/questions/33972/es6%e3%81%a7class%e3%81%a8%e3%81%af/33973?noredirect=1#comment33579_33973)  
の続き

＿＿＿＿＿＿＿＿＿＿＿＿＿  
何度もご対応大変ありがとうございます。

＞＞＞  
ClassがInstanceを作るための設計図だということは理解していただいているかと思います。

クッキーの抜き型には、丸や四角、星型などいろいろな形があります。一度クッキーの抜け型を作っておけば、同じ形のクッキーを幾つでも作ることが出来ます。クッキーは実際に食べることが出来ますが、クッキーの型は食べることが出来ません。  
という例えを見たのですが、  
どうも型とは関数のように何度も再利用するための式などのまとまりの事で、関数とそっくりなもののようですね。  
つまり関数の定義とほぼ同じだが、すべてがグローバルになるので、外からでも利用ができる関数の定義がクラスの作成という事になるのですかね？

そしてインスタンス化とはクラスは作成定義しただけでは使えないので、関数の呼び出しのようにクラスのインスタンス化をnewで行い実際にクラスを使えるようにする、呼び出しできるようにする  
という事ですかね？

[code]

    class Cat {
    constructor(name) {this.name = name}
    meow() {alert( this.name + 'はミャオと鳴きました' )}
    }
    
[/code]

から

[code]

    clsObj = {
        constructor:function(name) {this.name = name},
        meow:function() {alert( this.name + 'はミャオと鳴きました' )}
    };
    
[/code]

が作成されるという事ですか？

＞＞＞  
上記のような感じですと実行されるときのthisがInstance(Object)を指すイメージが付きますでしょうか？

thisはクラス名ではなくコンストラクタを実行した結果具現化されるインスタンスを示すようですが、  
具体的にソースのどれでしょうか？

＞＞＞  
そして、このInstanceを作成した際にはコンストラクタが実行されるので下記のように変化します。

constructor:function(name) {this.name = name},  
を実行した結果

[code]

    clsObj = {
        name:"my cat",
        constructor:function(name) {this.name = name},
        meow:function() {alert( this.name + 'はミャオと鳴きました' )}
    };
    
[/code]

となるという事なのは分かったのですが、  
変更されたのは、name:"my cat",だけのようですね。

constructor:function(name) {this.name = name}は結局  
nameが引数の無名関数を定義して、内容はインスタンスの中のnameプロパティにnameを代入しているのでしょうか？

また、name引数はvar name = というローカル変数に何を代入した状態になるのでしょうか？  
実引数があればそれが入るとわかるのですが、これは見当たりません

またなせ代入作業がされただけで  
name:"my cat",  
というプロパティが生成されるのでしょうか？


CC BY-SA 3.0
2017-04-16T08:11:22.810
34047
2017-04-17T12:27:19.530
2017-04-17T06:16:24.087
20834
20834
question
javascript
JSのクラスについて


まず基本的なことですが、[クラス - JavaScript |
MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Classes)より引用します。

> ECMAScript 6 で導入された JavaScript クラスは、JavaScript にすでにあるプロトタイプベース継承の **糖衣構文**
> です。クラス構文は、新しいオブジェクト指向継承モデルをJavaScript に導入しているわけ **ではありません** 。JavaScript
> クラスは、オブジェクトを作成して継承を扱うためのシンプルで明確な構文を用意します。

初心者さんということでprototypeがどうだとか言われてももしかしたらご存じないかもしれませんが、元来jsはprototypeベースの継承をコアにした言語で、クラスのようなものを作る際にはprototypeとよばれる特別なプロパティ/オブジェクトを拡張していました。

最も一般的な方法は、[Function](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Global_Objects/Function)オブジェクトを生成し、そのprototypeを拡張します。このFunctionオブジェクトそれ自身はコンストラクタと呼ばれる特別な関数としても使用でき、これがご質問のコードでいうところの`constructor`に当たります。[
_new_ キーワード](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Operators/new)を伴う呼び出しの場合、関数はコンストラクタ呼び出しとなり、
**自身のprototypeを継承したあらたなオブジェクトを生成し** 、関数内の処理を適用してからこのオブジェクトを返す、という動作になります。

[code]

    // class Cat {
    //   constructor(name) {this.name = name}
    const Cat = function (name) {
        // var this = Object.create(Cat.prototype); // new をつけての呼び出しの場合、内部的に実行される
        this.name = name;
        // return this; // new をつけての呼び出しの場合、内部的に実行される
    };
    
    // メンバ変数/メソッドはFunctionオブジェクトのprototypeを拡張します
    //  meow() {alert( this.name + 'はミャオと鳴きました' )}
    Cat.prototype.meow = function () {
        alert(this.name + 'はミャオと鳴きました');
    };
    // }
    
    // Functionオブジェクトはそれ自身はふつうの関数です。
    const dummy = {};
    console.assert(Cat.call(dummy, 'my cat') === undefined);
    console.assert(!(dummy instanceof Cat));
    console.assert(Object.getPrototypeOf(dummy) !== Cat.prototype);
    console.assert(dummy.name === 'my cat');
    
    // newキーワードを伴う呼び出しはコンストラクタとして働きます
    // コンストラクタ呼び出しは新たなインスタンスを生成しそれを返します。
    const clsObj = new Cat('your cat');
    console.assert(clsObj instanceof Cat);
    console.assert(Object.getPrototypeOf(clsObj) === Cat.prototype);
    console.assert(clsObj.name === 'your cat');
    
    // clsObjはCatクラスのインスタンス、すなわちCat.prototypeを継承したオブジェクトです
    clsObj.meow();// your catはミャオと鳴きました
    // この呼び出しは次の処理に等価です
    Cat.prototype.meow.call(clsObj);
    
[/code]

この内容を簡単に書けるようにしたのがES6のClassということになります。どれが必須、といわれれば必須なものは特にありません。次のコードも完全なクラス定義です。

[code]

    // as Function object
    const myClass = function () {};
    
    // using ES6 class syntax
    class myClass {
    }
    
[/code]

ユーザー定義クラスmyClassはなにもしないコンストラクタを持ち、メンバ変数やメソッドはありません。

少々難しいかもしれませんので、不明な点があればコメントからご指摘ください。


CC BY-SA 3.0
2017-04-16T09:08:03.700
34049
2017-04-16T09:40:31.073
2017-04-16T09:40:31.073
34047
answer


> `Cat {name: "my cat"}`となるのがいまいちわかりません。

ClassがInstanceを作るための設計図だということは理解していただいているかと思います。  
あくまでイメージなので実際の型とは異なりますが`new`を行った場合、  
設計図を元に下記のようなObjectが作られることを想像してみてください。  
下記は`var clsObj = new Cat("my cat");`を行ったときの流れのイメージになります。

[code]

    clsObj = {
        constructor:function(name) {this.name = name},
        meow:function() {alert( this.name + 'はミャオと鳴きました' )}
    };
    
[/code]

上記のような感じですと実行されるときの`this`がInstance(Object)を指すイメージが付きますでしょうか？  
そして、このInstanceを作成した際にはコンストラクタが実行されるので下記のように変化します。

[code]

    clsObj = {
        name:"my cat",
        constructor:function(name) {this.name = name},
        meow:function() {alert( this.name + 'はミャオと鳴きました' )}
    };
    
[/code]

上記のコンストラクタや関数は実際にはprototype宣言なので  
ObjectをChromeなどでみても出力はされません。  
ですので、Consoleに出力した際の表示がこうなります。

[code]

    Cat {name: "my cat"}
    
[/code]

上記の応用として、例えばconstructorで引数を2つにして、  
下記のように実行すると別のネームスペースが作られます。

[code]

    //clsObj = new Cat("my cat", "owner");
    clsObj = {
        name:"my cat",
        parent:"owner",
        constructor:function(name,par) {
            this.name = name;
            this.parent = par;
        },
        meow:function() {alert( this.parent + 'の' + this.name + 'はミャオと鳴きました' )}
    };
    
[/code]

rio.irikamiさんが回答いただいている内容は、  
この`new`されてInstanceが作成されるまでの流れ(内部的な処理の内容)を  
もっと厳密に説明されている内容になります。


CC BY-SA 3.0
2017-04-16T13:33:11.953
34053
2017-04-17T12:27:19.530
2017-04-17T12:27:19.530
34047
answer