Si tengo la siguiente función constructora;
function Person(age) { this.age = age; this.talk = function() { return “talking”; }; }Y creo un objeto.
me = new Person();ahora aquí es donde se vuelve confuso. El objeto prototipo dentro de "Objeto" (el Objeto base, lo referiré con una O mayúscula) debe estar vacío, como nulo. Pero no lo es.
El objeto "yo" hereda de la función constructora "persona" y la función constructora "persona" hereda de la función constructora "Objeto", pero el prototipo dentro de la función constructora "Objeto" debe apuntar a Nulo.
En cambio, si hago clic en él. Muestra que el prototipo dentro de la función Objeto nuevamente hereda de Persona (no tiene sentido) y luego el Prototipo de Objeto dentro que hereda de "Objeto" nuevamente y el interior que nuevamente hereda de "Objeto" y el objeto prototipo dentro de él , es el que tiene nulo.
Entonces, ¿cómo funciona esto realmente? ¿Qué me estoy perdiendo? ¿Por qué apunta hacia adelante y hacia atrás? 
La consola del navegador le permite ver el prototipo de un objeto en [[Prototype]] porque esa es la sintaxis utilizada en la especificación ECMAScript para referirse a los datos internos de los objetos a los que no se puede acceder como propiedades.
Históricamente, los navegadores comenzaron a exponer este valor interno bajo la propiedad no estándar __proto__ . Ahora que se Object.getPrototypeOf y Object.setPrototypeOf al lenguaje, __proto__ se considera obsoleto y no debe usarse.
De hecho, la cadena de prototipos sigue sus expectativas:
Object.getPrototypeOf(me) === Person.prototype; // true Object.getPrototypeOf(Person.prototype) === Object.prototype; // true Object.getPrototypeOf(Object.prototype) === null; // true Lo que te confundió es que __proto__ es una propiedad de acceso definida en Object.prototype . Las propiedades de acceso llaman implícitamente a las funciones getter/setter, y estas funciones pueden calcular su resultado en función del objeto al que se aplican.
Si __proto__ no existiera en los navegadores, podríamos implementarlo con el siguiente código:
Object.defineProperty(Object.prototype, "__proto__", { configurable: true, enumerable: false, get() { return Object.getPrototypeOf(this); }, set(value) { Object.setPrototypeOf(this, value); }, }); Cuando me.__proto__ , el motor JS sube por la cadena de prototipos hasta que encuentra la función getter __proto__ definida en Object.prototype , pero luego implícitamente llama a esa función me como su argumento this , por lo tanto, devuelve el protoptye de me .
Cuando ingresa a la consola del navegador y me despliega, luego [[Prototype]] , luego [[Prototype]] donde puede encontrar __proto__ , está haciendo manualmente lo que hace el motor JS para buscar propiedades en la cadena de prototipos. Lo que es un poco contradictorio es que el valor que se muestra dentro __proto__ será me prototipo, a pesar de que se muestra más abajo en el árbol. Esto se debe a que this argumento no cambia a medida que despliega las entradas [[Prototype]] en el depurador.