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

时间:2017-11-08 00:11:44

标签: javascript class object ecmascript-6 static-methods

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

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

我的问题: 这样做是一种可怕的方法吗?如果不, 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 }

有没有办法实现使用create()类的Monster?或者这是正确的方法吗?

1 个答案:

答案 0 :(得分:3)

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

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

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

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

  3. 其中任何一个都可以同样有效。

      

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

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

      

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

    您可以像使用其他任何地方一样使用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
    
    }
    

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

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

相关问题