回到课程
本资料仅提供以下语言版本:English, 日本語。请 帮助我们 将其翻译为 简体中文 版本。

使用相同的构造函数创建一个对象

重要程度: 5

想象一下,我们有一个任意对象 obj,由一个构造函数创建 —— 我们不知道这个构造函数是什么,但是我们想用它创建一个新对象。

我们可以这样做吗?

let obj2 = new obj.constructor();

给出一个代码可以正常工作的 obj 的构造函数的例子。再给出一个会导致错误的例子。

如果我们确信 "constructor" 属性具有正确的值,我们可以使用这种方法。

例如,如果我们不访问默认的 "prototype",那么这段代码肯定会起作用:

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

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

alert( user2.name ); // Pete (worked!)

它起作用了,因为 User.prototype.constructor == User

…但是如果有人说,覆盖 User.prototype 并忘记重新创建 "constructor",那么它就会失败。

例如:

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

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

alert( user2.name ); // undefined

为什么 user2.nameundefined

new user.constructor('Pete') 的工作原理是:

  1. 首先,它在 user 中寻找 constructor。什么也没有。
  2. 然后它追溯原型链。user 的原型是 User.prototype,它也什么都没有。
  3. User.prototype 的值是一个普通对象 {},其原型是 Object.prototype。还有 Object.prototype.constructor == Object。所以就用它了。

最后,我们有 let user2 = new Object('Pete')。内置的 Object 构造函数忽略参数,它总是创建一个空对象 —— 这就是我们在 user2 中所拥有的东西。