2017-01-24 10 views
0

JavaScriptでプロトタイプとコンストラクタがどのように動作しているかを理解しようとしています。オブジェクトはどのように作成されますか?

  • によって空のオブジェクトはコンストラクタ関数
  • のオブジェクトが関数のプロトタイプにリンクされている
  • オブジェクト検索を
  • を作成している

    私は常にオブジェクトをJavaScriptで作成されましたかピクチャでありますこのコンストラクタ関数が実行され、そのオブジェクトにプロパティが割り当てられた

  • 暗黙的にオブジェクトが返されるreturn this

この方法は、obj2obj3を説明できないようです。

たとえば、Foo.prototype.constructorobj2の別のものに明示的に設定しますが、obj2のプロパティはまだbarです。さんはbarを言ってみましょうobj2プロパティbarを持っていると、なぜobj3Objectによって作成された理由を説明するのFooのプロトタイプ、に保存されているが、私はカップルより多くを作成した場合obj2 S、彼らはのFooのプロトタイプで同じ変数barを共有する意味であろうとされており、私はそうではないと思う。

誰かがobj2obj3がこのような理由についてもっと合理的な説明をすることはできますか?

function Foo(){ 
 
    this.bar = true; 
 
} 
 

 
console.log('obj1'); 
 
var obj1 = new Foo(); 
 
console.log(obj1); 
 
console.log(obj1.constructor === Foo); 
 

 
console.log('obj2'); 
 
Foo.prototype.constructor = 3; //a dummy value 
 
var obj2 = new Foo(); 
 
console.log(obj2); 
 
console.log(obj2.constructor === Foo); 
 

 

 
function Bar(){ 
 
    this.foo = true; 
 
} 
 
console.log('obj3'); 
 
Bar.prototype = 3; 
 
var obj3 = new Bar(); 
 
console.log(obj3); 
 
console.log(obj3.constructor === Bar); 
 
console.log(obj3.constructor === Object);

+0

http://stackoverflow.com/questions/572897/how-does-javascript-prototype-workオブジェクトは、本質的な特性を含む変数(コンテキストまたはそれ以外)されているJavaScriptの – Abhitalks

+0

- これらのプロパティメソッドでも、値でもかまいません。プロトタイプ(Object.prototype.prototype)は、これらのプロパティを変更します。 – Crowes

+0

@Abhitalksもしあなたが私の言ったことを読んだら、私はあなたのリンクが何を話しているかをすでに理解していることを知っているでしょう。 2番目の箇条書きのポイント私はすでにリンケージ '__proto__'を話しています。私は' __proto__'または '[[Prototype]]'を明示的に記述していません。 – kevguy

答えて

1

私は昨日あなたのポストを見ましたが、私はその時に少し忙しかった、今私は自由だと私は思いますあなたの質問に答えるのが好きです。

コードnew Foo()を実行すると、以下のことが起こる:

  1. 機能はFoo()関数は、それは次のように扱われnewキーワードと呼ばれているので、前述@slebetmanとして、呼ばれていますコンストラクタでは、空のオブジェクトが作成されます。

  2. オブジェクトは、Foo.prototypeから継承した関数のプロトタイプにリンクされています。

  3. this新しく作成されたオブジェクトにバインドされています。 this.bar = trueが実行されました。 new Foonew Foo()に相当します。つまり、引数リストが指定されていない場合、引数なしでFooが呼び出されます。

  4. コンストラクタ関数によって返されるオブジェクトは、新しい式全体の結果になります。コンストラクタ関数が明示的にオブジェクトを返さない場合は、最初の手順で作成したオブジェクトが代わりに使用されます。 (通常はコンストラクタは値を返しませんが、彼らは通常のオブジェクトの作成プロセスを無効にしたい場合は、彼らがそうすることを選択できます。)

のバーが理由を説明するのFooのプロトタイプに格納されているとしましょうobj2にはプロパティバーがあり、なぜobj3がObjectによって作成されたのですか?しかし、もっと複雑なobj2を作成すると、Fooのプロトタイプで同じ変数バーを共有することになります。

あなたは正しいです。

console.log(obj1.hasOwnProperty("bar")); // true 

しかし、あなたはこのようにプロパティを追加した場合::

barは、たとえば、obj1obj2が所有する財産です

Foo.prototype.bar2 = true; 
console.log(obj1.hasOwnProperty("bar2")); // false 

bar2の値は、すべてのFooによって共有されていますインスタンスであるが、barプロパティがFooインスタンスによって共有されていない場合、各Fooインスタンスは独自のbar値。

obj2とobj3がこのような理由について、誰かがより合理的な説明をすることができますか?

  • obj2には何が起こりましたか?もしコンストラクタFooFoo.prototype.constructorが自動的Fooをポイントする宣言する場合、console.log(Foo.prototype)はそれを表示します

、実際にこれは、再帰的にオブジェクトを通過するときに検出されなければならない円形参照と呼ばれます。しかし、あなたのケースでは、Foo.prototype.constructor = 3、幸いにも、new Foo()の表現のプロセスはFoo.prototype.constructorプロパティを含まないので、正しく行われますが、obj2.constructorまたはFoo.prototype.constructorの値はまだ3です。

  • obj3はどうなりましたか?ステップ2で、作成したオブジェクトはBar.prototypeにリンクになっているとして、しかしBar.prototypeの値は暗黙のうちにA、オブジェクトを参照しないため

Bar.prototype = 3、私の理論は、new Bar()が実行されたときに、ということですデフォルト値が割り当てられました。これはObject.prototypeです。これによりobject.prototype.constructor

console.log(Object.prototype === Object.getPrototypeOf(obj3)); // true 

'Objectへの参照、obj3.constructorObjectを参照するが、obj3デファクトコンストラクタは理由によっても証明することができるステップ1の、まだBarでありますconsole.log(obj3.foo); // true

詳細情報:How objects are created when the prototype of their constructor isn't an object?

+0

'obj3'については、' 3'がオブジェクトに囲まれているかのように 'Number'だったと思いましたが、そうではありません。そして、明らかに代入は無視されず、コンストラクタはまだ 'Bar'になります。そして、私はプロトタイプがどのように 'Object'になるのか疑問に思っていました。私はFirefox Chrome Safariでテストしましたが、それらはすべて同じように動作します。だから私はECMA-262で明確に規定されたものでなければならないと思う。しかし、私は正しい場所にいない。内部メカニズムについての詳細情報を提供できますか? – Leo

+0

@Leoこれは私の理論ですが、私はそれをサポートするための文書を見つけることができませんので、私はこの質問をしました - http://stackoverflow.com/questions/41846565/how-objects-are-created-when -the-constructor-a-primitive-nのプロトタイプ-n –

+0

@Leo「グローバル変数の自動作成」のようなものだと思っていましたが、厳密なモードでは、エラー。 –

0

あなたの理解はほとんど正しいこれを除いてです:いいえ、コンストラクタ関数がこれですコンストラクタ関数

ため

  • オブジェクトを検索:

    function Foo(){ 
        this.bar = true; 
    } 
    

    は、そして、あなたは、既存のオブジェクトを使用せず、直接コンストラクタ関数を呼び出している:単なる関数呼び出しです

    new Foo(); 
    new Bar(); 
    

    を。それはnewキーワードのためにちょっと特別です。だから、あなたの理解私はあなたの説明を取り、それを少し変更するつもりビットを変更する:関数はnewキーワードと呼ばれているので

    • 関数が、それは次のように扱われ
    • と呼ばれています空のオブジェクトが作成されたコンストラクタ
    • オブジェクトは関数のプロトタイプ
    • にリンクされている
    • オブジェクトはこの
    暗黙の復帰で返されます

    コンストラクタを呼び出すときにコンストラクタを作成するときに、コンストラクタを検索するオブジェクトは必要ありません。コンストラクタへの呼び出しは、最初の手順であり、3番目の手順ではありません。

    これは、オブジェクトの構築方法の非常に高度な説明です。 thisがどのように扱われているかのようないくつかの詳細がグロスオーバーされています。

+0

'new Foo()'を実行すると、 'this'は作成されたオブジェクトに設定され、' return'ステートメントを持たない関数の最後に暗黙の 'return this'があります。だからあなたはそこにそれ以上のことがあると言っているのですか? @slebetman – kevguy

0

たとえば、Foo.prototype.constructorを明示的に何か obj2に対して設定しましたが、obj2にはまだプロパティバーがあります。 [..]あなたのケースconstructor

Foo上だけprototypeプロパティです。 コンストラクタobj2ではありません。 コンストラクタobj2です。Fooです。プロトタイプにconstructorという名前のプロパティを適用すると、のコンストラクタは変更されません

[..]が、あなたの信念、barに反してはFooに格納されていない

[..]のバーがobj2は、プロパティバーを持っている理由を説明するのFooのプロトタイプ、 に保存されているとしましょうのプロトタイプ。 obj2インスタンスに存在するプロパティです。プロトタイププロパティ ではなく、のインスタンスプロパティです。あなたのケースのプロトタイププロパティは constructorです。よりわかりやすくするためにこれらの例で

ルック:

function Foo() { 
 
    this.bar = true; 
 
} 
 

 
var obj = new Foo(); 
 
console.log('The instance property "bar" is ' + obj.bar); 
 

 
Foo.prototype.baz = 4; 
 
console.log('The prototype property "baz" is ' + obj.baz); 
 

 
Foo.prototype.bar = 5; 
 
console.log('The prototype property "bar"=' + Foo.prototype.bar + ' is overridden by instance property "bar"=' + obj.bar);

関連する問題