Disclaimer: I am not entirely sure about this answer.
__proto__ refers to the object that is being constructed (it's part of the constructor).
[[Prototype]] is the object that is meant to prototype the current object.
[[Prototype]] refers to the internal prototype that every object is created with. It is not accessible, for example
o.prototype.b
returns undefined.
The deprecated __proto__ is initially uncalled, and, when it is called, fills up with the values of [[Prototype]], hence the duplication. So,
o.__proto__.b
returns 3.
The preferred access method is to use the getPrototypeOf() static method of Object.
Object.getPrototypeOf(o).b
returns 3.