【问题标题】:Multiple constructors in a class. Javascript一个类中有多个构造函数。 Javascript
【发布时间】:2019-10-28 18:48:04
【问题描述】:

所以这就是他们要求我做的事情: 1) 使用以下条件创建一个名为 Person 的类。 属性:姓名、年龄、DNI、性别(M 为男性,F 为女性)、体重和身高。 除 DNI 外,每个属性都将根据其类型(数字为 0,字符串为空字符串等)具有默认值。性别默认为男性。

2) 创建以下构造函数: • 具有默认值的构造函数。 • 以姓名、年龄和性别为参数的构造函数(默认为其他值)。 • 将所有属性作为参数接收的构造函数。

我需要知道执行此操作的正确方法,以便能够创建具有不同值的类的 3 个对象。

class Person {
constructor(name, age, sex, dni, weight, height){
    this.name = '';
    this.age = 0;
    this.sex = 'M';
    this.dni = createDni();
    this.weight = 0;
    this.height = 0;
}

static Person1(name, age, sex){
    return new Person(name,age,sex);
}

static Person2(name, age, sex, dni, weight, height){
    return new Person(name, age, sex, dni, weight, height);
}
}

var Person1 = new Person(){
this.name = 'Manuel'
this.age = 25;
this.sex = 'M';
this.height = 1,75;
this.weight = 90;
}

我应该能够将不同的值传递给从“类”创建的 3 个不同的对象。

【问题讨论】:

  • 这个任务是不可能的。一个类只能有一个constructor。
  • 你确定这是一个 Javascript 而不是 Java 作业吗?
  • 他们给了我这个练习来获得一份工作的面试,这些文件都被称为“测试 JS”,所以我不得不假设它是 Javascript。当类似的事情可以更简单地完成时,这种复杂的答案不可能是他们想要的。

标签: javascript class constructor


【解决方案1】:

在javascript中你只能有一个构造函数,和你开始的一样,我使用静态方法作为命名构造函数,所以我会这样写这个类:

class Contract {
    static notNull(value, message) { if(!value) throw new Error(message);  }
    static isArray(value, message) { if(!Array.isArray(value)) throw new Error(message);  }
    static isTrue(value, message)  { if(!value) throw new Error(message);  }
}

class Person {
    constructor (dni, name = "", age = 0, sex='M', width=0, height=0) {
        Contract.notNull(dni, "Parameter dni not specified");
        //check other parameters as well 
        this.dni = dni;
        this.name = name; // etc.
    }

    static fromArray(values) {
        Contract.isArray(values, "Parameter values must be array");
        Contract.isTrue(values.length === 6, "Expected 6 elements in array");
        return new Person(...values);
    }

    static fromNameAgeAndSex(name, age, sex) {
          return new Person(createDni(), name, age, sex);
    }
}

【讨论】:

    【解决方案2】:

    JavaScript 的class 语法创建一个构造函数和一个关联的原型对象。 JavaScript 中没有内置的函数重载,包括构造函数。在 JavaScript 中进行“重载”的唯一方法是在一个函数本身的代码中处理它。

    在您的情况下,您有几个选择,但最简单的可能是简单地对所有参数使用默认参数值:

    constructor(name = '', age = 0, sex = 'M', dni = createDni(), weight = 0, height = 0) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.dni = dni;
        this.weight = weight;
        this.height = height;
    }
    

    别担心,createDni 只有在调用构造函数时没有为dni 提供参数时才会调用(或者如果提供的值为undefined)。

    这样做的一个好处是调用者可以为任何参数、所有参数或介于两者之间的任何参数提供参数,而不仅仅是 0、3 和 6。

    现场示例:

    function createDni() {
        console.log("createDni was called");
        return 42;
    }
    class Person {
        constructor(name = '', age = 0, sex = 'M', dni = createDni(), weight = 0, height = 0) {
            this.name = name;
            this.age = age;
            this.sex = sex;
            this.dni = dni;
            this.weight = weight;
            this.height = height;
        }
    }
    console.log("No arguments:");
    console.log(JSON.stringify(new Person()));
    console.log("Three arguments:");
    console.log(JSON.stringify(new Person("Joe Bloggs", 42, "M")));
    console.log("Six arguments:");
    console.log(JSON.stringify(new Person("Joe Bloggs", 42, "M", 67, 182, 6)));
    .as-console-wrapper {
        max-height: 100% important;
    }

    如果你真的想只允许没有参数、三个参数或六个参数,你可以使用一个 rest 参数或 arguments 对象。使用arguments 看起来像这样:

    constructor(name = '', age = 0, sex = 'M', dni = createDni(), weight = 0, height = 0) {
        const alen = arguments.length;
        if (alen !== 0 && alen !== 3 && alen !== 6) {
            throw new Error("0, 3, or 6 arguments are required");
        }
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.dni = dni;
        this.weight = weight;
        this.height = height;
    }
    

    使用rest参数看起来像这样,注意你丢失了命名参数:

    constructor(...args) {
        const alen = args.length;
        if (alen !== 0 && alen !== 3 && alen !== 6) {
            throw new Error("0, 3, or 6 arguments are required");
        }
        [
            this.name = "",
            this.age = 0,
            this.sex = "M",
            this.dni = createDni(),
            this.weight = 0,
            this.height = 0
        ] = args;
    }
    

    ...同样,createDni 仅在需要时调用。

    【讨论】:

    • 你的最后两个例子有些混乱。两者都忽略了args,倒数第二个没有定义name、age等变量。
    • 感谢您的回答。我觉得第一个例子是要走的路。虽然它没有解决他们要求的三个构造函数。
    • @ScottSauyet - 谢谢!愚蠢的编辑错误,我已经修复了。
    • @ManuelSilva - 因为你不能在 JavaScript 中做到这一点。 :-) 是的,第一种方式是我使用的方式,除非有很好的理由要求特定数量的参数。
    猜你喜欢
    • 1970-01-01
    • 2011-11-20
    • 2015-06-20
    • 1970-01-01
    • 1970-01-01
    • 2013-08-28
    • 2022-10-17
    • 2014-07-29
    • 2012-06-22
    相关资源
    最近更新 更多