2

in this case

var A = function(){
    this.d = 123;
}
A.prototype.c = 999;
A.prototype.d = 333;
var B = (new A()).constructor;

console.log(""+B);

console.log(new A().d); // 123
console.log(new B().d); // 123
console.log(new A().c); // 999
console.log(Object.getPrototypeOf(new B()).c); // 999 why?

A and B share same constructor but B is not A, why has same prototype of A?

in this case

var A = function(){
    this.d = 123;
}
A.prototype.c = 999;
A.prototype.d = 333;
var B = A.constructor;

console.log(""+B);

console.log(new A().d); // 123
console.log(new B().d); // undefined
console.log(B.d); // still undefined
console.log(new A().c); // 999
console.log(Object.getPrototypeOf(new B()).c); // undefined

B is constructor of A and not of his instance

what is B? how to access constructor of A with no instance of A?

Matteo Rubini
  • 831
  • 5
  • 9
  • Related [Is JavaScript a pass-by-reference or pass-by-value language?](http://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language) – Liam Mar 18 '15 at 11:32
  • if B is constructor of A, why the last line? c is property of A.prototype and not of constructor or.. what? – Matteo Rubini Mar 18 '15 at 11:35
  • 1
    @Liam sorry, i can't get it, how this solution solves my answers? – Matteo Rubini Mar 18 '15 at 11:37
  • 1
    I've retracted my close vote. It explains the first example but not the second – Liam Mar 18 '15 at 11:38
  • This is likely useful here [Object.prototype.constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor) – Liam Mar 18 '15 at 11:47

3 Answers3

4

When you call new A(), you create a new A object whose prototype is A.prototype. When you ask for (new A()).constructor, you're accessing the constructor property from the prototype chain of that A instance; this would be A.prototype.constructor.

A itself is a Function object. That is to say: A is an instance of Function. When you ask for A.constructor, you're accessing the constructor property from the prototype chain of that Function instance; this would be Function.prototype.constructor.

In your first case, B and A are references to the exact same function. It's totally expected that the results of new A() and new B() would have the same properties and the same prototype chain.

In your second example, B is the Function constructor -- i.e., a function that constructs functions. Calling new B() creates a new Function object. Thus, the result of new B() has none of the same properties as an A instance.

apsillers
  • 112,806
  • 17
  • 235
  • 239
  • Good answer, explains it well. – Liam Mar 18 '15 at 11:46
  • so, if you set B = A.constructor you are cloning A? – Matteo Rubini Mar 18 '15 at 11:52
  • 2
    @MatteoRubini `A` is an instance of `Function`, so `A.constructor` is the `Function` constructor (just like how `new A()` is an instance of `A`, so `(new A().constructor` is the `A` constructor). When you do `B=A.constructor` you're storing the `Function` constructor in `B`. If you ask for the `constructor` property of any function, you'll get the `Function` constructor (e.g., try `(function(){}).constructor`). – apsillers Mar 18 '15 at 11:58
2

To tell the difference you might want to look at what is A and what is new A():

c = new A(); // This is an instance of A. The constructor property is A.
console.log(c.constructor) // function() { this.d = 123; }
console.log(new c.constructor()) // Creates another instance of A.
console.log(Object.getPrototypeOf(new c.constructor())) // A {c: 999, d: 333}

var c = A; // This is a function. The constructor property is a base Function.
console.log(c.constructor) // function Function() { [native code] }
console.log(new c.constructor()) // Creates instance of base Function.
console.log(Object.getPrototypeOf(new c.constructor())) // function Empty() {}

Without the new operator on your custom constructor (A) you are not creating an instance of A.

More information on new operator: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new

Artyom Neustroev
  • 8,627
  • 5
  • 33
  • 57
0

Even though it's already answered, I did not see it made clear that B is A (oops, its late missed apsillers mentioned it):

var A = function(){};
var B = (new A()).constructor;
console.log(B===A,B===A.prototype.constructor
  ,A.prototype.constructor ===A);//true true true
//Something.prototype.constructor is a circular reference as constructor
//references Something
console.log(A.prototype.constructor.prototype.constructor.prototype
  .constructor.prototype.constructor === A);//true

Constructor comes with prototype and is set to the constructor function but you can overwrite it (usually done when inheriting so you usually see it repaired after inheriting)

Child.prototype=Parent.prototype;
//Child.prototype.constructor now incorrectly refers to Parent
console.log(Child.prototype.constructor===Parent);//true
//repair constructor
Child.prototype.constructor=Child;

More on inheritance, constructor functions and prototype here.

Since all objects have a prototype (unless created with Object.create(null)) all objects have a constructor property pointing to the function that created them:

console.log([].constructor===Array);
var arr = new [].constructor(1,2,3);//same as new Array(1,2,3)
console.log(arr);//[1,2,3]
//the following temporarily casts the string to String
console.log("hello".constructor===String);//true
//same with numbers
console.log(1..constructor===Number);//true
console.log(function(){}.constructor === Function);//true
Community
  • 1
  • 1
HMR
  • 37,593
  • 24
  • 91
  • 160
  • and why B.prototype = A.prototype; console.log((new B()).constructor === A); // true but A = function(){console.log('hey!')} ----> new B(); // do nothing ? – Matteo Rubini Mar 18 '15 at 14:44
  • solved... constructor is just a link and, when changed, does not affect original "class" construction – Matteo Rubini Mar 18 '15 at 15:15