仍記得剛來到公司的時候,老大跟我們說起原型鏈、閉包、MV*之類的東西,當時真的是一臉懵逼的樣子啊哈哈
在公司做前端開發也差不多四個月了,每一天感覺都是很忙碌,都是忙著寫業務代碼或者自己在學習新東西,總感覺很多知識點在這樣的狀態下,匆匆忙忙就略過了,自己並沒有真正理解掌握下來,還是要趁有時間還是把那些東西撿回來
先看一段JS代碼:
function a(){ var num = 0; function b(){ num++; console.log(num); } return b; } var add = a(); add(); // 1 add(); // 2 add(); // 3
這段代碼的特點:
·函數a裡面定義了一個函數b,函數b裡面的操作讓變量num自加的,最後一句是return b,將函數b返回了;
·add變量是指向了函數a的(有點像C的指針),函數a裡面的函數b是被外部變量add引用了,函數b就形成了一個閉包了。
那閉包一般用來干嘛呢?
·在JavaScript模擬實現塊級作用域,封裝私有變量,防止污染全局變量
舉個栗子??
var foo = (function(){ var secret = "secret"; return { //特權方法 get_secret : function () { return secret; }, set_secret :function(new_secret){ secret = new_secret; } } })();
alert(secret) //undefined alert(foo.get_secret()); //secret foo.set_secret("x"); alert(foo.get_secret()); //x
JS是沒有類似Java的class、private關鍵字來封裝一個私有變量的,在JS是使用閉包機制去模擬實現的,首先在匿名函數裡聲明一個secret變量值也為'secret',在函數的外部呢是無法訪問到的。在匿名函數裡return的是setter和getter方法,foo對象指向的是匿名函數,這樣就能在外部去訪問一個局部變量了,但是要通過setter和getter的方法,它們也叫做特權方法
再或者呢,不設置setter的方法,只有個getter的方法,老大跟我說這樣就用在游戲裡能防作弊了0.0
閉包的弊端:
javascript是高級語言,擁有自動的垃圾回收機制,所需內存的分配以及無用內存的回收完全實現了自動管理。簡單來說就是找出那些不再繼續使用的變量,然後釋放其占用的內存。
垃圾收集方式主要有:1、標記清除;2、引用計數;
常見的方式就是標記清除了,垃圾收集器會給所有貯存在內存的變量加上標記,然後它會去掉環境中的變量以及被環境中被其他變量引用的變量的標記,剩下還有標記的變量就被視為准備刪除垃圾了,因為它們不會再被環境所使用到,最後,垃圾收集器完成內存清除工作。
到 2008 年為止,IE、Firefox、Opera、Chrome 和 Safari 的 JavaScript 實現使用的都是標記清除式的 垃圾收集策略(或類似的策略),只不過垃圾收集的時間間隔互有不同。
正如上面說到的,閉包是在一個函數裡面函數,但是被外部的變量所引用到了,所以它是會永遠貯存在內存裡而不會被銷毀,造成了內存洩露,所以對於閉包還是要謹慎使用
以上,是對於閉包機制的一些個人理解,如果文中出現錯誤,歡迎大家指正:)