2
function dog(){
    this.barking = "woof";
    this.bark = function(){console.log(this.barking)}   
}

var tony = new dog();

var stark = {}; 
dog.call(stark);

tony.bark();// "woof"
stark.bark();// "woof"

console.log(tony.prototype == stark.prototype);// true
console.log(tony.__proto__ == stark.__proto__);// false

console.log(tony instanceof dog)//true
console.log(stark instanceof dog)//false

console.log(tony.constructor == stark.constructor);// false

console.log(tony.constructor.toString() == tony.constructor.toString());// true

What is the difference causing those results ?

Why do Tony and Stark have the same prototype but not the same proto and constructor ? (I guess instanceof results are different because of _ proto __ )

Detailed answers are very welcome

Rayjax
  • 7,494
  • 11
  • 56
  • 82

2 Answers2

2

What is the difference causing those results?

Understand how new works. In your case new dog() is almost equivalent to dog.call(Object.create(dog.prototype)).

Why do Tony and Stark have the same prototype

Actually neither of them have a .prototype. You're getting true because undefined == undefined. Only the dog constructor has a .prototype.

but not the same proto and constructor? (I guess instanceof results are different because of __proto__)

The constructor is inherited from the prototype, and that one is different.

It is different because of the different ways they were constructed - one using new inherits from dog.prototype, while the other using an object literal {} inherits from Object.prototype.

See also __proto__ VS. prototype in JavaScript.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

The new keyword uses a ECMAScript function called [[Construct]]. Let's step through what [[Construct]] does in ECMAScript 5 with a constructor function called F:

1) Let obj be a newly created native ECMAScript object.

2) Set all the internal methods of obj as specified in 8.12.

3) Set the [[Class]] internal property of obj to "Object".

4) Set the [[Extensible]] internal property of obj to true.

Okay, so far we've just set up a plain object, called obj. We will eventually use obj as the constructor function's this value, when we get around to invoking the constructor F.

5) Let proto be the value of calling the [[Get]] internal property of F with argument "prototype".

6) If Type(proto) is Object, set the [[Prototype]] internal property of obj to proto. ...

8) Let result be the result of calling the [[Call]] internal property of F, providing obj as the this value...

Here is where the magic happens: when we call new F(), the new object we use for this has its internal [[Prototype]] property (accessible with __proto__) set to F.prototype.

This special step does not happen with F.call(someObj), because in that case, the this value of the F call is supplied by call, not by the JavaScript engine going through the [[Construct]] steps. Thus, the object passed into the F.call has the same prototype chain before and after the call.

apsillers
  • 112,806
  • 17
  • 235
  • 239