web-dev-qa-db-ja.com

JavaScriptでのオブジェクト指向プログラミング。それなしの人生はありますか?

私たちの会社では、かなり大きなPrototypeJSベースのJavaScriptコードを使用していますが、いくつかの理由でjQueryに移植しています(ここではそれほど重要ではありません)。移植中に物事を整頓/整理するためのコーディングガイドラインを設定しようとしています。

プロトタイプベースの実装を歩くことからの1つの観察は、多くのコードがOOPスタイルで(プロトタイプのClass.createを使用して)書かれているが、コードは精神で「オブジェクト指向」ではないということです。 。私が見た一般的なパターン:呼び出すと予想される1つの「コンストラクター」(ただし、コンストラクターはハードコードされたDOM IDを使用するため、2回呼び出すことはありません)、予想外の他の「関数」とイベントハンドラーの束を呼び出す(ただし、JavaScriptには「プライベート」がないため、それを知らないため)およびthisを介してこれらすべての関数間でデータを共有します。呼び出し側の観点から見ると、「callable " 何もありません。

私はJavaScriptのOOPは回避できる可能性があり、おそらく回避すべきであると多くの場合に信じ始めています。少なくとも、次世代のGoole Wave UIではないが、簡単に言えば、AJAXベースの拡張機能、いくつかのイベントハンドラーをあちこちに登録、マイナーなDOM操作など) 。

  • 必要な機能は、一般的なjQueryの非OOPの方法で、カプセル化とプライベート性を得るためにクロージャマジックを使用して、うまく実装できるようです。副作用として、移植されたコードの最小化効率ははるかに優れています。
  • JavaScriptのOOPは非伝統的であり、「伝統的」背景から来ている場合は混乱を招きます。従来のOOPに近づくための多くの試みとフレームワークがありますが、これは物事をさらに混乱させ、もろくします。
  • Crockfordの「JavaScriptの良い部分」が私に教えてくれたことの1つは、JavaScriptの真の力は関数のスコープとクロージャにあり、OOPパターンでははるかに少ないということです。

他の言語/プラットフォームのように、JavaScriptのOOPは神聖なマントラとして実際にそれをカットしないというこの気持ちに対する幅広いサポートがあるかどうか疑問に思っています。どのような非OOP /クロージャベースのパターンがはるかに望ましいか。

12
Stefaan

人々はOOPで高度なパターンに巻き込まれる傾向があります。 MVC、MVVM、MVVC、およびその他すべての「M」、「V」、および「C」の順列。 20,000行以上のjsプロジェクトを開いたことは一度もありませんでした。「ありがとうございます、これはMVCにあります」。20,000行以上のプロジェクトのほとんどは、ひどい混乱を招くためです。

そうは言っても、大規模なプロジェクトはOOPなしではほぼ不可能だと私は思います。少なくとも、複雑なオブジェクトを作成して別々のファイルに保存し、dojoなどのライブラリを使用して衝突からオブジェクトを名前空間で保護する機能により、何千時間もの苦痛なデバッグを節約できます。

「ああ」と自分に言うかもしれませんが、「まあ、関数のモジュラーグループを別々のjavascriptファイルに書き込めます。それらの中で最高のものを使用できます。OOPを使う必要はありません。」ええと、おめでとうございます。あなたは既にOOPを知らなくても効果的に使用しているためです。そのため、実際にクラスを使用して、さらに進んでみませんか?

Javascriptがプロトタイプモデルに依存していることは事実ですが、OOPのベースは継承/カプセル化/ポリモーフィズムであり、javascriptはそれを完全にうまく実行できます。dojo.jsをご覧ください。

4
CodeOwl

私はいくつかのことを指摘することが重要だと感じています:

  1. OOPとクラスは2つの完全に直交する概念です。クラスは、構造体/レコードと同様に機能します(実際、一部の言語では機能します)。それらは偶然にが特定の種類のオブジェクトを構築するのに役立つことがあります。
  2. アクセス制御はカプセル化のための素晴らしいツールですが、それは前提条件ではありません。 JavaScriptでは、オブジェクトの「プライベート」メンバーの前にアンダースコアを付けるのが一般的です。とにかくそれらにアクセスすることを選択するかどうかは、あなたが決めることです。ほとんどの言語では、本当に必要な場合に過去のアクセス制御を取得するいくつかの手段があります。一般的に、人間が意識的にさらさずに消費できる(そしていつでも変更できるなど)何かに対してコードを書くのは、本当にばかげたことです。
  3. OOPは、システムの特定の部分がどのように実装されているか(構文が含まれていることは言うまでもありません)ではないので、実装は「オブジェクト指向の精神」ではないかと私は主張します。 OOPは、カプセル化とポリモーフィズムに基づいて作成された間接化のための比較的巧妙なメカニズムです。本質的には、「Tell、Do n't Ask」に過ぎません。

フープを飛び越えてJavaScriptをそうでないものに変えたい場合、結果に不満を感じるかもしれません。そのため、代わりに、JavaScriptにコンパイルできるが、プログラミング言語に似せたい言語に近いものを選択できます(Haxe、ParenScript、TypeScript、CoffeeScript、ScriptSharp、Dart、Java( GWTを介して)、C/C++(Emscriptenを介して)...実際、他のほとんどすべての一般的な言語をさまざまな品質のJavaScriptに変換できます)。

しかし、JavaScriptを使用すると、「クラスOID」、ミックスイン/トレイト、AOPなどを許可しない言語が見つかります。多くの場合、Java特有のイディオムに制限することは最善のアイデアではない可能性があることに気づくでしょう。それにもかかわらず、それらは時々間違いなく役に立つでしょう。

2
back2dos

プロトタイプベースの実装を歩くことからの1つの観察は、多くのコードがOOPスタイル(プロトタイプのClass.createを使用)で記述されている)が、コードは精神で「オブジェクト指向」ではないことです。私が見た一般的なパターン:呼び出すと予想される1つの「コンストラクター」(ただし、コンストラクターはハードコードされたDOM IDを使用するため、2回呼び出すことはありません)、その他の「関数」とイベントハンドラーの束(ただし、JavaScriptには「プライベート」がないため、それを知らないため)、これを介してこれらすべての関数間でデータを共有します。呼び出し側の観点から見ると、「呼び出し可能」は1つだけで、他には何もありません。

すべてのJavaScriptプロジェクトがOOPを必要とするわけではありません。 ExtJSのような既存のOOフレームワークを使用していない限り、私はそこに行きません。あなたの場合、OOPの唯一の使用は誤用ですが、 jQueryに切り替えるので、jQueryプラグインアーキテクチャに従ってください。必要に応じてカスタムプラグインを作成してください。

0
kevin cline