モジュール対クラス- JSでプライバシーを管理する方法


オブジェクト指向のパラダイムは、開発者がそれを好きでないか、その前提が好きでないとしても、コードを考えて、コードを書く方法で大きな揺れを作りました.これは、属性やメソッドの形でデータや手続きをカプセル化するような新しいパラダイムではなく、それらのいくつかがその主要なパラダイムとしてそれを使用していない場合でも、多くの最近の言語に影響を与えた.
C +やJava、Python、さらにはJavaScriptのような言語が考えられ、オブジェクト指向のパラダイム(OOP)を実装する言語を宣言した.説明するように、JavaScriptはいくつかの特異性を持つオブジェクトを扱う独自の方法を持っています.しかし最初に、議論されるべき出発点があります.
また、いくつかのテストとレポだ!Check it out !

クラスとオブジェクト


クラスはデータ型の定義です.それらはどのようなデータを格納するか/隠すか、どのように動作するべきですか.つのクラスのインスタンスは、メソッドとしての機能を実行し、データを属性として格納することができます.それらのインスタンスは、プログラムの実行時実行の中で生きるいわゆるオブジェクトです.

Unsplashでダンディンモックの写真
OOPの重要な特徴の1つは、オブジェクトがそのデータをカプセル化する能力を持つ必要があるという事実です.つまり、誰かがオブジェクトから何らかの情報にアクセスしようとすると、クラスがそうするなら、それをすることができないはずです.次の例を考えます.
Elonムスクと言いましょう🧑‍💼 素晴らしい作成Trash Can これは3つの単純なタスクを実行できます.
  • つの'ジャンク'アイテムをゴミに投げることができます
  • ゴミ箱内のすべてのアイテムをきれいに、すべて一度に
  • ゴミ箱が完全に空であるかどうか、ディスプレイで示す1つのボタン
  • そのためのインタフェースTrashCan 以下のようになります.
    TrashCan {
      throwAway(item);
      clean();
      isEmpty();
    }
    
    JavaScriptがclass キーワード、この1つの実装を検討することが可能ですTrash 次のように
    class TrashCan {
      constructor() {
        this.items = [];
      }
    
      throwAway(item) {
        this.items = [...this.items, item];
      }
    
      clean() {
        this.items = [];
      }
    
      isEmpty() {
        return this.items.length === 0;
      }
    }
    
    var elonTrashCan = new TrashCan();
    
    現在elonTrashCan が空で、その仕事を始める準備ができています.しかし、
    elonTrashCan.throwAway('paper ball');
    elonTrashCan.throwAway('empty Starbucks cup of coffee');
    elonTrashCan.throwAway('empty package of Cookies');
    
    elonTrashCan.clean();
    
    elonTrashCan.items = ['SpaceX secret project'];
    
    console.log(elonTrashCan.isEmpty()); // --> ???
    
  • エロンムスク🧑‍💼 我々が彼のゴミを壊すことができると我々に怒っています
  • elonTrashCan.isEmpty()false , 我々が定義したのでelonTrashCan.items 内1アイテム
  • elonTrashCan.items がアクセスできないので、elonTrashCan.isEmpty() 返り値true
  • 答えはオプション2です.アクセス可能ですitems 明示せずにオブジェクトインスタンス内でitems 外部宣言constructor .
    その例を使用して、理想的なオブジェクト指向言語実装を考慮してelonTrashCan.items プライベート属性にアクセスしようとするプログラムのエラーになります.JavaScriptでは、これらの呼び出しは可能です、有効なものとエラーなしで結果.
    だから、JavaScriptのプライバシーを作成することはできませんか?オブジェクトの外側からデータを隠して、露出する方法はありますかpublic データ?

    Unsplashの上でFolcoマシによる写真

    モジュールパターン


    良いニュースは、プライバシーに関連する何かを提供するJavaScriptの中の1つの振舞いです:閉鎖.このポストは、興味のある閉鎖について書かれている


    変数と関数を隠すためのクロージャを使用すると、1つのインスタンス内のデータをカプセル化するだけでなく、目的のインターフェイスを公開する良い方法です.
    しかし、これは実際にどのように動作しますか?
    同じエロンムスクをつくりましょう🧑‍💼 TrashCan オブジェクトの関数を記述し、その次のコードとしてだけパブリックインターフェイスを返す
    const TrashCan = () => {
      let items = [];
    
      const throwAway = item => {
        items = [...items, item];
      }
    
      const clean = () => {
        items = [];
      }
    
      const isEmpty = () => {
        return items.length === 0;
      }
    
      return {
        throwAway,
        clean,
        isEmpty,
      }
    }
    
    var elonTrashCan = TrashCan();
    
    そして新しいelonTrashCan 上記と同じコードを実行してみましょう
    elonTrashCan.throwAway('paper ball');
    elonTrashCan.throwAway('empty Starbucks cup of coffee');
    elonTrashCan.throwAway('empty package of Cookies');
    
    elonTrashCan.clean();
    
    elonTrashCan.items = ['SpaceX secret project'];
    
    console.log(elonTrashCan.isEmpty()); // --> ???
    
  • エロンムスク🧑‍💼 我々が我々の第2のゴミを壊すことができるという我々のMacherでさえあります
  • elonTrashCan.isEmpty()false , 我々が再び定めたのでelonTrashCan.items 内1アイテム
  • elonTrashCan.items がアクセスできないので、elonTrashCan.isEmpty() 返り値true
  • 実際に何か奇妙なことが起こる
  • elonTrashCan.isEmpty() リターンfalse 我々の内部items 空です
  • elonTrashCan.items その中に1アイテム

  • Unsmohの上のスコットGummersonによる写真
    このアプローチを使用すると、希望のインターフェイスだけにアクセスし、その中にコンテンツを隠している外部の世界を制限することが可能です.一方、JavaScriptは、ランタイム実行で新しいプロパティの定義を、クロージャが使用するのと同じ名前を使用しても定義できます.
    クロージャの内部のコードは、それらの新しいプロパティに依存しません.オリジナルのものはそのクロージャの内部にアクセスできません.そして、元の使命は現在達成されます:プライバシー.モジュールパターンは属性に対して実行可能であり、メソッドの隠蔽にも使用できます.
    新しいプロパティの作成による副作用については、元のインターフェイスを変更しないように提案されていません
    if(typeof elonTrashCan.items === 'undefined') {
      console.log('No exposed items!') // --> No exposed items!
    }
    

    包む


    オブジェクト指向のパラダイムとJavaScriptのクラス実装についてのいくつかの議論の後、多分、あなたがBabelのようなトランジスターを使用していないならば、JSクラスは個人データでオブジェクトをつくるための最も良い選択でありません.
    クロージャとモジュールパターンを使用すると、JavaScriptのプライバシーをシンプルで再利用可能な方法で実現できます.If the class 実装は避けられないです、モジュールパターンのいくらかの使用でトランスポーターまたはより堅牢なアプローチを使用することを考えてください.Transiilersの使用はほとんどincouragedです!
    見かけ上の損失もinheritance , この利点をモジュールでも実装するには、まだ有効な方法があります.
    何かミスか?あなたがそれが明確でないと思うものがありますか?コメントのセクションやメッセージで私に到達し、それを議論する無料!

    参考文献

  • カバー写真Ciprian Boiciuc on Unsplash
  • Article at MDN about Class fields(attributes) options

  • Babel
  • GitHub repo with tests