$(function() {})
是$(document).ready(function()
的簡寫, 這個函數(shù)什么時候執(zhí)行的呢?
答案:DOM
加載完畢之后執(zhí)行。
立即執(zhí)行函數(shù)(function(){})()屬于匿名函數(shù),并且優(yōu)先于$(function() {})加載
很多JS加載文件都裝在這樣的匿名函數(shù)內(nèi)
1. {(function(window, undefined) { 2. //do something 3. })(window);
1首先,(function(window, undefined) {})(window)可以簡化看成這樣()();而()()就是一個匿名函數(shù)自執(zhí)行的寫法.
當然(function() {})(window)好像也更加精簡.后面的圓括號中的window為實參,接受window對象(window對象是全局環(huán)境下的),
2而function后面的圓括號中的window為局部變量,不是全局的window對象.所以這樣寫可以提高js性能,減少作用域鏈查詢時間.(如果在函數(shù)體內(nèi)多次使用到window對象,那么把window對象當著實參穿進去,是十分必要的;如果函數(shù)內(nèi)部不需要,那么就無需傳遞該參數(shù).);
3.function后面的形參undefined又有什么用呢?其實在一些老的瀏覽器中,undefined不被支持,直接使用會導致錯誤,所以考慮兼容性,就增加一個形參undefined;
4.(function() {})()主要用于存放開發(fā)插件的代碼,執(zhí)行其中的代碼時DOM不一定存在,所以直接自動執(zhí)行DOM操作的代碼,請放心使用;
//普通函數(shù) function box(){ return 'lee';};
//把匿名函數(shù)自我執(zhí)行的返回值賦值給變量var b=function(){ //單獨的匿名函數(shù),是無法執(zhí)行的 就算執(zhí)行也無法調(diào)用 return 'lee';};
// 匿名函數(shù)自我執(zhí)行(function (){ //(匿名函數(shù))(); 第一圓括號放匿名函數(shù),第二個圓括號執(zhí)行 return 'lee'; //()表示執(zhí)行})();alert((function (){ return 'lee';})());
//自我執(zhí)行匿名函數(shù)的傳參alert((function(age,name){ return age+name;})(100,200));
匿名函數(shù)最大的用途是創(chuàng)建閉包(這是JavaScript語言的特性之一),并且還可以構(gòu)建命名空間,以減少全局變量的使用。閉包是指有權(quán)訪問另一個函數(shù)作用域中的變量的函數(shù),創(chuàng)建閉包的常見的方式,就是在一個函數(shù)內(nèi)部創(chuàng)建另一個函數(shù),通過另一個函數(shù)訪問這個函數(shù)的局部變量。
//函數(shù)里的匿名函數(shù)(閉包)function box(){ return function(){ //閉包 return 'lee';}};alert(box()()); //box() 返回是匿名函數(shù)的結(jié)構(gòu) box()()返回函數(shù)中匿名函數(shù)的返回值
//通過閉包可以返回局部變量function box(){ return function(){ //通過匿名函數(shù)返回box()局部變量 return 'Lee'; };};alert(box()()); //通過box()()來直接調(diào)用匿名函數(shù)返回值var b=box(); alert(b()); //另一種調(diào)用匿名函數(shù)返回值
使用閉包有一個優(yōu)點,也是他的缺點;就是可以把局部變量留在內(nèi)存中,可以避免使用全局變量。(全局變量污染導致應用程序不可預測性,每個模塊都可調(diào)用必將引來災難,所以拓建使用私有的,封裝的局部變量)
//全局變量累加// var b=100;// function box(){// b++;// };// alert(b);// box();// alert(b);//使用匿名函數(shù)實現(xiàn)局部變量駐留內(nèi)存中從而累加function box(){ var age=100; return function(){ age++; return age; };};var b=box();alert(b()); //每次都要匿名函數(shù)alert(b());alert(b());alert(b());//循環(huán)里的匿名函數(shù)的取值問題1function box(){ var arr=[]; for(var i=0;i<5;i++){ arr[i]=function(){ return i; }; }; return arr;};var b=box();for(var i=0;i<5;i++){ alert(b[i]()); //這么寫取值返回的都是5}//循環(huán)的匿名函數(shù)取值問題2function box(){ var arr=[]; for(var i=0;i<5;i++){ arr[i]=(function(num){ //通過自我及時執(zhí)行匿名函數(shù) return num; })(i); }; return arr;};var b=box();for(var i=0;i<5;i++){ alert(b[i]); //這么寫取值返回的都是5}//循環(huán)里的閉包的取值問題3function box(){ var arr=[]; for (var i =0; i<5;i++) { arr[i]=(function(num){ //arr【0】=0,arr[1]=1,arr[2]=2....... return function(){ //閉包可以將變量駐留到內(nèi)存中。 return num }; })(i); } return arr;};var b=box();for(i=0;i<5;i++){ alert(b[i]());};
function divShow(){ var b=document.getElementById("di"); //b 用完之后會一直駐留到內(nèi)存中 b.onclick=function(){ alert(b.innerHTML); //這里用b導致內(nèi)存泄漏 };}divShow();
javascript沒有塊級作用的概念
//塊級作用域(私有作用域)function box(count){ for(var i=0;i<count;i++) //i不會因為離開了for塊就失效 var i; //就算重新聲明,也不會前面的數(shù)據(jù) alert(i); };box(2);
//模仿塊級作用域(私有作用域)function box(count){ (function(){ //包含自我執(zhí)行函數(shù),就可以實現(xiàn)私有作用域 for(var i=0;i<count;i++) alert(i); })(); alert(i); //報錯,無法訪問 被銷毀了 };
function box(){ var b=100; //私有變量,外部無法訪問};
//對象共有化function Box(){ this.age=100; //屬性,共有的 this.run=function(){ //方法,共有的 return '運行中....'; }};var box=new Box();alert(box.age); //返回100alert(box.run()); //返回運行中//私有化function Box(){ var age=100; //私有屬性 function run(){ //私有方法 return '運行中'; }; this.publicGo=function (){ //對外可見的公共接口,特權(quán)方法 return age+run(); };};var box=new Box();alert(box.age); //返回 undefined 找不到alert(box.run()); //返回 undefined 找不到alert(box.publicGo()); //返回 100 運行中//通過構(gòu)造函數(shù)傳參function Box(value){ var age=value; this.getAge=function(){ return age; };};var box=new Box('杜偉');alert(box.getAge());
var box={ //這樣寫其實已經(jīng)實例化了 age:100, run:function(){ return '運行中'; }};alert(box.age); //直接就可以調(diào)用alert(box.run());//字面量私有化var box=function(){ var age=100; //私有變量 function run(){ //私有函數(shù) return '運行中....'; }; return { //返回對象 publicGo:function (){ //對外公共接口的特權(quán)方法 return age+run(); } };}();alert(box.publicGo());
聯(lián)系客服