web-dev-qa-db-ja.com

オブジェクトリテラルvsコンストラクター+プロトタイプ

オブジェクトリテラル=中括弧で囲まれた名前と値のペア。

コンストラクタ= newキーワードを使用して複数のインスタンスを作成するために使用される関数。

プロトタイプ=リテラルの拡張用。

これが今まで私が理解してきたことですが、研究すればするほど、それぞれのsignificanceが何であるかについて混乱します。私はコードでコンストラクタ、プロトタイプ、リテラルを数回使用しましたが、それらを使用するたびに、私はまだそれの完全な可能性を認識していません。私は今、初心者になる前に一歩行きたいと思います。

  1. どちらがbestプログラミングの好ましい方法ですか(オブジェクトリテラルvsコンストラクタvsプロトタイプ

  2. コンストラクタとプロトタイプを使用して、オブジェクトリテラルだけを使用してコードを記述できますなし.

  3. 無名関数の意味は何ですか。

彼らの重要性を示す非常に単純な例でも効果があります。私は彼らが何であるかは知っていますが、彼らがどんな魔法を実行できるのかは知りません。

37
HIRA THAKUR

オブジェクトのリテラルと関数、「プライベート」変数の間に(私の意見では基本的な)違いがあります。オブジェクトはインスタンス化できないため(既にObjectのインスタンスであるため)、独自の(新しい)スコープを持つ可能性はありません。これは、高度なJSプログラミングの基本概念です。新しいスコープを使用すると、ほとんどすべてのことが可能になります(独自のwindowdocument、またはJSキーワード自分のスコープ内)。さて、いくつかの簡単な例:

同じオブジェクトの多数のインスタンスを作成するとします(できるだけ少ない行を使用)。

function MyObj(i) {
    var privateCounter = "I am the instantiated object " + i + " .";
    this.counter = function() {
        return privateCounter;
    };
}

var MyObjList = [],
    ObjLitList = [];
for (var i = 0; i < 100; i++) {
    MyObjList.Push(new MyObj(i));
    ObjLitList.Push({counter: "I am the literal object number " + i + "."});
}

これで、ほとんどであるが、preciselyではない200のオブジェクトが同じになりました。関数オブジェクトなので、必要に応じて拡張できますが、関数の場合はprivate変数に直接アクセスできません。関数の利点を見てみましょう:

  • Objectのように扱われます
  • 独自のPrototype
  • プライベート変数があります

そしてObjects?

  • それはisObject
  • 独自のPrototypeはありませんが、関数を宣言してオブジェクト自体を拡張できます
  • プライベート変数はありません

プライベート変数を除いて、それらは互いにそれほど違いはありません。

関数のプロトタイプができることを見てみましょう:

MyObj.prototype.setX = function(x) {
    this.x = x;
}

プロトタイプを使用すると、インスタンス間で共有される無名関数(名前を付けて割り当てることができる)の唯一のインスタンスを作成できます。オブジェクトリテラルで同じことをするにはどうすればよいですか?

function setX(x) {
    this.x = x;
}
var obj = {
    setX: setX
};

ご覧のとおり、setXであるプロパティを毎回定義するオブジェクトを作成する必要があります。それ以外の場合は、Object.prototype自体(ただし、ネイティブJSオブジェクトのプロトタイプの拡張については長い議論があります)。

ベストの方法はどれですか?誰もいない、それはあなたが何をしなければならないか、あなたがスクリプトから何を必要としているのか、どちらがあなたがより快適に感じるかによる。

私は自分の関数を記述し、それらをクラスのように扱うことを好みます。なぜなら、それらはより読みやすく、「プライベート」変数を使用できるからです。関数の代わりにリテラルを使用している人を知りません。

質問に関しては:

プログラミングの最も好ましい方法です(オブジェクトリテラルvsコンストラクタvsプロトタイプ)

答えました。

コンストラクターとプロトタイプを使用せずに、オブジェクトリテラルだけを使用して、コンストラクターとプロトタイプを含むコードを記述できます。

はい、プライベート変数が必要ない場合(およびスクリプトが大きすぎない場合は、オブジェクトリテラルとして記述されたjQueryを想像してください:D)。

匿名関数の重要性は何ですか。

まあ、私は例で答えることができます:

//code
myNamedFunction();
//code
function myNamedFunction() {
    alert("I'm defined everywhere! :)");
}

これは機能し、TypeErrorを生成しません。

myAnonymousFunction();
var myAnonymousFunction = function() {
    alert("I'm defined after this declaration :(");
}
myAnonymousFunction(); // works!

これにより、Uncaught TypeError: undefined is not a functionmyAnonymousFunctionは有効な関数への参照にすぎないため(名前のないため、スクリプトから呼び出すことはできません) 。

この議論については多くのことを言う必要がありますが、高度なプログラミングを開始する良い点は Javascript Garden です。他の良い読みは OOP= NetTutsPlusWorking with Objects-MDNJSでのOOP-Phrogzです)

お役に立てれば!

補足:関数もコンテキスト(this)を関数(たとえば[call)だけで変更できるため、オブジェクトにはできません。

28