【问题标题】:Why was JavaScript implemented using prototypal inheritance?为什么 JavaScript 使用原型继承来实现?
【发布时间】:2011-01-06 15:08:54
【问题描述】:

有很多文章和帖子解释了 JavaScript 继承是如何工作的,但是为什么 JavaScript 使用原型继承而不是经典继承来实现呢?

我喜欢 JavaScript,所以我并不是说它是坏事……我只是好奇。

【问题讨论】:

  • 请标记为社区 wiki..
  • JavaScript 的创建者是 Stackoverflow 用户吗?
  • @Gaby - 某处有答案。
  • @André Brendan Eich? - 你可以查一下他/users/
  • 我的问题是:为什么没有更多的语言使用原型继承?

标签: javascript inheritance prototypal-inheritance


【解决方案1】:

以下是 Brendan Eich 对所发生事件的看法: https://brendaneich.com/2008/04/popularity/

正如我经常说的那样,正如 Netscape 的其他人所证实的那样,我被招募到 Netscape 的承诺是在浏览器中“执行 Scheme”。至少包括 Tom Paquin、Michael Toy 和 Rick Schell 在内的客户工程管理人员以及一些名叫 Marc Andreessen 的人都确信 Netscape 应该在 HTML 中嵌入一种源代码形式的编程语言。

高层工程管理部门的命令是该语言必须“看起来像 Java”。这排除了 Perl、Python 和 Tcl 以及 Scheme。

我并不自豪,但我很高兴我选择了类似于 Scheme 的一流函数和 Self-ish(尽管是单一的)原型作为主要成分。 Java 的影响,尤其是 y2k 日期错误以及原始与对象的区别(例如,字符串与字符串)是不幸的。

【讨论】:

    【解决方案2】:

    原型继承(带有闭包)允许其他人做从未设想过的事情。它是几种范式的结合,共同实现了通用编程。

    使用原型语言,您可以为您的课程添加“混入”。您可以实现所需的封装级别,而无需特定语言的关键字。简而言之,原型语言很棒。

    我不想这么说,但是 JavaScript 和一些库可以完成我需要它做的所有事情。它的发展是颠覆性的(应该是从属于 Java 的)。在最简单的实现中,它具有强大的功能。

    通过足够的学习/玩耍,您将开始看到它的灵感的优势。 JavaScript 是少数有意“隐藏”其潜力的语言之一。如果你想知道“为什么”,就必须涉足政治。但是,正是因为这个原因,它很棒。

    【讨论】:

    • @Pestilence,你能给我指出一些“做从未想过的事情”的资源吗?例如,使用 mix-ins,我可以通过设置我的原型来从对象中获取方法,但我只能这样做一次,对吗?除非我在不需要原型的情况下做某事,例如: - 我有一个对象 X,我希望它拥有 Y.doSomething - X.doSomething = Y.doSomething - (不过,它只是设置了对 Y.doSomething 的引用,对吧?如果我希望它独立拥有)
    • 嗯,模拟类继承是您可以做的一件事……但是,您真的不必担心动态类型语言中的层次结构。只需将一个或多个原型克隆到一个新实例中。您可以做的事情包括: 通过混合来自其他“类”的方法和初始化程序来动态构建“类”和实例。在“构造”期间以编程方式更改界面。甚至改变基“类”。修改所有字符串对象以包含 Base64 方法是我喜欢做的事情:“foo”.base64()。
    • 您所指的原型属性对于自定义类可以被认为是可选的。您可以完全控制并绕过它。
    • 这是对在 JS 中构建类的不同方式的一个不错的描述:ruzee.com/blog/2008/12/… 注意他是如何创建和扩展的(内联)。我不认为在创建 JS 的时候,这种设计模式存在。
    【解决方案3】:

    因为它深受 Self 的影响。维基百科和 ECMA 规范都提到了这一点。

    【讨论】:

      【解决方案4】:

      我认为选择它是因为它易于实现,不需要额外的关键字,而且用户不需要理解它就能使用该语言。它也比基于类的继承更强大、更灵活。

      这是无类型语言的自然选择。基于类的继承的主要优点是它允许静态类型,从而允许类型检查和更快的基于表的查找实现。

      【讨论】:

        【解决方案5】:

        JavaScript 最初应该与 Lisp 非常相似。即使在语法更改为更接近 C/Java 之后,它仍然是 Lisp in C's clothing。我认为答案在于它的函数式编程起源。在纯 FP 中,没有可变状态,这意味着没有可变对象。如果你稍微放宽规则并稍微有创意,你最终会得到类似原型继承的东西,即你可以扩展对象但不能修改原始对象。它提供与继承相同的功能,并且仍然为您提供一些不变性。

        最后,扭转语言,让它看起来像 C++ 和 Java,还有 viola,你有 new someFunction(),剩下的就是历史了。

        【讨论】:

        • “没有可变状态,也就意味着没有可变对象”是什么意思?
        • @Andre:在 pure 函数式编程(例如 Erlang)中,所有变量都是常量。变量实例化后,它们持有的值不能修改。由于我们使用变量来引用对象,这意味着纯 FP 中的对象不能被修改:所有对象都是常量。
        • 好吧,但是,在 javascript 中,如果我这样做:var a = {name="n",age=1}。 a.age = 2. 我在做什么?重新实例化'a'?
        • @Andre 我的观点是 JavaScript 放宽了规则并允许可变状态,但是因为它起源于 FP,所以原型继承具有某种意义,因为它允许您在扩展对象的同时保持原件不变。
        • lisp 具有可变状态;不变性与原型继承无关。
        猜你喜欢
        • 2015-10-29
        • 2011-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-28
        • 2018-02-21
        • 1970-01-01
        相关资源
        最近更新 更多