Javascript混合模式设置特定于此变量的实例

Javascript混合模式设置特定于此变量的实例,javascript,oop,mixins,Javascript,Oop,Mixins,如果我对对象使用构造函数,对共享功能使用原型,我希望将共享功能(函数)混合到对象的原型中,但将特定于实例的(thisvaraibles)混合到对象实例中 添加我找到的原型零件。为了设置原型函数假定存在的实例变量,我提出了一个init(每个mixin一个) 下面是一个简单的例子: var mixIn=function(target,source){ for(fn in source){ if(source.hasOwnProperty(fn)){ target.protot

如果我对对象使用构造函数,对共享功能使用原型,我希望将共享功能(函数)混合到对象的原型中,但将特定于实例的(
this
varaibles)混合到对象实例中

添加我找到的原型零件。为了设置原型函数假定存在的实例变量,我提出了一个init(每个mixin一个)

下面是一个简单的例子:

var mixIn=function(target,source){
  for(fn in source){
    if(source.hasOwnProperty(fn)){
      target.prototype[fn]=source[fn];
    }
  }
};
var SpeakEnable = {
  say:function(){
    console.log(this.message);
  },
  initSpeak:function(){// for initializing instance vars
    this.message="Hello World Mixed in!";
    this.object=[];
  }
};
var Person=function(){
  this.initSpeak();//have to init instance vars
};
// set up inheritance
// set up Person.prototype
// set speak enable
mixIn(Person,SpeakEnable);

var lulu=new Person();
lulu.say();

var june=new Person();
console.log(june.say===lulu.say);//true
console.log(june.object===lulu.object);//false
这一切都很好,但初始化实例变量是我遇到一些问题的地方。不知何故,这似乎不是一个非常干净的方式。当我混合几个mixin时,Person构造函数必须调用所有init函数来设置实例变量。忘记调用它将导致奇怪的错误(在这种情况下,当对实例调用
时,控制台日志记录未定义)


所以问题是:有没有更干净的方法来设置初始实例变量,这些变量是mixin函数假定存在的?

您可以从基本对象继承所有可混合的对象,以确保正确的初始化。这是一种实现目标的干净方法

以下代码演示了这一原则:

//------------ framework

var inherits = function(childCtor, parentCtor) {
  function tempCtor() {};
  tempCtor.prototype = parentCtor.prototype;
  childCtor.superClass_ = parentCtor.prototype;
  childCtor.prototype = new tempCtor();
  childCtor.prototype.constructor = childCtor;
};

var mixIn=function(target,source){
  for(fn in source){
    if(source.hasOwnProperty(fn) && fn.name != 'init'){
      target.prototype[fn]=source[fn];
    }
  }

  if (typeof source.init == 'function') { 
      if (target.prototype._mixInits === undefined) { 
          target.prototype._mixInits = [];
      }
      target.prototype._mixInits.push(source.init);
  }
};

// all objects that can be mixin's should inherit from
// this object in order to ensure proper initialization
var Mixable = function() {
    var mixInits = this.__proto__._mixInits;
    if (mixInits !== undefined) {
        for (var i = 0; i < mixInits.length; i++) {
            mixInits[i].call(this);
        }
    }
};

//------------ testcode

var SpeakEnable = {
  say:function(){
    console.log(this.message);
  },
  init:function(){
    console.log('say init called');
    this.message="Saying Hello World Mixed in!";
    this.object=[];
  }
};

var WalkEnable =  {
  walk:function(){
    console.log(this.walk_message);
  },
  init:function(){
    console.log('walk init called');
    this.walk_message="Walking step 1.2.3.";
  }
};


var Person=function() {
  Mixable.call(this);
};

inherits(Person, Mixable);

mixIn(Person,SpeakEnable);
mixIn(Person,WalkEnable);

var lulu=new Person();
lulu.say();
lulu.walk();
/--------------框架
var inherits=函数(childCtor、parentCtor){
函数tempCtor(){};
tempCtor.prototype=parentCtor.prototype;
childCtor.superClass=parentCtor.prototype;
childCtor.prototype=新的tempCtor();
childCtor.prototype.constructor=childCtor;
};
var mixIn=函数(目标、源){
for(来源中的fn){
if(source.hasOwnProperty(fn)&&fn.name!=“init”){
target.prototype[fn]=源[fn];
}
}
if(typeof source.init=='function'){
if(target.prototype.\u mixInits==未定义){
prototype.\u mixInits=[];
}
target.prototype.\u mixInits.push(source.init);
}
};
//可以作为mixin的所有对象都应该从
//此对象以确保正确初始化
var Mixable=函数(){
var mixInits=这个;
if(mixInits!==未定义){
对于(var i=0;i
谢谢,您可以删除inherrit,因为
Mixable.call(this)
足以初始化实例。True。不过,我会考虑这个适当的设计,虽然。您还可以将其用作检查mixIn是否可行(即,在mixIn函数中,您将检查目标是否从Mixable继承)。确实,这仍然不能保证调用super的构造函数,但这不仅仅是空话。