Crockfordは、優れたJavaScript技術を普及させるために多くのことを行いました。言語の主要な要素についての彼の意見に固執したスタンスは、多くの有益な議論を引き起こしました。とはいえ、「悪い」または「有害な」という宣言を福音とする人が多すぎて、一人の人の意見を超えて見ることを拒否しています。それは時々少しイライラすることができます。
new
キーワードによって提供される機能を使用すると、各オブジェクトを最初から構築するよりもいくつかの利点があります。
- プロトタイプの継承。クラスベースのオブジェクト指向言語に慣れている人による疑惑と軽蔑の混合でよく見られますが、JavaScriptのネイティブ継承技術は、コードを再利用するためのシンプルで驚くほど効果的な手段です。そして、新しいキーワードは、それを使用するための標準的な(そして利用可能なクロスプラットフォームのみの)手段です。
- パフォーマンス。これは、#1の副作用である:私は私が作成したすべてのオブジェクトに10個のメソッドを追加したい場合は、私は可能性だけ手動でそれぞれの新しいオブジェクトへの各メソッドを割り当て作成機能を書く...それとも、私はそれらを割り当てることができます作成関数
prototype
とnew
新しいオブジェクトをスタンプするために使用します。これはより高速であるだけでなく(プロトタイプのすべてのメソッドにコードが不要)、メソッドごとに個別のプロパティを使用して各オブジェクトにバルーニングを回避できます。低速のマシン(または特に低速のJSインタープリター)では、多くのオブジェクトが作成されているため、時間とメモリーを大幅に節約できます。
そして、はい、new
重大な欠点が1つあります。他の回答で説明されているように、それを使用し忘れると、コードは警告なしに壊れます。幸い、その欠点は簡単に軽減されます。関数自体にコードを少し追加するだけです。
function foo()
{
// if user accidentally omits the new keyword, this will
// silently correct the problem...
if ( !(this instanceof foo) )
return new foo();
// constructor logic follows...
}
これでnew
、誤って誤用したことによる問題を心配する必要がないという利点があります。壊れたコードのサイレント動作が気になる場合は、チェックにアサーションを追加することもできます。あるいは、いくつかはコメントし、実行時例外を導入するために、チェックを使用します。
if ( !(this instanceof arguments.callee) )
throw new Error("Constructor called as a function");
(前の例とは異なり、実際にオブジェクトをインスタンス化する必要がないため、このスニペットはコンストラクター関数名のハードコーディングを回避できることに注意してください。したがって、変更せずに各ターゲット関数にコピーできます。)
John Resigは、彼のシンプルな「クラス」インスタンス化の投稿でこの手法について詳しく説明し、この動作をデフォルトで「クラス」に組み込む手段を含めています。確かに価値Aは読んだ...彼の今後の本、であるとして、JavaScriptの忍者の秘密(この中に隠し金を発見し、他の多くの「有害」はJavaScript言語の特徴、章にはwith
、特に最初に却下人たちのもののために啓発されたが、ギミックとしてこの非常に悪質な機能)。