web-dev-qa-db-ja.com

__proto__ VS. JavaScriptのプロトタイプ

この図も、すべてのオブジェクトにプロトタイプがあることを示しています。コンストラクタ関数Fooには、Function.prototypeという独自の__proto__もあります。これは、__proto__プロパティを介して再びObject.prototypeを参照します。繰り返しますが、Foo.prototypeはFooの明示的なプロパティであり、bおよびcオブジェクトのプロトタイプを参照します。

var b = new Foo(20);
var c = new Foo(30);

__proto__プロパティとprototypeプロパティの違いは何ですか?

enter image description here

図は ここ からとられています。

692
0x90

__proto__は、メソッドなどを解決するためにルックアップチェーンで使用される実際のオブジェクトです。prototypeは、newを使用してオブジェクトを作成するときに__proto__を構築するために使用されるオブジェクトです。

( new Foo ).__proto__ === Foo.prototype;
( new Foo ).prototype === undefined;
675
Mark Kahn

prototypeは、Functionオブジェクトのプロパティです。それはその関数によって構築されたオブジェクトのプロトタイプです。

__proto__は、そのプロトタイプを指すオブジェクトの内部プロパティです。事実上の標準__proto__がより速いのですが、現在の標準は同等のObject.getPrototypeOf(O)メソッドを提供します。

関数のinstanceofをオブジェクトの__proto__チェーンと比較することによってprototypeの関係を見つけることができます、そしてprototypeを変更することによってこれらの関係を破ることができます。

function Point(x, y) {
    this.x = x;
    this.y = y;
}

var myPoint = new Point();

// the following are all true
myPoint.__proto__ == Point.prototype
myPoint.__proto__.__proto__ == Object.prototype
myPoint instanceof Point;
myPoint instanceof Object;

ここでPointはコンストラクタ関数で、手続き的にオブジェクト(データ構造)を構築します。 myPointPoint()によって構築されたオブジェクトなので、その時点でPoint.prototypemyPoint.__proto__に保存されます。

308
Imp

プロトタイププロパティは、関数が宣言されたときに作成されます。

例えば:

 function Person(dob){
    this.dob = dob
 }; 

Person.prototypeプロパティは、上記の関数を宣言すると内部的に作成されます。 new Person()を使用して作成されたPersonインスタンスによって共有される多数のプロパティをPerson.prototypeに追加できます。

// adds a new method age to the Person.prototype Object.
Person.prototype.age = function(){return date-dob}; 

Person.prototypeがデフォルトでObjectリテラルであることは注目に値します(必要に応じて変更できます)。

New Person()を使用して作成されたすべてのインスタンスは、Person.prototypeを指す__proto__プロパティを持ちます。これは特定のオブジェクトのプロパティを見つけるためにトラバースするために使用されるチェーンです。

var person1 = new Person(somedate);
var person2 = new Person(somedate);

personのインスタンスを2つ作成します。これらの2つのオブジェクトは、Person.prototypeのageプロパティをperson1.age、person2.ageとして呼び出すことができます。

上の図では、Fooは関数オブジェクトなので、それはObjectのインスタンスであるFunction.prototypeへの__proto__リンクを持ち、Object.prototypeへの__proto__リンクを持ちます。プロトリンクは、ここでnullを指すObject.prototype内の__proto__で終わります。

__proto__によってリンクされているように、どのオブジェクトもそのプロトチェーン内のすべてのプロパティにアクセスすることができ、したがってプロトタイプ継承の基礎を形成します。

__proto__はプロトタイプチェーンにアクセスするための標準的な方法ではありません。標準的ですが類似したアプローチはObject.getPrototypeOf(obj)を使用することです。

以下のinstanceof演算子のコードは、よりよく理解するためのものです。

object instanceof Class演算子は、オブジェクトがClassのインスタンスである場合、具体的にはそのオブジェクトのプロトチェーン内でClass.prototypeが見つかった場合、そのオブジェクトはそのClassのインスタンスである場合にtrueを返します。

function instanceOf(Func){
var obj = this;
while(obj !== null){
    if(Object.getPrototypeOf(obj) === Func.prototype)
        return true;
    obj = Object.getPrototypeOf(obj);
}
return false;
}

上記のメソッドは、instanceOf.call(object,Class)として呼び出すことができ、objectがClassのインスタンスであればtrueを返します。

107
sid_k_reddy

それを考える良い方法は….

prototypeconstructor()関数によって使用されます。それは本当に"prototypeToInstall"のような名前で呼ばれるべきです。

そして__proto__はオブジェクトの「インストールされたプロトタイプ」(それは前述のconstructor()関数からオブジェクト上に作成/インストールされたものです)

60
sarink

説明するには、関数を作成しましょう

 function a (name) {
  this.name = name;
 }

JavaScriptがこのコードを実行すると、prototypeプロパティがaに追加されます。prototypeプロパティは、2つのプロパティを持つオブジェクトです。

  1. constructor
  2. __proto__

そうするとき

a.prototypeが返す

     constructor: a  // function definition
    __proto__: Object

ご覧のとおり、constructorは関数a自体と__proto__がJavaScriptのルートレベルObjectを指しているだけです。

a関数をnewキーWordで使用するとどうなるかを見てみましょう。

var b = new a ('JavaScript');

JavaScriptがこのコードを実行すると、4つのことを行います。

  1. 新しいオブジェクト、空のオブジェクトを作成します// {}
  2. b__proto__を作成し、a.prototypeを指すようにするため、b.__proto__ === a.prototype
  3. コンテキスト[this]として新しく作成されたオブジェクト(ステップ#1で作成された)を使用してa.prototype.constructor(関数aの定義)を実行します。したがって、_JavaScriptとして渡されるnameプロパティ(thisに追加されます)新しく作成されたオブジェクトに追加されます。
  4. (ステップ#1で作成された)で新しく作成されたオブジェクトを返すので、var bが新しく作成されたオブジェクトに割り当てられます。

a.prototype.car = "BMW"を追加してb.carを実行すると、出力「BMW」が表示されます。

これは、JavaScriptがこのコードを実行したときにcarbプロパティを検索したときに、JavaScriptがb.__proto__(ステップ#2で 'a.prototype'を指すように作成された)を使用し、carプロパティを見つけることができなかったためです「BMW」を返します。

49
Manishz90

上記の優れた回答に加えて、もう少し明確にします。

function Person(name){
    this.name = name
 }; 

var eve = new Person("Eve");

eve.__proto__ == Person.prototype //true

eve.prototype  //undefined

インスタンス have __proto__ classes have prototype

26
serkan

JavaScriptでは、関数をコンストラクタとして使用できます。つまり、newキーワードを使用して、それらからオブジェクトを作成できます。すべてのコンストラクタ関数には、それらと連鎖した組み込みオブジェクトが付属しています。この組み込みオブジェクトはプロトタイプと呼ばれます。Instances of a constructor function use __proto__ to access the prototype property of its constructor function.

prototype diagram

  1. 最初にコンストラクタを作成しました:function Foo(){}。明確にするために、Fooは単なる別の機能です。しかし、newキーワードを使って、そこからオブジェクトを作ることができます。だから我々はそれをコンストラクタ関数と呼んでいます。

  2. すべての関数はプロトタイププロパティと呼ばれる固有のプロパティを持っています。そのため、コンストラクタ関数Fooはプロトタイプを指すプロトタイププロパティを持ちます。これはFoo.prototypeです(画像を参照)。

  3. コンストラクタ関数はそれ自体、[[Function]]コンストラクタと呼ばれるシステムコンストラクタのインスタンスである関数です。したがって、function Fooは[[Function]]コンストラクタによって構築されていると言えます。したがって、__proto__Foo functionは、そのコンストラクターのプロトタイプ(Function.prototype)を指すようになります。

  4. Function.prototype自体は[[Object]]と呼ばれる別のシステムコンストラクタから構築されたオブジェクトに他なりません。したがって、[[Object]]Function.prototypeのコンストラクタです。したがって、Function.prototype[[Object]]のインスタンスであると言えます。したがって、__proto__Function.prototypeObject.prototypeを指しています。

  5. Object.prototypeはプロトタイプチェーンの最後の人物です。私はそれが構築されていないことを意味します。それはすでにシステムにあります。そのため、その__proto__nullを指しています。

  6. 今、私たちはFooのインスタンスに来ます。 new Foo()を使ってインスタンスを作成すると、それはFooのインスタンスである新しいオブジェクトを作成します。つまり、Fooはこれらのインスタンスのコンストラクタです。ここでは2つのインスタンス(xとy)を作成しました。したがって、xとyの__proto__Foo.prototypeを指します。

8
AL-zami

私は偶然 You Don't Know JS:this&Object Prototypes からプロトタイプを学んでいます。継承とinstanceof)のようなもの。

しかし、私は人々がここで尋ねたのと同じ質問をしています。いくつかの答えは本当に役に立ち、啓発的です。私はまた私の理解を共有したいと思います。


プロトタイプとは何ですか?

JavaScriptのオブジェクトには内部仕様があり、これは仕様では[[Prototype]]として示されています。これは単に別のオブジェクトへの参照です。作成時には、ほとんどすべてのオブジェクトにこのプロパティの非null値が与えられています。

オブジェクトのプロトタイプを取得する方法

__proto__またはObject.getPrototypeOfを介して

var a = { name: "wendi" };
a.__proto__ === Object.prototype // true
Object.getPrototypeOf(a) === Object.prototype // true

function Foo() {};
var b = new Foo();
b.__proto__ === Foo.prototype
b.__proto__.__proto__ === Object.prototype

prototypeとは何ですか?

prototype function の特別なプロパティとして自動的に作成されたオブジェクトで、これは委任(継承)チェーン、別名プロトタイプチェーンを確立するために使用されます。

aという関数を作成すると、prototypeは自動的にaの特別なプロパティとして作成され、その関数コードはconstructorprototypeとして保存されます。

function Foo() {};
Foo.prototype // Object {constructor: function}
Foo.prototype.constructor === Foo // true

関数オブジェクトのプロパティ(メソッドを含む)を格納する場所としてこのプロパティを検討したいと思います。これが、JSのユーティリティ関数がArray.prototype.forEach()Function.prototype.bind()Object.prototype.toString().のように定義されている理由でもあります。

関数 の性質を強調する理由

{}.prototype // undefined;
(function(){}).prototype // Object {constructor: function}

// The example above shows object does not have the prototype property.
// But we have Object.prototype, which implies an interesting fact that
typeof Object === "function"
var obj = new Object();

したがって、AraryFunctionObjectはすべての関数です。これは私のJSに対する印象をリフレッシュすることを認めておくべきです。私は関数がJSの第一級の市民であることを知っていますが、それは関数の上に構築されているようです。

__proto__prototypeの違いは何ですか?

__proto__a参照は、すべての object に対して、その[[Prototype]]プロパティを参照するように機能します。

prototypeは、 function の特別なプロパティとして自動的に作成されたオブジェクトで、これは関数オブジェクトのプロパティ(メソッドを含む)を格納するために使用されます。

これら二つで、私たちは精神的にプロトタイプチェーンを描くことができました。この写真のように:

function Foo() {}
var b = new Foo();

b.__proto__ === Foo.prototype // true
Foo.__proto__ === Function.prototype // true
Function.prototype.__proto__ === Object.prototype // true
7
ifyouseewendy

それを理解するためのもう一つの良い方法:

var foo = {}

/* 
foo.constructor is Object, so foo.constructor.prototype is actually 
Object.prototype; Object.prototype in return is what foo.__proto__ links to. 
*/
console.log(foo.constructor.prototype === foo.__proto__);
// this proves what the above comment proclaims: Both statements evaluate to true.
console.log(foo.__proto__ === Object.prototype);
console.log(foo.constructor.prototype === Object.prototype);

IE11の__proto__がサポートされた後でのみ。 IE9のようなそのバージョンの前は、constructorを使って__proto__を取得することができました。

6
Yad Smood

簡単に言えば:

> var a = 1
undefined
> a.__proto__
[Number: 0]
> Number.prototype
[Number: 0]
> Number.prototype === a.__proto__
true

これにより、X型のオブジェクトがインスタンス化された後でもX.prototypeにプロパティをアタッチすることができます。これらのオブジェクトは、Javascriptエンジンがプロトタイプチェーンをたどるために使用する__proto__参照を通じて、これらの新しいプロパティにアクセスできます。

4

プロトタイプ

prototypeはFunctionのプロパティです。 new(キーワード)を付けてその(コンストラクター)関数を使用してオブジェクトを作成するための青写真です。

__proto__

__proto__は、メソッド、プロパティを解決するためにルックアップチェーンで使用されます。オブジェクトが作成されると(newキーワードを持つコンストラクタ関数を使用)、__proto__は(Constructor)Function.prototypeに設定されます。

function Robot(name) {
    this.name = name;
}
var robot = new Robot();

// the following are true   
robot.__proto__ == Robot.prototype
robot.__proto__.__proto__ == Object.prototype

混乱を解消するための私の(想像上の)説明は次のとおりです。

機能に関連する架空のクラス(青写真/クッキーカッター)があると想像してください。その架空のクラスは、オブジェクトをインスタンス化するために使用されます。 prototypeは、その架空のクラスに物事を追加するための拡張メカニズム(C#の拡張メソッド、またはSwift Extension)です。

function Robot(name) {
    this.name = name;
}

上記のように想像することができます:

// imaginary class
class Robot extends Object{

    static prototype = Robot.class  
    // Robot.prototype is the way to add things to Robot class
    // since Robot extends Object, therefore Robot.prototype.__proto__ == Object.prototype

    var __proto__;

    var name = "";

    // constructor
    function Robot(name) {

        this.__proto__ = prototype;
        prototype = undefined;

        this.name = name;
    }

} 

そう、

var robot = new Robot();

robot.__proto__ == Robot.prototype
robot.prototype == undefined
robot.__proto__.__proto__ == Object.prototype

Robotのprototypeにmethodを追加する:

Robot.prototype.move(x, y) = function(x, y){ Robot.position.x = x; Robot.position.y = y};
// Robot.prototype.move(x, y) ===(imagining)===> Robot.class.move(x, y)

上記はRobotクラスの拡張として想像することができます。

// Swift way of extention
extension Robot{
    function move(x, y){    
        Robot.position.x = x; Robot.position.y = y
    }
}

順番に、

// imaginary class
class Robot{

    static prototype = Robot.class // Robot.prototype way to extend Robot class
    var __proto__;

    var name = "";

    // constructor
    function Robot(name) {

        this.__proto__ = prototype;
        prototype = undefined;

        this.name = name;
    }

    // added by prototype (as like C# extension method)
    function move(x, y){ 
        Robot.position.x = x; Robot.position.y = y
    };
}
4
Hassan Tareq

私は知っている、私は遅れているが、それを単純化しようとしましょう。

関数があるとしましょう

    function Foo(message){

         this.message = message ; 
     };

     console.log(Foo.prototype);

Foo関数はプロトタイプオブジェクトをリンクさせます。つまり、JavaScriptで関数を作成するときはいつでも、それには常にプロトタイプオブジェクトがリンクされています。

それでは先に進み、関数Fooを使って2つのオブジェクトを作成しましょう。

    var a = new Foo("a");
    var b = new Foo("b");
    console.log(a.message);
    console.log(b.message);
  1. オブジェクトaとオブジェクトbの2つのオブジェクトがあります。どちらもコンストラクタFooを使って作成されます。覚えておいてくださいコンストラクタはここでは単なる言葉です。
  2. オブジェクトaとbの両方に、メッセージプロパティのコピーがあります。
  3. これら2つのオブジェクトaとbは、コンストラクタFooのプロトタイプオブジェクトにリンクされています。
  4. オブジェクトaとbでは、すべてのブラウザで proto propertyを使用してFooプロトタイプにアクセスでき、IEではObject.getPrototypeOf(a)またはObject.getPrototypeOf(b)を使用できます。

今、Foo.prototype、a. proto 、およびb. proto allは同じオブジェクトを表します。

    b.__proto__ === Object.getPrototypeOf(a);
    a.__proto__ ===  Foo.prototype;
    a.constructor.prototype  === a.__proto__;

上記のすべてがtrueを返します。

ご存知のとおり、JavaScriptではプロパティを動的に追加できます。オブジェクトにプロパティを追加することができます

    Foo.prototype.Greet = function(){

         console.log(this.message);
    }
    a.Greet();//a
    b.Greet();//b
    a.constructor.prototype.Greet();//undefined 

ご覧のとおり、Foo.prototypeにGreet()メソッドを追加しましたが、aとb、またはFooを使用して構築されたその他のオブジェクトでアクセスできます。

A.Greet()を実行している間、JavaScriptは最初にobject a onプロパティリストでGreetを検索します。見つからなかった場合、それは proto のaのチェーンに上がります。 . proto とFoo.prototypeは同じオブジェクトなので、JavaScriptはGreet()メソッドを見つけて実行します。

プロトタイプと proto が少し単純化されたことを願います。

3
debugmode

プロトタイプまたはObject.prototype は、オブジェクトリテラルのプロパティです。プロトタイプチェーンに沿ってさらにプロパティやメソッドを追加するためにオーバーライドできるObject prototypeオブジェクトを表します。

__proto__ は、アクセスされるオブジェクトの内部プロトタイプを公開するアクセサプロパティ(getおよびset関数)です。

参照:

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype
  2. http://www.w3schools.com/js/js_object_prototypes.asp

  3. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto

3
akodevs

概要:

オブジェクトの__proto__プロパティは、オブジェクトのコンストラクタ関数のprototypeにマップするプロパティです。言い換えると:

instance.__proto__ === constructor.prototype // true

これはオブジェクトのprototypeチェーンを形成するために使用されます。 prototypeチェーンは、オブジェクトのプロパティに対する検索メカニズムです。オブジェクトのプロパティにアクセスすると、JavaScriptはまずそのオブジェクト自体を調べます。その物件が見つからない場合は、見つかるまで(または見つからないまで)protochainまで登ります。

例:

function Person (name, city) {
  this.name = name;
}

Person.prototype.age = 25;

const willem = new Person('Willem');

console.log(willem.__proto__ === Person.prototype); // the __proto__ property on the instance refers to the prototype of the constructor

console.log(willem.age); // 25 doesn't find it at willem object but is present at prototype
console.log(willem.__proto__.age); // now we are directly accessing the prototype of the Person function 

最初のログはtrueになります。これは、前述のとおり、コンストラクタによって作成されたインスタンスの__proto__プロパティが、コンストラクタのprototypeプロパティを参照しているためです。 JavaScriptでは、関数もオブジェクトです。オブジェクトはプロパティを持つことができ、関数のデフォルトプロパティはprototypeという名前のプロパティです。

次に、この関数がコンストラクタ関数として利用されると、それからインスタンス化されたオブジェクトは__proto__というプロパティを受け取ります。そしてこの__proto__プロパティはコンストラクタ関数のprototypeプロパティを参照します(デフォルトではすべての関数が持っています)。

これはなぜ便利なのでしょうか。

JavaScriptは 'プロトタイプの継承' と呼ばれるObjectsのプロパティを検索するときのメカニズムを持っています、これが基本的にしていることです:

  • まず、プロパティがオブジェクト自体にあるかどうかをチェックします。そうであれば、このプロパティが返されます。
  • プロパティがオブジェクト自体に配置されていない場合は、「プロトチェーンを登る」ことになります。基本的には__proto__プロパティによって参照されるオブジェクトを調べます。そこで、プロパティが__proto__によって参照されるオブジェクトで利用可能かどうかをチェックします。
  • プロパティが__proto__オブジェクト上にない場合は、__proto__チェーンを上り、Objectオブジェクトまで続きます。
  • オブジェクトとそのprototypeチェーンのどこにもプロパティが見つからない場合は、undefinedを返します。

例えば:

function Person (name) {
  this.name = name;
}

let mySelf = new Person('Willem');

console.log(mySelf.__proto__ === Person.prototype);

console.log(mySelf.__proto__.__proto__ === Object.prototype);
2

定義

(()内の数字は、下記のコードへの「リンク」です)

prototype - 次のものからなるオブジェクト。
=>この特定のConstructorFunction.prototype(5)の、このコンストラクタを介して作成または作成される各オブジェクトからアクセス可能なfunctions(3)function(1)
=>コンストラクタ関数そのもの(1)
この特定のオブジェクトの => __proto__(プロトタイプオブジェクト)

__proto__(dandor proto?) - 特定のコンストラクタ関数(1)を通じて作成された任意のオブジェクト(2)と、その作成された各オブジェクト(2)のプロトタイプオブジェクトのプロパティ(5)とのリンクプロトタイプの関数とメソッドへのアクセス(4)(__proto__はデフォルトでJSのすべてのオブジェクトに含まれています)

コードの明確化

1。

    function Person (name, age) {
        this.name = name;
        this.age = age;  

    } 

2。

    var John = new Person(‘John’, 37);
    // John is an object

3。

    Person.prototype.getOlder = function() {
        this.age++;
    }
    // getOlder is a key that has a value of the function

4。

    John.getOlder();

5。

    Person.prototype;
2
Eduard

 JavaScript prototype vs __prototype__

'use strict'
function A() {}
var a = new A();
class B extends A {}
var b = new B();
console.log('====='); // =====
console.log(B.__proto__ === A); // true
console.log(B.prototype.__proto__ === A.prototype); // true
console.log(b.__proto__ === B.prototype); // true
console.log(a.__proto__ === A.prototype); // true
console.log(A.__proto__ === Function.__proto__); // true
console.log(Object.__proto__ === Function.__proto__); // true
console.log(Object.prototype === Function.__proto__.__proto__); // true
console.log(Object.prototype.__proto__ === null); // true

JavaScriptでは、すべてのオブジェクト(関数もオブジェクトです)に__proto__プロパティがあり、そのプロパティはそのプロトタイプへの参照です。

new演算子をコンストラクタと共に使用して新しいオブジェクトを作成すると、新しいオブジェクトの__proto__プロパティはコンストラクタのprototypeプロパティを使用して設定されます。その場合、コンストラクタは新しいオブジェクトによって呼び出されます。コンストラクタスコープ内の新しいオブジェクト、最後に新しいオブジェクトを返します。

コンストラクタのプロトタイプは__proto__プロパティであり、コンストラクタのprototypeプロパティはnew演算子で動作します。

コンストラクタは関数でなければなりませんが、たとえprototypeプロパティを持っていても、関数は必ずしもコンストラクタであるとは限りません。

プロトタイプチェーンは、実際には、そのプロトタイプを参照するためのオブジェクトの__proto__プロパティ、およびプロトタイプのプロトタイプを参照するためのプロトタイプの__proto__プロパティなどです。これは、Objectのプロトタイプのnullを参照する__proto__プロパティを参照するまでです。

例えば:

console.log(a.constructor === A); // true
// "a" don't have constructor,
// so it reference to A.prototype by its ``__proto__`` property,
// and found constructor is reference to A

[[Prototype]]__proto__プロパティは実際には同じものです。

ObjectのgetPrototypeOfメソッドを使って、何かのプロトタイプを取得することができます。

console.log(Object.getPrototypeOf(a) === a.__proto__); // true

私たちが書いたどんな関数でもnew演算子を使ってオブジェクトを作成するために使うことができるので、それらの関数のどれでもコンストラクタになることができます。

2
林奕忠

あなたが作成するすべての関数はprototypeと呼ばれるプロパティを持ち、それは空のオブジェクトとしての寿命から始まります。このプロパティは、この関数をコンストラクタ関数として、つまり 'new'キーワードを付けて使用するまで使用できません。

これは多くの場合、オブジェクトの__proto__プロパティと混同されます。ある人は混乱するかもしれませんし、オブジェクトのprototypeプロパティがそれらをオブジェクトの原型にするかもしれないことを除いて。しかし、そうではありません。 prototypeは、関数コンストラクタから作成されたオブジェクトの__proto__を取得するために使用されます。

上記の例では:

function Person(name){
    this.name = name
}; 

var eve = new Person("Eve");

console.log(eve.__proto__ == Person.prototype) // true
// this is exactly what prototype does, made Person.prototype equal to eve.__proto__

私はそれが理にかなっていると思います。

1
Malkeet Singh

説明的な例:

function Dog(){}
Dog.prototype.bark = "woof"

let myPuppie = new Dog()

現在、myPupppieにはDog.prototypeを指す__proto__プロパティがあります。

> myPuppie.__proto__
>> {bark: "woof", constructor: ƒ}

しかしmyPuppieはプロトタイププロパティを持っていません。

> myPuppie.prototype
>> undefined

そのため、mypuppieの__proto__は、このオブジェクトをインスタンス化するために使用されたコンストラクタ関数の.prototypeプロパティへのreferenceです(現在のmyPuppieオブジェクトは、この__proto__オブジェクトへの「委任先」関係を持ちます)。 myPuppieのプロパティは単に存在しません(設定していないため)。

ここMPJによる良い説明: proto vs prototype - JavaScriptでのオブジェクト作成

1
Nitin Jadhav

私は4年生の説明をしようと思います:

物事は非常に簡単です。 prototypeは、何かを構築する方法の例です。そう:

  • 私はfunctionであり、私はprototypeに似た新しいオブジェクトを構築します。

  • 私はobjectであり、私は私の__proto__を例として使用して構築されました

証明

function Foo() { }

var bar = new Foo()

// `bar` is constructed from how Foo knows to construct objects
bar.__proto__ === Foo.prototype // => true

// bar is an instance - it does not know how to create objects
bar.prototype // => undefined
1
vladCovaliov

__proto__prototypeとコンストラクタ関数を構築するためのベースです。例:function human(){}はコンストラクタ関数の新しいインスタンスの__proto__を介して共有されるprototypeを持ちます。もっと詳しく読む ここ

1
Jyoti Duhan

静的メソッドに__proto__を使うことについてはどうですか?

function Foo(name){
  this.name = name
  Foo.__proto__.collection.Push(this)
  Foo.__proto__.count++

}

Foo.__proto__.count=0
Foo.__proto__.collection=[]

var bar = new Foo('bar')
var baz = new Foo('baz')

Foo.count;//2
Foo.collection // [{...}, {...}]
bar.count // undefined
0
Barrard

this 正しく述べられているように

__proto__は、メソッドなどを解決するためにルックアップチェーンで使用される実際のオブジェクトです。prototypeは、newを使用してオブジェクトを作成するときに__proto__を構築するために使用されるオブジェクトです。

( new Foo ).__proto__ === Foo.prototype;
( new Foo ).prototype === undefined;

さらに、関数コンストラクタを使用して作成されたオブジェクトの__proto__プロパティは、それぞれのコンストラクタのprototypeプロパティが指すメモリ位置を指すことに注意できます。 。

コンストラクター関数のprototypeのメモリー位置を変更しても、派生オブジェクトの__proto__は引き続き元のアドレス空間を指し示します。したがって、共通のプロパティを継承チェーンで使用できるようにするには、プロパティを再初期化する(メモリアドレスを変更する)代わりに、常にコンストラクタ関数prototypeにプロパティを追加します)。

次の例を考えてみましょう。

function Human(){
    this.speed = 25;
}

var himansh = new Human();

Human.prototype.showSpeed = function(){
    return this.speed;
}

himansh.__proto__ === Human.prototype;  //true
himansh.showSpeed();    //25

//now re-initialzing the Human.prototype aka changing its memory location
Human.prototype = {lhs: 2, rhs:3}

//himansh.__proto__ will still continue to point towards the same original memory location. 

himansh.__proto__ === Human.prototype;  //false
himansh.showSpeed();    //25
0
Himansh
(function(){ 
      let a = function(){console.log(this.b)};
      a.prototype.b = 1;
      a.__proto__.b = 2;
      let q = new a();
      console.log(a.b);
      console.log(q.b) 
    })()

理解するためにこのコードを試してください

0
Timur