如何在 JavaScript ECMA6 中重载构造函数? [复制]

Posted

技术标签:

【中文标题】如何在 JavaScript ECMA6 中重载构造函数? [复制]【英文标题】:How to overload constructors in JavaScript ECMA6? [duplicate] 【发布时间】:2016-11-09 11:50:02 【问题描述】:

目标

实现一种机制以允许 javascript ECMA6 中的构造函数重载

为什么这不是重复的

话题Why doesn't JavaScript ES6 support multi-constructor classes?,虽然相似,但和这个不一样。另一个主题仅关注使用 old ECMAScript 版本的构造函数重载,而本主题关注 ECMA6。如果您正在寻找更新的答案,那就是这里。

背景

我有一个带有给定构造函数的 JavaScript 类,我希望用户在实例化对象时能够拥有不同的构造函数。我假装的一个例子可能如下:

const DEFAULT_WHEEL_NUMBER = 4;
const DEFAULT_COLOR = "black";    
const DEFAULT_NAME = "myCar";

class Car

    constructor(numberWheels, aName, aColor)
        this.wheelsNum = numberWheels;
        this.name = aName;
        this.color = aColor;
    

    constructor(aName)
        this(DEFUALT_WHEEL_NUMBER, aName, DEFAULT_COLOR);
    

    constructor()
        this(DEFUALT_WHEEL_NUMBER, DEFAULT_NAME, DEFAULT_COLOR);
    

在这段代码中,用户可以使用三个构造函数,每个构造函数采用不同数量的参数。使用示例如下:

var car1 = new Car(3, "tricicle-car", "white");
var car2 = new Car("Opel"); //creates black car with 4 wheels called Opel
var car3 = new Car(); //creates a black car, with 4 wheels called myCar

问题

如果使用 Java 或 C#,这是一个简单的示例,因为这些语言具有构造函数重载。

但是,从documentation on classes from MDN 可以得出结论,JavaScript 没有。

问题

    有没有办法为使用 ECMA6 的 JavaScript 类实现类似的机制?如果不是,最好/最接近的选择是什么?

【问题讨论】:

看看这个非常相似的问题:Why JavaScript ES6 doesn't have multi-constructor class? 我认为最终的问题是 Javascript 不是 Java,而模仿 Java 习语通常会带来很多麻烦。不过,这只是我的看法。 如果您真的认为重载是个好主意,这是一个很好的问题。你的例子尖叫着“建造者”。 @zeroflagL:也许你可以提供一个例子的答案?我是模式的粉丝! 看看 TypeScript。他们使用类型化的对象,例如object: int 【参考方案1】:

您是对的(据我所知)这不是 JavaScript 类支持的功能。我在这里的建议是,因为您已经在使用 ES6 功能,所以改为使用 default parameters:

class Car 
    constructor(numberWheels = 4, aName = "myCar", aColor = "black")
        this.wheelsNum = numberWheels;
        this.name = aName;
        this.color = aColor;
    

这显然伴随着一个警告,即您不能像在示例中那样使用不同的参数顺序进行“重载”(尽管在我看来,这是一件好事 - 使用一致的 API 会更好)。

meskobalazs 的回答也是一个不错的选择,尤其是当您希望对象接受很多选项时。通过这样的函数参数执行此操作可能会有点混乱!

【讨论】:

【参考方案2】:

在 JavaScript 中没有内置的解决方案。另一种解决方案是使用arguments 对象(在某些情况下),或者传递您自己的配置选项,类似于:

const defaults = 
    numberWheels: 4,
    color: "black",   
    name: "myCar"


class Car 
    constructor(options) 
         this.wheelsNum = options.numberWheels || defaults.numberWheels;
         this.name = options.name || defaults.name;
         this.color = options.color || defaults.color;
    

这基本上是老派的解决方案,我在 ES3 中使用相同的逻辑。

【讨论】:

您可以使用...restParameters 代替arguments 对象,它会为您提供一个真正的数组。 当使用||操作符时,你应该把options参数放在前面,否则你总是会得到默认对象。 哎呀,真的 :) 更新了,谢谢

以上是关于如何在 JavaScript ECMA6 中重载构造函数? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥在析构函数中抛出异常时不调用重载删除?

ECMA6--面向对象

是否在重载的运算符删除函数中隐式调用析构函数?

如何在javascript中重载函数?

适当的空手道ecma javascript版本

ECMA6 中 nameFunction() 和 nameFunction () => 的区别