• ExtJS 2.3版 源代码的解析(转)


    原创地址:  http://www.iteye.com/topic/1120551

    选择2.3版本来分析,是因为其代码量相对较少,而且不依赖其他js库,值得一读。

    官方下载地址:http://dev.sencha.com/deploy/ext-2.3.0.zip

    文件:ext-2.3.0/source/core/Ext.js

    概述:Ext.js主要负责创建Ext全局对象,构建其命名空间,定义extend类继承方法,探测浏览器信息和对Javascript原生库进行扩展。

    分析:

    一、创建Ext全局对象

    Js代码  收藏代码
    1. // 创建Ext全局对象,大多数JS库为了避免和其他JS库命名冲突,都会把自己创建的类或函数封装到一个全局变量中去,  
    2. // 这样就相当于创造了自己的命名空间,可以算是一个单例模式。例如,jQuery就是全部都封装到$变量中去。  
    3. Ext = {version: '2.3.0'};  

    二、设置全局undefined变量

    Js代码  收藏代码
    1. // 兼容旧浏览器,早期的浏览器实现中,undefined并不是全局变量。就是说,你要判断一个变量是否是没定义,  
    2. // 你需要这样写if (typeof  a == 'undefined'),不可以写成if (a == undefined)。所以,上面的代码就可以理解了。  
    3. // 右面的window["undefined"],因为window对象没有undefined属性,所以其值为undefined,  
    4. // 把undefined赋值给window的undefined属性上,就相当于把undefined设置成了全局变量,  
    5. // 这样以后你再判断一个变量是否是未定义的时候,就不需要使用typeof,直接判断就可以了。  
    6. window["undefined"] = window["undefined"];  

    三、定义apply方法属性复制函数

    Js代码  收藏代码
    1. // apply方法,把对象c中的属性复制到对象o中,支持默认属性defaults设置。这个方法属于对象属性的一个浅拷贝函数。  
    2. Ext.apply = function(o, c, defaults){  
    3.     if(defaults){  
    4.         // 如果默认值defaults存在,那么先把defaults上得属性复制给对象o  
    5.         Ext.apply(o, defaults);  
    6.     }  
    7.     if(o && c && typeof c == 'object'){  
    8.         for(var p in c){  
    9.             o[p] = c[p];  
    10.         }  
    11.     }  
    12.     return o;  
    13. };  

    四、扩展Ext对象

    Js代码  收藏代码
    1. (function(){  
    2.     // idSeed,用来生成自增长的id值。  
    3.     var idSeed = 0;  
    4.   
    5.     // ua,浏览器的用户代理,主要用来识别浏览器的型号、版本、内核和操作系统等。  
    6.     var ua = navigator.userAgent.toLowerCase(),  
    7.         check = function(r){  
    8.             return r.test(ua);  
    9.         },  
    10.         
    11.         // isStrict,表示当前浏览器是否是标准模式。  
    12.         // 如果正确的设置了网页的doctype,则compatMode为CSS1Compat,否则为BackCompat  
    13.         isStrict = document.compatMode == "CSS1Compat",  
    14.   
    15.         // isOpera,表示是否是opera浏览器。  
    16.         isOpera = check(/opera/),  
    17.   
    18.         // isChrome,表示是否是谷歌浏览器。  
    19.         isChrome = check(/chrome/),  
    20.   
    21.         // isWebKit,表示当前浏览器是否使用WebKit引擎。  
    22.         // WebKit是浏览器内核,Safari和Chrome使用WebKit引擎。  
    23.         isWebKit = check(/webkit/),  
    24.   
    25.         // isSafari,表示是否是苹果浏览器,下面代码是对其版本识别。  
    26.         isSafari = !isChrome && check(/safari/),  
    27.         isSafari2 = isSafari && check(/applewebkit\/4/), // unique to Safari 2  
    28.         isSafari3 = isSafari && check(/version\/3/),  
    29.         isSafari4 = isSafari && check(/version\/4/),  
    30.   
    31.         // isIE,表示是否是IE浏览器,下面代码是对其版本识别。  
    32.         isIE = !isOpera && check(/msie/),  
    33.         isIE7 = isIE && check(/msie 7/),  
    34.         isIE8 = isIE && check(/msie 8/),  
    35.         isIE6 = isIE && !isIE7 && !isIE8,  
    36.   
    37.         // isGecko,表示当前浏览器是否使用Gecko引擎。  
    38.         // Gecko是浏览器内核,Firefox使用Gecko引擎。  
    39.         isGecko = !isWebKit && check(/gecko/),  
    40.         isGecko2 = isGecko && check(/rv:1\.8/),  
    41.         isGecko3 = isGecko && check(/rv:1\.9/),  
    42.   
    43.         // isBorderBox,表示浏览器是否是IE的盒模式。  
    44.         // 众所周知,IE的盒模式和W3C的盒模式不一致。当IE浏览器在怪异模式下,就会导致错误的盒模式。  
    45.         isBorderBox = isIE && !isStrict,  
    46.   
    47.         // isWindows,表示是否是windows操作系统。  
    48.         isWindows = check(/windows|win32/),  
    49.   
    50.         // isMac,表示是否是苹果操作系统。  
    51.         isMac = check(/macintosh|mac os x/),  
    52.   
    53.         // isAir,AIR(Adobe Integrated Runtime),是adobe开发的一个平台吧,不太了解,没用过。  
    54.         isAir = check(/adobeair/),  
    55.   
    56.         // isLinux,表示是否是Liunx操作系统。  
    57.         isLinux = check(/linux/),  
    58.   
    59.         // isSecure,表示是否是https连接。  
    60.         isSecure = /^https/i.test(window.location.protocol);  
    61.   
    62.     // 缓存一下CSS的背景图像,防止图像闪烁,应该是IE6的一个bug。  
    63.     if(isIE6){  
    64.         try{  
    65.             document.execCommand("BackgroundImageCache"falsetrue);  
    66.         }catch(e){}  
    67.     }  
    68.   
    69.     // 扩展Ext对象,有一些属性,这个文件中没有使用,现在先不解释其作用,后面遇到了再讲。  
    70.     Ext.apply(Ext, {  
    71.   
    72.         // isStrict,表示是否是标准模式。  
    73.         isStrict : isStrict,  
    74.   
    75.         // isSecure,表示是否是https连接。  
    76.         isSecure : isSecure,  
    77.   
    78.         // isReady,表示Dom文档树是否加载完成  
    79.         isReady : false,  
    80.   
    81.         // enableGarbageCollector和enableListenerCollection这两个变量在Element中使用了,解析到Element时再解释其含义。  
    82.         enableGarbageCollector : true,  
    83.   
    84.         enableListenerCollection:false,  
    85.   
    86.         // SSL_SECURE_URL,这个值在构造隐藏的iframe时,用来设置src属性的,只是当是https连接的时候才用。  
    87.         SSL_SECURE_URL : "javascript:false",  
    88.   
    89.         // BLANK_IMAGE_URL,1像素透明图片地址  
    90.         BLANK_IMAGE_URL : "http:/"+"/extjs.com/s.gif",  
    91.   
    92.         // emptyFn,空函数  
    93.         emptyFn : function(){},  
    94.   
    95.         // applyIf,把对象c的属性复制到对象o上,只复制o没有的属性  
    96.         applyIf : function(o, c){  
    97.             if(o && c){  
    98.                 for(var p in c){  
    99.                     if(typeof o[p] == "undefined"){ o[p] = c[p]; }  
    100.                 }  
    101.             }  
    102.             return o;  
    103.         },  
    104.   
    105.         // addBehaviors函数可以一次给多个Ext.Element添加不同的事件响应函数  
    106.         addBehaviors : function(o){  
    107.   
    108.             // 判断Dom树是否已经加装成功  
    109.             if(!Ext.isReady){  
    110.                 // 如果Dom树没有加载好,那么等到加载好了,再执行此函数  
    111.                 Ext.onReady(function(){  
    112.                     Ext.addBehaviors(o);  
    113.                 });  
    114.                 return;  
    115.             }  
    116.   
    117.             // cache,简单缓存一下选择过的CSS Selector。  
    118.             var cache = {};   
    119.   
    120.             // 遍历对象o,b的格式应该是selector@eventName  
    121.             for(var b in o){  
    122.   
    123.                 // parts[0]=selector,parts[1]=eventName  
    124.                 var parts = b.split('@');  
    125.                 if(parts[1]){  
    126.                     // 如果事件名称存在,s为selector  
    127.                     var s = parts[0];  
    128.   
    129.                     // 判断一下cache缓存中是否已经查询过该selector  
    130.                     if(!cache[s]){  
    131.   
    132.                         // 如果没有查询过,那么用select方法查询一下  
    133.                         cache[s] = Ext.select(s);  
    134.                     }  
    135.   
    136.                     // 调用Element的on方法来注册事件函数  
    137.                     cache[s].on(parts[1], o[b]);  
    138.                 }  
    139.             }  
    140.   
    141.             // 释放cache变量,防止内存泄露  
    142.             cache = null;  
    143.         },  
    144.   
    145.         // 取得el的id属性。el可以是Ext.Element或者是Dom元素。  
    146.         // 如果el不存在,那么生成一个自增长的id,并返回这个id。  
    147.         // 如果el存在,但是没有id属性,那么生成一个自增长的id,并赋值给el的id属性,最后返回id值。  
    148.         // 如果el存在,并且也有id属性,那么直接返回el的id值。  
    149.         // prefix表示生成自增长的id的前缀,默认值为ext-gen  
    150.         id : function(el, prefix){  
    151.             prefix = prefix || "ext-gen";  
    152.             el = Ext.getDom(el);  
    153.             var id = prefix + (++idSeed);  
    154.             return el ? (el.id ? el.id : (el.id = id)) : id;  
    155.         },  
    156.   
    157.         // 类继承函数,基于javascript的prototype,模仿面相对象的继承特性。  
    158.         // 整个ExtJS框架的继承机制就是这个函数实现的。  
    159.         extend : function(){  
    160.             // override函数,用来覆盖prototype上的属性的  
    161.             var io = function(o){  
    162.                 for(var m in o){  
    163.                     this[m] = o[m];  
    164.                 }  
    165.             };  
    166.   
    167.             // Object的构造函数  
    168.             var oc = Object.prototype.constructor;  
    169.   
    170.             return function(sb, sp, overrides){  
    171.                 // sb表示subclass,sp表示superclass,overrides是默认值为对象型  
    172.                 // 如果sp是对象,表示没有传sb变量进来,所以重新设置一下参数  
    173.                 if(typeof sp == 'object'){  
    174.                     overrides = sp;  
    175.                     sp = sb;  
    176.                     // 如果overrides中提供了构造函数,那么就用提供的,  
    177.                     // 否则用下面这个匿名函数,匿名函数会调用父类的构造函数  
    178.                     sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};  
    179.                 }  
    180.   
    181.                 // F是一个临时的类,其prototype指向superclass的prototype,  
    182.                 // 同时也把subclass的prototype指向了F对象,  
    183.                 // 这样可以避免在类继承的时候,调用superclass的构造函数  
    184.                 var F = function(){}, sbp, spp = sp.prototype;  
    185.                 F.prototype = spp;  
    186.                 sbp = sb.prototype = new F();  
    187.                 sbp.constructor=sb;  
    188.                 sb.superclass=spp;  
    189.                 if(spp.constructor == oc){  
    190.                     spp.constructor=sp;  
    191.                 }  
    192.   
    193.                 // 覆盖函数  
    194.                 sb.override = function(o){  
    195.                     Ext.override(sb, o);  
    196.                 };  
    197.                 sbp.override = io;  
    198.   
    199.                 // 设置默认值  
    200.                 Ext.override(sb, overrides);  
    201.   
    202.                 // 继承函数,这样写方便,可以直接从别的类继承新类  
    203.                 sb.extend = function(o){Ext.extend(sb, o);};  
    204.                 return sb;  
    205.             };  
    206.         }(),  
    207.   
    208.         // 覆盖函数,直接把属性复制到origclass的prototype上  
    209.         override : function(origclass, overrides){  
    210.             if(overrides){  
    211.                 var p = origclass.prototype;  
    212.                 for(var method in overrides){  
    213.                     p[method] = overrides[method];  
    214.                 }  
    215.   
    216.                 // 下面是处理IE浏览器在枚举对象的属性时,  
    217.                 // 原生的方法toString枚举不出来,即使是自定义的toString也不行  
    218.                 if(Ext.isIE && overrides.toString != origclass.toString){  
    219.                     p.toString = overrides.toString;  
    220.                 }  
    221.             }  
    222.         },  
    223.   
    224.         // 生成命名空间。javascript语言没有命名空间这么一说,所以只好用对象的属性来实现。  
    225.         namespace : function(){  
    226.             var a=arguments, o=null, i, j, d, rt;  
    227.             for (i=0; i<a.length; ++i) {  
    228.                 d=a[i].split(".");  
    229.                 rt = d[0];  
    230.                 eval('if (typeof ' + rt + ' == "undefined"){' + rt + ' = {};} o = ' + rt + ';');  
    231.                 for (j=1; j<d.length; ++j) {  
    232.                     o[d[j]]=o[d[j]] || {};  
    233.                     o=o[d[j]];  
    234.                 }  
    235.             }  
    236.         },  
    237.   
    238.         // URL编码函数  
    239.         urlEncode : function(o){  
    240.             if(!o){  
    241.                 return "";  
    242.             }  
    243.             var buf = [];  
    244.             for(var key in o){  
    245.                 var ov = o[key], k = encodeURIComponent(key);  
    246.                 var type = typeof ov;  
    247.                 if(type == 'undefined'){  
    248.                     buf.push(k, "=&");  
    249.                 }else if(type != "function" && type != "object"){  
    250.                     buf.push(k, "=", encodeURIComponent(ov), "&");  
    251.                 }else if(Ext.isDate(ov)){  
    252.                     var s = Ext.encode(ov).replace(/"/g, '');  
    253.                     buf.push(k, "=", s, "&");  
    254.                 }else if(Ext.isArray(ov)){  
    255.                     if (ov.length) {  
    256.                         for(var i = 0, len = ov.length; i < len; i++) {  
    257.                             buf.push(k, "=", encodeURIComponent(ov[i] === undefined ? '' : ov[i]), "&");  
    258.                         }  
    259.                     } else {  
    260.                         buf.push(k, "=&");  
    261.                     }  
    262.                 }  
    263.             }  
    264.             buf.pop();  
    265.             return buf.join("");  
    266.         },  
    267.   
    268.         // URL解码函数  
    269.         urlDecode : function(string, overwrite){  
    270.             if(!string || !string.length){  
    271.                 return {};  
    272.             }  
    273.             var obj = {};  
    274.             var pairs = string.split('&');  
    275.             var pair, name, value;  
    276.             for(var i = 0, len = pairs.length; i < len; i++){  
    277.                 pair = pairs[i].split('=');  
    278.                 name = decodeURIComponent(pair[0]);  
    279.                 value = decodeURIComponent(pair[1]);  
    280.                 if(overwrite !== true){  
    281.                     if(typeof obj[name] == "undefined"){  
    282.                         obj[name] = value;  
    283.                     }else if(typeof obj[name] == "string"){  
    284.                         obj[name] = [obj[name]];  
    285.                         obj[name].push(value);  
    286.                     }else{  
    287.                         obj[name].push(value);  
    288.                     }  
    289.                 }else{  
    290.                     obj[name] = value;  
    291.                 }  
    292.             }  
    293.             return obj;  
    294.         },  
    295.   
    296.         // each函数,迭代数组时候用的,和jQuery的each方法差不多,不过Ext的each只能迭代数组或者类数组  
    297.         each : function(array, fn, scope){  
    298.             if(typeof array.length == "undefined" || typeof array == "string"){  
    299.                 array = [array];  
    300.             }  
    301.             for(var i = 0, len = array.length; i < len; i++){  
    302.                 if(fn.call(scope || array[i], array[i], i, array) === false){ return i; };  
    303.             }  
    304.         },  
    305.   
    306.         // 组合函数,标识了过期不推荐,这里也就不看了  
    307.         combine : function(){  
    308.             var as = arguments, l = as.length, r = [];  
    309.             for(var i = 0; i < l; i++){  
    310.                 var a = as[i];  
    311.                 if(Ext.isArray(a)){  
    312.                     r = r.concat(a);  
    313.                 }else if(a.length !== undefined && !a.substr){  
    314.                     r = r.concat(Array.prototype.slice.call(a, 0));  
    315.                 }else{  
    316.                     r.push(a);  
    317.                 }  
    318.             }  
    319.             return r;  
    320.         },  
    321.   
    322.         // 处理需要转义的字符,在需要转义的字符前面多加一个反斜线  
    323.         escapeRe : function(s) {  
    324.             return s.replace(/([.*+?^${}()|[\]\/\\])/g, "\\$1");  
    325.         },  
    326.   
    327.         // 回调函数,可以指定this值和参数,还可以延迟执行  
    328.         callback : function(cb, scope, args, delay){  
    329.             if(typeof cb == "function"){  
    330.                 if(delay){  
    331.                     cb.defer(delay, scope, args || []);  
    332.                 }else{  
    333.                     cb.apply(scope, args || []);  
    334.                 }  
    335.             }  
    336.         },  
    337.   
    338.         // 取得html元素,el可以是id,也可以是Ext的Element对象  
    339.         getDom : function(el){  
    340.             if(!el || !document){  
    341.                 return null;  
    342.             }  
    343.             return el.dom ? el.dom : (typeof el == 'string' ? document.getElementById(el) : el);  
    344.         },  
    345.   
    346.         // 取得document的Element对象  
    347.         getDoc : function(){  
    348.             return Ext.get(document);  
    349.         },  
    350.   
    351.         // 取得文档对象。  
    352.         // document.body = document.getElementsByTagName('body')[0];  
    353.         // document.documentElement = document.getElementsByTagName('html')[0];  
    354.         getBody : function(){  
    355.             return Ext.get(document.body || document.documentElement);  
    356.         },  
    357.   
    358.         // 取得组件对象  
    359.         getCmp : function(id){  
    360.             return Ext.ComponentMgr.get(id);  
    361.         },  
    362.   
    363.         // 这个用来取得数字,可以设置默认值  
    364.         num : function(v, defaultValue){  
    365.             v = Number(v == null || typeof v == 'boolean'? NaN : v);  
    366.             return isNaN(v)? defaultValue : v;  
    367.         },  
    368.   
    369.         // 销毁函数,销毁的对象可以是Element或者是Component  
    370.         destroy : function(){  
    371.             for(var i = 0, a = arguments, len = a.length; i < len; i++) {  
    372.                 var as = a[i];  
    373.                 if(as){  
    374.                     if(typeof as.destroy == 'function'){  
    375.                         as.destroy();  
    376.                     }  
    377.                     else if(as.dom){  
    378.                         as.removeAllListeners();  
    379.                         as.remove();  
    380.                     }  
    381.                 }  
    382.             }  
    383.         },  
    384.   
    385.         // 清除Dom节点n  
    386.         removeNode : isIE ? function(){  
    387.             var d;  
    388.             return function(n){  
    389.                 if(n && n.tagName != 'BODY'){  
    390.                     d = d || document.createElement('div');  
    391.                     d.appendChild(n);  
    392.                     d.innerHTML = '';  
    393.                 }  
    394.             }  
    395.         }() : function(n){  
    396.             if(n && n.parentNode && n.tagName != 'BODY'){  
    397.                 n.parentNode.removeChild(n);  
    398.             }  
    399.         },  
    400.   
    401.         // javascript是一个弱类型的语音,所以下面这个type函数可以正确返回测试变量的类型  
    402.         type : function(o){  
    403.             // 其实undefined和null也可以算两种类型,这里把他们俩全归类到false了  
    404.             if(o === undefined || o === null){  
    405.                 return false;  
    406.             }  
    407.             if(o.htmlElement){  
    408.                 return 'element';  
    409.             }  
    410.             var t = typeof o;  
    411.             if(t == 'object' && o.nodeName) {  
    412.                 switch(o.nodeType) {  
    413.                     case 1: return 'element';  
    414.                     case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace';  
    415.                 }  
    416.             }  
    417.             if(t == 'object' || t == 'function') {  
    418.                 switch(o.constructor) {  
    419.                     case Array: return 'array';  
    420.                     case RegExp: return 'regexp';  
    421.                     case Date: return 'date';  
    422.                 }  
    423.                 if(typeof o.length == 'number' && typeof o.item == 'function') {  
    424.                     return 'nodelist';  
    425.                 }  
    426.             }  
    427.             return t;  
    428.         },  
    429.   
    430.         // 判断v是否为空或者未定义,allowBlank表示是否允许空字符串,默认值是false。  
    431.         // 当allowBlank设置为true时,isEmpty('')返回false  
    432.         isEmpty : function(v, allowBlank){  
    433.             return v === null || v === undefined || (!allowBlank ? v === '' : false);  
    434.         },  
    435.   
    436.         // 判断v是否为空,为空的话可以设置默认值,不为空的话返回v值  
    437.         value : function(v, defaultValue, allowBlank){  
    438.             return Ext.isEmpty(v, allowBlank) ? defaultValue : v;  
    439.         },  
    440.   
    441.         // 判断v是否是数组对象  
    442.         isArray : function(v){  
    443.             return v && typeof v.length == 'number' && typeof v.splice == 'function';  
    444.         },  
    445.   
    446.         // 判断v是否是日期对象  
    447.         isDate : function(v){  
    448.             return v && typeof v.getFullYear == 'function';  
    449.         },  
    450.   
    451.         // isOpera,表示是否是opera浏览器。  
    452.         isOpera : isOpera,  
    453.   
    454.         // isWebKit,表示当前浏览器是否使用WebKit引擎。  
    455.         isWebKit: isWebKit,  
    456.   
    457.         // isChrome,表示是否是谷歌浏览器。  
    458.         isChrome : isChrome,  
    459.   
    460.         // isSafari,表示是否是苹果浏览器,下面代码是对其版本识别。  
    461.         isSafari : isSafari,  
    462.    
    463.         isSafari4 : isSafari4,  
    464.   
    465.         isSafari3 : isSafari3,  
    466.   
    467.         isSafari2 : isSafari2,  
    468.   
    469.         // isIE,表示是否是IE浏览器,下面代码是对其版本识别。  
    470.         isIE : isIE,  
    471.   
    472.         isIE6 : isIE6,  
    473.   
    474.         isIE7 : isIE7,  
    475.   
    476.         isIE8 : isIE8,  
    477.   
    478.         // isGecko,表示当前浏览器是否使用Gecko引擎。  
    479.         isGecko : isGecko,  
    480.   
    481.         isGecko2 : isGecko2,  
    482.   
    483.         isGecko3 : isGecko3,  
    484.   
    485.         // isBorderBox,表示浏览器是否是IE的盒模式。  
    486.         isBorderBox : isBorderBox,  
    487.   
    488.         // isLinux,表示是否是Liunx操作系统。  
    489.         isLinux : isLinux,  
    490.   
    491.         // isWindows,表示是否是windows操作系统。  
    492.         isWindows : isWindows,  
    493.   
    494.         // isMac,表示是否是苹果操作系统。  
    495.         isMac : isMac,  
    496.   
    497.         // isAir,AIR(Adobe Integrated Runtime)  
    498.         isAir : isAir,  
    499.   
    500.         // useShims,表示是IE 6浏览器或者是苹果系统上的Firefox浏览器,并且gecko内核版本小于3。  
    501.         // 具体哪里使用到了,还不知道,读到后面代码发现了,再解释。  
    502.         useShims : ((isIE && !(isIE7 || isIE8)) || (isMac && isGecko && !isGecko3))  
    503.     });  
    504.   
    505.     // namespace函数的简写方式  
    506.     Ext.ns = Ext.namespace;  
    507. })();   

     

    五、创建Ext所用的命名空间

    Js代码  收藏代码
    1. Ext.ns("Ext""Ext.util""Ext.grid""Ext.dd""Ext.tree""Ext.data",  
    2.                 "Ext.form""Ext.menu""Ext.state""Ext.lib""Ext.layout""Ext.app""Ext.ux");  

    六、扩展原生Function

    Js代码  收藏代码
    1. Ext.apply(Function.prototype, {  
    2.   
    3.     // 创建回调函数,这个有点太简单了,并且this指向了window,不可以自定义。功能不是很强  
    4.     createCallback : function(/*args...*/){  
    5.         var args = arguments;  
    6.         var method = this;  
    7.         return function() {  
    8.             return method.apply(window, args);  
    9.         };  
    10.     },  
    11.   
    12.     // 创建委托(注:Delegate在C#里是叫委托的,其实就是c语音里的函数指针,js中叫匿名函数)  
    13.     // createDelegate比createCallback高级了一点可以设置this指针,同时也可以设置传入的参数  
    14.     createDelegate : function(obj, args, appendArgs){  
    15.         var method = this;  
    16.         return function() {  
    17.             var callArgs = args || arguments;  
    18.             if(appendArgs === true){  
    19.                 callArgs = Array.prototype.slice.call(arguments, 0);  
    20.                 callArgs = callArgs.concat(args);  
    21.             }else if(typeof appendArgs == "number"){  
    22.                 callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first  
    23.                 var applyArgs = [appendArgs, 0].concat(args); // create method call params  
    24.                 Array.prototype.splice.apply(callArgs, applyArgs); // splice them in  
    25.             }  
    26.             return method.apply(obj || window, callArgs);  
    27.         };  
    28.     },  
    29.   
    30.     // defer是createDelegate的延迟版,可以延迟执行  
    31.     defer : function(millis, obj, args, appendArgs){  
    32.         var fn = this.createDelegate(obj, args, appendArgs);  
    33.         if(millis){  
    34.             return setTimeout(fn, millis);  
    35.         }  
    36.         fn();  
    37.         return 0;  
    38.     },  
    39.   
    40.     // 这个函数可以在你执行完原函数以后,执行一下自定义的函数。  
    41.     createSequence : function(fcn, scope){  
    42.         if(typeof fcn != "function"){  
    43.             return this;  
    44.         }  
    45.         var method = this;  
    46.         return function() {  
    47.             var retval = method.apply(this || window, arguments);  
    48.             fcn.apply(scope || this || window, arguments);  
    49.             return retval;  
    50.         };  
    51.     },  
    52.   
    53.     // 这个就是完全的函数代理了,和Spring的AOP是一个概念。  
    54.     createInterceptor : function(fcn, scope){  
    55.         if(typeof fcn != "function"){  
    56.             return this;  
    57.         }  
    58.         var method = this;  
    59.         return function() {  
    60.             fcn.target = this;  
    61.             fcn.method = method;  
    62.             if(fcn.apply(scope || this || window, arguments) === false){  
    63.                 return;  
    64.             }  
    65.             return method.apply(this || window, arguments);  
    66.         };  
    67.     }  
    68. });  

     

    七、扩展原生String

    Js代码  收藏代码
    1. Ext.applyIf(String, {  
    2.   
    3.     // 转义单引号和反斜杠  
    4.     escape : function(string) {  
    5.         return string.replace(/('|\\)/g, "\\$1");  
    6.     },  
    7.   
    8.     // 这个函数是对数组进行空格补位  
    9.     leftPad : function (val, size, ch) {  
    10.         var result = new String(val);  
    11.         if(!ch) {  
    12.             ch = " ";  
    13.         }  
    14.         while (result.length < size) {  
    15.             result = ch + result;  
    16.         }  
    17.         return result.toString();  
    18.     },  
    19.   
    20.     // 这个是格式化字符串,很多语言都有的功能  
    21.     format : function(format){  
    22.         var args = Array.prototype.slice.call(arguments, 1);  
    23.         return format.replace(/\{(\d+)\}/g, function(m, i){  
    24.             return args[i];  
    25.         });  
    26.     }  
    27. });  
    28.   
    29. // 切换值函数  
    30. String.prototype.toggle = function(value, other){  
    31.     return this == value ? other : value;  
    32. };  
    33.   
    34. // 去空格函数  
    35. String.prototype.trim = function(){  
    36.     var re = /^\s+|\s+$/g;  
    37.     return function(){ return this.replace(re, ""); };  
    38. }();  

     

    八、扩展原生Number

    Js代码  收藏代码
    1. Ext.applyIf(Number.prototype, {  
    2.     // 对当前数值取一个范围  
    3.     constrain : function(min, max){  
    4.         return Math.min(Math.max(this, min), max);  
    5.     }  
    6. });  

     

    九、扩展原生Array

    Js代码  收藏代码
    1. Ext.applyIf(Array.prototype, {  
    2.       
    3.     indexOf : function(o){  
    4.        for (var i = 0, len = this.length; i < len; i++){  
    5.           if(this[i] == o) return i;  
    6.        }  
    7.        return -1;  
    8.     },  
    9.   
    10.       
    11.     remove : function(o){  
    12.        var index = this.indexOf(o);  
    13.        if(index != -1){  
    14.            this.splice(index, 1);  
    15.        }  
    16.        return this;  
    17.     }  
    18. });  

     

    十、扩展原生Date

    Js代码  收藏代码
    1. // 返回一个时间差  
    2. Date.prototype.getElapsed = function(date) {  
    3.     return Math.abs((date || new Date()).getTime()-this.getTime());  
    4. };  
  • 相关阅读:
    Kprobes—insight into the Linux kernel—replace kernel function with module
    Go将统治下一个十年
    linux—网络仿真开源软件—network simulator—ns
    Serval Project——Android
    CentOS7—Firefox—截图工具—fireshot插件
    Wi-Fi Direct技术
    国产CPU迷局 龙芯该如何参与市场竞争
    《深入理解Android:Wi-Fi,NFC和GPS》—android源码下载
    wifi direct—深入理解Wi-Fi P2P
    c语言学习基础:[1]开发工具介绍
  • 原文地址:https://www.cnblogs.com/gdutbean/p/2357655.html
Copyright © 2020-2023  润新知