Javascript 如何在类静态方法中创建对象
我开始学习更多关于类中静态方法的知识,并想知道以下方法是否可行:Javascript 如何在类静态方法中创建对象,javascript,class,object,ecmascript-6,static-methods,Javascript,Class,Object,Ecmascript 6,Static Methods,我开始学习更多关于类中静态方法的知识,并想知道以下方法是否可行: 拥有一个实例化怪物的类(类怪物{…}) 允许某人通过传递他们希望怪物拥有的所有属性来创建怪物实例 有一个静态方法(Monster.create()),它将生成一个新的Monster实例并随机分配属性,而不需要将值作为输入 我的问题是: 1.这是一种可怕的做法吗?如果没有, 2.如何在静态方法中创建新实例 我的第一个想法是,您可以让静态方法返回一个对象,然后执行任意逻辑来随机分配该对象的值,但我不确定是否有更好的方法。(我认为该
- 拥有一个实例化怪物的类(
)类怪物{…}
- 允许某人通过传递他们希望怪物拥有的所有属性来创建
实例怪物
- 有一个静态方法(
),它将生成一个新的Monster.create()
实例并随机分配属性,而不需要将值作为输入Monster
新怪物(…)
?)创建的实例原型链之外)
这是我第一次尝试时想到的,但这必然会创建怪物,模仿怪物类:
class Monster {
constructor(hp) {
this.hp = hp;
}
static create() {
const obj = Object.create(Monster.prototype);
obj.hp = Math.floor(Math.random() * 100);
return obj;
}
attack(obj) {
const randDamage = Math.floor(Math.random() * 10);
console.log(`Monster deals ${randDamage} damage!`);
obj.hp -= randDamage;
}
}
const monster = Monster.create();
const me = {hp: 100};
monster.attack(me);
console.log(me); // { hp: 91 }
有没有一种方法可以实现使用
Monster
类的create()
?或者这是正确的方法吗?返回对象实例的函数通常称为“工厂函数”。这是特定类型对象的常见设计模式
对于您正在做的事情,您有两个选择:
new
有没有一种方法可以实现使用Monster类的create()
对。您只需在静态方法中使用new
,即可创建对象
// since your constructor already accepts an hp parameter as an argument
// you can just create a random hp value and pass it to the constructor
static create() {
let hp = Math.floor(Math.random() * 100);
return new Monster(hp);
}
但是,您也可以修改构造函数,以便在未传递任何参数的情况下,构造函数本身为其创建一个随机值,而不使用静态工厂函数:
class Monster {
constructor(hp) {
if (hp === undefined) {
this.hp = Math.floor(Math.random() * 100);
} else {
this.hp = hp;
}
}
// rest of class definition here
}
然后,只需使用构造函数创建对象:
// create monster object with random hp value
const monster = new Monster();
或者,如果参数足够简单,可以使用ES6默认值:
class Monster {
// supply default value for hp parameter if not present
constructor(hp = Math.floor(Math.random() * 100)) {
this.hp = hp;
}
}
允许某人通过传递他们希望怪物拥有的所有属性来创建怪物实例 这通常是通过将对象传递给构造函数来完成的,无论对象上存在什么属性,这些属性都用于初始化对象的特性。如果传入构造函数的对象上不存在属性,则构造函数将使用默认值
class Monster {
constructor(options) {
if (options.hp === undefined) {
this.hp = Math.floor(Math.random() * 100);
} else {
this.hp = options.hp;
}
// similar logic can be used for other properties on the options object
}
// rest of class definition here
}
此示例显示了检查对象上每个特定属性的代码,但也可以通过将传入对象上的所有属性复制到新创建的对象,或者通过创建属性名称的白名单并复制白名单和对象上存在的任何属性来实现自动化
// since your constructor already accepts an hp parameter as an argument
// you can just create a random hp value and pass it to the constructor
static create() {
let hp = Math.floor(Math.random() * 100);
return new Monster(hp);
}
或者,传入的对象可以与属性的一组默认值合并,然后合并到新对象中。根据您所拥有的特定属性以及如果它们存在或不存在,您希望如何处理它们,有很多方法可以做到这一点。您对使用@Mark_M下面的答案中所示的默认参数而不是冗长的if/else if语句有何想法?或者这仅仅取决于传递的事物的复杂性?@bobbyz-这完全取决于你想要应用的逻辑。如果只有几个参数,并且它们的默认值足够简单,那么参数的默认值就是一个很好的选择。如果您试图检测存在哪些参数或测试它们的值,则需要实际的代码。你的问题提到了传递他们想要怪物拥有的所有属性,所以我想你是在问一个有很多属性的情况,其中很多属性可能会被传递,也可能不会被传递。这就是为什么我建议传递一个具有任意属性集的对象。总的来说,这是有意义的。我想这可能会有更复杂的需求,所以你说的有道理。如果您可以更新您的答案,使其可能包含默认参数,我将继续并将其标记为例外答案。@bobbyz-我刚才已经在我的答案中添加了默认参数选项。回答很棒;谢谢你的努力。