繁体   English   中英

如何在类静态方法中创建一个对象

[英]How to create an object inside class static method

我开始在类中了解有关静态方法的更多信息,并且想知道以下是否可行:

  • 有一个实例化怪物的class Monster {...}class Monster {...}
  • 允许某人通过传递他们想要怪物拥有的所有属性来创建monster实例
  • 有一个静态方法( Monster.create() ),它会生成一个新的monster实例并随机分配属性,而不是将值作为输入。

我的问题:1。这是一个糟糕的做法吗? 如果没有,2。如何在静态方法中创建新实例?

我的第一个想法是你可以让静态方法返回一个对象并做任何你希望随机化该对象值的逻辑,但我不确定是否有更好的方法。 (我认为该对象将在用new 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() 或者这是正确的方法吗?

返回对象实例的函数通常称为“工厂函数”。 这是某些类型对象的常见设计模式。

对于你正在做的事情,你有几个选择:

  1. 您可以创建一个工厂函数,该函数生成并返回以某种方式或随机方式预先设置的对象。

  2. 您可以创建构造函数变量(可以传递给构造函数的一组参数),这将导致它创建所需对象的类型和配置。

这些中的任何一个都可以同样有效。

这样做是一种可怕的方法吗?

不。工厂功能是一种非常合理的做事方式。 通常,我首先考虑让构造函数为您完成工作而不使用工厂函数,但有时候有充分的理由收集某个序列,以某种方式将对象构建到工厂函数而不是构造函数中。

如何在静态方法中创建新实例?

你像其他地方一样使用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

}

此示例显示了检查对象上每个特定属性的代码,但通过将传入对象上的所有属性复制到新创建的对象,或者通过创建属性名称的白名单并复制两者中存在的任何属性,这也可以在某种程度上自动化。白名单和对象。

或者,传入的对象可以与属性的一组默认值合并,然后合并到新对象中。 有很多方法可以做到这一点,具体取决于您具有哪些特定属性以及如果它们存在或不存在,您希望如何处理它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM