面试之作用域链与闭包
閉包有多重要?如果你是初入前端的朋友,我沒有辦法直觀的告訴你閉包在實際開發中的無處不在,但是我可以告訴你,前端面試,必問閉包。面試官們常常用對閉包的了解程度來判定面試者的基礎水平,保守估計,10個前端面試者,至少5個都死在閉包上。
作用域鏈【主要作用:變量名解析】
如果你理解了作用域鏈,那么閉包對于你而言,理解起來就相當地簡單了。
作用域鏈,當然可以看成是一個(有序檢索)的對象列表。
有序檢索:即就近原則“由近及遠”,全所以大家一定要明白局對象始終是最后一個!
舉例來說,也就是:
假如JS的頂級代碼(不包含在函數內的代碼),它的作用域鏈就是一個全局對象;
假如JS代碼中有函數,但是沒嵌套,它的作用域鏈有兩個對象,第一個是函數內的變量即函數參數,第二個就是全局對象【第一第二的順序很重要】;
假如有函數嵌套,那么作用域鏈至少有3個對象。
了解完作用域鏈的主要作用,這個時候我們就要知道它的【創建規則】
定義函數的時候,會保存一個作用域鏈;
調用函數的時候,有兩個操作:一是將函數內的局部變量保存在一個新建對象中,然后添加到函數定義時的作用域鏈中;二是會創建一個“運行期上下文”的內部對象,每一個運行期上下文都有一個單獨的作用域鏈,而調用時會將上面提到那個作用域鏈中的對象相當于復制一份到運行期上下文這個作用域鏈中。
在嵌套函數時,有些不一樣,我們每一次調用外部函數的時候,內部函數都需要重新定義一次,因為每次運行外部函數時,它的作用域鏈都是不相同的。內部函數在每次定義時也有微妙的差別——在每次調用外部函數的時候,內部函數的代碼是相同的,而且關聯這段代碼的作用域鏈也不相同。
function buttonInit(){for(var i=1;i<4;i++){var b=document.getElementById("button"+i);b.addEventListener("click",function(){alert("Button"+i); },false);} } window.onload=buttonInit; //--結果:都是button4 function buttonInit(){for(var i=1;i<4;i++){(function a(j) {console.log(j);var b=document.getElementById("button"+j);b.addEventListener("click",function(){alert("Button"+j); },false);})(i)} } window.onload=buttonInit; //--結果:button1、button2、button3復制代碼閉包:【主要作用:變量私有化】
缺點:
1、 閉包會讓函數內部變量始終保存在內存中,需要手動釋放資源;
【解決辦法:即將函數設置為null】
2、過多的閉包導致內存泄漏。
實現閉包:
當嵌套函數被作為外部函數的返回值返回或者存儲在某處的屬性里,這時會有一個外部引用指向這個嵌套函數,就不會被回收,并且這個嵌套函數所指向的變量綁定對象也不會回收。
var name = 'one';function a() {var name = 'two';function f() {return name;}return f;}a()();function counter(m) {return{get count(){return m++;},set count(n){if(m<=n) m=n;else throw Error('count can only be set to a larger value');}};}var c = counter(100);console.log(c.count);//--100console.log(c.count);//--101c.count = 200;console.log(c.count);//--200console.log(c.count=200);//--throw Errorconsole.log(c.count=300);//--300 復制代碼本次給大家推薦一個最后給大家推薦一個免費的學習群,里面概括移動應用網站開發,css,html,webpack,vue node angular以及面試資源等。 對web開發技術感興趣的同學,歡迎加入Q群:864305860,不管你是小白還是大牛我都歡迎,還有大牛整理的一套高效率學習路線和教程與您免費分享,同時每天更新視頻資料。 最后,祝大家早日學有所成,拿到滿意offer,快速升職加薪,走上人生巔峰。
轉載于:https://juejin.im/post/5bb21922e51d4527ed004af4
總結
以上是生活随笔為你收集整理的面试之作用域链与闭包的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU-6290_奢侈的旅行(Dijst
- 下一篇: 伪元素的margin值挤压主体元素解决