1

I am not getting this into my head properly. I have seen a question which is related to it, but could not quite get anything out of it.

function Shane(){}
var sha = new Shane();
console.log(sha.__proto.__.__proto.__.__proto.__) //null
console.log(sha.constructor.prototype.constructor.prototype.
                                         constructor.prototype) 
                   //Shane [Can anyone explain me what5 is happening here]
  1. Is constructor.prototype != .__proto.__?
  2. Why do we have two ways to know the prototype chain?
Shane
  • 5,517
  • 15
  • 49
  • 79
  • `sha.__proto__ === Shane.prototype` but `Shane.prototype !== Shane.constructor.prototype` thus .. (Start from there; also as shown that will throw a TypeError - undefined - exception.) – user2864740 Feb 17 '15 at 22:24
  • 1
    @user2864740 wanted to say: `sha.__proto__ === Shane.prototype` but `Shane.prototype.__proto__ !== Shane.prototype.constructor.prototype`! – Bergi Feb 17 '15 at 23:31
  • @Bergi That's not a duplicate. The question is actually about the constructor of the prototype. – freakish Feb 17 '15 at 23:40
  • Ah, maybe better [How does `__proto__` differ from `constructor.prototype`?](http://stackoverflow.com/q/650764/1048572) @freakish. It's linked from the top comment there anyway… – Bergi Feb 17 '15 at 23:47

2 Answers2

1

__proto__ is the actual object used in the lookup chain to resolve methods.

prototype is the object used to create __proto__ with new.

Also, you have a typo, it should be .__proto__ not .__proto.__

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor

Tui Popenoe
  • 2,098
  • 2
  • 23
  • 44
0

What really answers the question is that if

var fn = function() { ... };
var obj = new fn();

then

obj.__proto__ === fn.prototype

however

fn.prototype.constructor == fn

if fn has no preset prototype (i.e. the initial value). This is according to the specification:

http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.4

So what you are observing is that there are objects such that

obj.__proto__ !== obj.constructor.prototype

Very subtle differnce from the equality far far above. :)

As for the second question: historical reasons + bad design.

freakish
  • 54,167
  • 9
  • 132
  • 169
  • 1
    Well, apparently the second is not a valid way to access the prototype chain so I'd argue that we only have one? – Bergi Feb 17 '15 at 23:33
  • @Bergi What do you mean by "not a valid way"? If it is supported by all js engines (actually I don't know that) then I don't see anything wrong with it. Plus the observation above proves that you can't get to the higher level prototypes via `.constructor.prototype` which means that it actually is the correct way. – freakish Feb 17 '15 at 23:36
  • 1
    Yes, you can't get to "higher level prototypes", i.e. you *fail to access the chain* - it's not a valid way to do what you wanted. I don't know how that would be "correct". – Bergi Feb 17 '15 at 23:41
  • @Bergi Dude, the words "correct" or "valid" are your personal opinions really. If I can do it then it is valid for me. – freakish Feb 17 '15 at 23:42
  • Well, but you said yourself that you cannot so I wondered about that :-) – Bergi Feb 17 '15 at 23:46
  • @Bergi I said you cannot via `.constructor.prototype`. And that is an argument for me to treat it worse. I'm sorry, you've misunderstood me, I meant that `.__proto__` is the correct way IMHO. – freakish Feb 17 '15 at 23:46
  • Yes, `.constructor.prototype` is worse ("not valid", "not correct" :-) and should be neglected in favour of `Object.getPrototypeOf` (or `.__proto__` if you must). Sorry for the confusion – Bergi Feb 17 '15 at 23:50
  • @Bergi Oh, ok, then I've misunderstood you. :) I thought that by "second" you mean `.__proto__`. – freakish Feb 17 '15 at 23:51