gpt4 book ai didi

javascript - 初级 JavaScript 模式

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:31:32 24 4
gpt4 key购买 nike

我最近开始研究对象、闭包、作用域等。我正在尝试使用这些技术实现我自己的代码,但遇到了问题。

function Person(name, age) {
this.name = name;
this.age = age;

return {
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();

奇怪的是,这返回 undefined is undefined years oldprintInfo 属性是否在其范围内没有 this.name 因为返回的对象没有函数的记忆?

同样奇怪的是,如果我将 this.namethis.age 的所有实例更改为常规私有(private)变量(例如 var personName = name; ),返回的对象将以某种方式正常运行,我可以按预期使用 ageUpprintInfo

我是否结合了两种不应该的设计模式?解决此问题的最佳方法是什么?

最佳答案

问题是当你这样做的时候:

return { ...

您正在创建一个新对象,与 new 关键字先前创建的对象(您为其分配了两个属性的对象)分开。您可能会注意到 jeff instanceof Person 为 false 并且 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 的实例,它们是普通的旧对象。有更好的方法。

Am I combining two design patterns that I shouldn't be? What would be the best way to go about this?

我会说您正在将揭示模块模式与普通的 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();

但由于这些函数不使用构造函数中的任何封闭变量,因此实际上应该将它们添加到构造函数的原型(prototype)中:

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();

关于javascript - 初级 JavaScript 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36995542/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com