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];
		}
	}
}
posted @ 2010-04-05 03:46  MKing's Kindom  阅读(253)  评论(0编辑  收藏  举报