I'm looking at this from memory position angle. Because F's prototype points to the same memory position as P's prototype and because prototype is an object and objects get passed around by reference so they reference same memory position during assignment.
p proto (memory position 001)
F.prototype = P.prototype;
F proto (memory position 001)
C.prototype = new F();
C proto (memory position 001)
So if interpreter can't find property in C's proto, it looks up parent object F and checks if it has the proto property and if it doesn't, then it searches P. Hence, C can inherit from P.
But when you change C, and if C points to memory position 001, how can P not be affected, if P itself points to memory position 001?
You mentioned it's like C.prototype.prototype = P.prototype;
I don't see how the language interprets that prototype property has a property called prototype when it's not outright declared. All C's prototype does is point to an object, which has its own prototype.
I've been stuck on understanding this for a week. Someone please explain why my memory position argument fails (despite the fact that objects passed by reference) and how one of the answers said that behind scenes a new prototype object is creared on C's prototype without ever being declared as an object. In reality, it's just a reference to an object.