void muse.extend(object, object) :: Javascript深表复制
前面的原则之一:有限开发。所以,我觉得可以尝试一下通过深表复制来实现继承的问题。
问题最初出现在类的配置对象上。现在很流行象jq那样写直接量的对象作为配置文件,所以,如果你想把类做得很灵活,就有可能出现一个比类的行数还多的配置对象。到最后,还极有可能出现不知道到底谁是对象模板的尴尬。其实这些倒不重要,但是那超长的配置文件实在让人不胜繁琐。
由于我采用的类构造模式,是构造函数模式和原型模式混合的方式,加之在C#中的书写习惯,所以我自然想到去做一个默认配置,然后通过构造函数,继承外部的配置。这样,每次我只要写需要改动的配置就可以了,配置会小很多。
那么这个继承如何实现?如果我能一直采用浅表对象来充当配置文件,那我可以只做浅表复制的方法。但是配置越来越复杂,甚至我写了一个style属性在配置里面。比如,一个menu的ui控件,我的配置文件习惯写成这个样子:
var config = { className : 'menu', style : { width : '50px', height : '30px', lineHeight : '30px' }, onclick : function(){ alert('I am the Menu.'); } }
这个配制,仅仅浅表复制是肯定不行的,否则每次做修改,都必需将该属性的同级属性和下级属性都写全,否则属性值将被覆盖。
我写完自己的深表复制以后,又翻看了jQuert的extend函数,觉得递归作为基本思路没有争议。关于function属性的处理,我则希望能尽可能实现继承和重载。由于现在还没有太复杂的需求,所以仅仅是将两个函数叠加到一起了。
extend : function(o0, o1){ for(var p in o1){ if(o0[p] === o1[p]) continue; if(typeof o0[p] === typeof o1[p]){ switch(typeof o1[p]){ case 'object': muse.extend(o0[p], o1[p]); break; case 'function': var f = o0[p]; o0[p] = !!o0[p + '$'] ? function(){ o1[p].apply(this, arguments); f.apply(this, arguments); } : function(){ f.apply(this, arguments); o1[p].apply(this, arguments); } break; default : o0[p] = o1[p]; break; } } else { o0[p] = o1[p]; } } }