Javascript 继承调用父级的非默认构造函数

标签 javascript inheritance prototype super default-constructor

我知道原型(prototype)继承的经典模式是基于设置构造函数的对象原型(prototype)。 然而,我愿意能够从派生类构造函数调用父构造函数,并使用一些在调用之前不可用的参数。

这在 Java/Python/PHP 中可以通过 super(...) 或 Parent.__init__(...) 方法很好地完成。

然而,在普通的 Javascript(不是 coffescript 或类似的)中,没有办法做到这一点( parent.apply(this,arguments) 可以,但它不会设置原型(prototype))。

经过一些阅读后,我得到了这个解决方案,将“inherits”方法添加到 Function 的原型(prototype)中。 这只是将 super 的定义添加到派生函数中,以便根据一些参数初始化原型(prototype)。

Function.prototype.inherits=function(parent)
{
    var ctor=this;
    var p=Object.create(parent);
    ctor.super=function()
    {
        parent.apply(p,arguments);
    }
    ctor.prototype=p;
}


//testing

function A(x)
{
    this.x=x;
}

function B(y)
{
    B.super(y*2);//Here "super" is available and I can pass parameters. 
    this.y=y;
}
B.inherits(A);//here I define the inheritance


a=new A(3);
b=new B(5);


console.log(a);//returns { x: 3 }
console.log(b);//returns { y: 5 }
console.log(b.x);//returns 10


console.log(a instanceof A);//returns true
console.log(b instanceof B);//returns true

通过这种方式,我得到了我期望的行为。 我的问题是:这个解决方案有什么缺点?对于同样的问题是否有更有效的解决方案?这个解决方案是跨浏览器的吗?

PS:我自己发明的:)

编辑:为了避免与其他库发生冲突,我可以定义一个像这样的独立函数来实现相同的目标。

function inherits(klass,parent)
{
    var p=Object.create(parent);
    klass.super=function()
    {
        parent.apply(p,arguments);
    }
    klass.prototype=p;
}

在 B 定义后的测试中,只需调用

inherits(B,A);

编辑2: 经过Moolamaduck的考虑,我重写了代码以解决共享原型(prototype)的问题。结果非常简单易用且优雅(恕我直言)。
https://stackoverflow.com/a/33270707/76081

最佳答案

这是一个实现您想要的最小示例(从派生类的构造函数中调用父构造函数):

var Shape = function(sides) {
  this.sides = sides;
};

var Square = function(size) {
  /* Just call the parent constructor function with `this` as context. */
  Shape.call(this, 4);
  this.size = size;
};

/* Set up the prototype chain. Use a shim for `Object.create` if you want. */
Square.prototype = Object.create(Shape.prototype);

这就是它的全部内容:使用正在构造为上下文的对象调用父构造函数,并设置原型(prototype)链。

您发布的代码中存在一个严重缺陷。也就是说,您正在使用派生类的原型(prototype)作为上下文来调用父构造函数,而不是正在构造的对象。这意味着父构造函数初始化的成员将在派生类的所有实例的原型(prototype)上更新,因此所有实例都将被更新。这不是你想要的。

为了说明问题:

Function.prototype.inherits=function(parent)
{
    var ctor=this;
    var p=Object.create(parent);
    ctor.super=function()
    {
        parent.apply(p,arguments);
    }
    ctor.prototype=p;
}


function A(x)
{
    this.x=x;
}

function B(y)
{
    B.super(y*2);
    this.y=y;
}

B.inherits(A);

var b1 = new B(1);
var b2 = new B(2);
alert(b1.x); // displays "4" instead of "2"!

关于Javascript 继承调用父级的非默认构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33225825/

相关文章:

javascript - 如何删除/重置window.onfocus功能?

c# - 可以在 Dictionary 继承的类中重新定义索引器吗?

java - 对java中 protected 成员的行为感到困惑

javascript - JS 中属性值为 n 的循环对象

javascript - 获取 SVG 中路径的维度

javascript - 如何从浏览器 JavaScript 访问 Thingsboard REST API?

javascript - 如何在 EXT JS 中渲染 10,000 多条记录的图表?

ios - 对对象的引用返回 null(iOS 类继承)

javascript 原型(prototype)继承和 'new' 关键字

javascript - 在原型(prototype)中进行事件绑定(bind)是否明智,为什么它的上下文会丢失?