批判我的原型继承模式

时间:2015-08-14 05:24:55

标签: javascript oop prototypal-inheritance

我决定使用Object.create,因为它似乎比使用'new'更直观,并且必须为每个函数编写Car.prototype.func1 = function(){},例如;好像有点太干了。

我有一个使用$ .extend来增强属性和函数的顿悟,使得从我想要使用的任何对象中获取代码变得更容易。一旦对象被扩展,我就会使用Object.create()来设置原型,因此这些函数对所有实例都是通用的,并将属性作为第二个参数传递。

以下模式可以吗? jsfiddle

// props use Object.defineProperties() format; can configure each prop as writable, enumerable, etc

var Vehicle = {
    props : { 'colour' : {value:'black'}, 'wheels' : {value:4} },
    proto : { 'drive' : function(){console.log('drive ' + this.colour + ' ' +     this.wheels);} }
};

var Ferrari = {
    props : { 'colour' : {value:'red'}, 'seats' : {value:2} },
    proto : { 'fast' : function(){console.log('ferrari power ' + this.colour + ' ' + this.wheels + ' ' + this.seats);} }
}; 

function init(){

    // copy Vehicle object, so it remains untouched
    var vehicle = $.extend(true,{}, Vehicle); 

    // augment vehicle super-class with sub-class
    $.extend(vehicle.props, Ferrari.props);
    $.extend(vehicle.proto, Ferrari.proto);

    // prototypal inheritance
    var ferrari = Object.create(vehicle.proto, vehicle.props);
    ferrari.drive();
    ferrari.fast();
}

init();
编辑:我放弃了这个想法,太乱了;我正在使用原型模式,显示在this article的末尾。

2 个答案:

答案 0 :(得分:2)

这是创造性的代码,但它感觉模糊不清并引入了太多偶然的复杂性,例如需要jQuery(如果你的项目已经依赖于jQuery,这不一定是坏事)。 JavaScript专门基于原型继承而设计......为什么不利用它?

另外,关于添加原型属性的感觉似乎过于重复:

var Cat = function() { ... };

// then when defining the prototype...

Cat.prototype.purr = function() { ... };
Cat.prototype.meow = function() { ... };

你会发现人们通常会推荐上面定义原型属性的方法有几个原因(相对于我将在下面展示的方法),因为,就一个方面而言,关于垃圾收集和循环引用的消除。但是,如果您担心“重复自己”太多,只需将原型设置为普通对象:

Cat.prototype = {
  purr: purr,
  meow: meow
};

function purr() {
  // whatever
}

function meow() {
  // whatever
}

如上所示,第二种方式利用了JavaScript的功能提升功能,并引入了类似于the revealing module pattern的概念。

答案 1 :(得分:2)

您不应该使用$.extend进行继承,并且应该立即在类的定义中声明继承,而不是稍后在init函数中声明继承。
此外,你的“增强车辆超级级别与子级”似乎真的倒退了。需要“复制Vehicle对象,因此它保持不变”并且您要从ferrari而不是vehicle创建Ferrari实例。

我建议使用两个辅助函数:

function inherit(superClass, props, proto) {
    return {
        props: $.extend(Object.create(superClass.props), props),
        proto: $.extend(Object.create(superClass.proto), proto)
    };
}
function create(template) {
    return Object.create(template.proto, template.props);
}

您可以使用

var Vehicle = {
    props : { 'colour' : {value:'black'}, 'wheels' : {value:4} },
    proto : { 'drive' : function(){console.log('drive ' + this.colour + ' ' +     this.wheels);} }
};

var Ferrari = inherit(Vehicle, {
    'colour' : {value:'red'},
    'seats' : {value:2}
}, {
    'fast' : function(){console.log('ferrari power ' + this.colour + ' ' + this.wheels + ' ' + this.seats);}
});

var ferrari = create(Ferrari);
ferrari.drive();
ferrari.fast();

除了这些问题,你的模式也很好。使用纯原型继承是一种既定模式。您可以通过向模板对象(类)添加初始化函数来修改它,例如, .constructor,你又恢复了典型阶级模式的力量。