JavaScriptでのカプセル化

これは今日の「JavaScript for(C/)AL Developers」シリーズの最後の投稿になります。 私はほぼ純粋なJavaScriptのものについてブログを続けた場合,これは実際にはNAVのブログやJavaScriptのものであるかどうかを合理的に尋ねることができます. それはまだNAVであり、私が書こうとしているものは純粋にJavaScriptの概念ですが、コントロールアドイン開発者にとっては非常に関連性が高いと思います。 だから、私のビールを保持し、別のもののために私と一緒に負担します。

JavaScriptについてよく聞く苦情の一つは、JavaScriptにはカプセル化がないということです。 これは、それが完全に偽であるという事実を除いて、ほぼ完全に真実です。

そもそも問題はどこにあるのか、そして解決策は何ですか? 飛び込みましょう

問題

あなたがコンストラクタを宣言していると想像してください。 私たちがES5の世界にいることを想像してみてください(残念ながら、コントロールアドインをNAVとBusiness Centralの両方がサポートされているすべてのプラット

これは私のコードです:

明らかに、これは私の現在の年齢である42を示しています。

すぐに、それは私の誕生日になりますので、これは表示されます43:

今、私は絶対に現実の生活の中でこのような何かをすることができるようにしたいと思いますが:

… それは起こらないだろう。 まともなオブジェクト指向の世界では、”age”はカプセル化されたプロパティでなければならず、vjekoを呼び出すことはできません。年齢=25歳 C#と”通常の”オブジェクト指向言語にはカプセル化の概念があり、プライベートフィールドを使用してこれを処理できますが、JavaScriptにはプライベートの概念 オブジェクトコンストラクタ内で(または後で構築されたオブジェクトのインスタンス上で)thisで定義されたものは、そのインスタンスにアクセス 上記の私の例では、誰でも年齢を設定して逃げることができます。

JavaScriptにはカプセル化がないと言うことができます。 そして、私が上で言ったように、あなたは完全に間違っているでしょう。

解決策

私たちが直接プライベートとして宣言することはできないということは明らかですが、まだ使用できるものがあります。 便利になる一つの美しい概念は、クロージャと呼ばれています。 クロージャは、インターネット上のブログ、ドキュメントサイト、およびコード例の百万で長さで説明されており、あなたは自分のペースでそれらのうちbejesusをグー 私は単にカプセル化の問題を解決するためにそれらを適用することに飛び込むでしょう。

これを処理するには少なくとも二つの方法があります。 まず、より明白なものを行いましょう:アクセス関数。

オブジェクトができないプロパティのない世界を想像してみてください。プロパティ=値(vjekoのように。私たちの場合、年齢=25、私は完全にそれを愛すると同じくらい!). その世界では、getter関数とsetter関数があります:

(私はまだこれを使用しているという事実をしばらく無視してください。”プロパティ”を”カプセル化”する年齢)

明らかに、あなたはこのようにこれらを呼び出すことができるでしょう:

次に、ageを読み取り専用にしたい場合は、setAge setter関数をドロップするだけです。 これなら。年齢は本当にプライベートでした(そうではありません)、これはあなたのためのトリックを行います。 問題は、これで定義されたものはプライベートではなく、オブジェクトの任意のインスタンスにアクセスできる誰でもアクセスできることです。 それはそれが取得するように公開されています。

この問題を解決するには、最初にgetter関数宣言をプロトタイプからインスタンスに移動する必要があります。 プロトタイプメンバーは、実行時に静的メンバーとインスタンスメンバーの両方の特定の動作特性を持っていても、C#で静的と呼ぶものに最も近いです。 ただし、最初にメンバーをprototypeから離れてインスタンスに移動しましょう:

これは、getAgeがインスタンスではなくプロトタイプで定義されていたという問題の最初の部分だけを解決します。 しかし、このような単純な変更で:

… 私たちは問題を完全に解決します:

年齢は完全にカプセル化されています。 Getter関数を使用してアクセスできますが、thisのクロージャスコープでのみアクセスできるため、直接設定することはできません。getAgeインスタンス関数。

Personクラスを完全に実装するには、growolder関数をプロトタイプからインスタンスに移動する必要があります:

そして、これはあなたがそれを動作させるのとまったく同じように動作します:

しかし、なぜそれが動作しますか? それは閉鎖のために働く。 コンストラクタのageパラメータは、getAge関数とgrowOlder関数の両方のclosureスコープにキャプチャされ、これらの関数の両方からその値にアクセスできますが、他の誰かには完全にアクセスできなくなりました。

さらに良い解決策

getter関数を介してアクセスしたくないと言うことができ、本格的な読み取り専用プロパティ構文が必要です。 あなたの年齢は読み取り専用で、同時にカプセル化されたいと思っています。 捕まえた! JavaScriptはそれをカプセル化できません! それは絶対にできることを除いて。

私はオブジェクトに対処しました。私の以前の投稿でdefinePropertyメソッドを読んで、それを読んだ場合、ここでどのように適用できるかをすぐに見ることができます。

では、Personクラスの読み取り専用インスタンスプロパティを定義しましょう:

そこだ 痛くなかった そして、それは動作します:

だからそこにあなたはそれを持っています。 JavaScriptでの本格的なカプセル化により、優れた分離されたコードを記述し、コントロールアドインを実際のキックレベルに引き上げるのに役立ちます。

幸せなJavaScripting、そして私は(C/)AL開発者のための他のクールで便利なJavaScriptのヒントやトリックについてブログに多くの時間を得ることを願っています。

コメントを残す

メールアドレスが公開されることはありません。