44 lines
1.3 KiB
Markdown
44 lines
1.3 KiB
Markdown
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:
|
|
|
|
```js run
|
|
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 say, overwrites `User.prototype` and forgets to recreate `"constructor"`, then it would fail.
|
|
|
|
For instance:
|
|
|
|
```js run
|
|
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:
|
|
|
|
1. First, it looks for `constructor` in `user`. Nothing.
|
|
2. Then it follows the prototype chain. The prototype of `user` is `User.prototype`, and it also has nothing.
|
|
3. The value of `User.prototype` is a plain object `{}`, it's prototype is `Object.prototype`. And there is `Object.prototype.constructor == Object`. So it is used.
|
|
|
|
At the end, we have `let user2 = new Object('Pete')`. The built-in `Object` constructor ignores arguments, it always creates an empty object -- that's what we have in `user2` after all.
|