匿名函数中的Javascript inhertiance

时间:2016-04-10 01:47:33

标签: javascript

我正在尝试运行以下代码,我在最后一行收到错误。根据我的理解,x的原型链看起来不错。我在这里错过了什么

var Child = (function(){

  function Parent(){
    this.name ="parent";
    this.parentHello = function(){
      console.log("parent hello "+this.name);
    };
  }

  return function(){
    function Bridge(){

    }
    Bridge.prototype = new Parent();    
    this.constructor.prototype = new Bridge();    
    this.hello = function(){
        console.log('hello');
    };
  };
})();

var x = new Child();


console.log(x.constructor);
console.log(x.constructor.prototype);
x.hello();
x.constructor.prototype.parentHello();  // This works
x.parentHello();  // TypeError: x.parentHello is not a function

这是在现有代码之后建模的,我无法改变它的结构。我稍微修改了原文作为问题发布。

1 个答案:

答案 0 :(得分:1)

我将尝试解释你的代码出了什么问题,并展示了一种更好的方法来实现你现在拥有的相同继承。

分析您的代码:

  1. Child是构造函数。
  2. 在该函数的私有范围内是Parent()构造函数
  3. 使用Child来调用new函数以返回初始化Bridge构造函数和原型的新对象,然后尝试将当前对象的原型的构造函数设置为{{1 }}。
  4. 我猜这里是因为你没有明确描述你想要完成的事情,但看起来你可能正在尝试创建两个级别的继承,其中Parent是基础,然后Bridge派生自Parent,然后Child来自Bridge。
  5. 但是,您无法在new Bridge()的构造函数中设置Child的原型。由于第一个Child对象已经创建,因此设置它为时已晚。
  6. 因此,当您执行Child时,x将只是一个Child对象,而不继承Bridge。因此,它没有x = new Child();方法。
  7. 当您使用继承创建新对象时,还需要调用继承的构造函数,以便它们可以正确初始化它们的实例。
  8. 修复代码:

    1. 由于这里的继承结构是固定的并且提前完全知道,因此没有理由尝试动态地执行此操作。它应该在Child IIFE运行时分配一次,而不是在Child构造函数内。这将解决时间问题并使代码正常运行。
    2. 此外,它是2016年,因此我们应该使用.parentHello()来创建原型,而不是Object.create()
    3. 而且,对象需要调用它们继承的东西的构造函数。
    4. 以下是我的建议(您可以运行此代码段并查看调试控制台):

      new

      而且,这是使用more modern ES6 class syntax的类似实现(您可以在支持ES6类的浏览器中运行此代码段,例如Chrome,Firefox或Edge):

      var Child = (function(){
      
        // define base class
        function Parent(){
          this.name ="parent";
          this.parentHello = function(){
            console.log("parent hello "+this.name);
          };
        }
        Parent.prototype.constructor = Parent;
        
        // define Bridge which inherits from Parent
        function Bridge() {
            // call parent constructor
            Parent.call(this);
        }
        Bridge.prototype = Object.create(Parent.prototype);    
        Bridge.prototype.bridgeHello = function() {
            console.log("bridge hello");
        }
        Bridge.prototype.constructor = Bridge;
      
        function Child() {
            // call parent constructor
            Bridge.call(this);
            this.hello = function(){
              console.log('hello');
            };
        }
        Child.prototype = Object.create(Bridge.prototype);
        Child.prototype.constructor = Child;
        
        return Child;
      })();
      
      var x = new Child();
      
      console.log(x);
      console.log(x.constructor);
      x.hello();
      x.bridgeHello();
      x.parentHello();