深入浅出ES 6(13):クラスクラスクラス

8209 ワード

編集者によると、ECMAScript 6は正式に発表されました.最も重要な方言として、Javascriptももうすぐ文法上の大きな変革を迎えます.このコラムの記事はMozilla Web開発者のブログから来ました.
前に説明した内容は少し複雑だと思いますが、今日は比較的簡単な内容を説明します.ジェネレータ(Generator)のような前代未聞の新しいコード方式ではなく、プロキシ(Proxy)のようなJavaScript内部アルゴリズムの動作原理にフックの万能対象を提供します.簡単に言えば、言語習慣に従ってオブジェクト構造関数の作成を簡単にする方法について一緒に議論します.
当面の問題
もし私たちがクラシックなオブジェクト指向の設計例を作成したいなら、Circuleクラスです.私たちは簡単なCanvasライブラリのためにこのCircure類を作成しています.多くの考慮すべき要素の中で、以下の機能の実現方法をもっと知りたいかもしれません.
  • は与えられたCanvas上に与えられた円を描く.
  • は、生成円の総数を追跡する.
  • は、与えられた円の半径を追跡し、その値を円にするための不変条件を追跡する.
  • は、与えられた円の面積を計算する.
  • 現在の一般的なJSコードスタイルによれば、まず関数としてコンストラクタを作成し、関数に任意の私たちが望む属性を追加し、次にオブジェクトを用いてコンストラクタのprototype属性を置換します.このprototypeオブジェクトは、コンストラクタによって作成されたインスタンスのすべての初期化属性を含むであろう.以下は簡単な例です.直接にサンプルファイルとして繰り返し使用できます.
    
        function Circle(radius) {
            this.radius = radius;
            Circle.circlesMade++;
        }
        Circle.draw = function draw(circle, canvas) { /* Canvas     */ }
        Object.defineProperty(Circle, "circlesMade", {
            get: function() {
                return !this._count ? 0 : this._count;
            },
            set: function(val) {
                this._count = val;
            }
        });
        Circle.prototype = {
            area: function area() {
                return Math.pow(this.radius, 2) * Math.PI;
            }
        };
        Object.defineProperty(Circle.prototype, "radius", {
            get: function() {
                return this._radius;
            },
            set: function(radius) {
                if (!Number.isInteger(radius))
                    throw new Error("         。");
                this._radius = radius;
            }
        });

    , , 。 , , 。

    ES6 , 。 Circle.prototypeareaを するのは ですが、radiusにgetter/setter を するのは しいです.JSがより くのオブジェクト を するにつれて、オブジェクトへのアクセスを にする に を ち めた.obj.prop = methodと の を する しい が、Object.definePropertyの を りずにオブジェクトに「 」を する がある. は の を に したいです.

  • は、オブジェクトに な を する.
  • は、オブジェクトにジェネレータ を する.
  • は、オブジェクトに なアクセス を する.
  • は、オブジェクトに の[] を して された を し、これを (computed) と びます.
  • いくつかの は は できませんでした. えば、obj.propに を り てることによって、getterまたはsetterを することはできません.したがって、 たちは しい を として、 のコードを します.
    
        var obj = {
            //       function          
            //                。
            method(args) { ... },
            //                “*”,            。
            *genMethod(args) { ... },
            //   |get| |set|          。
            //         ,       。
            //            getter      
            get propName() { ... },
            //            setter        
            set propName(arg) { ... },
            // []                   ,       4   。
            //          symbol,    ,     
            //       property.id      。
            //                 ,          。
            [functionThatReturnsPropertyName()] (args) { ... }
        };

    , :

    
        function Circle(radius) {
            this.radius = radius;
            Circle.circlesMade++;
        }
        Circle.draw = function draw(circle, canvas) { /* Canvas     */ }
        Object.defineProperty(Circle, "circlesMade", {
            get: function() {
                return !this._count ? 0 : this._count;
            },
            set: function(val) {
                this._count = val;
            }
        });
        Circle.prototype = {
            area() {
                return Math.pow(this.radius, 2) * Math.PI;
            },
            get radius() {
                return this._radius;
            },
            set radius(radius) {
                if (!Number.isInteger(radius))
                    throw new Error("         。");
                this._radius = radius;
            }
        };

    , , (configurable) (enumerable) , 。 , , 。

    , , ? , , , Circleクラスです. を するときに を する はありません.
    クラス
    これは よりも いですが、 なJavaScript に する の を たすことができません. の では、 が に けて された を するために され、 された にクラスと されます.
    じゃ、 もいくつかの を します.
    このクラスで された は、 の.prototype にも する を するシステムが である. たちは しい で を することをマスターした 、 たちは ずものを い たします.クラスのすべての では、 と を する だけが です.C++またはJavaでは、この に するキーワードはstaticです.この はよさそうです. いましょう.
    また つの が です. の で の を できます.C++またはJavaでは、クラスと じ のコンストラクタが されませんでした.JSがタイプに っていない 、いずれにしても.constructor が をサポートするために です. と ぶことができます.
    すべての を み わせると、Curceクラスを き えて、すべての を できます.

    
        class Circle {
            constructor(radius) {
                this.radius = radius;
                Circle.circlesMade++;
            };
            static draw(circle, canvas) {
                // Canvas    
            };
            static get circlesMade() {
                return !this._count ? 0 : this._count;
            };
            static set circlesMade(val) {
                this._count = val;
            };
            area() {
                return Math.pow(this.radius, 2) * Math.PI;
            };
            get radius() {
                return this._radius;
            };
            set radius(radius) {
                if (!Number.isInteger(radius))
                    throw new Error("         。");
                this._radius = radius;
            };
        }

    Circleに な は、コードをこのように にすることができます.これは よりずっといいです.
    このように、ある は に うかもしれません.あるいは に れる もあります.あなたたちが う を して えてみます.

  • セミコロンはどういうことですか?「 なクラスをつくる」という みの で、より なセパレータを することにしました. に らないなら かなくてもいいです.セパレータはオプションです.
  • が しくないなら、 されたオブジェクトに を いてもいいですか?はい、constructor もオプションです.オブジェクトの では の constructor() {}をデフォルトで します.
  • は、 として を ってもいいですか? じていけませんコンストラクタは、 な ではなく、 に すると、 (TypeError)をトリガし、この は、 とアクセス にも に される.
  • は で ができますか? なことに、いけません.それは が しくなりますので、 は しません. される で と する を すると、 という が られます.
  • もし がconstructorの を したら、Circleの に が じますか?できませんクラスは と ていて、 の の が られます.このバインディングは によって されません.だから、 でnew Circle にどんな を しても、コンストラクタのCircleは りに されます.
  • はいいですが、 に に の をパラメータとして えることができます. は されませんか?ラッキーなことに、ES 6でもクラス がサポートされています. や の であってもよく、 は と しています. の いは、それらがあなたがそれらの に を しないことです.
  • に げたエニュメレート・コンフィギュレーションはどう されますか?クラスに する は で、 できないものと されています. つは に を することができます. つは の を する 、 した を しないで、 たのは なデータ だけです.
  • ハイ、ちょっと ってください. ですか? のインスタンス はどこですか?Circle.circlesMade++と は?はい、お きしました.ES 6の の には がありません.しかし、 くの プロセスにおいて、 はクラス にオプションの staticのキーワードを することを く しています.この は に に され、 に っています.これからもっと くの ができると しています.
  • はい、それでも、これらの は らしいです.これらの は えますか? です. 、あなた はpolyfill( にBabel)を して の を することができて、すべての のブラウザーの が するまでまだしばらくの が です.FirefoxのNightlyバージョンにおいて、 たちが した ての を しました. に、これらの はEdgeとChromeでも されていますが、デフォルトでは になりません.Safariはまだ する を していません.
  • ここではJavaとC++のサブクラス(subclassing)とconstキーワードについて していませんが、JSもありますか?–はい、あります は に の の で しく することができて、 で と にサブクラスを することを して、 に くのJavaScript の の さを り こします.
  • Jason OrendorffとJeff Waldenがこの を するように いてくれたことに します.そして、 のすべての のためにコード をします.
    はJason Orendorffが たちのために しく します.letとconstを き き してください.super