来自[url]http://www.beyondrails.com/blogs/17[/url]
Ext版本: 2.1
Ext.js位于Ext源代码的core目录下,它定义了Ext的核心工具和方法集
Ext是一个singleton,不能直接使用new来创建,因为Ext源码中没有声明Ext的constructor
[code]
Ext = {version: '2.1'};
[/code]
声明了Ext对象,其中version属性为'2.1'
然后定义了Ext.apply方法:
[code]
Ext.apply = function(o, c, defaults){
if(defaults){
// no "this" reference for friendly out of scope calls
Ext.apply(o, defaults);
}
if(o && c && typeof c == 'object'){
for(var p in c){
o[p] = c[p];
}
}
return o;
};
[/code]
Ext.apply方法将c对象中的属性全部copy到o对象中,并且最后返回o对象
然后紧接着是一个"[url=http://yuiblog.com/blog/2007/06/12/module-pattern/]Module Pattern[/url]"的使用:
[code]
(function(){
// ...
Ext.apply(Ext, {
// ...
});
// ...
})();
[/code]
Module Pattern实际上是一个Singleton模式,最后的()表示该匿名方法会立即执行
其中在Ext.apply那一大段代码里,声明了很多public的属性和方法,如:
[code]
Ext.isIE
Ext.isGecko
Ext.isSafari
Ext.isWindows
Ext.isLinux
Ext.isMac
------------------------
Ext.namespace()
Ext.applyIf()
Ext.extend()
Ext.override()
Ext.getDom()
Ext.isArray()
[/code]
接下来对一些类进行扩展,添加了一些方法:
对Function类全局添加了几个方法,这样所有的Function对象(也即所有的JavaScript方法)都具有如下方法: createCallback/createDelegate/createInterceptor/createSequence/defer
对String类添加了escape/format/leftPad/toggle/trim方法
对Number类添加了constrain方法
对Array类添加了indexOf/remove方法
对Date类添加了getElapsed方法
我们重点分析一下Ext.namespace/Ext.extend/Ext.override方法
首先分析一下Ext.namespace方法
[code]
namespace : function(){
var a=arguments, o=null, i, j, d, rt;
for (i=0; i<a.length; ++i) {
d=a[i].split(".");
rt = d[0];
eval('if (typeof ' + rt + ' == "undefined"){' + rt + ' = {};} o = ' + rt + ';');
for (j=1; j<d.length; ++j) {
o[d[j]]=o[d[j]] || {};
o=o[d[j]];
}
}
}
[/code]
该方法实现的非常灵活,可以给namespace传递多个String参数,每个String又可以带'.'来描述命名空间的父子关系,调用方式:
[code]
Ext.namespace('com.beyondrails.hideto');
// com = { beyondrails : { hideto : {} } }
Ext.namespace('foo', 'bar')
// foo = {}
// bar = {}
[/code]
然后我们看看Ext.override方法:
[code]
override : function(origclass, overrides){
if(overrides){
var p = origclass.prototype;
for(var method in overrides){
p[method] = overrides[method];
}
}
}
[/code]
很简单,将overrides中所有方法覆盖到origclass中
最后我们来看看Ext.extend方法:
[code]
extend : function(){
// inline overrides
var io = function(o){
for(var m in o){
this[m] = o[m];
}
};
var oc = Object.prototype.constructor;
return function(sb, sp, overrides){
if(typeof sp == 'object'){
overrides = sp;
sp = sb;
sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};
}
var F = function(){}, sbp, spp = sp.prototype;
F.prototype = spp;
sbp = sb.prototype = new F();
sbp.constructor=sb;
sb.superclass=spp;
if(spp.constructor == oc){
spp.constructor=sp;
}
sb.override = function(o){
Ext.override(sb, o);
};
sbp.override = io;
Ext.override(sb, overrides);
sb.extend = function(o){Ext.extend(sb, o);};
return sb;
};
}()
[/code]
这段代码比较诡异,一般来说继承的JavaScript实现就将subclass.prototype = new superclass(),这里也是这样实现的
不过Ext在这里还给subclass加上了一个superclass属性和一个override方法
而且这里支持两种方式的调用:
[code]
Ext.extend(Class1, {a:1, b:2})
Ext.extend(Class1, Class2, {a:1, b:2})
[/code]
其中需要注意的是直接写成Object Literal方式的对象会override而不是extend
Ext版本: 2.1
Ext.js位于Ext源代码的core目录下,它定义了Ext的核心工具和方法集
Ext是一个singleton,不能直接使用new来创建,因为Ext源码中没有声明Ext的constructor
[code]
Ext = {version: '2.1'};
[/code]
声明了Ext对象,其中version属性为'2.1'
然后定义了Ext.apply方法:
[code]
Ext.apply = function(o, c, defaults){
if(defaults){
// no "this" reference for friendly out of scope calls
Ext.apply(o, defaults);
}
if(o && c && typeof c == 'object'){
for(var p in c){
o[p] = c[p];
}
}
return o;
};
[/code]
Ext.apply方法将c对象中的属性全部copy到o对象中,并且最后返回o对象
然后紧接着是一个"[url=http://yuiblog.com/blog/2007/06/12/module-pattern/]Module Pattern[/url]"的使用:
[code]
(function(){
// ...
Ext.apply(Ext, {
// ...
});
// ...
})();
[/code]
Module Pattern实际上是一个Singleton模式,最后的()表示该匿名方法会立即执行
其中在Ext.apply那一大段代码里,声明了很多public的属性和方法,如:
[code]
Ext.isIE
Ext.isGecko
Ext.isSafari
Ext.isWindows
Ext.isLinux
Ext.isMac
------------------------
Ext.namespace()
Ext.applyIf()
Ext.extend()
Ext.override()
Ext.getDom()
Ext.isArray()
[/code]
接下来对一些类进行扩展,添加了一些方法:
对Function类全局添加了几个方法,这样所有的Function对象(也即所有的JavaScript方法)都具有如下方法: createCallback/createDelegate/createInterceptor/createSequence/defer
对String类添加了escape/format/leftPad/toggle/trim方法
对Number类添加了constrain方法
对Array类添加了indexOf/remove方法
对Date类添加了getElapsed方法
我们重点分析一下Ext.namespace/Ext.extend/Ext.override方法
首先分析一下Ext.namespace方法
[code]
namespace : function(){
var a=arguments, o=null, i, j, d, rt;
for (i=0; i<a.length; ++i) {
d=a[i].split(".");
rt = d[0];
eval('if (typeof ' + rt + ' == "undefined"){' + rt + ' = {};} o = ' + rt + ';');
for (j=1; j<d.length; ++j) {
o[d[j]]=o[d[j]] || {};
o=o[d[j]];
}
}
}
[/code]
该方法实现的非常灵活,可以给namespace传递多个String参数,每个String又可以带'.'来描述命名空间的父子关系,调用方式:
[code]
Ext.namespace('com.beyondrails.hideto');
// com = { beyondrails : { hideto : {} } }
Ext.namespace('foo', 'bar')
// foo = {}
// bar = {}
[/code]
然后我们看看Ext.override方法:
[code]
override : function(origclass, overrides){
if(overrides){
var p = origclass.prototype;
for(var method in overrides){
p[method] = overrides[method];
}
}
}
[/code]
很简单,将overrides中所有方法覆盖到origclass中
最后我们来看看Ext.extend方法:
[code]
extend : function(){
// inline overrides
var io = function(o){
for(var m in o){
this[m] = o[m];
}
};
var oc = Object.prototype.constructor;
return function(sb, sp, overrides){
if(typeof sp == 'object'){
overrides = sp;
sp = sb;
sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};
}
var F = function(){}, sbp, spp = sp.prototype;
F.prototype = spp;
sbp = sb.prototype = new F();
sbp.constructor=sb;
sb.superclass=spp;
if(spp.constructor == oc){
spp.constructor=sp;
}
sb.override = function(o){
Ext.override(sb, o);
};
sbp.override = io;
Ext.override(sb, overrides);
sb.extend = function(o){Ext.extend(sb, o);};
return sb;
};
}()
[/code]
这段代码比较诡异,一般来说继承的JavaScript实现就将subclass.prototype = new superclass(),这里也是这样实现的
不过Ext在这里还给subclass加上了一个superclass属性和一个override方法
而且这里支持两种方式的调用:
[code]
Ext.extend(Class1, {a:1, b:2})
Ext.extend(Class1, Class2, {a:1, b:2})
[/code]
其中需要注意的是直接写成Object Literal方式的对象会override而不是extend