4

I have such example

function test1(){this.a = 1;}
function test2(){this.b = 2;}
function test3(){this.c = 3;}
test2.prototype = Object.create(test1.prototype);
test2.prototype.constructor = test2;
test3.prototype = Object.create(test1.prototype); // lose constructor
var q = new test2();//we can find constructor test2 in __proto__
var q2 = new test3();//there is no such field in __proto__

enter image description here

in q2 link to constructor test3 was lost.

Why and how could it influence in the bad way?

Kirill Matrosov
  • 5,564
  • 4
  • 28
  • 39

2 Answers2

3

Usually you'll get away with that, but I'd recommend you don't. (Not least because I'd recommend using class syntax if you're going to use constructor function hierarchies, not ES5-style patterns, and class sets things up correctly for you automatically.)

For a long time, although JavaScript set the constructor property on the default object it assigned to the prototype of a function, it didn't use it for anything. But userland code sometimes did, for the obvious purpose: To get the constructor function that (probably) constructed an object. As of ES2015, JavaScript itself uses the constructor property for that too, in places where it's creating a new object from an existing one, such as a new array from an existing array (for instance, slice), or a new RegExp from an existing RegExp (it does that behind the scenes when you use a regular expression in String#split), a new promise from an existing promise (for instance, then), etc.

So if you leave your hierarchy with the wrong effective constructor property, operations expecting it to be correct will fail. But it's rare for an operation to actually use it, if you're not subclassing a built-in (and if you are, again, use class) and you don't write code to use constructor explicitly, it won't get used for anything.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Maybe you can add that one implication is breaking the `instanceof` operator – Moritz Roessler Aug 06 '18 at 08:55
  • 2
    @MoritzRoessler - `constructor` has nothing to do with `instanceof` (you're not the first to think it does, though). :-) `o instanceof F` checks to see if the object referenced by `F.prototype` appears in `o`'s prototype chain. `constructor` is completely ignored. – T.J. Crowder Aug 06 '18 at 08:56
1

Lets take the example. We can get new array of 1,2,3 in 4 ways;

  1. [1,2,3]
  2. new Array(1,2,3)
  3. Array(1,2,3)
  4. new Array.prototype.constructor(1,2,3)

In the last variant we use constructor. So if we want new array which creates reversed instance, we will inherit from Array, but if we lose constructor, the 4th will do things in an other way.

const myArray = function(){ 
   const args = Array.prototype.slice.call(arguments); 
   return args.reverse();    
};    
myArray.prototype = Object.create(Array.prototype);
console.log(new myArray(1, 2, 3, 4, 5)); //reversed
const newMyArray = new myArray.prototype.constructor(1,2,3,4,5); //not reversed
Kirill Matrosov
  • 5,564
  • 4
  • 28
  • 39