Create an object with the same constructor
Imagine, we have an arbitrary object obj
, created by a constructor function – we don’t know which one, but we’d like to create a new object using it.
Can we do it like that?
let obj2 = new obj.constructor();
Give an example of a constructor function for obj
which lets such code work right. And an example that makes it work wrong.
We can use such approach if we are sure that "constructor"
property has the correct value.
For instance, if we don’t touch the default "prototype"
, then this code works for sure:
function User(name) {
this.name = name;
}
let user = new User('John');
let user2 = new user.constructor('Pete');
alert( user2.name ); // Pete (worked!)
It worked, because User.prototype.constructor == User
.
…But if someone, so to speak, overwrites User.prototype
and forgets to recreate constructor
to reference User
, then it would fail.
For instance:
function User(name) {
this.name = name;
}
User.prototype = {}; // (*)
let user = new User('John');
let user2 = new user.constructor('Pete');
alert( user2.name ); // undefined
Why user2.name
is undefined
?
Here’s how new user.constructor('Pete')
works:
- First, it looks for
constructor
inuser
. Nothing. - Then it follows the prototype chain. The prototype of
user
isUser.prototype
, and it also has noconstructor
(because we “forgot” to set it right!). - Going further up the chain,
User.prototype
is a plain object, its prototype is the built-inObject.prototype
. - Finally, for the built-in
Object.prototype
, there’s a built-inObject.prototype.constructor == Object
. So it is used.
Finally, at the end, we have let user2 = new Object('Pete')
.
Probably, that’s not what we want. We’d like to create new User
, not new Object
. That’s the outcome of the missing constructor
.
(Just in case you’re curious, the new Object(...)
call converts its argument to an object. That’s a theoretical thing, in practice no one calls new Object
with a value, and generally we don’t use new Object
to make objects at all).