ES6からはclass構文が実装されましたが、まだES5を使っている方もいますよね。
かくいう私もそうです。
例えばユーティリティ系クラスは静的クラスとして定義される事が多いかと思いますが、それをES5で実装する方法をメモします。
ES5で(通常の)クラスを実装する
「通常の」というのは静的ではない、という意味です。
つまりはインスタンス化して使用するクラス。
これに関しては、Qiitaでとてもわかりやすい記事が書かれていたので、
特に説明の必要は無いかもですが。
車クラスを想定すると以下のようになります(型式が意味を成していないので例としてはあまり良くない・・・)
const Car = (function() { const Car = function(model) { this.model = model; // 型式 }; const p = Car.prototype; p.move = function() { // 走る処理 console.log("走り始めました。"); }; p.stop = function() { // 止まる処理 console.log("止まりました。"); }; return Car; })(); const myCar = new Car("ABCDE-001"); myCar.move(); myCar.stop();
実行すると、以下が表示されます。
走り始めました。 止まりました。
という具合に、擬似的にES5でクラスが実装できる事がわかりました。
詳しくは先述のQiita様の記事から。
ES5で静的クラスを実装する
本題。
静的クラスはインスタンス化せずに使いたいクラス。
まずは先ほどの実装方法でインスタンス化しないとどうなるかを確認。
※new をせずにメソッドを呼び出してみる。
const myCar = Car("ABCDE-001"); myCar.move(); myCar.stop();
以下のように「ちゃんと」エラーになりました。
Uncaught TypeError: Cannot set property 'model' of undefined
コンストラクタのthis.modelで、「this」が拾えていないようです。
通常のクラスの実装方法では静的クラスは実装できない模様。
苦肉の策で以下の様な書き方。
const Utility = { variable1: 10, variable2: 20, func1: function() { console.log("call by func1"); console.log("variable1 is " + this.variable1); }, func2: function() { console.log("call by func2"); console.log("variable2 is " + this.variable2); }, func3: function() { console.log("call by func3"); this.func1(); this.func2(); }, } Utility.func1(); Utility.func2(); Utility.func3();
何だろう。普通にオブジェクトとして定義すればよいだけでした。
コンソール上も期待通りの動きを確認。
call by func1 variable1 is 10 call by func2 variable2 is 20 call by func3 call by func1 variable1 is 10 call by func2 variable2 is 20
気付きとしては、同オブジェクト内の変数や関数にthis.○○○でアクセス可能という事。
オブジェクトを定義している(=Utilityに代入している)段階なので、Undefinedになるかと思いましたが、普通にアクセスできました。