TL:DR
__proto__ is a legacy feature that should generally be avoided MDN
What is __proto__
Simply put, __proto__ is just a propertyKey. And that's really all that you should see it as, because while there is a common behaviour among most builtin objects, It is by no means something that has to (or even should) behave in any specific manner.
Look at it as a regular getter/setter-pair
we can easily make any key behave in the same manner as __proto__:
const provingAPoint = {
  get thisIsANormalKey () { return Reflect.getPrototypeOf(this) },
  set thisIsANormalKey (proto) { Reflect.setPrototypeOf(this, proto) }
}
And that's basically all that __proto__ really is.
Always expect an object to differ from the default __proto__ behaviour
If you are recieving an object from some API you should not expect __proto__ to behave like it does in a default object. looking at the above example, it becomes clearer that it's not a reliable thing. We could for example do this:
Reflect.defineProperty(provingAPoint, '__proto__', {
  get: () => { throw new Error('you are not getting my prototype like this') },
  set: () => { throw new Error('you will not set my prototype like this') }
})
Now if someone tries to access this property, they will get an error. it's now also readonly and can't be changed or deleted.
Use the proper methods instead
The global objects Object and Reflect both have the static methods getPrototypeOf and setPrototypeOf (not going to go into detail about Reflect and it's differences). If you're going to manipulate the prototype chain, use these
The single valid use for __proto__ in todays Java/EcmaScript
There is one valid use that's suprisingly not well known. When you create an object literal, if you define a __proto__ property on it, if it's value is an object or null, the resulting object will use that value as it's prototype
// this can save you some of the annoyances of `Object.create(null, {...descriptors})`
const objectWithNullPrototype = {
  __proto__: null,
  propA: 'valueA',
  prop0: 'value0'
}
Object.getPrototypeOf(objectWithNullPrototype) // => `null`
// and again, don't extect any consistent behaviour of `__proto__` because:
objectWithNullPrototype.__proto__ // => `undefined`
About prototype
The prototype property on a function defines what the is inherited when constructing an object
In short
A constructors prototype property is equal to the prototype of the object it constructs. eg:
Object.getPrototypeOf(new Array(12)) === Array.prototype // => true
// NOTE: don't do this, use literals or `Object.create`
Object.getPrototypeOf(new Object()) === Object.prototype // => true
Object.getPrototypeOf(new Map()) === Map.prototype // => true
Java/EcmaScript is a prototype-based language
If you have any doubts on what this means, i highly recomend you google and read some articles about it, as misunderstanding (or not knowing) of the implications is a very common source of errors and confusion.