函数调用的目的和艺术web前端,源代码的辨析

2019-05-13 作者:web前端   |   浏览(181)

部分时候,咱们会在JS框架中来看那行

原创地址:  

假诺您确实精通Javascript函数是哪些调用职业的,那么就能够防止有些bug的产生;
第二让大家成立二个简短的函数,这些函数将要下文中选拔,那些函数仅仅重返当前的this的值和五个提供的参数.

(function(window, undefined) {})(window) ,它是做什么用的,大家来解析下它

首先那正是一个无名函数,立刻施行它

(function(window, undefined) {
    // coding
})(window)

 

 

复制代码 代码如下:

为如此要如此写,有啥效果

对js举办削减的时候

均能够替换来其余简写字符,从而减弱文件大小,因为他俩被视为局地变量使用。

(function(w, u) {
    // coding
})(w)

 

window: 表示 BOM 浏览器对象模型中的 window 对象

undefined:对于undefined,因为她不是javascript关键字,轻巧遭遇污染。

 

举个例证

function foo() {
     var undefined = 10;
     alert(undefined);
}
foo(); // 打印10

再举个例证:

 var undefined = 10;
    function foo() {
       alert(undefined);
    }
 foo(); // undefined

为啥又产生undefined了呢 ^(0_0)^

再来3个

 var undefined = 10;
    function foo() {
       alert(window.undefined);
       alert(undefined);
    }
 foo(); // undefined

window.undefined和undefined·为啥要变为了undefined了吧?<-_<-

undefined是window的一个属性,是不行写的,所以你在大局成效域改换window这几个天性,根本写不进.

 

var fun = function (){
    var undefined = 2;
    console.log(undefined); //2
}
var undefined = 1;
console.log(undefined);  //undefined 
fun(); 

 

如此就能够看的相比直观的打听undefined了

 

自然从随着浏览器的随处提高,浏览器API不断变动从 jquery2.0.3 2013-07-03 13:30 那1版之后,能够窥见不再行使

(function(window, undefined) {})(window)

经过3个测试beta版

逐步改成了

(function( global, factory ) {

}(this,function(window){}));

这边(this,function(window){})

但有比非常的大可能率导致多个标题,由此this,window可能未有被定义

 

所以让typeof 一下window。

(typeof window !== "undefined" ? window : this, function( window, noGlobal );

 

 

 

 

function makeArray(arg1, arg2){
return [ this, arg1, arg2 ];
}

挑选2.3版本来深入分析,是因为其代码量相对较少,而且不借助于其余js库,值得壹读。

调用那一个函数极其的总结,大家需求做的无非是:

 

复制代码 代码如下:

合法下载地址:

makeArray('one', 'two');

 

返回值:=> [ window, 'one', 'two' ]
主题材料现身了,this的值怎么会成为了window?下边做个简易分析:
在Javascript里,有2个大局的目的, 那多少个看起来散落在你的脚本里的每1行代码,其实都被写在了一个大局对象的前后文里.在大家的例子中,其实10分makeArray 函数能够说不是三个麻痹的全局函数,而是全局对象的2个方法, 让咱们回到来看浏览器,在那几个条件里它的全局对象被映射到window对象.让大家来证实一下:

 

复制代码 代码如下:

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

alert( typeof window.makeArray);

 

返回值:=> function

概述:Ext.js主要承担创立Ext全局对象,塑造其命名空间,定义extend类承继方法,探测浏览器音讯和对Javascript原生库进行扩充。

具有的那一个代表大家从前调用makeArray的点子是和底下调用的点子同样的,

 

复制代码 代码如下:

分析:

window.makeArray('one', 'two');

 

返回值:=> [ window, 'one', 'two' ]

一、创设Ext全局对象

JavaScript函数调用规则一:在未有通过明显全数者对象而直接调用的函数中,如myFunction(),将形成this的值成为暗中同意对象(浏览器中的窗口)。

Js代码 

现创建2个归纳的对象,使用makeArray函数作为它的二个办法,大家将应用json的艺术来声称叁个对象,大家也来调用这一个点子:

 web前端 1

复制代码 代码如下:

  1. // 成立Ext全局对象,大好多JS库为了防止和其余JS库命名争辨,都会把团结创办的类或函数封装到1个全局变量中去,  
  2. // 那样就也正是创设了和谐的命名空间,能够算是3个单例情势。举例,jQuery便是一体都打包到$变量中去。  
  3. Ext = {version: '2.3.0'};  

var arrayMaker = {
someProperty: 'some value here',
make: makeArray
};
arrayMaker.make('one', 'two');
// 返回:=> [ arrayMaker, 'one', 'two' ]
arrayMaker['make']('one', 'two');
// 返回:=> [ arrayMaker, 'one', 'two' ]

 

this的值造成了对象arrayMaker自身.你恐怕会疑窦原始的函数定义并从未改造,为啥它不是window了呢.函数是一个对象,你能够传递它们如故复制他们.就就如整个函数连带参数列表和函数体都被复制,且被分配给了arrayMaker里的属性make,那就恍如那样定义1个arrayMaker:

2、设置全局undefined变量

复制代码 代码如下:

Js代码 

var arrayMaker = {
someProperty: 'some value here',
make: function (arg1, arg2) {return [ this, arg1, arg2 ];}
};

 web前端 2

JavaScript函数调用规则贰: 在1个使用方法调用语法,像 obj.myFunction()或然obj['myFunction'](),这时this的值为obj。

  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"];  

那是事件管理代码中bug的首要源头,看看上面的事例:

 

复制代码 代码如下:

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

<input type="button" value="Button 1" id="btn1" />
<input type="button" value="Button 2" id="btn2" />
<input type="button" value="Button 3" id="btn3" onclick="buttonClicked();"/>
<script type="text/javascript">
function buttonClicked(){
var text = (this === window) ? 'window' : this.id;
alert( text );
}
var button1 = document.getElementById('btn1');
var button2 = document.getElementById('btn2');
button1.onclick = buttonClicked;
//重返值:=> btn1,它是七个艺术调用,this为所属的靶子(按键成分)
button2.onclick = function(){buttonClicked();};
//重临值:=> window ,因为buttonClicked()是被一向调用的(不像 obj.buttonClicked().) 那和大家第一个按键,将事件管理函数直接放在标签里是同等的.所以点击第三个开关的结果是和第三个同样,都以window.
</script>

Js代码 

咱俩掌握在Javascript中绝非类,而且别的1个自定义的门类必要三个开始化函数,使用原型对象(作为开头化函数的一个属性)定义你的项目,让我们来创立一个简易的品种

 web前端 3

复制代码 代码如下:

  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. };  

function ArrayMaker(arg1, arg2) {
this.someProperty = 'whatever';
this.theArray = [ this, arg1, arg2 ];
}
// 注解实例化方法
ArrayMaker.prototype = {
someMethod: function () {
alert( 'someMethod called');
},
getArray: function () {
return this.theArray;
}
};
var am = new ArrayMaker( 'one', 'two' );
var other = new ArrayMaker( 'first', 'second' );
am.getArray();
// 返回值:=> [ am, 'one' , 'two' ]

 

值得注意的是出新在函数调用后边的new运算符,未有它,函数就好像全局函数同样,且大家创制的那贰个属性都将是创建在大局对象上(window),而你并不想那样,另三个话题是,因为在您的布局器里没有再次回到值,所以借令你忘记行使new运算符,将招致您的有些变量被赋值为 undefined.因为那么些原因,构造器函数以大写字母开始是二个好的习于旧贯,那足以看成八个提示,让你在调用的时候绝不忘记前边的new运算符.

四、扩展Ext对象

Javascript函数调用规则3: 当你将函数用作初步化函数的时候,像MyFunction(),Javascript的周转时将把this的值内定为新建的对象.

Js代码 

首先让我们创建3个简易的函数,这么些函数将要下文中使用...

 web前端 4

  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为CSS一Compat,不然为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.         // Web基特是浏览器内核,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,AI奥迪Q三(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的背景图像,幸免图像闪烁,应该是IE陆的1个bug。  
  63.     if(isIE6){  
  64.         try{  
  65.             document.execCommand("BackgroundImageCache", false, true);  
  66.         }catch(e){}  
  67.     }  
  68.   
  69.     // 扩大Ext对象,有1部分性质,那几个文件中未有行使,现在先不解释其效果,后边超越了再讲。  
  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_URAV四L,这些值在组织隐藏的iframe时,用来设置src属性的,只是当是https连接的时候才用。  
  87.         SSL_SECURE_URL : "javascript:false",  
  88.   
  89.         // BLANK_IMAGE_U景逸SUVL,一像素透明图片地址  
  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函数可以2遍给多个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是3个临时的类,其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语言未有命名空间这么1说,所以只可以用对象的性质来兑现。  
  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.         // UCR-VL编码函数  
  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.         // UWranglerL解码函数  
  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是1个弱类型的话音,所以上面那些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,表示最近浏览器是或不是选择Web基特引擎。  
  455.         isWebKit: isWebKit,  
  456.   
  457.         // isChrome,表示是不是是Google浏览器。  
  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 六浏览器照旧是苹果系统上的Firefox浏览器,并且gecko内核版本小于3。  
  501.         // 具体哪儿使用到了,还不掌握,读到前面代码发掘了,再解释。  
  502.         useShims : ((isIE && !(isIE7 || isIE8)) || (isMac && isGecko && !isGecko3))  
  503.     });  
  504.   
  505.     // namespace函数的简写格局  
  506.     Ext.ns = Ext.namespace;  
  507. })();   

 

5、创立Ext所用的命名空间

Js代码 

 web前端 5

  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");  

 

6、扩张原生Function

Js代码 

 web前端 6

  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代码 

 web前端 7

  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代码 

 web前端 8

  1. Ext.applyIf(Number.prototype, {  
  2.     // 对近些日子数值取1个限量  
  3.     constrain : function(min, max){  
  4.         return Math.min(Math.max(this, min), max);  
  5.     }  
  6. });  

 

九、增添原生Array

Js代码 

 web前端 9

  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. });  

 

10、扩大原生Date

Js代码 

 web前端 10

  1. // 重临2个日子差  
  2. Date.prototype.getElapsed = function(date) {  
  3.     return Math.abs((date || new Date()).getTime()-this.getTime());  
  4. };  

本文由www.bifa365365.com发布于web前端,转载请注明出处:函数调用的目的和艺术web前端,源代码的辨析

关键词: www.bifa3653