使用带有可变长度参数数组的JavaScript new关键字

时间:2012-05-20 23:05:53

标签: javascript inheritance

我正在构建一个允许对象被任何其他对象扩展的函数

Object.prototype.extend = function(constructor, args) {
    var proto = this;
    while(proto.__proto__.constructor !== Object) {
        proto = proto.__proto__
    }
    proto.__proto__ = new constructor(args)
    console.log(this); 
}

该方法将被调用如下:

function ChildModelConstructor(1,2,3) {
    this.extend(ParentModel, arguments)
}
or
instanceOfChildModel.extend(ParentModel, [1,2,3])
问题是如果我像这样打电话给新人:

new constructor(args)

父对象的构造函数接收参数,该参数是参数对象或数组。

我想要的是能够致电

new constructor.apply(args)

或类似的东西,我不是试图改变这个新的上下文,apply是使用args对象或我所知道的数组调用方法的唯一方法。

感谢您的帮助:)

更新,我找到了更好的方法

这是一种更好的继承方法我想出了它,它避免使用折旧的原型

与我发现的其他继承方案相比,这种方法有几个优点。最大的问题是它不会合并多个级别的原型链。许多方案将childClass的proto方法与父类实例变量混合,或者更糟糕的是,父类初始化的所有方法和属性直接进入childClass的主体。

缺点是,它是单继承,并且您无法更改单个实例的继承,因为prototype属性属于构造函数。

Function.prototype.inherit = function(parentClass) {
    var newPrototype = Object.create(Object.create(parentClass.prototype));
    for(key in this.prototype){
        newPrototype[key] = this.prototype[key];
    }
    this.prototype = newPrototype;    
    this.prototype.constructor = this;
    this.prototype.parentClass = parentClass;
    this.prototype.initParent = function(args) {
        var proto = Object.getPrototypeOf(Object.getPrototypeOf(this))
        this.parentClass.apply(proto, args);
    }
    this.prototype.uber = function() {
        return Object.getPrototypeOf(Object.getPrototypeOf(this));
    }        
}

你可以设置这样的继承:

function Model(n) {
    this.initParent(arguments)
    this.test = n*2;
}
Model.inherit(BaseClass);

以下是JSFiddle http://jsfiddle.net/michaelghayes/2rHgK/

中稍微详细的版本

2 个答案:

答案 0 :(得分:0)

这是未经测试的,但我认为它会起作用。替换:

proto.__proto__ = new constructor(args)

使用:

proto.__proto__ = {};
proto.__proto__.prototype = constructor.prototype;
constructor.apply(proto.__proto__, args);

请注意,__proto__已弃用。

答案 1 :(得分:0)

最好不要将东西附加到对象原型,只需手动设置继承:

Model function() {
  //init parent first because of chromes hidden classes
  ParentClass.apply(this, [].slice.call(arguments))
  //new instance properties
  this.something = 'something'
}

Model.prototype = Object.create(ParentClass.prototype, {
  constructor: {value: Model}
})

//Prototype props
Model.prototype.whatever = function(){return 'whatever'}

这也允许你在启动父类之前修改args,因为新类不应该被限制为使用与其父类完全相同的args