【问题标题】:Is it true that Javascript, before ECMA-262 or ECMA 5.1, doesn't have pseudo-classical inheritance or prototypal inheritance support?Javascript 在 ECMA-262 或 ECMA 5.1 之前是否没有伪经典继承或原型继承支持?
【发布时间】:2012-10-02 17:26:49
【问题描述】:

原因是,虽然我们可以在 Javascript 中使用伪经典继承,但实际上我们必须实现自己的 extendinherit

原型继承呢——我认为它确实有这样的特点,如果foo.bar被使用,如果bar不是foo的属性,解释器或编译代码(例如如果使用Google V8) 将沿原型链向上,但没有内置方法使对象b 的隐藏原型属性指向a 作为原型链。我们必须通过定义clone() 函数或Object.create() 来添加它。更重要的是,我想我在纯原型继承代码中看到没有任何构造函数。所以看起来在原型代码中,没有构造函数(构造函数)。但是如果我们使用原型继承,我们实际上必须使用构造函数来实现clone()——这更像是伪经典继承方面。

所以看起来原来的 Javascript 实际上既不是伪经典也不是原型继承?根据this Wikipedia article,我读到它需要在 10 天内上市,否则市场上会出现更糟糕的情况。但我也有些纳闷,为什么在 1995 年 Javascript 出现后的 1 年或 2 年,至少 Netscape 版本的 Javascript 还没有添加 extendObject.create() 方法?

本题旨在理解和澄清 Javascript 的伪经典和原型部分中的一些概念。是真的吗 - 原始 Javascript 本身不支持伪经典或原型继承?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    最初的目标是模仿类 C 语言,让 JS 看起来足够熟悉以加快采用速度。

    在 1997 年,没有人以任何接近先进的方式使用 JS,甚至懒得考虑查看原型。

    人们仍在制作如下物品:

    var car = new Object();
    car.doors = 4;
    car.wheels = 4;
    car.position = new Object();
    car.position.x = 230;
    car.position.y = 400;
    

    使用数组来制作这些对象的人更好。

    var car = new Array();
    car["doors"] = 4;
    car["wheels"] = 4;
    car["position"] = new Array();
    car["position"]["x"] = 230;
    car["position"]["y"] = 400;
    

    这就是当时 A 很多 JS 的样子。

    老实说,仍然有很多看起来像这样,因为人们仍然从 Java 或 C# 或 C++ 或 PERL 或 PHP 进来,并认为它看起来如此熟悉以至于他们不需要费心去学习它——他们可以把数组变成对象,或者变成集合,或者变成字典,这没关系......

    他们就是这样做的。

    没有人认为 JS 会很重要。从来没有人想到过。所以浏览器间的标准直到它已经成为一件大事时才出现,那时,每个人对 JS 是什么都有不同的想法。

    即便如此,Internet Explorer 拥有最广泛的市场份额,以及最糟糕和最不标准的 JS 实现...... 这已经改变了,但说真的,我们现在刚刚达到一个点,所有重要的浏览器新版本(5 大)都支持五年前概述和标准化的功能......

    ...当你在谈论这样的事情时,这就是让船掉头所需要的时间。

    【讨论】:

      【解决方案2】:
      【解决方案3】:

      Classical Inheritance 不是官方语言功能,但 Prototypical Inheritance (并且已经很长时间了),但它有点笨拙。

      但事实证明,您可以使用原型复制经典继承,但反之则不行。并且有很多图书馆可以做到这一点。我喜欢 John Resig 的 herebackbonecoffee script classes

      你确实有构造函数,但没有超级。

      Here's an example of how to do simple inheritance in plain old javascript.

      // Parent "class"
      var Foo = function() {
        this.barVal = 'baz';
      };
      
      // Parent instance method
      Foo.prototype.bar = function() {
        return this.barVal;
      };
      
      // Test out an instance
      var foo = new Foo();
      console.log(foo.bar()); // 'baz'
      
      
      
      
      
      
      // Child "class"
      var Foo2 = function() {
        Foo.call(this); // invokes previous constructor 
      };
      
      // Assign prototypical ancestor
      Foo2.prototype = new Foo();
      
      // Child instance method
      Foo2.prototype.bar = function() {
        var prevResult = Foo.prototype.bar.call(this); // invoke previous method implementation
        return prevResult + '!';
      }
      
      // New child instance method
      Foo2.prototype.newMethod = function() { // new method only on child class
        return 'Some new method!'
      };
      
      // Test out an instance
      var foo2 = new Foo2()
      console.log(foo2.bar()) // 'baz!'
      console.log(foo2.newMethod()) // 'Some new method!'​
      

      但这里也有边缘情况。使用一个小的帮助库来简化这一切并不丢人。

      【讨论】:

      • 是的,Foo2.prototype = new Foo();Foo2.prototype.constructor = Foo2;extend 函数的一部分,有些人喜欢使用空的F(),因为这样Foo2.prototype 就没有全部了如果Foo() 运行复杂,这些额外的属性将不会运行很长时间。
      • 有很多方法可以在 JS 中构建经典继承,这是我的观点。
      猜你喜欢
      • 2015-10-12
      • 2013-11-07
      • 1970-01-01
      • 1970-01-01
      • 2016-04-10
      • 2016-07-30
      相关资源
      最近更新 更多