确定Javascript中的对象类型的最佳做法

如果您在JavaScript中有一个对象的实例,似乎可能难以找到其实际类型,即

var Point2D = function Point2D(x, y) {
  return {
    X: x,
    Y: y
  }
}

var p = new Point2D(1,1);

typeof p // yields just 'Object' not 'Point2D'

我发现的一种方法是使对象成为自己的原型,然后可以通过调用prototype.constructor.name有效地获取其名称,

var Point2D = function Point2D(x, y) {
  return {
    X: x,
    Y: y,
    prototype: this
  }
}

new Point2D(1,1).prototype.constructor.name // yields 'Point2D'

这会是一个很好的方法吗(有什么利弊)还是有更好的做法我错过了?

谢谢.

最佳答案
首先,我们需要解决你们建立你的课程,因为你绊倒了一些JS的陷阱,做了一些非常奇怪的事情:

function Point2D(x, y){
    //Our constructor/initialization function
    //when run, the 'this object will have
    //Point2D.prototype as its prototype

    this.x = x;
    this.y = y;

    //Don't return a value here! Doing so overrides
    //the default "return this" that we actually want.
}

//You can put things in the Point2D prototype in order to have them
//be shared by all Point2D objects. Normally you want the methods to be shared.
Point2D.prototype.getX = function(){
    return this.x;
};

//Note that there is nothing magical about the "prototype" property.
//It is just where the `new` syntax expects the prototype it will use to be.
//The actual magic property is __proto__ (don't depend on it though
// __proto__ is browser specific and unsafe/evil)

//We now can create points!
var p = new Point2D(17.0, 42.0);
p.getX();

现在我们可以解决有关获取类型名称的部分.你所缺少的更好的做法是不首先检查类型.从OO的角度来说,如何实现一个对象(ts类),但它的行为和它的接口是什么(暴露的方法和属性)也不重要.此外,从Javascript的角度来看,类型名称是一个二级黑客,与实际使用的原型OO方案不兼容.

由于有很多原因,您可能会首先检查类型名称,因此有许多不同的“最佳”解决方案.有些可以想到的:

>如果你所有的情况都是“这个对象实现一个特定的点接口”,那么你可以直接进行特征检查:

function isPoint(p){
    //check if p has all the methods I expect a point to have:
    //(note that functions are truthy in a boolean context)
    return (p.getX && p.getY);
}

>如果您使用类型名称进行调度,请考虑使用方法.它是自然的OO方式.

function speak(obj){
    //fake pseudo-syntax:
    if(obj is of type Cat){ console.log("meow"); }
    if(obj is of type Dog){ console.log("woof"); }
}

Cat.prototype.speak = function(){ console.log("meow"); };
Dog.prototype.speak = function(){ console.log("woof"); };

>如果你真的需要某种标签,你可以明确地做出一个,就像其他一些答案所指出的那样:

Point2D.prototype.pointType = "2D";

这里的优点是,如果需要,您可以有多个类具有相同的“类型”,并且您不必担心任何棘手的实例或类型的角色情况.

转载注明原文:确定Javascript中的对象类型的最佳做法 - 代码日志