あらためて復習。
CoffeeScriptのクラスではprivateな変数・関数はつくれないっぽい。
(継承のオーバーライドを想定しない場合は、できないことはないっぽい →参考欄の1つ目)
最初に比較用のASのコードを載せています。
– AS脳で理解するための比較用 ActionScript
→ private var, private function がcoffeeだと使えない
package{ class SampleClass{ public static var staticVar:String = "staticVar"; public static var staticVar2:String = "staticVar2"; private static var _staticVar3:String = "_staticVar3"; public var publicVar2:String= "publicVar2"; /* CONSTRUCTOR */ function SampleClass(){ // インスタンスのプロパティ this.publicVar = "publicVar"; } // PUBLIC STATIC FUNCTION public static staticPublicFunction(){ trace("\n**** from staticPublicFunction"); trace(this); trace(_staticVar3); trace(SampleClass.staticVar); trace(publicVar); trace(publicVar2); } /* PRIVATE FUNCTION */ private function _privateFunction(){ trace("\n**** from _privateFunction"); trace(this); trace(_staticVar3); trace(SampleClass.staticVar); trace(publicVar); trace(publicVar2); } // PUBLIC FUNCTION public function publicFunction(){ trace("\n**** from publicFunction"); trace(this); trace(_staticVar3); trace(SampleClass.staticVar); trace(publicVar); trace(publicVar2); } public function callPrivateFunction(){ _privateFunction(); } public function updateStaticVar3(){ _staticVar3 = "_staticVar3:changed"; } } }
– CoffeeScript
class SampleClass ### PUBLIC STATIC VAR ### @staticVar: '@staticVar' @staticVar2 = '@staticVar2' ### # PRIVATE STATIC VAR # クロージャー内の変数扱い? インスタンスの変数ではない ### _staticVar3 = '_staticVar3' ### PUBLIC INSTANCE VAR ### publicVar2: 'publicVar2' ### # ここまでのまとめ: # ・頭に@がつく場合 # 無条件で静的なプロパティになる # ・@がない場合 # =を使うと静的なプロパティに、 # :を使うとインスタンス(prototype)のプロパティになる ### ### CONSTRUCTOR ### constructor: -> # インスタンスのプロパティ @publicVar = '@publicVar' ### PUBLIC STATIC FUNCTION ### @staticPublicFunction = -> console.log('\n**** from staticPublicFunction') console.log(@) console.log _staticVar3 #OK console.log SampleClass.staticVar #OK console.log @publicVar #NG console.log @publicVar2 #NG @ ### # PRIVATE FUNCTION の出来損ない # インスタンスのメンバー変数にアクセスできない! # クロージャー内の関数扱い? ### _privateFunction = -> console.log('\n**** from _privateFunction') console.log(@) console.log _staticVar3 #OK console.log SampleClass.staticVar #OK console.log @publicVar #NG console.log @publicVar2 #NG @ ### PUBLIC FUNCTION ### publicFunction: -> console.log('\n**** from publicFunction') console.log(@) console.log _staticVar3 #OK console.log SampleClass.staticVar #OK console.log @publicVar #OK console.log @publicVar2 #OK @ callPrivateFunction: -> _privateFunction() @ updateStaticVar3: -> _staticVar3 = '_staticVar3:changed' @ ### 1つ目のインスタンス sample をつくって色々テスト ### sample = new SampleClass() console.log('\n**** from global') console.log SampleClass.staticVar #OK console.log sample.publicVar #OK console.log sample.publicVar2 #OK console.log sample._staticVar3 #NG sample.publicFunction() sample.callPrivateFunction() SampleClass.staticPublicFunction() ### _staticVar3を更新する ### sample.updateStaticVar3() ### 2つ目のインスタンス sample2 をつくって色々テスト ### console.log '\n#### sample2 ####' sample2 = new SampleClass() console.log('\n**** from global') console.log SampleClass.staticVar console.log sample2.publicVar console.log sample2.publicVar2 console.log sample2._staticVar3 sample2.publicFunction() sample2.callPrivateFunction() SampleClass.staticPublicFunction() ### # sample2をつくっての実験のまとめ: # _staticVar3 が変わってしまっていることからも、 # インスタンス変数ではなく、スタティックな変数であることがわかる。 ###
– コンパイル結果 JavaScript
// Generated by CoffeeScript 1.4.0 (function() { var SampleClass, sample, sample2; SampleClass = (function() { /* PUBLIC STATIC VAR */ var _privateFunction, _staticVar3; SampleClass.staticVar = '@staticVar'; SampleClass.staticVar2 = '@staticVar2'; /* # PRIVATE STATIC VAR # クロージャー内の変数扱い? インスタンスの変数ではない */ _staticVar3 = '_staticVar3'; /* PUBLIC INSTANCE VAR */ SampleClass.prototype.publicVar2 = 'publicVar2'; /* # ここまでのまとめ: # ・頭に@がつく場合 # 無条件で静的なプロパティになる # ・@がない場合 # =を使うと静的なプロパティに、 # :を使うとインスタンス(prototype)のプロパティになる */ /* CONSTRUCTOR */ function SampleClass() { this.publicVar = '@publicVar'; } /* PUBLIC STATIC FUNCTION */ SampleClass.staticPublicFunction = function() { console.log('\n**** from staticPublicFunction'); console.log(this); console.log(_staticVar3); console.log(SampleClass.staticVar); console.log(this.publicVar); console.log(this.publicVar2); return this; }; /* # PRIVATE FUNCTION の出来損ない # インスタンスのメンバー変数にアクセスできない! # クロージャー内の関数扱い? */ _privateFunction = function() { console.log('\n**** from _privateFunction'); console.log(this); console.log(_staticVar3); console.log(SampleClass.staticVar); console.log(this.publicVar); console.log(this.publicVar2); return this; }; /* PUBLIC FUNCTION */ SampleClass.prototype.publicFunction = function() { console.log('\n**** from publicFunction'); console.log(this); console.log(_staticVar3); console.log(SampleClass.staticVar); console.log(this.publicVar); console.log(this.publicVar2); return this; }; SampleClass.prototype.callPrivateFunction = function() { _privateFunction(); return this; }; SampleClass.prototype.updateStaticVar3 = function() { _staticVar3 = '_staticVar3:changed'; return this; }; return SampleClass; })(); /* 1つ目のインスタンス sample をつくって色々テスト */ sample = new SampleClass(); console.log('\n**** from global'); console.log(SampleClass.staticVar); console.log(sample.publicVar); console.log(sample.publicVar2); console.log(sample._staticVar3); sample.publicFunction(); sample.callPrivateFunction(); SampleClass.staticPublicFunction(); /* _staticVar3を更新する */ sample.updateStaticVar3(); /* 2つ目のインスタンス sample2 をつくって色々テスト */ console.log('\n#### sample2 ####'); sample2 = new SampleClass(); console.log('\n**** from global'); console.log(SampleClass.staticVar); console.log(sample2.publicVar); console.log(sample2.publicVar2); console.log(sample2._staticVar3); sample2.publicFunction(); sample2.callPrivateFunction(); SampleClass.staticPublicFunction(); /* # sample2をつくっての実験のまとめ: # _staticVar3 が変わってしまっていることからも、 # インスタンス変数ではなく、スタティックな変数であることがわかる。 */ }).call(this);
参考:
・CoffeeScriptでstatic/private/publicなメンバ/メソッドをもったクラスのつくりかた « DevJamMemo
・[改訂]CoffeeScriptでstatic/private/publicなメンバ/メソッドをもったクラスのつくりかた « DevJamMemo
・JavaScriptでstatic/private/publicなメンバ/メソッドをもったクラスのつくりかた | ALUMICAN.NET
・JavaScript のスコープチェーンとクロージャを理解する – tacamy memo
・AcrionScript3やってた自分からみたCoffeeScript | 宇都宮ウエブ制作所
アルミ缶先生さすがっす