2014-03-27 51 views
1

首先大家好,对不起我的英文。
我仍然会利用这个社区的专业知识和可用性。
在此期间,我正在学习javascript,Crockford模式,deepcopy shallowCopy等的继承。
我也在stakoverflow(here,here ecc ..)中阅读过许多文章,但我并没有隐藏,我的疑惑仍然很多。
我的目标是创建一种伪多重继承而不使用jQuery或ObjectCreate方法。
伪是因为,正如我从阅读各种帖子了解到的,JavaScript中的多重继承不存在。
在我的脚本中有两个“超类”(HomoErectus和HomoSapiens)和一个“子类”(ModernMan)。
我的copyProtoDeep函数复制了子类原型中超类原型的所有属性。
此函数接受无限数量的参数,第一个参数是从函数调用中指定的其他类继承的类。
为避免浅拷贝,如果copyProtoDeep找到一个对象或一个数组,函数会克隆这些元素。
oop javascript deepcopy mixins多重继承

这就是说,我想,如果可能的话,下面的问题的答案。
我的代码是否正确?
这种无害的混合类型是什么?
这个过程的负面方面(或缺点)是哪些?
超级的使用是正确的吗?
我可以改进我的代码吗?

我知道我的问题对于单个帖子来说可能太多了,但是也会很愉快地阅读部分回复。
感谢所有提前

<script type="text/javascript"> 
    function copyProtoDeep() { 
     var len = arguments.length; 
     arguments[0].prototype.uber=[] 
     for (j = 1; j <len; j++) { 
      var parent = arguments[j].prototype; 
      var child = arguments[0].prototype; 
      for (var i in parent) { 
       if (parent.hasOwnProperty(i)) { 
        if (typeof parent[i] === 'object') { 
         child[i] = Array.isArray(parent[i]) ? parent[i].slice(0) : JSON.parse(JSON.stringify(parent[i])); 
         } else { 
         child[i] = parent[i]; 
        }    
       } 
      } 
      child.uber[j] = arguments[j].prototype 
     } 
    }  

    function HomoErectus(name){ 
     this.name=name 
     this.sayHello=function(){return 'Hello from '+this.name} 
     } 
    HomoErectus.prototype.discovery='fire' 
    HomoErectus.prototype.scream='yabadabadoo' 
    HomoErectus.prototype.friends=['wilma','Betty','Barney'] 
    HomoErectus.prototype.uberTest1=function(){ 
     if(this.uber){return 'the ancestor of '+this.name+" discovered "+this.uber[1].discovery} 
     else{return this.name+' discovered '+this.discovery} 
     } 

    function HomoSapiens(name){ 
     this.name=name 
     this.iam=function(){return 'I am an Homosapiens an my name is '+this.name+' and my weapons are '+this.dangerousWeapons.w1} 
     } 
    HomoSapiens.prototype.discovery='wheel' 
    HomoSapiens.prototype.dangerousWeapons={w1:'bow and arrows',w2:'Spear and shield'} 
    HomoSapiens.prototype.uberTest2=function(){if(this.uber){return 'yes yes'}else{return 'no no'}} 

    function ModernMan(){ 
     HomoErectus.apply(this, arguments); 
     HomoSapiens.apply(this, arguments); 
     } 
    copyProtoDeep(ModernMan, HomoErectus,HomoSapiens) 
    ModernMan.prototype.discovery='pc' 

    var fred=new HomoErectus('Fred') 
    console.log(fred.uberTest1()) 

    var bubba=new HomoSapiens('Bubba') 
    console.log(bubba.uberTest2()) 

    var john = new ModernMan('John') 
    john.friends.push('Riky') 
    john.dangerousWeapons.w3='guns and bombs' 

    console.log(john.uber[1].friends) 
    console.log(john.uber[2].dangerousWeapons) 
    console.log(john.uberTest1()) 
    console.log(john.uberTest2()) 
</script> 
+1

为什么javascripters讨厌组成这么多他们诉诸这样的廉价技巧?有了这种帮手,人们几乎无法控制被覆盖或不被覆盖的东西。比方说,我们想让HomoErectus的朋友发现HomoSapiens的发现......猜测是什么,帮手完全没有帮助。战略将解决这一混乱。 – mpm

+0

[JavaScript中的多重继承/原型]的可能重复(http://stackoverflow.com/questions/9163341/multiple-inheritance-prototypes-in-javascript) – kol

回答

0

有我的答案:

是我的代码是否正确?

我认为mixin没有确切的规则,所以你的代码可能是正确的。我没有发现任何更大的问题。

这种类型的不适是混合吗?

如果您继承了所有方法,那么mixin(可以)等于多重继承。而且因为你也称为超级构造函数,它看起来更像继承而不是mixin。

这个过程的负面方面(或缺点)是哪些?

钻石问题。你可能听说过它。它是一个多重继承的常见问题。如果HomoSapiensHomoErectus会有相同的方法,那么根据你的最后一个参数你的copyProtoDeep获胜,那么将使用HomoSapiens方法。但是关于mixin ...与继承有关,它是已知的问题和继承不应该解决它。另一方面,mixin的每个解决方案都是可以接受的。所以如果你定义了最后一个参数方法将有一个优先级,那么这是一个正确的解决方案。

超级使用是否正确?

我看到一个问题。如果父母也是一个混蛋?然后它有parent.prototype.uber,它将覆盖child.prototype.uber

我可以改进我的代码吗?

我会尝试用uber修复上一个问题。例如手表ecma-262 5.1 specification of Property Attributes。对于库或模式这是好事。有了它,你可以实现uber不同的方式,因此不能被覆盖。

遗言

我不得不说,我不是一个混合或多重继承的专家。我避开它。我只是很好的JavaScript,而是使用简单的继承和接口。所以这只是我的观点。

+0

虽然有些延迟,但感谢您的关注。 我以为我已经投了你的答案,但我错了。 我现在投票,谢谢。 – Devima