1.什么是閉包? 有什么作用?
閉包的英文單詞是closure,是指有權訪問另一個函數作用域中變量的函數。
閉包在本質上,就是將函數內部和函數外部連接起來的一座橋梁,內層函數可以使用外層函數的所有變量,即使外層函數已經執行完畢。
-
閉包的作用
1.使用閉包可以大大減少我們的代碼量,是代碼看上去更加清晰。
2.保護函數內變量的安全
3.在內存中維持一個變量
4.閉包使得Javascript的垃圾回收機制(GC)不會收回變量所占用的資源,GC指的是*垃圾收集器會定期(周期性)找出那些不在繼續使用的變量,然后釋放其內存,不再使用的變量也就是生命周期結束的變量,當然只可能是局部變量,全局變量的生命周期直至瀏覽器卸載頁面才會結束。局部變量只在函數的執行過程中存在,而在這個過程中會為局部變量在?;蚨焉戏峙湎鄳目臻g,以存儲它們的值,然后在函數中使用這些變量,直至函數結束,而閉包中由于內部函數的原因,外部函數并不能算是結束。
以下詳細的代碼實例:
//創建閉包
function myfn(){
return function(){
return ("我是內層匿名函數")
}
}
console.log(myfn)//輸出整個函數表達式
console.log(myfn())//輸出內部的匿名函數表達式
調用方式1
console.log(myfn()())//輸出內部匿名函數的返回值:“我是內層匿名函數”
調用方式2
var bb=myfn()
console.log(bb())//輸出:“我是內層匿名函數”
作用1- 通過閉包訪問局部變量
function myfn(){
var aa="局部變量aa"
}
console.log(aa);// aa is not defined,由于aa是局部變量函數外無法訪問function myfn(){ var aa="局部變量aa" return function(){ return(aa)//通過匿名函數返回函數myfn()的局部變量aa } } console.log(myfn()())//調用方式1:輸出-“局部變量aa” var bb=myfn() console.log(bb());//調用方式2:輸出-“局部變量aa” //作用2:把局部變量的值始終保存在內存中,可以避免使用全局變量,全局變量會導致命名沖突、垃圾回收等麻煩,閉包的缺陷就是由于閉包資源不會被立刻銷毀會大量的占用內存,導致性能下降 var num=10; function add(){ console.log(++num); } add();//輸出10 add();//輸出11 add();//輸出12,函數沒執行一次,累計一次,因為num是全局變量 function ad(){ var num=100;//改為局部變量 console.log(++num); } ad();ad();ad();//3次輸出結果都是100,局部變量無法實現累加 //閉包實現局部變量的累加 function addd(){ var num=1000;//局部變量 return function(){ num++; console.log(num) } } addd()(); addd()(); addd()();//輸出結果都為1000,調用方式1失敗,因為 //每調用一次函數,初始化函數一次, var fn=addd(); fn();fn();fn();//輸出結果1001,1002,1003,調用方式2成功,因為執行3次函數只初始化函數一次,后面調用時執行里面的匿名函數 fn=null //賦值為null,有利于垃圾回收器回收,釋放內存,提高性能
2.setTimeout 0 有什么作用
-
實現實現javascript的異步,正常情況下javascript都是按照順序執行的。但是我們可能讓該語句后面的語句執行完再執行本身,這時就可以用到setTimeout延時0ms來實現了
console.log(1) setTimeout("console.log(2)",0); console.log(3); //正常按順序執行輸出結果為1,2,3 //但是延時了0ms后,輸出結果為:1,3,2
-
在事件中,setTimeout 會在其完成當前任何延宕事件的事件處理器的執行,以及完成文檔當前狀態更新后,告訴瀏覽器去啟用 setTimeout 內注冊的函數。
<input id="lower" type="text" placeholder="請輸入字母"> <script type="text/javascript"> var lower=document.getElementById("lower"); lower.addEventListener("keydown",function(){ var a=this; setTimeout(function(){ a.value=a.value.toUpperCase(); },0); }) </script>