问题是当你这样做时:
return { ...
您正在创建一个新对象,该对象与先前使用 new 关键字创建的对象(您为其分配了两个属性的对象)分开。你可能会注意到jeff instanceof Person 是假的,jeff.constructor === Object。
看这个例子:
function Person(name, age) {
this.name = name;
this.age = age;
return {
theObjectThatNewCreated: this
}
}
var jeff = new Person('jeff', 28);
console.log( JSON.stringify( jeff ) );
// {"theObjectThatNewCreated":{"name":"jeff","age":28}}
console.log( jeff.constructor );
// Object
console.log( jeff.theObjectThatNewCreated.constructor );
// Person
您可以通过将 name 和 age 属性分配给您返回的对象而不是 this 来修复它:
function Person(name, age) {
return {
name: name,
age: age,
ageUp: function ageUp() {
this.age++;
},
printInfo: function printInfo() {
console.log(this.name + " is " + this.age + " years old");
},
changeName: function changeName(newName) {
this.name = newName;
}
}
}
var jeff = new Person('jeff', 28);
jeff.printInfo();
但是 Person 并不是真正的构造函数,它只是一个对象工厂,用new 调用它是没有意义的。它返回的对象不是 Person 的实例,它们是普通的旧对象。有更好的办法。
我是否结合了两种不应该的设计模式?解决此问题的最佳方法是什么?
我会说你正在将显示模块模式与普通的 JavaScript 构造函数结合起来。
您可以一直使用this,而不是返回一个新对象,将这些函数分配为 Person 对象的属性,而不是一个新对象:
function Person(name, age) {
this.name = name;
this.age = age;
this.ageUp = function ageUp() {
this.age++;
};
this.printInfo = function printInfo() {
console.log(this.name + " is " + this.age + " years old");
};
this.changeName = function changeName(newName) {
this.name = newName;
};
}
var jeff = new Person('jeff', 28);
jeff.printInfo();
但由于这些函数不使用构造函数中的任何封闭变量,因此实际上应该将它们添加到构造函数的原型中:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.ageUp = function ageUp() {
this.age++;
};
Person.prototype.printInfo = function printInfo() {
console.log(this.name + " is " + this.age + " years old");
};
Person.prototype.changeName = function changeName(newName) {
this.name = newName;
};
var jeff = new Person('jeff', 28);
jeff.printInfo();