javascript中的多个构造函数

multiple constructor in javascript

我有一个问题:我想知道是否可以模拟多个构造函数,类似于Java(是的,我知道语言是完全不同?

假设我有一个叫做"点"的班,有两个值"x"和"y"。

现在,假设它是Java版本,我想要两个构造函数:一个接受两个数字,另一个接受字符串:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Point {
    private int x;
    private int y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
    public Point(String coord) {
        this.x = coord.charAt(0);
        this.y = coord.charAt(1);
    }
    //...
}


//In JavaScript, so far I have
Point = function() {
    var x;
    var y;
    //...
}

是否可以为point.prototype.init提供两个声明?在javascript中是否可能有多个构造函数?


您可以在javascript中通过测试参数的数量或参数的类型来实现这一点。

在这种情况下,您可以通过测试参数的数量来做到这一点:

1
2
3
4
5
6
7
8
9
10
function Point(/* x,y | coord */) {
    if (arguments.length == 2) {
        var x = arguments[0];
        var y = arguments[1];
        // do something with x and y
    } else {
        var coord = arguments[0];
        // do something with coord
    }
}


是的,你可以,尽管不是你所期望的那样。由于Javascript是弱类型的,没有人关心或检查您提供的参数是什么类型。

Java需要两种不同的构造函数,因为它是强类型的,并且参数类型必须与方法签名匹配,但是JavaScript不是这样的。

1
2
3
4
5
6
7
8
9
function Point(arg1, arg2) {
    if (typeof arg1 ==="number" && typeof arg2 ==="number") {
        // blah
    } else if (typeof arg1 ==="string" && arguments.length == 1) {
        // blah
    } else {
        throw new Error("Invalid arguments");
    }
};


这是从iOS获得的灵感。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Point {
    constructor() {
        this.x = 0; // default value
        this.y = 0; // default value
    }
    static initWithCoor(coor) {
        let point = new Point();
        point.x = coor.x;
        point.y = coor.y;
        return point;            
    }
    static initWithXY(x,y) {
        let point = new Point();
        point.x = x;
        point.y = y;
        return point;            
    }
}

就像那样,你可以有任意多的初始值设定项,而不需要写很多if-else。

1
2
let p1 = Point.initWithCoor({ x:10, y:20 });
let p2 = Point.initWithXY(10, 20);

只需让一个构造函数包装另一个构造函数:

1
2
3
4
5
6
7
8
9
function Point(x,y) {
//make the point and do what the constructor is designed to do
}

function PointStr(str) {
var xp = arguments[0];
var yp = arguments[1];
return new Point(xp, yp);
}