【问题标题】:Critique my prototypal inheritance pattern - ver2批评我的原型继承模式 - ver2
【发布时间】:2015-08-18 01:27:06
【问题描述】:

我的previous post 的后续行动 - 我的目标是避免构造函数并创建一种模式,以便我可以轻松继承功能

以下代码可以继承任意数量的对象。 construct() 函数,使用 Object.create() 将所有继承的对象放到原型上,然后用传入的属性实例化该对象;可选地,您可以传入在对象上下文中调用的其他函数。

作为内务处理,init 函数会自行删除,因此您最终会得到一个干净的对象,即 obj.props,然后所有继承的函数/props 都驻留在第一个原型链上。通常,当级联链式继承时,您最终会得到一个多级 _proto__ 链,但在这里它们都位于第一个链接中,因此编译器具有一些查找速度优势。

再次,我欢迎您的反馈...

jsfiddle

var Vehicle = {
    colour : 'blue',
    info   : function() { console.log('wheels:' + this.wheels + ' colour:' + this.colour); }
};

var Car = {
    wheels : 4,
    drift  : function() { console.log('drifting'); }
};

var Bike = {
    wheels : 2,
    wheelie : function() { console.log('stunt riding'); }
};

var ferrari = construct( $.extend({}, Vehicle, Car),  {colour:'red'} ); 
var yamaha  = construct( $.extend({}, Vehicle, Bike) ); 

ferrari.drift(); // difting
ferrari.info(); // wheels:4 colour:red
yamaha.wheelie(); // stunt riding
yamaha.info(); // wheels:2 colour:blue

/*
    construct(proto, props, funcs)
    sets prototype functions from inherited classes
    invokes any functions passed
*/

function construct(proto, props, funcs)
{
    return Object.create(proto, {

        init : { value : function() {

            $.extend(this, props);
            if (funcs) for (var i=0; i<funcs.length; i++) funcs[i].call(this);
            delete this.init;

            return this;

        }, configurable : true } // used to delete init prop from object

    }).init(); 
}

【问题讨论】:

  • 如果此代码按预期工作,那么所有这些问题都缺少适合Code Review,是一个大致说明代码作用的标题。
  • 不,我不会批评你的代码。但我会批评你的问题:它的题外话。
  • 继承不会生效,您将在各处拥有属性的副本。不要重新发明轮子,最好使用典型的继承模式。
  • 我投票结束这个问题,因为这个问题应该在codereview.stackexchange.com上。

标签: javascript oop prototypal-inheritance


【解决方案1】:

继承不会生效,您将拥有多个属性副本。

相反,我建议使用Object.create 进行正常继承:

var vehicle = {
  colour: 'blue',
  info: function() {
    console.log('wheels:' + this.wheels + ' colour:' + this.colour);
  }
};
var car = Object.assign(Object.create(vehicle), {
    wheels: 4,
    drift: function() { console.log('drifting'); }
});
var bike = Object.assign(Object.create(vehicle), {
    wheels: 2,
    wheelie: function() { console.log('stunt riding'); }
});
var ferrari = Object.assign(Object.create(car), {colour:'red'} ); 
var yamaha  = Object.create(bike);

【讨论】:

  • 你说“继承不会生效”是什么意思?
  • @grammar 我的意思是如果你给vehicle添加一些属性,它会被ferrari继承,即使它已经被创建了。
  • @Oriol - Object.assign 正是我一直在寻找的工具,感谢您提醒我。
  • @Oriol - 包含引擎的正确方法是什么? jsfiddle.net/u9ax5xzz/3 提前感谢您的帮助。
  • @Data 对象只能从另一个对象继承,不能从多个对象继承。所以你应该使用ferrari.engine.rev而不是ferrari.rev来访问它。但是,继承具有数据的对象(不仅仅是方法)是有问题的,因为所有实例都将继承同一个对象,因此在一个实例上更改该数据将改变所有实例。所以在这种情况下,我建议为每个实例分配一个对象的副本:ferrari = Object.assign(Object.create(car), {engine: Object.create(engine)}
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-06
  • 1970-01-01
相关资源
最近更新 更多