【问题标题】:Possible to have Abstract class in JS?JS中可能有抽象类吗?
【发布时间】:2011-05-04 04:57:46
【问题描述】:

我在 javascript 中遇到过原型继承。

我想要实现的是方法的大纲,当被继承时必须实现/定义。

我想知道这是否可行,如果可行,如何实现。

【问题讨论】:

标签: javascript inheritance prototype


【解决方案1】:

JavaScript 真的没有这样的东西。正如你所说,JavaScript 是prototype-oriented


正如其他答案所说,当然,你可以模拟这个。但我看不出这样做的充分理由。为什么面向对象的程序员使用接口和抽象类? Astractiondecoupling。这些允许您做各种好事,例如编写消耗(作为参数)和产生(返回)具有抽象类型的值的方法 - 对象将至少满足有关其方法的某些约定和字段。

反过来,我们得到了其他“好东西”,例如类型安全的编译时检查。尝试将 Foo 类型的对象传递给只接受 Bar* 类型的对象的方法,您将收到编译器警告。

现在是实际的解释

  1. JavaScript 将允许您将任何对象传递给任何函数。您在函数内部对那个对象执行可能会导致运行时错误 - 但没有什么能阻止您传递任意参数,即使是与函数声明的参数数量不同的参数。
  2. JavaScript 变量没有明确的类型。当您仍然必须执行手动、显式类型检查时,“保证”某个对象具有某些方法的意义何在?
  3. 在 JavaScript 中,函数并不局限于从属于对象——它们是语言的一等公民,可以像对象一样使用。所以? 对象的函数可以在运行时更改。您可以向对象添加其他函数,或从对象中删除它们(或在原型中隐藏函数)。因此,虽然您无法在创建后真正更改对象的 prototypeconstructor(阅读:new),但您可以更改对象的属性。
  4. 与第 2 点类似,无法保证函数返回什么,甚至无法保证函数将返回任何值。函数在 JavaScript 中不像在许多 OO 语言中那样具有显式声明的签名。

你实际上想做什么?

听起来您正试图将强类型、面向对象的语言的相对刚性强加到 JavaScript 的“宽松、随波逐流”的动态类型系统上。恕我直言,这不是一个好主意。也许您可以解释一下您要解决的实际问题?

对不起,如果这是冗长的,咆哮的,或不连贯的。我敢肯定,至少有一种语言 (OCaml?) 完全颠覆了我的逻辑。给我一些反馈。


*当然,假设Foo 不是Bar 的子类型。

...但仅在运行时,所以它实际上并不能比 JavaScript 的类型系统已经获得的保证更多。

因此可能

【讨论】:

  • +1 支持在 JavaScript 中模拟强类型语言的概念可能不是一个好主意的论点。故事的寓意,不要尝试像 Java 那样编写 JavaScript。
  • 我不确定是赞成还是反对。 javascript 使用原型继承并且是动态的,这是有争议的,随它去吧。并且有一些论点认为经典的类 java OO 有一些好东西,所以如果你想要抽象语义,请使用它们。
  • @hvgotcodes:IMO,如果您正在寻找抽象语义,JavaScript 是错误的语言。有比试图破解不自然的范式更好的方式来消磨时间(用任何语言)。这类似于通过使用映射作为唯一的对象类型将动态类型强加到 Java 上。 为工作使用正确的工具。
  • @matt 你有没有注意到很多像 Ext/Sencha 和 Sproutcore 这样的 js 框架是如何采用原型 JS 的,并且他们做的第一件事就是放置机器来模仿经典继承?更何况 Crockford the king 在他的网站上也有关于如何做到这一点的代码?你在争论这两种范式不混合。我认为两者可以互补。 Crockford 指出,原型继承可以使经典模式变得更好:crockford.com/javascript/inheritance.html
  • @hvgotcodes 呃...你看到文章底部的 Crockford 注释了吗,“我现在认为我早期尝试在 JavaScript 中支持经典模型是一个错误。”
【解决方案2】:

Javascript 不支持开箱即用,但很容易模拟所需的语义。如果您有一个想要抽象的基“类”,请将抽象的方法放在上面,并让它们抛出错误。如果用户扩展了您的“类”并且没有提供实现,则会引发错误。例如,你可以这样做

function Thing() {...}
Thing.prototype.abstractMethod = function() {
    throw 'You must implement abstractMethod';
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多