Javascript继承调用父';s的非默认构造函数

Javascript继承调用父';s的非默认构造函数,javascript,inheritance,prototype,super,default-constructor,Javascript,Inheritance,Prototype,Super,Default Constructor,我知道原型继承的经典模式是基于设置构造函数的对象原型。 但是,我希望能够从派生类构造函数中调用父构造函数,并且在调用之前使用一些不可用的参数 这在Java/Python/PHP中通过super(…)或Parent.\uuuu init\uuuu(…)方法很好地实现了 但是,在纯Javascript(不是coffescript或类似的)中,没有办法做到这一点(parent.apply(这是参数)不设置原型) 经过一些阅读,我得到了这个解决方案,将“inherits”方法添加到函数的原型中。 这只是

我知道原型继承的经典模式是基于设置构造函数的对象原型。 但是,我希望能够从派生类构造函数中调用父构造函数,并且在调用之前使用一些不可用的参数

这在Java/Python/PHP中通过
super(…)
Parent.\uuuu init\uuuu(…)
方法很好地实现了

但是,在纯Javascript(不是coffescript或类似的)中,没有办法做到这一点(
parent.apply(这是参数)
不设置原型)

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

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
这样我就有了我所期望的行为。 我的问题是:这个解决方案的缺点是什么?对于同一个问题有没有更有效的解决方案?此解决方案是否跨浏览器

附言:这是我自己发明的:)

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

function inherits(klass,parent)
{
    var p=Object.create(parent);
    klass.super=function()
    {
        parent.apply(p,arguments);
    }
    klass.prototype=p;
}
并在测试后定义B简单调用

inherits(B,A);
编辑2: 经过考虑,我已经重写了代码,以解决共享原型的问题。其结果非常简单易用且优雅(IMHO)。

一个缺点是,扩展内置对象(如函数或数组)的原型可能会与页面上运行的第三方脚本发生冲突。如果两个脚本试图覆盖同一个原型,您可能会得到意外的结果


就浏览器兼容性而言,最薄弱的环节似乎是
Object.create
,这在IE 8及更早版本中不受支持。请参见

一个缺点是,扩展内置对象(如函数或数组)的原型可能会与页面上运行的第三方脚本冲突。如果两个脚本试图覆盖同一个原型,您可能会得到意外的结果


就浏览器兼容性而言,最薄弱的环节似乎是
Object.create
,这在IE 8及更早版本中不受支持。请参见

一个缺点是,扩展内置对象(如函数或数组)的原型可能会与页面上运行的第三方脚本冲突。如果两个脚本试图覆盖同一个原型,您可能会得到意外的结果


就浏览器兼容性而言,最薄弱的环节似乎是
Object.create
,这在IE 8及更早版本中不受支持。请参见

一个缺点是,扩展内置对象(如函数或数组)的原型可能会与页面上运行的第三方脚本冲突。如果两个脚本试图覆盖同一个原型,您可能会得到意外的结果


就浏览器兼容性而言,最薄弱的环节似乎是
Object.create
,这在IE 8及更早版本中不受支持。请参见

您似乎正在寻找一种通用模式,在该模式中可以在JavaScript中重新创建经典的面向对象的范例(包括使用
super

几年前,johnresig(jQuery的创建者)提出了一组函数,允许您在Javascript中模拟这一点

但是,由于一些原因(包括使用
参数.被调用方
属性),该属性现在被认为是不推荐的,但仍然可以作为良好的基础

有许多建议的改进取代了
参数。被调用方
属性,包括:


如果您正在寻找一种可靠的方法来用JavaScript重新创建经典的面向对象,我会进一步研究John原始代码的改进(这家伙知道他在说什么,这是一个很好的基础)

几年前,johnresig(jQuery的创建者)提出了一组函数,允许您在Javascript中模拟这一点

但是,由于一些原因(包括使用
参数.被调用方
属性),该属性现在被认为是不推荐的,但仍然可以作为良好的基础

有许多建议的改进取代了
参数。被调用方
属性,包括:


如果您正在寻找一种可靠的方法来用JavaScript重新创建经典的面向对象,我会进一步研究John原始代码的改进(这家伙知道他在说什么,这是一个很好的基础)

几年前,johnresig(jQuery的创建者)提出了一组函数,允许您在Javascript中模拟这一点

但是,由于一些原因(包括使用
参数.被调用方
属性),该属性现在被认为是不推荐的,但仍然可以作为良好的基础

有许多建议的改进取代了
参数。被调用方
属性,包括:

如果您正在寻找一种可靠的方法来用JavaScript重新创建经典的面向对象,我会进一步研究John原始代码的改进(这家伙知道他在说什么,这是一个很好的基础)。

看起来您是在
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);
function inherits(ctor,parent)
{
    ctor.prototype=Object.create(parent.prototype);
    ctor._super=function()
    {
        parent.apply(this,arguments);
    }
}


//testing

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

function B(y)
{
    B._super.call(this,y*2);//Here "_super" is available (after calling inherits) and I can pass parameters to the parent constructor.
    this.y=y;
};
inherits(B,A);// Here we call inherits, after this parent will be available in the B constructor


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


console.log(a);//returns A {x: 3}
console.log(b);//returns B {x: 10, y: 5}
console.log(b.x);//returns 2*5=10

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

//post instantiation method definition and inheritance
A.prototype.test=function(){console.log(this.x+1);};
a.test();//returns 3+1=4
b.test();//returns 2*5+1=11



var b1 = new B(1);
var b2 = new B(2);


console.log(b1.x);//returns 2
console.log(b2.x);//returns 4