5

この質問は、サポートと下位互換性に関するものです。次のコードをテストしました。

function newFunc() {}

newFunc.prototype = {

    literal : {
        init : function() {
            console.log(this);
            this.test();
        },
        test : function() {
            console.log('test');
        }
    }
}

var inst = new newFunc();

inst.literal.init();

これは機能しますが、他のコードでオブジェクト リテラルをプロトタイプとして見たことはありません。これには理由がありますか?これは私には論理的なコーディング方法のように思えますが、深刻な落とし穴がある場合は追求したくありません。

4

4 に答える 4

2

オブジェクト リテラルを使用して関数のプロトタイプを作成するのはまったく普通のことですが、通常はオブジェクトの実際の値としてのみ使用しprototypeます。

珍しいのは、あなたが行ったことを実行し、プロトタイプ内にネストされたオブジェクトを含めることです。

実際には、 という名前のオブジェクトを1 つだけプロトタイプに追加しましliteralた。すべてのメソッドは、そのオブジェクトのプロパティです。技術的には有効な構文ですが、これまで使用されたことはありません。@squint がコメントで指摘しているように、関数呼び出しで使用された「次の左」プロパティthisにバインドされるため、変数の動作方法が壊れているようにも見えます。this

var inst = new newFunc();
inst.literal.init();
> Object { init: function, test: function }

つまり、作成された実際のインスタンスではなくthis、オブジェクトを指すように設定されています。.literal

于 2013-05-29T13:47:08.197 に答える
1

はい、リテラルの使用prototypeは正しいです。たとえば、Mozilla はプロトタイプのドキュメントで明示的にリテラルを使用しています。

var Customer = function(name) {
    this.name = name;
}

var Person = { // this is a literal
    canTalk : true,
    greet : function() { /* ... */ }
}

Customer.prototype = Person;

いくつかの説明:の値prototypeobjectです。オブジェクトがどのように作成されたかは問題ではありません。単に使用しても問題ありません{}。のようなものを使用して初期化されることがよくありますMyClass1.prototype = new MyClass2()new 、新しいオブジェクトを作成するだけです。また、prototypeプロパティを設定し、コンストラクター ( MyClass2) を実行しますが、新しいオブジェクトにはまったく影響しません(こちらMyClass1の説明を参照してください)。

ネストされたリテラルを使用しても違いはありません。質問では、プロトタイプは に設定されてい{ literal : { ... } }ます。呼び出したときに実際に起こることinst.literal.init()は次のとおりです。

  1. ランタイムはinst、オブジェクトが property に割り当てられた値を持っているかどうかを調べてチェックしますliteral
  2. instにはそのようなプロパティがないため、ランタイムはそのprototypeプロパティを使用して続行します
  3. inst.prototype初期化されたリテラル オブジェクトを参照します。このオブジェクト、プロパティ に値を割り当てましたliteral
  4. inst.literalしたがって、ネストされたリテラルに評価されますinst.prototype.literal
  5. リテラル オブジェクトにはプロパティの値がありますinit
  6. init()関数が呼び出されます

これは JavaScript (ECMA Script) の原則の 1 つであるため、互換性の問題はありません。

于 2013-05-29T13:38:02.147 に答える