在ES6中创建多个构造函数

时间:2018-07-29 12:01:13

标签: javascript ecmascript-6 es6-class

在ES5中,可以为一个类创建多个构造函数,同时使用原型保留两者的共同部分,如下所示

function Book() {
    //just creates an empty book.
}


function Book(title, length, author) {
    this.title = title;
    this.Length = length;
    this.author = author;
}

Book.prototype = {
    ISBN: "",
    Length: -1,
    genre: "",
    covering: "",
    author: "",
    currentPage: 0,
    title: "",

    flipTo: function FlipToAPage(pNum) {
        this.currentPage = pNum;
    },

    turnPageForward: function turnForward() {
        this.flipTo(this.currentPage++);
    },

    turnPageBackward: function turnBackward() {
        this.flipTo(this.currentPage--);
    }
};

var books = new Array(new Book(), new Book("First Edition", 350, "Random"));

我想使用ES6类和构造函数语法实现相同的结果

class Book{
    constructore (){}
}

4 个答案:

答案 0 :(得分:2)

ECMAScript不支持函数/构造函数重载。如果您仍想修改它,则可以使用arguments对象这样做。

constructor(title, length, author) {
        if(!arguments.length) {
            // empty book
        }
        else {
            this.title = title;
            this.Length = length;
            this.author = author;
        }
    }

答案 1 :(得分:0)

实际上,确实可以为一个原型创建多个构造函数。您只需要查看原型QuerySnapshotlet ref = db.collection('post').doc(this.$route.params.id) ref.get() .then(snapshot => { //DocSnapshot if (snapshot.exists) { let post = snapshot.data() } else { // snapshot.data() will be undefined in this case console.log("No such document!"); } }) 属性即可。因此,您可以创建多个构造函数,如下所示:

constructor

只需为构造函数指定不同的名称。希望有帮助。

答案 2 :(得分:0)

您还可以通过将ES6类与扩展一起使用来解决此限制。

class Base{
    Foo;
    Bar;
}

class TypeA extends Base {
    constructor(value) {
        this.Foo = value;
    }
}

class TypeB extends Base {
    constructor(value) {
        this.Bar = value;
    }
}

答案 3 :(得分:0)

我相信有两个答案。一种使用带有 IIFE 函数的“纯”Javascript 来隐藏其辅助构造函数。另一个使用 NodeJS 模块也隐藏了它的辅助构造函数。

我将仅展示带有 NodeJS 模块的示例。

类 Vector2d.js:



/*

    Implement a class of type Vetor2d with three types of constructors.

*/

// If a constructor function is successfully executed,
// must have its value changed to 'true'.let global_wasExecuted = false;  
global_wasExecuted = false;   

//Tests whether number_value is a numeric type
function isNumber(number_value) {
    
    let hasError = !(typeof number_value === 'number') || !isFinite(number_value);

    if (hasError === false){
        hasError = isNaN(number_value);
    }

    return !hasError;
}

// Object with 'x' and 'y' properties associated with its values.
function vector(x,y){
    return {'x': x, 'y': y};
}

//constructor in case x and y are 'undefined'
function new_vector_zero(x, y){

    if (x === undefined && y === undefined){
        global_wasExecuted = true;
        return new vector(0,0);
    }
}

//constructor in case x and y are numbers
function new_vector_numbers(x, y){

    let x_isNumber = isNumber(x);
    let y_isNumber = isNumber(y);

    if (x_isNumber && y_isNumber){
        global_wasExecuted = true;
        return new vector(x,y);
    }
}

//constructor in case x is an object and y is any
//thing (he is ignored!)
function new_vector_object(x, y){

    let x_ehObject = typeof x === 'object';
    //ignore y type

    if (x_ehObject){

        //assigns the object only for clarity of code
        let x_object = x;

        //tests whether x_object has the properties 'x' and 'y'
        if ('x' in x_object && 'y' in x_object){

            global_wasExecuted = true;

            /*
            we only know that x_object has the properties 'x' and 'y',
            now we will test if the property values ​​are valid,
            calling the class constructor again.            
            */
            return new Vector2d(x_object.x, x_object.y);
        }

    }
}


//Function that returns an array of constructor functions
function constructors(){
    let c = [];
    c.push(new_vector_zero);
    c.push(new_vector_numbers);
    c.push(new_vector_object);

    /*
        Your imagination is the limit!
        Create as many construction functions as you want.    
    */

    return c;
}

class Vector2d {

    constructor(x, y){

        //returns an array of constructor functions
        let my_constructors = constructors(); 

        global_wasExecuted = false;

        //variable for the return of the 'vector' function
        let new_vector;     

        //traverses the array executing its corresponding constructor function
        for (let index = 0; index < my_constructors.length; index++) {

            //execute a function added by the 'constructors' function
            new_vector = my_constructors[index](x,y);
            
            if (global_wasExecuted) {
            
                this.x = new_vector.x;
                this.y = new_vector.y;

                break; 
            };
        };
    }

    toString(){
        return `(x: ${this.x}, y: ${this.y})`;
    }

}

//Only the 'Vector2d' class will be visible externally
module.exports = Vector2d;  

useVector2d.js 文件使用 Vector2d.js 模块:

const Vector = require('./Vector2d');

let v1 = new Vector({x: 2, y: 3});
console.log(`v1 = ${v1.toString()}`);

let v2 = new Vector(1, 5.2);
console.log(`v2 = ${v2.toString()}`);

let v3 = new Vector();
console.log(`v3 = ${v3.toString()}`);

终端输出:

v1 = (x: 2, y: 3)
v2 = (x: 1, y: 5.2)
v3 = (x: 0, y: 0)

这样我们就可以避免脏代码(许多 if 和 switch 散布在整个代码中),难以维护和测试。每个建筑功能都知道要测试哪些条件。增加和/或减少您的建筑功能现在很简单。