Javascript继承 - 使用.call方法

时间:2016-04-12 09:32:25

标签: javascript inheritance

所以我目前正在使用多个类继承JavaScript继承,因此继承有多个级别。

我已经四处寻找了很多方法,我发现最容易和最好的方法是使用.call()。例如:

function DerivedClass ( para1, para2)
{
    BaseClass.call(this, para1, para2);
    //Insert more code here
}

DerivedClass.prototype = Object.create(BaseClass.prototype);
DerivedClass.prototype.constructor = DerivedClass;

现在,这对我有用,那很好,我很高兴。但我是那种程序员,需要知道为什么或如何运作才能继续。

但是,上面的代码工作正常,并且完全相同(至少对于我正在做的事情),如果我只使用.call()并且不将.prototype和.constructor的东西放在端。

有人可以向我解释为什么如果没有它们的继承仍能正常工作,这个方法需要两个底线吗?

感谢。

2 个答案:

答案 0 :(得分:1)

我认为您已经在JavaScript中查看了很多方法来进行继承,但错过了所有这些方法背后的核心概念。

在JavaScript中实现继承的一种方法是通过原型链接。通过这个过程,子类通过__ proto__(下划线下划线proto下划线下划线)链接指向父类。

简而言之,在JavaScript中继承时需要查找两个属性

  1. 原型 - >功能的属性
  2. __ proto__ - >对象的属性
  3. 如果未在子级中找到,则JavaScript使用proto链接查找父级中存在的属性。

    让我们举一个例子:

    var base{
        prop1 : 4,
        prop2 : 100
    }
    

    假设base是其他子类想要继承的对象

    继承此对象,子类需要将其原型链接指向此对象

    function Child1(){
      //child1 function body
    } 
    
    Child1.prototype = base;
    

    通过这样做,从Child1函数创建的对象也将具有基础对象的属性,但这些对象的构造函数将显示为Object而不是Child1。

    要解决此问题,还需要更新构造函数属性

    Child1.prototype.constructor = Child1
    

    .call函数所做的只是调用父函数将当前子类的'this'或上下文传递给另一个尚未继承它的函数。

    如果省略最后两行,则DerivedClass创建的对象将不包含BaseClass的属性

答案 1 :(得分:0)

DerivedClass.prototype = Object.create(BaseClass.prototype);

这是实现整个继承所必需的。 DerivedClass继承了BaseClass,因为DerivedClass原型是BaseClass.prototype以及新的DerivedClass成员。

这样,DerivedClass个实例也可以访问BaseClass个成员,依此类推(如果你继续使用第三个对象的原型链)。

另一方面,如果你错过了链接原型的部分,那么你就不会实现继承。代码......

BaseClass.call(this, para1, para2);

...等同于基于类的OOP语言call to the base constructor。 ECMA-Script 6/2015及以上版已经有了:

class Derived extends Base
{
      constructor(a, b) 
      {
          // This is the same as Base.call(a, b);
          super(a, b);
      }
}

总之,您将添加BaseClass构造函数中添加的属性,但这不是JavaScript工作方式的继承。请参阅此其他问答以获取更多详细信息:Javascript: Understanding Prototype chain

对于其他代码(构造函数设置),你应该检查另一个Q& A:Why is it necessary to set the prototype constructor?