打字稿:避免通过引用进行比较

lhk*_*lhk 5 javascript comparison reference web typescript

我需要存储点列表并检查该列表中是否已包含新点

class Point {
    x: number;
    y: number;
    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }
}

window.onload = () => {
    var points : Point[] = [];
    points.push(new Point(1,1));
    var point = new Point(1,1);
    alert(points.indexOf(point)); // -1 
}
Run Code Online (Sandbox Code Playgroud)

显然打字稿使用引用比较,但在这种情况下没有意义。在 Java 或 C# 中,我会equals在似乎不可能的打字稿中重载该方法。

我考虑过遍历数组foreach并检查每个条目是否相等,但这看起来相当复杂并且会使代码膨胀。

equals打字稿中有类似的东西吗?我怎样才能实现我自己的比较?

Wir*_*rie 5

Typescript 不会向 JavaScript 添加任何功能。它只是“键入”和一些语法改进。

因此,没有一种方法可以equals与您在 C# 中所做的等效方式进行重写。

但是,您最终可能会在 C# 中使用 aHash或 a 强类型Dictionary来进行有效的查找(除了可能的数组之外),而不是使用“索引”函数。

为此,我只是建议您使用关联数组结构来存储Points。

你会做类似的事情:

class Point {
    constructor(public x:Number = 0, 
        public y:Number = 0 ) {     
    }   
    public toIndexString(p:Point):String {
        return Point.pointToIndexString(p.x, p.y);  
    }       
    static pointToIndexString(x:Number, y:Number):String {
        return x.toString() + "@" + y.toString();   
    }       
}

var points:any = {};
var p: Point = new Point(5, 5);
points[p.toIndexString()] = p;
Run Code Online (Sandbox Code Playgroud)

如果 aPoint不存在,则检查points关联数组将返回undefined

包装数组的函数很简单:

function findPoint(x:Number, y:Number):Point {
    return points[Point.pointToIndexString(x, y)];
}
Run Code Online (Sandbox Code Playgroud)

循环遍历所有点很容易:

// define the callback (similar in concept to defining delegate in C#)
interface PointCallback {
    (p:Point):void;
}

function allPoints(callback:PointCallback):void {
    for(var k in points) {
        callback(points[k]);
    }
}

allPoints((p) => {
   // do something with a Point...
});
Run Code Online (Sandbox Code Playgroud)


Fen*_*ton 4

您可以将集合包装在PointList仅允许Point通过方法添加对象的集合中add,该方法会检查以确保不添加重复项。

这样做的好处是将“无重复”规则封装在一个地方,而不是希望所有调用代码在添加重复之前进行检查,这会在许多地方重复该规则。

class Point {
    constructor(public x: number, public y: number) {
    }
}

class PointList {
    private points: Point[] = [];

    get length() {
        return this.points.length;
    }

    add(point: Point) {
        if (this.exists(point)) {
            // throw 'Duplicate point';
            return false;
        }

        this.points.push(point);
        return true;
    }

    exists(point: Point) {
        return this.findIndex(point) > -1;
    }

    findIndex(point: Point) {
        for (var i = 0; i < this.points.length; i++) {
            var existingPoint = this.points[i];
            if (existingPoint.x === point.x && existingPoint.y === point.y) {
                return i;
            }
        }

        return -1;
    }
}

var pointList = new PointList();

var pointA = new Point(1, 1);
var pointB = new Point(1, 1);
var pointC = new Point(1, 2);

pointList.add(pointA);
alert(pointList.length); // 1

pointList.add(pointB);
alert(pointList.length); // 1

pointList.add(pointC);
alert(pointList.length); // 2
Run Code Online (Sandbox Code Playgroud)