Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在类静态方法中创建对象_Javascript_Class_Object_Ecmascript 6_Static Methods - Fatal编程技术网

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

Javascript 如何在类静态方法中创建对象,javascript,class,object,ecmascript-6,static-methods,Javascript,Class,Object,Ecmascript 6,Static Methods,我开始学习更多关于类中静态方法的知识,并想知道以下方法是否可行: 拥有一个实例化怪物的类(类怪物{…}) 允许某人通过传递他们希望怪物拥有的所有属性来创建怪物实例 有一个静态方法(Monster.create()),它将生成一个新的Monster实例并随机分配属性,而不需要将值作为输入 我的问题是: 1.这是一种可怕的做法吗?如果没有, 2.如何在静态方法中创建新实例 我的第一个想法是,您可以让静态方法返回一个对象,然后执行任意逻辑来随机分配该对象的值,但我不确定是否有更好的方法。(我认为该

我开始学习更多关于类中静态方法的知识,并想知道以下方法是否可行:

  • 拥有一个实例化怪物的类(
    类怪物{…}
  • 允许某人通过传递他们希望怪物拥有的所有属性来创建
    怪物
    实例
  • 有一个静态方法(
    Monster.create()
    ),它将生成一个新的
    Monster
    实例并随机分配属性,而不需要将值作为输入
我的问题是: 1.这是一种可怕的做法吗?如果没有, 2.如何在静态方法中创建新实例

我的第一个想法是,您可以让静态方法返回一个对象,然后执行任意逻辑来随机分配该对象的值,但我不确定是否有更好的方法。(我认为该对象将位于使用
新怪物(…)
?)创建的实例原型链之外)

这是我第一次尝试时想到的,但这必然会创建怪物,模仿怪物类:

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-我刚才已经在我的答案中添加了默认参数选项。回答很棒;谢谢你的努力。