Upgrade to Pro — share decks privately, control downloads, hide ads and more …

javascriptにおけるpublicとprivateについて

soplana
August 18, 2012

 javascriptにおけるpublicとprivateについて

調べていたら纏めておきたくなったので。
基本的な事がおおいですが。

soplana

August 18, 2012
Tweet

Other Decks in Technology

Transcript

  1. Javascriptにおける
    publicとprivate
    Twitter : @soplana

    View full-size slide

  2. 1. Javascriptのスコープ
    2. thisとは
    3. functionの実行
    4. functionの引数について
    5. クラス宣言とインスタンス
    6. publicとprivateを実装する
    7. pia.jsを使う【ステマ】

    View full-size slide

  3. まずは軽くJavascriptのおさらいから。
    おさらいする点は以下の5点。
    ・スコープ
    ・this
    ・メソッド呼び出し
    ・arguments
    ・クラス宣言とインスタンス

    View full-size slide

  4. 1. Javascriptのスコープ
    ・ブロックレベルのスコープは存在しない

    View full-size slide

  5. 1. Javascriptのスコープ
    ・あるのはfunction毎のスコープのみ

    View full-size slide

  6. 2. thisとは
    ・基本的には常にグローバルオブジェクトを指す

    View full-size slide

  7. 2. thisとは
    ・レシーバがあるfunction呼び出しの場合は、レシーバを指す

    View full-size slide

  8. 3. functionの実行
    ・極普通に実行
    user.getName();
    ・function名を文字列で指定して実行
    user["getName"]();
    ・call or applyで実行
    user.getName.call();
    user.getName.apply();
    ・()を使い実行(即時関数パターン)
    ( user.getName )();
    ( function(){return "name"} )(); //即時関数

    View full-size slide

  9. 3. functionの実行
    callとapplyについて
    ・functionを実行させるメソッド
    ・第一引数にfunction内でのthisが指すオブジェクトを指定することが可能

    View full-size slide

  10. 3. functionの実行
    callとapplyについて
    ・callは、第二引数以降にfunctionに渡すべき引数をカンマ区切りで渡す
    ・applyは、第二引数にfunctionに渡すべき引数を配列で渡す

    View full-size slide

  11. ・functionの引数チェックはしない
    4. functionの引数について

    View full-size slide

  12. 4. functionの引数について
    argumentsについて
    ・functionに渡された引数は全てargumentsオブジェクトに格納されている
    ・Arrayの様に振舞うが、Arrayではない

    View full-size slide

  13. 5. クラス宣言とインスタンス
    ・他のオブジェクト指向言語のようなクラス宣言のシンタックスは無い
    ・でも立派なクラスは作れるよ
    基本的なクラス宣言の構文
    ・User変数に渡しているfunctionがコンストラクタになる
    ・コンストラクタが与えられたUser変数はnewによりインスタンスを生成出来る

    View full-size slide

  14. 5. クラス宣言とインスタンス
    その① - インスタンスメソッドの追加
    ・インスタンスに追加
    問題点
    ・インスタンス毎にfunctionを持つので大量にインスタンスを生成するような
     処理だとメモリを余計に使ってしまう

    View full-size slide

  15. 5. クラス宣言とインスタンス
    その② - インスタンスメソッドの追加
    ・User.prototypeに追加
    ・インスタンス毎にfunctionを持つ問題はprototypeベースでクラスを作成する事
     で避ける
    ・基本的にはprototypeベースで作成していきましょう!

    View full-size slide

  16. prototypeの特徴についてもう少し
    ・prototypeが参照されるのは読み取り時のみ
    ・書き込みはインスタンス毎に新しいpropertyが追加される
    ・インスタンスからは__proto__でprototypeへの参照が取れる

    View full-size slide

  17. いよいよ本題のpublic / privateについて話そうか…。

    View full-size slide

  18. 6. publicとprivateを実装する
    その① - 全部コンストラクタのスコープに実装
    ・コンストラクタ内のthisがインスタンスを指すので、全てのメソッドを
     コンストラクタ内に記述する

    View full-size slide

  19. 解説
    ・コンストラクタfunctionのローカルスコープにprivatreメソッドを定義。
    ・コンストラクタ内でのthisはインスタンスを指すので、そのthisにメソッドと
     propertyを宣言する事でpublicメソッドを定義。
    ・privateであるupperCaseを呼び出す時はレシーバが存在しない為、
     upperCase内でのthisがグローバルオブジェクトを指してしまう。
    ・その為、upperCaseを呼び出す際は、callを使い第一引数にUserインスタンス
     を渡す事でupperCase内のthisもUserインスタンスを指すようにする。
    ・prototypeを使ってないのでメモリ食う

    View full-size slide

  20. その② - privilegedを使う
    ・privateにもpublicにもアクセス出来る、privilegedを定義する

    View full-size slide

  21. 解説
    ・コンストラクタfunctionのローカルスコープにprivatreメソッドを定義。
    ・privateメソッドにアクセスするためのprivilegedメソッドを定義。
     (今まではコレをpublicだと言っていたけど…。)
    ・prototypeにpublicメソッドを定義。publicからはprivilegedを介してprivateに
     アクセスする。
    ・しかし、privilegedはインスタンス毎に持つfunctionなので結局メモリは食う。
    ・そもそもprivateにアクセスできないpublicの存在意義が怪しい。
    ・パッと見で外部に向けて公開されているインターフェイスが分かりやすいと
     言う意味では良いかもしれない。

    View full-size slide

  22. その③ - 即時関数のスコープを使う
    ・即時関数のローカルスコープにprivateを実装する

    View full-size slide

  23. 解説
    ・即時関数のローカルスコープにprivateを実装。
    ・publicはprototypeに実装する。publicもprivateも即時関数のスコープ内で定義
     するので、publicからprivateも直接参照できる。
    ・若干無理矢理感が漂うものの一番マシ(個人的には)。

    View full-size slide

  24. その④ - publicとprivateを別のオブジェクトで定義

    View full-size slide

  25. 解説
    ・public用のclass、private用のclassを用意する
    ・public用のclassのコンストラクタで、インスタンス変数にprivate用のclassを
     newして突っ込んでおく
    ・private用のclassのコンストラタにpublic用のclassのインスタンスを渡して
     インスタンス変数に突っ込んでおく
    ・publicメソッドからprivateを参照する場合は、this.private経由で参照する
    ・privateメソッドからpublicを参照する場合は、this.public経由で参照する
    ・this.privateをイチイチつけて呼び出すの
     が面倒すぎる
    ・publicとprivateを分ける為だけにしては
     なんだか大げさすぎる感がある

    View full-size slide

  26. まとめると
    ・public / privateを実装しようとすると、可読性が下がったり
     メモリの無駄食いが発生したり、メソッド呼び出しが長ったらしくなったり
     thisが指すオブジェクトを毎回指定してあげないといけなかったり
     いまいちどれがベストプラクティスなのか分からない

    View full-size slide

  27. 7. pia.jsを使う【ステマ】
    なにそれ
    ・Javascriptにおけるclass宣言をサポートするライブラリ
    ・public / privateも簡単に宣言できる
    ・classメソッド、instanceメソッドの定義もらくちん
    ・継承もサポート
    pia.js - Github Link

    View full-size slide

  28. pia.js使うとclass宣言がこんな感じ

    View full-size slide

  29. 解説
    ・initializeとか.new()でインスタンス生成とかRubyっぽく書ける
    ・publicというプロパティにネストした形でpublicメソッドを定義していく
    ・privateというプロパティにネストした形でprivateメソッドを定義していく
    ・thisが指すのは常にUserクラスのインスタンス

    View full-size slide

  30. おしまい!!!!

    View full-size slide