1

違いは正確には何ですか

function ObjA() {
  this.a = 'text';
}

var obj = new ObjA();

function ObjB() {
  return {
    a: 'text'
  };
}

var obj = new ObjB();

私はこの質問を読んでいて、答えの1つで次のことに気づいたので質問しています。

function Test() {
  this.a = 1;

  return {
    get A() { return this.a; },
    set A(v) { this.a = v; }
  };
}

だから私はそれと次の違いは何ですか?

function Test() {
    this.a = 1;
}

Test.prototype = { 
    get A() { return this.a; },
    set A(v) { this.a = v; }
};

彼らはコメントの中で、前者は「ゲッターとセッターが各オブジェクトごとに「ユニーク」であるため、メモリを占有する」と述べています。誰かがこれについて詳しく説明してもらえますか?

4

5 に答える 5

1

最後の例は機能しません。

function Test() {
    var a = 1;
}

Test.prototype = { 
    // This code has no clue what a is
    get A() { return a; },
    set A(v) { a = v; }
};

しかし、もしそうなら

function Test() {
    this.a = 1;
}

Test.prototype = { 
    get A() { return this.a; },
    set A(v) { this.a = v; }
};

次に、2 つのコードは似ていますが、最初の例 (モジュール パターン)Test.prototypeのインスタンスを作成するものを除いて、常にFactory メソッドを使用して基本型の何かを作成します。TestObject

于 2012-09-24T17:55:03.907 に答える
1

あなたは実際にいくつかの異なる質問をしています。それでは、最初のものに集中させてください (変数名を変更して、変数名をより簡単に参照し、上書きしないようにしますObject)。

正確には次の違いは何ですか:

function ObjA() {
  this.a = 'text';
}

var objA = new ObjA();

function ObjB() {
  return {
    a: 'text'
  };
}

var objB = new ObjB();

違いは、前のバージョンではプロトタイプ チェーンが維持されるのに対し、後のバージョンではプロトタイプ チェーンが破棄されることです。次のコード行を検討してください。

ObjA.prototype.b = "something";
ObjB.prototype.b = "something";

次に、次が true になります。

objA.b; //is "something"
objB.b; //is undefined

その理由は、「コンストラクター」から返されたオブジェクトが ObjB のプロトタイプ チェーンを追加しないためです。新品のオブジェです。それが「違い」です。

2 番目の例 (.prototypeオブジェクトを使用する場合と返す場合) は、実際には私の知る限り、メモリを実際に「無駄にする」ことはありません(更新を参照)。関数で演算子を呼び出すプロセスはnew、オブジェクトのプロトタイプのコピーを作成してから、その関数を呼び出すためです。良い点は、 を使用すると、プロトタイプ化されたメソッドが「コンストラクター」関数内で使用可能になり.prototype、そのバージョンでプロトタイプ チェーンを維持できることです。しかし、リターンベースのメソッドを使用することについて本当に「間違っている」ことがあるかどうかはわかりません。

アップデート:

私はこの件に関する ECMAScript 仕様を調べました (そして私の思考装置に少し油を差しました) が、メモリの浪費について私が間違っていたようです。「クラス」関数のプロトタイプ プロパティのメソッド/プロパティが参照によってリンクされているようです。したがって、プロトタイプを使用するのではなく、新しいオブジェクトを生成するために、実際には少しのメモリが浪費されます。さらに、返されたオブジェクトで宣言されたプロパティはすべてインスタンス レベルですが、プロトタイプ オブジェクトで宣言されたプロパティは「クラス」に対して静的です (つまり、すべてのインスタンスで共有されます)。

そして、他の人が指摘したように、あなたの例には小さなバグがあります(aプロトタイプオブジェクトでは利用できません)。しかし、それは当面の質問には重要ではないので、無視しました。(バグを修正したようです)。

于 2012-09-24T17:58:15.967 に答える
1

の違い

function Obj () {
  this.a = 'text';
}

var obj = new Obj();

function Obj () {
  return {
    a: 'text'
  };
}

var obj = new Obj();

最初のものは安全ではないと考えられていますか。つまり、new演算子の使用を忘れると、グローバル名前空間がプロパティで汚染されます。

オブジェクトを定義する 2 番目の方法は、はるかに優れていますvar obj = new Obj();との両方を行うことができvar obj = Obj();、結果はまったく同じになります。

さらにvar、コンストラクター内で s を使用すると、コンストラクター自体のスコープ外からアクセスできなくなります。したがって、それらをプライベートとして使用し、ゲッター/セッターとして機能する関数を定義できます。次に例を示します。

function Obj () {
    var privateVar = 'xxx';

    return {
        getPrivateVar: function () {
            return privateVar;
        },
        setPrivateVar: function (val) {
            privateVar = val;
        }
    };
}

このようにして、コンストラクターの外部から変数にアクセスできますが、適切な関数 (セッター) を呼び出さずに変数を変更することはできません。

プロトタイプの使用は広範なトピックです。メモリを節約できます (メソッドは、新しいオブジェクトを作成するたびに作成されるのではなく、オブジェクト インスタンス間で共有されます)。プロトタイプを変更するだけで、オブジェクトのすべてのインスタンスのメソッドを変更できます。さらに、prototype を使用して継承を模倣することもできます (「prototype chain」を探してください)。

「JavaScript: 良い部分」を読むことをお勧めします。

于 2012-09-24T18:10:36.680 に答える
0

プライベート メソッド/関数を使用せずにオブジェクトを作成できるようにします (シミュレートされますが、そうです)

   function Object() {
      // a can be change via OBJECTs API
      this.a = 7;
    }

コードでアクセスできない「内部ジョブ」への関数と変数の使用を許可する

 function Object() {
      // b CAN BE CHANGED FROM OBJECTs  API 
      var b = 125;          
      return {
        a: 7+b
      };
    }
于 2012-09-24T17:54:22.487 に答える
0
function Object() {
  this.a = 'text';
}
var obj = new Object();

function Object() {
  return {
    a: 'text'
  };
}
var obj = new Object();

それぞれ次のように使用されます。

console.log(obj.a); // 'text'

でも、

function Test() {
  var a = 1;

  return {
    get A() { return a; },
    set A(v) { a = v; }
  };
}
var obj = new Test();

のように使用されます

console.log(obj.A); // 1
obj.A = "banana";
console.log(obj.A) // 'banana'

/それaに対して外部プロパティAを作成して非公開にしています。これの利点は、プロパティを作成したり、取得/設定時に計算を実行したり、他の多くのことを実行できることです。getsetstaticreadonly

于 2012-09-24T17:58:36.073 に答える