【问题标题】:oop javascript deepcopy mixins multiple inheritanceoop javascript deepcopy mixins 多重继承
【发布时间】:2014-03-27 09:35:49
【问题描述】:

首先大家好,对不起我的英语。
我仍然会利用这个社区的专业知识和可用性。
在此期间,我正在研究 javascript、Crockford 模式、deepcopy shallowCopy 等中的继承。
我也在 stakoverflow (here,here ecc..) 中阅读了很多帖子,但我并不掩饰我的疑虑仍然很多。
我的目标是在不使用 jquery 或方法作为 objectCreate 的情况下创建一种伪多重继承。
伪,因为正如我从阅读各种帖子中了解到的那样,javascript 中的多重继承不存在。
在我的脚本中有两个“超类”(HomoErectus 和 HomoSapiens)和一个“子类”(ModernMan)。
我的 copyProtoDeep 函数将超类原型的所有属性复制到子类的原型中。
此函数接受不定数量的参数,第一个参数是从函数调用中指定的其他类继承的类。
如果 copyProtoDeep 找到对象或数组,为了避免浅拷贝,该函数会克隆此元素。

也就是说,如果可能的话,我想回答以下问题。
我的代码正确吗?
这种类型的 ineritance 是 mixin 吗?
这个过程有哪些负面(或缺点)?
uber的使用正确吗?
我可以改进我的代码吗?

我知道我的问题可能对于单个帖子来说太多了,但我也会很高兴地阅读部分回复。
在此先感谢大家

<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>

【问题讨论】:

  • 为什么 javascripters 如此讨厌组合,他们使用这样的廉价技巧?有了这种助手,人们几乎无法控制什么被覆盖或不被覆盖。假设一个人想要发现智人的直立人朋友……猜猜看,助手根本没有帮助。策略会解决这个问题。

标签: javascript oop inheritance


【解决方案1】:

这是我的答案:

我的代码正确吗?

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

这种类型的 ineritance 是 mixin 吗?

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

这个过程有哪些负面(或缺点)?

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

uber的使用正确吗?

我看到一个问题。如果 parent 也是 mixin 怎么办?然后它有parent.prototype.uber,它将覆盖child.prototype.uber

我可以改进我的代码吗?

我会尝试用uber 解决之前的问题。例如观看ecma-262 5.1 specification of Property Attributes。这对库或模式来说是件好事。有了它,您可以以不同的方式实现uber,例如,它不能被覆盖。

遗言

我不得不说我不是混入或多重继承专家。我避免它。我只是擅长 javascript,而是使用简单的继承和接口。所以这只是我的观点。

【讨论】:

  • 虽然有些延迟,但感谢您的关注。我以为我已经投票给你的答案,但我错了。我现在投票,谢谢。
猜你喜欢
  • 2016-06-25
  • 1970-01-01
  • 2017-09-23
  • 2017-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-24
相关资源
最近更新 更多