我应该在javascript中使用多态性吗?

我应该在javascript中使用多态性吗?,javascript,inheritance,polymorphism,Javascript,Inheritance,Polymorphism,我是一名程序员,用多种语言编程,包括函数式语言和面向对象语言。我也编写了一些Javascript,但从未在其中使用(或不得不使用)多态性 现在,作为一个爱好项目,我想移植一些用Java和C语言编写的应用程序,这些应用程序在Javascript中大量使用了多模式 但乍一看,我读了很多“这是可能的,但是……” 那么,还有其他选择吗 我想在pseudolang中用JS编写的一个示例: abstract class Shape{ { printSurface() } ; } class Rect :

我是一名程序员,用多种语言编程,包括函数式语言和面向对象语言。我也编写了一些Javascript,但从未在其中使用(或不得不使用)多态性

现在,作为一个爱好项目,我想移植一些用Java和C语言编写的应用程序,这些应用程序在Javascript中大量使用了多模式

但乍一看,我读了很多“这是可能的,但是……”

那么,还有其他选择吗

我想在pseudolang中用JS编写的一个示例:

abstract class Shape{ { printSurface() } ;  }

class Rect : Shape() {  printSurface() { print (sideA*sideB}}

class Circle : Shape() {  printSurface() { print { pi*r*r }}

TheApp { myshapes.iterate(shape s) {s.printSurface() } }
这是一个典型的多态情况:在基类上迭代

我想实现这种行为。我知道这是一种多门主义,但我是否忽略了实现这种行为的其他“模式”,或者我是否应该研究Javascript中的继承可能性?

这里使用的“模式”将是“接口”。只要
myshapes
集合中的所有对象都实现了
printSurface()
方法,就可以了


由于Javascript是一种动态类型化语言,集合中的对象根本不需要关联。

我知道这可以通过原型实现,但我不是使用它的高手。(更易于可视化并具有“私有”范围)


正如Weston所说,如果您不需要继承,那么动态语言(如Javascript)的duck类型特性会提供多态性,因为该语言本身不需要强类型基类或接口

如果您确实希望使用继承并轻松调用超类的实现,那么这可以通过原型或对象文本实现,如Joeseph所示


另一件事是要看一下,因为它可以编译成Javascript,用一种简单的语法为您提供所有面向对象的优点。它将为您编写所有的bollerplate原型。缺点是它增加了这个额外的编译步骤。也就是说,编写一个简单的类层次结构,比如上面的示例,然后查看javascript会弹出什么结果,这有助于展示如何完成这一切。

另一个注意事项。如果您想使用类以OO风格编程Javascript,可以查看Javascript的许多“类系统”。Joose就是一个例子(http://joose.it)


许多客户端框架实现自己的类系统。ExtJS就是一个例子。

如上所述,JavaScript是一种基于原型继承的动态类型化语言,因此不能真正使用类型化语言的相同方法。您所写内容的JS版本可能是:

function Shape(){
  throw new Error("Abstract class")
}

Shape.prototype.printSurface = function () {
  throw new Error ("Not implemented");
}

function Rect() {
  // constructor;
}

Rect.prototype = Object.create(Shape.prototype);
Rect.prototype.printSurface = function() {
  // Rect implementation
}

function Circle() {
  // constructor;
}

Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.printSurface = function() {
  // Circle implementation
}
然后,在你的应用程序中:

var obj = new Circle();

if (obj instanceof Shape) {
    // do something with a shape object
}
或者,使用duck键入:

if ("printSurface" in obj)
    obj.printSurface();

// or

if (obj.printSurface)
    obj.printSurface();

// or a more specific check
if (typeof obj.printSurface === "function")
    obj.printSurface();
您还可以将
Shape
作为没有任何构造函数的对象,它更像是一个“抽象类”:

请注意,在这种情况下,您不能再使用
instanceof
,因此,或者您退回到duck键入,或者您必须使用
isPrototypeOf
,但仅在最近的浏览器中可用:

if (Shape.isPrototypeOf(obj)) {
    // do something with obj
}

在未实现ES5规范的浏览器中不可用,但您可以轻松使用polyfill(请参见链接)。

即使是我使用的相同示例也显示在这里:我不明白为什么这个答案没有得到更高的评价。它指出了JavaScript的一个简单事实,即多态性只是命名相同的属性。没有任何类型约束需要担心。我必须稍后再讨论它,但总是+1,所以谁来提供codedamples呢@韦斯顿:这个问题不足以成为一个单独的答案吗?这些框架可以在那里讨论。现在:性能惩罚总是可以接受的吗?Tx,非常好的答案。但实际上,我会选择JOOSE,类框架。这不适用于文档。我想创建从文档继承的NMLDocument,但出现了一个奇怪的
[LenientThis]
错误。现在尝试一下,它真的非常好,或者干脆忘记类,接受对象。
var Shape = {
    printSurface : function () {
        throw new Error ("Not implemented");
    }
}

function Rect() {
  // constructor;
}

Rect.prototype = Object.create(Shape);
Rect.prototype.printSurface = function() {
  // Rect implementation
}

function Circle() {
  // constructor;
}

Circle.prototype = Object.create(Shape);
Circle.prototype.printSurface = function() {
  // Circle implementation
}
if (Shape.isPrototypeOf(obj)) {
    // do something with obj
}