javascriptobjectprototype

How can an object have a `.constructor` property if I reset its prototype to an empty object (`{}`)?


In this case prototype object doesn't have constructor property anymore. Here is just an empty object. But, despite this, somehow new obj.constructor still creates an empty object. How?

function Constructor() { 
    this.name = 'Kira';
    this.age = 35;
    this.city = 'New-York';
}; 
Constructor.prototype = {};

let obj = new Constructor;
let obj2 = new obj.constructor;
console.log(obj2); //{}

And here object is also created. In the console of Chrome browser, it's displayed as a String.

enter image description here

function User(name) {
  this.name = name;
}
User.prototype = {};

let user = new User('John');
let user2 = new user.constructor('Pete');

console.log(user2);

How can it be? How are objects created here?


Solution

  • When you set the prototype to {} that does not mean there are no properties. It means that the only properties are the ones you would find on a new object. In particular, the constructor property is coming from the prototype and points to Object

    const o = {};
    
    console.log("has constructor property:",
      "constructor" in o);
    console.log("constructor property is own:", 
      o.hasOwnProperty("constructor"));
    console.log("constructor property comes from prototype:",
      Object.getPrototypeOf(o).hasOwnProperty("constructor"));
    console.log("constructor property is Object():",
      o.constructor === Object);

    So, when you call new obj.constructor that is equivalent to new Object.

    function Foo() {}; 
    Foo.prototype = {};
    
    let obj = new Foo;
    console.log(obj.constructor === Object);
    console.log(obj.constructor === ({}).constructor);
    let obj2 = new obj.constructor;
    console.log(obj2); //{}

    When calling new user.constructor('Pete'); that is again just calling the global Object, so it's identical to new Object('Pete'). And if you pass a value that has an object wrapper, you get that wrapper from the constructor:

    const pete = new Object('Pete');
    console.log(typeof pete, pete instanceof String);
    
    const answer = new Object(42);
    console.log(typeof answer, answer instanceof Number);