proto VS. prototype в JavaScript


этот рисунок снова показывает, что каждый объект имеет прототип. Конструктор функция Foo также имеет свой собственный __proto__, который является функцией.прототип, и который в свою очередь также ссылается через его __proto__ собственность снова объект.прототип. Таким образом, повторяю, Фу.прототип-это просто явный свойство Foo, которое относится к прототипу объектов b и c.

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

в чем разница между __proto__ и prototype недвижимость?

цифра взята из здесь.

25 615

25 ответов:

__proto__ - это фактический объект, который используется в цепочке поиска для разрешения методов и т. д. prototype - это объект, который используется для построения __proto__ при создании объекта с new:

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

prototype - свойство объекта функции. Это прототип объектов, построенных с помощью этой функции.

__proto__ - внутреннее свойство объекта, указывающее на его прототип. Текущие стандарты обеспечивают эквивалент Object.getPrototypeOf(O) метод, хотя де-факто стандарт __proto__ быстрее.

вы можете найти instanceof отношения путем сравнения функции prototype для объекта __proto__ цепь, и вы можете разорвать эти отношения, изменив 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 является функцией конструктора, он строит объект (структуру данных) процедурно. myPoint объект построен Point() так Point.prototype сохраняется в myPoint.__proto__ в то время.

свойство Prototype создается при объявлении функции.

например:

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

человек.свойство prototype создается внутренне после объявления функции выше. Многие свойства могут быть добавлены к лицу.прототипа, которые являются общими экземплярами человек создан с использованием нового человека().

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

стоит отметить, что Person.prototype это Object литерал по умолчанию (может быть изменен по мере необходимости).

каждый экземпляр созданный с помощью new Person () имеет __proto__ свойство, которое указывает на человека.прототип. Это цепочка, которая используется для обхода, чтобы найти свойство конкретного объекта.

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

создает 2 экземпляра Person, эти 2 объекта могут вызывать свойство age человека.прототип как человека 1.возраст, персона2.возраст.

на приведенном выше рисунке вы можете видеть, что Foo является объектом функции и поэтому он имеет __proto__ ссылка на функцию.прототип, который в свою очередь является экземпляром объекта и имеет __proto__ ссылка на объект.прототип. Прото ссылка заканчивается здесь с __proto__ в объекте.прототип указывает на null.

любой объект может иметь доступ ко всем свойствам в своей прото-цепочке, связанной __proto__, тем самым образуя основу для прототипного наследования.

__proto__ не является стандартным способом доступа к цепочке прототипов, стандартный, но аналогичный подход заключается в использовании объекта.getPrototypeOf (obj).

ниже код instanceof оператор дает лучшее понимание:

объект instanceof оператор класса возвращает true если объект является экземпляром класса, более конкретно, если Class.prototype находится в цепи прото этого объекта, то объект является экземпляром этого класса.

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), которые возвращают true, если объект является экземпляром класса.

хороший способ думать об этом...

prototype используется constructor() функции. Это должно было действительно называться что-то вроде, "prototypeToInstall", так как это то, что есть.

и __proto__ это "установленный прототип" на объекте (который был создан/установлен на объекте из указанного

прототип против. свойство __proto__ против. [[Прототип]]

при создании функции объект свойства называется прототип создается автоматически (вы не создали его самостоятельно) и прикрепляется к объекту функции (constructor).
Примечание новая прототип объект также указывает или имеет внутреннюю частную ссылку на собственный JavaScript Объект.

пример:

function Foo () {
    this.name = 'John Doe';
}

// Foo has an object property called prototype.
// prototype was created automatically when we declared the function Foo.
Foo.hasOwnProperty('prototype'); // true

// Now, we can assign properties and methods to it:
Foo.prototype.myName = function () {
    return 'My name is ' + this.name;
}

если вы создадите новый объект из Foo С помощью new сайта, вы в основном создаете (среди прочего) новый объект, который имеет внутренняя или частная ссылка к прототипу функции Foo мы обсуждали ранее:

var b = new Foo();

b.[[Prototype]] === Foo.prototype  // true


Элемент частная связь с объектом этой функции называется прототип двойных скобок или просто [[Prototype]]. Многие браузеры предоставление нам общественные связь с ним, что называется __proto__!

чтобы быть более конкретным, __proto__ на самом деле функции добытчика которые принадлежат к собственному объекту JavaScript. Он возвращает внутреннюю частную связь прототипа независимо от this binding is (возвращает [[Prototype]] на b):

b.__proto__ === Foo.prototype // true

стоит отметить, что начало ECMAScript5, вы также можете использовать getPrototypeOf метод для получения внутреннего частного связь:

Object.getPrototypeOf(b) === b.__proto__ // true


Примечание: этот ответ не намерен охватить весь процесс создания новых объектов или новых конструкторов, но поможет лучше понять, что такое __proto__,prototype и [[Prototype]] и как это работает.

чтобы объяснить, давайте создадим функцию

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

когда JavaScript выполняет этот код, он добавляет prototype свойство a,prototype собственность-это объект с двумя свойствами это:

  1. constructor
  2. __proto__

поэтому, когда мы делаем

a.prototype возвращает

     constructor: a  // function definition
    __proto__: Object

теперь, как вы можете видеть constructor это не что иное, как функция и __proto__ указывает на корневой уровень Object в JavaScript.

давайте посмотрим, что происходит, когда мы используем

чтобы сделать его немного ясным в дополнение к выше большим ответам:

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

var eve = new Person("Eve");

eve.__proto__ == Person.prototype //true

eve.prototype  //undefined

экземпляров есть _ _ proto__,классы есть прототип.

еще один хороший способ понять это:

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__.

я случайно учусь прототип от вы не знаете JS: this & Object Prototypes, что является прекрасной книгой, чтобы понять дизайн под ним и прояснить так много заблуждений (вот почему я пытаюсь избежать использования наследования и таких вещей, как instanceof).

но у меня есть тот же вопрос, что и люди, заданные здесь. Несколько ответов действительно полезны и поучительны. Я также хотел бы поделиться своим пониманием.


что такое a прототип?

объекты в 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 - это объект, автоматически созданный как специальное свойство а функции, который используется для создания цепочки делегирования (наследования), ака прототип цепи.

когда мы создаем функцию a,prototype автоматически создается как специальное свойство на a и сохраняет код функции в качестве constructor on prototype.

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

я хотел бы рассмотреть это свойство как место для хранения свойств (включая методы) объекта функции. Это также причина, почему служебные функции в JS определяются как Array.prototype.forEach(),Function.prototype.bind(),Object.prototype.toString().

зачем подчеркивать свойство a функции?

{}.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();

и Arary,Function,Objectвсе функции. Я должен признать, что это освежает мое впечатление на JS. Я знаю, что функции являются первоклассными гражданами в JS, но кажется, что он построен на функциях.

в чем разница между __proto__ и prototype?

__proto__ссылка работает на всех объект ссылаться на его [[Prototype]]собственность.

prototype - это объект, автоматически созданный как специальное свойство функции, который используется для хранения свойств (включая методы) объекта функции.

С этими двумя, мы могли бы мысленно наметить цепочку прототипов. Как это изображение иллюстрирует:

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

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

в JavaScript функция может использоваться в качестве конструктора. Это означает, что мы можем создавать объекты из них, используя новое ключевое слово. Каждая функция конструктора поставляется со встроенным объектом, связанным с ними. Этот встроенный объект называется прототипом. Instances of a constructor function use __proto__ to access the prototype property of its constructor function.

prototype diagram

  1. Сначала мы создали конструктор: function Foo(){}. Чтобы быть ясным, Foo - это просто еще одна функция. Но мы можем создать объект из него с помощью новое ключевое слово. Вот почему мы называем его функцией конструктора

  2. каждая функция имеет уникальное свойство, которое называется свойство prototype. Итак, функция конструктора Foo имеет свойство prototype, которое указывает на его прототип, который Foo.prototype (см. рисунок).

  3. функции конструктора сами по себе являются функцией, которая является экземпляром системного конструктора, называемого конструктором [[Function]]. Так что можно сказать, что function Foo is построенный конструктором [[функция]]. Итак,__proto__ наших Foo function укажет на прототип своего конструктора, который является Function.prototype.

  4. Function.prototype сам по себе это не что иное, как объект, который построен из другого системного конструктора под названием [[Object]]. Итак,[[Object]] - это конструктор Function.prototype. Так что, можно сказать Function.prototype пример [[Object]]. Так что __proto__ на Function.prototype указывает на Object.prototype.

  5. Object.prototype последний человек стоя в цепи прототипа. Я имею в виду, что он не был построен. Это уже есть в системе. Так что его __proto__ указывает на null.

  6. теперь мы подходим к примерам Foo. Когда мы создаем экземпляр с помощью new Foo(), он создает новый объект, который является экземпляром Foo. Это значит Foo является конструктором этих экземпляров. Здесь мы создали два экземпляра (X и y). __proto__ из x и y таким образом указывает на Foo.prototype.

проще говоря:

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

Это позволяет присоединить свойства к X. Прототип после создания объектов типа X, и они все равно получат доступ к этим новым свойствам через ссылку __proto__, которую Javascript-движок использует для перехода по цепочке прототипов.

прототип

прототип-это свойство функции. Это схема элементов для создания объектов с помощью этой функции (конструктор) с новым ключевым словом.

_ _ proto__

__proto__ используется в цепочке поиска для разрешения методов, свойств. при создании объекта (с помощью функции конструктора с новым ключевым словом), __proto__ имеет значение (конструктор) функция.прототип

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

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

вот мое (воображаемое) объяснение, чтобы очистить замешательство:

представьте, что существует воображаемый класс (чертеж/coockie cutter), связанный с функцией. Этот воображаемый класс используется для создания объектов. 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

добавляем метод prototype робот:

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)

вышесказанное можно представить как расширение класса роботов:

// 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
    };
}

прототип или объект.прототип свойство литерала объекта. Он представляет собой объект объект прототипа, который можно переопределить, чтобы добавить дополнительные свойства или методы далее по цепочке прототипов.

_ _ 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

Я знаю, я опаздываю, но позвольте мне попытаться упростить его.

допустим есть функция

    function Foo(message){

         this.message = message ; 
     };

     console.log(Foo.prototype);

функция Foo будет иметь Связанный объект прототипа. Таким образом, всякий раз, когда мы создаем функцию в JavaScript, она всегда имеет прототип объекта, связанного с ней.

теперь давайте продолжим и создадим два объекта с помощью функции Foo.

    var a = new Foo("a");
    var b = new Foo("b");
    console.log(a.message);
    console.log(b.message);
  1. теперь у нас есть два объекта, объект a и объект b. оба созданы использование конструктора Foo. Держать в виду конструктор-это просто слово здесь.
  2. объект a и b оба имеют копию свойства сообщения.
  3. эти два объекта a и b связаны с прототипом объекта конструктора Foo.
  4. на объектах a и b мы можем получить доступ к прототипу Foo с помощью прото свойство во всех браузерах и в IE мы можем использовать объект.getPrototypeOf (a) или объект.getPrototypeOf (b)

Теперь, Фу.прототип,.прото, и б.прото все обозначает один и тот же объект.

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

все вышеперечисленное вернет истину.

как известно, в JavaScript свойства можно добавлять динамически. Мы можем добавить свойство к объекту

    Foo.prototype.Greet = function(){

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

как вы видите, мы добавили метод Greet () в Foo.прототип, но он доступен в a и b или любом другом объекте, который построен с использованием Foo.

во время выполнения.Приветствую(), JavaScript будет первый поиск приветствуют в объект на собственность список. На не находя, он будет идти вверх в прото цепь А. С а.прото и Foo.прототип-это тот же объект, JavaScript найдет метод Greet() и выполнит его.

надеюсь, теперь прототип и прото немного упрощен.

определения

(число в скобках () - это ссылка на код, который написан ниже)

prototype - объект, который состоит из:
=> функции (3) настоящего особенно ConstructorFunction.prototype(5), которые доступны каждому объект (4) создан или будет создан с помощью этой функции конструктора (1)
=> функции-конструктора (1)
= > __proto__ этого конкретного объекта (прототип объект)

__proto__ (дандор прото?)- связь между любым объектом (2), созданным с помощью определенной функции конструктора (1), и свойствами объекта-прототипа (5) этого конструктора, которая позволяет каждому созданному объекту (2) иметь доступ к функциям и методам прототипа (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;

Я попробую объяснение 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

каждая создаваемая функция имеет свойство 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__

Я надеюсь, что это имеет смысл.

(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) 
    })()

попробуйте этот код, чтобы понять

__proto__ является основой для построения prototype и функция конструктора например: function human(){} и prototype общий через __proto__ в новом экземпляре функции конструктора. А более подробно читайте здесь

 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__ собственности, свойство-это работа с new оператора.

конструктор должен быть функцией, но функция не всегда является конструктором, даже если она имеет prototype собственность.

прототип цепи на самом деле является объектом __proto__ свойство ссылаться на его прототип, и прототип __proto__ свойство ссылаться на прототип прототипа, и так на, пока не ссылаться на прототип объекта __proto__ свойство, которое является ссылкой на значение null.

например:

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__ свойство на самом деле то же самое.

мы можем использовать метод getPrototypeOf объекта, чтобы получить прототип чего-то.

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

любая функция, которую мы написали, Может быть использована для создания объекта с помощью new оператор, таким образом, любая из этих функций может быть конструктором.

резюме:

The __proto__ свойство объекта-это свойство, которое сопоставляется с prototype функции-конструктора объекта. Другими словами:

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

это используется для формирования prototype цепочка объекта. Элемент prototype chain-это механизм поиска свойств объекта. Если свойство объекта доступно 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, которая называется 'прототипным наследованием', вот что в основном тут:

  • первый проверяется, находится ли свойство на самом объекте. Если да, то это свойство возвращается.
  • если свойство не находится на самом объекте, он будет "подниматься вверх по protochain". Это в основном смотрит на объект, на который ссылается __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);

The прото свойство-это простое свойство доступа к объекту.прототип, состоящий из функции геттера и сеттера. Доступ к свойству для прото что в конечном итоге консультирует объекта.прототип найдет это свойство,но доступ, который не консультируется с объектом.прототип его не найдет. Если какой-то другой прото свойство находится перед объектом.прототип консультируется, что свойство скроет найденное на объекте.прототип.

в прото функция getter предоставляет значение внутреннего [[прототипа]] объекта. Для объектов, созданных с помощью литерала объекта, значение объекта.прототип. Объекты, созданные с помощью литералов массива, значение массива.прототип. Для функций это значение является функцией.прототип. Для объектов, созданных с помощью new fun, где fun - это одна из встроенных функций конструктора, предоставляемых JavaScript (массив, логическое значение, дата, число, объект, строка и т. д.-включая новые конструкторы добавлено по мере развития JavaScript), это значение всегда весело.прототип. Для объектов, созданных с помощью new fun, где fun-это функция, определенная в скрипте, это значение является значением fun.прототип. (То есть, если конструктор не вернул другой объект явно, или весело.прототип был переназначен с момента создания экземпляра).

The прото сеттер позволяет [[прототип]] объекта быть мутированным. Объект должен быть расширяемым в соответствии с Объект.isExtensible(): если это не так, будет выброшено исключение TypeError. Указанное значение должно быть объектом или значением null. Предоставление любого другого значения ничего не сделает.

чтобы понять, как прототипы используются для наследования, см. статью руководство наследование и цепочка прототипов.

Как насчет использования __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

мое понимание таково: _ _ proto__ и prototype все служат для прототипа цепной техники . разница заключается в том, что функции, названные с подчеркиванием (например, __proto__), вообще не предназначены для разработчиков, вызываемых явно. другими словами, они предназначены только для некоторых механизмов, таких как наследование и т. д. они являются "бэк-энд". но функции, названные без подчеркивания, предназначены для явного вызова, они являются "интерфейсными".

!!!ЭТО ЛУЧШЕЕ ОБЪЯСНЕНИЕ В МИРЕ!!!!!

var q = {}
var prototype = {prop: 11}

q.prop // undefined
q.__proto__ = prototype
q.prop // 11

в конструкторах функций javascript engine вызовите это q.__proto__ = prototype автоматически, когда мы пишем new Class и в __proto__ prop set Class.prototype

function Class(){}
Class.prototype = {prop: 999} // set prototype as we need, before call new

var q = new Class() // q.__proto__ = Class.prototype
q.prop // 999

наслаждайтесь %)