~Linux、MySQLからAJAXまでTypeScriptプログラミング、メモTypeScriptのプログラミングについて備忘としてメモ書きしています。※目次をクリックすると目次の下部にコンテンツが表示されます。typing21.型定義ファイルとDefinitelyTyped22.カプセル化23.コールバックの使用方法24.observerパターン25.イベントを使ったサンプル作成NPMでTypeScriptインストール、コンパイル、動作確認NPMを使ってTypeScriptのツールをインストール、TypeScriptのスクリプト作成、コンパイル、動作確認を行います。型注釈(型アノテーション)TypeScriptで型注釈を行う場合、変数宣言の後にコロンで区切りその変数の型を指定します。8.5}●undefined、null、void・undefined未割当ての変数の値。・nullオブジェクトに意図せずに値が割当てられていない事を表す。オブジェクトの配列検索するメソッドでマッチしなかった場合にnullを返す場合など。・void値をリターンしない関数などに使用。・ある一定数の数の定数を表すのに使用。・デフォルトでは0からインクリメントされる。下記のように同じ名前で再定義し、追加する事ができる。最初の要素に識別数値を指定する必要がある。・括弧内で各パラメータの型を指定。・括弧の後でリターン値の型を指定。リターン値がない場合はvoidを指定。・下記のようにオプションのパラメータにはクエスチョンマークを付与。・オプションのパラメータは必須パラメータの後に指定する。{//}●RestパラメータRestパラメータを使うと任意の数の引数を指定する事ができる。下記仕様に従って指定する必要がある。・パラメータの識別子に”...”のプレフィックスを付与。・Restパラメータは一つだけ指定できる。・Restパラメータはパラメータリストの最後に指定する。10);オーバーロードオーバーロードを使って一つの関数で異なる型、個数の引数、異なる型のリターンを指定して使用する事ができます。TypeScriptのオンラインマニュアルのサンプルコードを使って確認します。TypeScript●サンプルコードの仕様pickCard関数は、引数の指定の仕方によって以下の二つの処理を切り替えています。配列の中からランダムに選択して、選択したペアのインデックス番号をリターン。2トランプの0~51の間の数値を引数に指定した場合マークと数値(1~13)のペアのオブジェクトをリターン。下記のようにオブジェクトをリターンする場合は、括弧で囲みます。l});3)thisキーワードを使用する場合TypeScriptのオンラインマニュアルのサンプルコードを使って確認します。・アラートボックスが実行されずエラーとなる。createCardPicker()によって生成された関数内で使用される"this"は、"deck"オブジェクトではなく、windowオブジェクトを参照してしまう。関数が呼び出されるときには"deck"オブジェクトのスコープが失われてしまっているため。・lamda形式を使用すると関数生成時に自動で"this"キーワードが使用できるようになる。class)によって実装できる抽象型(abstracttype)として使用できる。・TypeScriptで記述されていないフレームワークやサードパーティライブラリ内で利用できる操作を定義するコードを記述できる。・interfaceキーワードを使用し、属性や関数などのアノテーションを含む。アノテーションは、属性や関数だけでなく、コンストラクタやインデクサ(indexer)も宣言できる。・クラスのインタフェースを記述する場合は、コンストラクタやインデクサを定義する必要はない。・TypeScriptのすべてのクラスは、明示的に記述するしないに関わらず、コンストラクタを持つ。明示的に記述していない場合は、コンパイラが自動で追加する。・他のクラスを継承していないクラスでは、自動で追加されるコンストラクタはパラメータがなく、任意のクラス属性を初期化する。・他のクラスを継承するクラスでは、自動コンストラクタは、そのクラス自身の属性を初期化する前に、スーパークラスのシグネチャとマッチングし、引数をスーパークラスに渡す。}}・コンストラクタのパラメータは、メンバー変数にマップしていない。コンストラクタのパラメータにprivateなどのアクセス修飾子を指定すると自動でマップされる。・このコンストラクタのパラメータは、そのクラス上の属性として宣言されたかのように参照する事ができ、this.nameのようにAnimalクラスのインスタンスで使用することができる。・アクセス修飾子を使ってクラス内の属性とメソッドのアクセス権(visibility)を制御する事ができる。・属性とメソッドのデフォルトのアクセス権はpublicなので、明示的にpublicを指定する必要はない。・コンストラクタのパラメーターを自動でpublic属性でマップさせたい場合は、コンストラクタのパラメータにpublicを指定する必要がある。・アクセス権をクラス内のみに制限したい場合は、privateを指定する。この場合、サブクラスからもそのメンバにアクセスできない。クラスのプロパティとメソッド(1)プロパティとメソッド1)インスタンスプロパティ・コンストラクタの前で宣言。・宣言と同時に初期化する事もできる。[];・インスタンスプロパティはthisキーワードを使ってクラス内でアクセスする事ができる。2)staticプロパティ・staticプロパティは、クラス名を使ってアクセスする。Memberslist.maxCount3)メソッド・メソッド名にアクセス修飾子を指定する事もできる。デフォルトはpublic。・メソッドのパラメータとリターン値にも型アノテーションを指定できる。・インスタンスプロパティと同様にインスタンスメソッドもクラス内でthisを使ってアクセスでき、publicの場合は、クラスの外からインスタンス名を使ってアクセスできる。4)staticメソッド・staticメンバは、クラスのインスタンスを生成していなく、各staicメンバの一つのインスタンスがプログラム内に存在するだけで呼び出す事ができる。・すべてのstaticメンバはインスタンス名ではなく、クラス名を介してアクセスされ、staticメンバは、staticではないプロパティやメソッドにはアクセスしない。Memberslist.maxMemberCount;(2)getterとsetter・TypeScriptは、setterとgetterのプロパティをサポートする。・getまたはsetキーワードをプレフィックスとして指定する以外は、メソッドと同じ書式。・implementsキーワードを使用。・一つのクラスは複数のインタフェースを実装できる。・インタフェースを実装する際、implementsの宣言はオプション。・クラスで実装するメソッドは、インタフェースで指定したパラメータの数より少なくてもよい。メソッドを実行するのに必要がない引数は無視してもよい。明示的に指定したパラメータはインタフェースのパラメータとマッチしなければならない。・extendsキーワードを使って他のクラスを継承。・継承したベースクラスのすべての属性とメソッドを受け継ぐ。・同じ名前のメンバーを追加する事によってベースクラスのpublicメンバをオーバーライドする事ができる。・クラスは一つのスーパークラスしか継承できない。・ベースクラスに対する"super"のコールは、サブクラスのコンストラクタの最初に記述しなければならない。}}スコープ、thisキーワードの注意点イベントやコールバックとしてインスタンスメソッドを使用するなどの場合、thisキーワードの指定が失われてしまうので注意。例)問題のあるコードbtnClick()メソッドは、インスタンスで直接コールされる場合は期待通りに動作するが、イベントとして実行するとthisキーワードの指定が失われてしまってthis.countが未定義になってしまう。count.btnClick;●回避方法1・メソッドを属性に変更し、属性をlamda形式の関数で初期化。count.btnClick;●回避方法2・クラスを変更せず、closureを作成。関数内にインスタンスメソッドへのコールをラップする。count.btnClick();};●回避方法3・JavaScriptのbind関数を使用。※クラスを継承している場合もチェックできる。※クラス継承している場合もチェックできる。※属性を定義していても値を割り当て初期化していなければfalseとなる。・ネームスペースを簡易にする仕組みを提供。Definition)などがある。・内部モジュールは、そのスコープを制限する関数内にメンバーをエンクローズする。内部モジュール名はグローバルスコープに追加され、エクスポートされたメンバーはグローバルにスコープされたモジュール識別子を介してアクセスできる。・外部モジュールはグローバルスコープに追加されない。外部モジュールのメンバーは、CommonJSを使用している場合はエイリアスを介して利用され、AMDを使用している場合はコールバック関数のスコープに制限される。・内部モジュールは、関連する機能をグループするのに使用できる。・内部モジュールは、モジュールのスコープ内にエンクローズされたモジュールコンテンツを含むシングルトンのインスタンス。・変数、関数、オブジェクト、クラス、インタフェースをモジュール内にグループ化する事によってグローバルスコープから隔離し、名前の重複を避ける事が出来る。・一つのモジュールを複数のファイルに分割する事が出来、一つのファイルのサイズを小さくする事が出来る。・クラスメンバはデフォルトでpublicだが、モジュール内のコンテンツはデフォルトでは隠蔽される。・モジュール外からモジュール内のメンバを利用できるようにするには、exportキーワードを付与する。ModA.ClsA();・内部モジュール内でimportキーワードを指定すると他のモジュールやそのメンバのエイリアスとして使用できる。モジュールをネストして定義し、モジュールの指定が長くなる場合に便利。・・}●内部モジュールのインクルード・内部モジュールは、外部モジュールのように自動モジュールロードによるメリットはないが、ロードするスクリプトのメソッドを好きなように実装できる。下記方法を使用できる。1それぞれのファイルをWebページ内のscriptタグでインクルードする。2プログラムを一つのファイルにコンパイルし、そのファイルをscriptタグでインクルードする。3プログラムを一つのファイルにコンパイルし、縮小化し、scriptタグでインクルードする。4外部モジュールに切り替え、モジュールローダーを使用する。・ある種の統合開発環境では、モジュールは自動で認識されるが、依存するファイルを自動で探索して認識できない場合は、リファレンスコメントを使ってヒントを記述できる。・・}※上記リファレンスコメントは、TypeScriptコンパイラで複数のファイルを一つのファイルにコンパイルする場合にも利用される。・大規模なアプリケーションを作成する際には外部モジュールとモジュールロードの仕組みは必須のツール。・外部モジュールの名前は、拡張子を除くソースファイル名と同じ。内部モジュールでは、下記のようにmoduleブロックを記述していたが、外部モジュールでは、ファイル名がモジュール名となるので記述する必要がない。{"・外部モジュールを実行時にロードして使用するには、下記例のようにrequire文とimport文でモジュールのパス(拡張子は除く)を指定する。importで指定した名前をエイリアスとして外部モジュールを参照できる。・AMDとCommonJDの二つのモジュールロードの方法がある。・TypeScriptのコンパイラにどちらのロード方法を使用するか指定する必要がある。1)CommonJSを使ってロード・NodeJS用。・require関数がコールされるたびにモジュールをロード。モジュールがロードされるとプログラムの実行が再開する。1;生成されたJavaScriptのコードでは、モジュールロードの後にコードが置かれる。2)AMDを使ってロード・モジュールロード中にプログラムの実行を停止せず、コードをコールバック関数に渡す。モジュールがロードされるとコールバック関数が実行される。これによってその間に他のコードを実行する事が出来る。1;});生成されたJavaScriptのコードでは、コールバック関数内に置かれている事が分かる。typing・同じ外部構造(インタフェース、特に暗黙的なもの)を持つ値を同じ型であるとするもの。・明示的に名前を指定する必要がなく、構造がマッチする型であれば利用可能。・同じ属性を有する同等の型を作成することが可能。・既存のコードを変更せずに、同等の型を導入できる。・外部クラスから継承せずに外部コードに渡す事が出来る。・既存のコードを変更せずに新しいスーパータイプを作成できる。・TypeScriptなど。typing・型宣言の構文からのみ型の同一性を判定する。型が同じ"名前"を持たなければならない。・インタフェースを実装する場合、明示的にインタフェース名を指定して宣言しなければならない。・偶然同じ属性を有する同等の型を作成することを防ぐ事が出来る。・C#やJavaなど。Person();型定義ファイルとDefinitelyTyped(1)型定義ファイル・ファイルの拡張子を".d.ts"とする。・ファイル内のモジュール、変数、関数、クラス、enumをdeclareキーワードでプレフィックスして宣言する。/>かimport文で指定する。import文を使用する場合は、同じフォルダー内でJavaScriptファイルと同じファイル名にする。(2)DefinitelyTypedとは?・TypeScriptの型定義のリポジトリ。Underscoreなどの定義ファイルが含まれている。qUnitなどのテストフレームワークの定義ファイルも含まれている。・TypeScriptではカプセル化をフルにサポート。・クラスインスタンスは、データとそのデータを操作するメソッドの両方を含む事ができ、そのデータをprivateのアクセス制限を指定してクラスインスタンス外部から隠蔽することが出来る。strict';でstrictモードにする。name_let);}//letで定義しているのでブロック外ではアクセスできない。name_let);●コンパイルletはECMAScript5ではサポートされていない。コンパイル時にes6を指定する。let.tsSystemJSでモジュールをエクスポート、インポート●SystemJSを使ってインポート・importの引数内でエクスポートしたクラス、関数、変数の名前などを指定。・別名を使用したい場合は、"as"を使って指定。world!');greeter.greet();変数の巻上げ(hoisting)とlet●変数の巻上げ(hoisting)・varキーワードで宣言した変数は、関数内のいかなる場所で宣言されたとしても、その関数の先頭で宣言されたのと同じように動作する。例1)関数の下の方で変数を宣言し値を割り当てたとしても、実際には(例1の実際の動作)にあるように関数の先頭で宣言が行われてしまい、値が割り当てられていない状態になってしまう。・letキーワードを使用する場合にも変数の巻上げが適用され、この場合は関数の先頭ではなく、ブロックスコープの先頭に巻き上げられる。・コールバック関数を引数として渡し、操作が完了したときにコールバック関数を実行する。これによってメインスレッドがブロッキングされるのを防ぐ事ができる。●コールバック関数の実行方法1callメソッドを使用コールバック関数内で使用する"this"キーワードのコンテキストをセットするのに使う値を指定する。alert(arg);}run1(callbackFunction);2applyメソッドを使用コールバック関数内で使用する"this"キーワードのコンテキストをセットするのに使う値を配列で指定する。alert(arg);}run3(callbackFunction);observerパターン●サンプルコード1subscriberをコレクションに追加。2メッセージをpublish3publisherがメッセージを受け取るとすべてのsubscriberに配布。●イベントフェーズ1キャプチャフェーズDOMツリーをたどってルート要素から発生要素を探しに行く。useCapture]);"useCapture"はデフォルトはfalseでバブリングフェーズ、trueを指定するとキャプチャフェーズで実行する。コメントをキャンセルメールアドレスが公開されることはありません。コメントデータの処理方法の詳細はこちらをご覧ください。