所以我目前正在使用多个类继承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的东西放在端。
有人可以向我解释为什么如果没有它们的继承仍能正常工作,这个方法需要两个底线吗?
感谢。
答案 0 :(得分:1)
我认为您已经在JavaScript中查看了很多方法来进行继承,但错过了所有这些方法背后的核心概念。
在JavaScript中实现继承的一种方法是通过原型链接。通过这个过程,子类通过__ proto__(下划线下划线proto下划线下划线)链接指向父类。
简而言之,在JavaScript中继承时需要查找两个属性
如果未在子级中找到,则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?