突发奇想想看下sina微博的js用的是啥框架,就看了下,应该是自己写的吧,js文件幸好没有混淆,仅用了下压缩,才有此文进行了分析(既然没混淆也就是公开的意思吧),此文仅为个人能力和兴趣所分析,请勿较真
var that={}
var ....
var register=function(){
....
}
that.xxx=function(){
...
}
return that
that.register= function(ns,maker,shortName) {
spec.dependCacheList[ns]= {
"args":arguments,
"depend":spec.importCacheList.slice(lastPoint,spec.importCacheList.length),
"short":shortName
};
lastPoint=spec.importCacheList.length;
checkDepend()
};
在spec.dependCacheList中遍历,查找遍历,其中checkPath的作用是逐级检查该命名空间下指定对象是否定义,若未定义则返回false,这里用的bool值好奇怪,如果checkPath中发现一个不存在的,立即返回false,外部确定为true,即执行loaded=false,这里checkPath叫做checkPathIsNull更准确一些.
var that={
"name":"i am that"
};
var a_fun=function(x){
var temp=that;
temp.name="i am temp";
}
that.call_fun=function(){
a_fun();
alert(this.name);
}
return that;
register:function(){},
......
core:{
},
position:function(){}
}
.....
}
核心方法 register
类似jQuery中的extend,在命名空间下注册,不同之处在于为的是创造多个命名空间,jQuery则只是扩展到其内部或jQuery对象中.
ns为命名空间,,这个是很受用哈,之前鼓捣的js框架均采用1层命名空间方式,新浪这个用"."分隔方法+循环方式制造多级命名空间,具体细节不太纠了,接下来会看到大量用register()注册的方法,另外在整个WBTopTray对象中用that命名全局返回变量,还是很有意思的.
that则相当于基类构造器,提供一些基本方法和引入参数,后文中register的方法均使用that作为参数,基本上所有方法内的参数均由that带入
由maker传入的方法,均为that参数,并返回一个function对象,这个function对象就绑定在curr之下,最终return that,也就是STK.(这里的register用var声明,为啥允许外部访问呢?继续看下去就知道啦)
STK对象本身提供一些基本公用方法,包括E(简单选择器),addEvent(事件绑定)等,随后可以通过register方法扩展.这里的STK采用了匿名函数+直接执行的方式来初始化,后面还有类似的初始化方式
var STK=(function(){
})();
这里为啥要区分私有和that呢,这时候出现问题了,好,我们上面的分析基本正确,但是大方向错误,按理说,STK.register()是通过var声明,外部环境无法访问的,那怎么实现呢,继续看下面有个that.register,这才是真正允许外部调用的注册方法,方法补偿,直接粘过来好了
这里有个关键方法是checkDepend,看看他在做什么
在spec.dependCacheList中遍历,查找遍历,其中checkPath的作用是逐级检查该命名空间下指定对象是否定义,若未定义则返回false,这里用的bool值好奇怪,如果checkPath中发现一个不存在的,立即返回false,外部确定为true,即执行loaded=false,这里checkPath叫做checkPathIsNull更准确一些.
如果遍历命名空间序列存在,则调用私有方法register.apply(that,spec.dependCacheList[k]["args"]);
将所有参数传入register方法,这里的apply用的不是很理解,看了下私有register中也没有引用到执行对象自身,这里貌似用apply貌似只是为了传入复数参数,而私有register中接受两个参数,换句话说这里精准的传入register(arg1,arg2)就行了呀,有待研究.
另外特意去试了一下,私有register中的var curr=that;对curr的操作可以影响到that的值,即此处是引用变量,并非在内部命名空间创建变量后操作,这样私有register中绑定方法的操作会影响that也说得通了,附个实验代码
var a=function(){
};
var x=a();
x.call_fun(); //结果是 i am temp
这样最后that就成为了拥有一定量基础方法,且可以通过register绑定多级命名空间的对象,大概会成为如下类似结构
that(WBTopTray)={
regShort:function(){},
util:{
browser:function(){}
storage:function(){}
dom:{
}
顶级命名空间为that,也就是最终返回的WBTopTray,其下公用方法若干,按功能划分的各个方法分布在core之下,例如core.util.browser等等
另外WBTopTray之下还有大量的私有属性和方法,没有做太详细的分析
启动方法则是由新浪页面中的typeof(WBTopTray)!='undefined'&&WBTopTray.init(TrayCONFIG);
判定WBTopTray是否存在,存在则调用init方法初始化,传入trayconfig作为参数,
其中包含一些延时加载,缓解页面加载速度等等ooxx各种操作啦
setTimeout(function(){
setAppList(config["uid"]);
startBreath(config["uid"],config) },3000); //延时3秒
setInterval( function() { startBreath(config["uid"],config)},
30*1000); //30秒一次
setInterval(function() {
onlineStatus()
},29*60*1000);//30分钟一次
setAppList(config["uid"]);
startBreath(config["uid"],config) },3000); //延时3秒
setInterval( function() { startBreath(config["uid"],config)},
30*1000); //30秒一次
setInterval(function() {
onlineStatus()
},29*60*1000);//30分钟一次
总结下,据说IBM用的Dojo,新版的dojo采用的动态加载的方式,页面自身只需要加载core核心js即可,所有插件和可选功能均通过依赖关系判断自动加载不同的js文件,新浪的这个呢有点模仿jQuery的结构,一种可扩展的,多级命名空间结构,不过可能是不需要太复杂的功能吧,没有进行文件分拆,1300多行算是很精巧了,
js框架基本都在向动态加载和命名空间这两个趋势上发展,自身可以封装的方法都大同小异差不多,执行效率问题呢经过一定时间的研究和浏览器自身优化也都解决的差不多了,剩下就是看谁的结构更优雅,在文件加载上更快.
另外,越短的代码,可读性越差,也就让其他人越难以研究,虽然有压缩前版本,如果设计思路很诡异,非压缩也看起来很麻烦,比如新浪微博的register方法,一开始就掉坑里了,带着诸多疑点看到后面才发现理解错误,就是没理解设计者的思路.