ええ、コンストラクターのアプローチを回避しようとしている理由や、コンストラクター自体がエレガントで柔軟な、そして、Crockford のような人々が OOP を好まない理由をどれだけ与えても、OOP への完全に合理的なアプローチです (新しいキーワードを使用するのを忘れているためです - 真剣に?)。JS は関数駆動型であり、その OOP メカニズムも例外ではありません。IMO、それから隠れるよりも、これを受け入れる方が良い.
まず、「当然」の下に記載されているポイント
JavaScript で言及する価値さえほとんどありません。高度な可変性は設計によるものです。私たちは自分自身や JavaScript の他の開発者を恐れていません。プライベート対パブリックのパラダイムは、愚かさから私たちを守るためではなく、他の開発者のコードの背後にある意図を理解しやすくするため、役に立ちません。
呼び出す努力は問題ではありません。やったことの理由が不明な場合、問題は後で発生します。コア言語のアプローチがあなたにとってより良い結果をもたらさないということで、あなたが何を達成しようとしているのか、私にはよくわかりません。
これは JavaScript です。何年もの間、JS 開発者以外のすべての人にとっては奇妙でした。特定のドメインの問題を解決するのに、より一般的な解決策よりもうまく機能する何かを行うためのより良い方法を見つけたとしても、それを気にしないでください。他の言語パラダイムから JS に移行するときに多くの人が持っているように、より一般的なアプローチを置き換える前に、より典型的なアプローチのポイントを理解していることを確認してください。JS で些細なことをするのは簡単ですが、もっと OOP を使いたいと思うようになったら、コア言語がどのように機能するかについてできる限りのことを学んでください。 JavaScriptを実際よりも恐ろしく、致命的なブービートラップでいっぱいにする副業をしている人々によって。
「プラス面」の下にあるあなたのポイントは、
まず第一に、反復的な関数定義は、実際には重いループのシナリオで心配するだけのものでした. プロトタイプ化されていない public メソッド定義がパフォーマンスの問題になるのに十分な速さで十分な量のオブジェクトを定期的に生成していた場合、おそらく、自明ではないオブジェクトのメモリ使用量の問題にすぐに遭遇するでしょう。ただし、過去形で話しているのは、どちらにしても、もはや実際には関連する問題ではないからです。最新のブラウザーでは、他の関数内で定義された関数は、最新の JIT コンパイラーの動作方法により、実際には通常、パフォーマンスが向上します。サポートしているブラウザーに関係なく、オブジェクトごとに定義されたいくつかの関数は、何万ものオブジェクトが予想される場合を除き、問題ではありません。
シンプルで理解しやすいかどうかについては、私にはわかりません。なぜなら、あなたがここで獲得した勝利が見えないからです。使用するオブジェクトを 1 つ持つ代わりに、オブジェクトとその疑似コンストラクターの両方を一緒に使用する必要があります。これは、定義を見ていない場合、オブジェクトを構築するために「new」キーワードで使用する関数を意味します。 . 私があなたのコードベースに不慣れだったら、私が理解していなかった他の懸念を壊すのを避けるために、なぜあなたがこのようにしたのかを理解しようとして多くの時間を無駄にしていただろう.
私の質問は次のとおりです。
そもそもコンストラクターのオブジェクト リテラルにすべてのメソッドを追加しないのはなぜですか? そこにはパフォーマンスの問題はなく、実際にあったこともないので、新しいオブジェクトを作成した後に person に新しいメソッドを追加できるようにすることだけが唯一の可能な勝利ですが、それが適切なコンストラクターでプロトタイプを使用するものです。 (プロトタイプ メソッドは一度しか定義されないため、古いブラウザのメモリには最適です)。
また、メソッドがプロパティを知るためにオブジェクトを渡し続ける必要がある場合、なぜオブジェクトが必要なのでしょうか? 特定のプロパティを持つ単純なデータ構造型オブジェクトを期待する関数だけではないのはなぜですか? もうOOPではありません。
しかし、私の主な批判点は
OOP の主なポイントが欠けています。これは、JavaScript がほとんどの言語よりも人々から隠れていないという点で優れています。次の点を考慮してください。
function Person(name){
//var name = name; //<--this might be more clear but it would be redundant
this.identifySelf = function(){ alert(name); }
}
var bob = new Person();
bob.identifySelf();
ここで、オブジェクトまたはメソッドを上書きせずに、bob が識別する名前を変更します。これは、最初に設計および構築されたオブジェクトを操作したくないことが明らかな場合にのみ行うことです。もちろんできません。これにより、この定義を見た人には、この場合名前が事実上定数であることは明らかです。より複雑なコンストラクターでは、名前を変更または変更できるのはインスタンス自体だけであることが確立されます。ただし、ユーザーが非検証セッター メソッドを追加した場合は、基本的に (Java Enterprise Beans を見て) MURDER THE OOP の中心的な目的。
明確な責任分担がカギ
彼らがすべての本に入れているキーワードを一瞬忘れて、全体のポイントが何であるかを考えてください. OOP が登場する前は、すべてが関数とデータ構造の山にすぎませんでした。OOP では、ほとんどの場合、実際にはオブジェクト自体のみが変更される一連のデータにバンドルされた一連のメソッドがあります。
それでは、出力で何か問題が発生したとしましょう。
ほとんどの場合、すべてのデータを公開するオブジェクトは、古い手続き型アプローチよりもわずかに優れているだけです。緩く関連するメソッドを分類するための名前を付けるだけです。
「これ」について大騒ぎ
「this」キーワードが乱雑で紛らわしいことに過度の注意が向けられていることを、私は理解したことがありません。それほど大したことではありません。「this」は、作業しているインスタンスを識別します。それでおしまい。メソッドがプロパティとして呼び出されない場合、どのインスタンスを探すべきかわからないため、デフォルトでグローバル オブジェクトになります。それはばかげていました (undefined の方が良かったでしょう) が、関数がデータのように移植可能であり、他のオブジェクトに非常に簡単にアタッチできる言語では、そのシナリオで適切に機能しないことが予想されます。次の場合は、関数で「this」を使用します。
インスタンスのプロパティとして定義され、呼び出されます。
これはイベント ハンドラーとして渡されます (リッスンされているもののメンバーとして呼び出されます)。
call または apply メソッドを使用して、他のオブジェクトのプロパティとして一時的に割り当てずに呼び出しています。
しかし、覚えておいてください、本当に重要なのは召しです。public メソッドをいくつかの var に割り当て、その var から呼び出すと、グローバルな処理が行われるか、strict モードでエラーがスローされます。オブジェクトのプロパティとして参照されていない場合、関数は定義されたスコープ (クロージャ) と渡された引数のみを気にします。