一、閉包
閉包(closure)是Javascript語言的一個難點,也是它的特點,不少高級應用都要依靠閉包實現。
閉包有三個特性:
1.函數嵌套函數;
2.函數內部能夠引用外部的參數和變量;
3.參數和變量不會被垃圾回收機制回收。
閉包是指有權訪問另外一個函數做用域中的變量的函數,建立閉包的最多見的方式就是在一個函數內建立另外一個函數,經過另外一個函數訪問這個函數的局部變量。使用閉包有一個優勢,也是它的缺點,就是能夠把局部變量駐留在內存中,能夠避免使用全局變量。全局變量在每一個模塊均可調用,這勢必將是災難性的。因此推薦使用私有的,封裝的局部變量。通常函數執行完畢後,局部活動對象就被銷燬,內存中僅僅保存全局做用域。但閉包的狀況不一樣!
示例一:
//閉包就是一個函數的返回值爲另一個函數,在outer外部能夠經過這個返回的函數訪問outer內的局部變量.javascript
1 function outer(){ 2 var val = 0; 3 return function (){ 4 val += 1; 5 document.write(val + "<br />"); 6 }; 7 } 8 var outObj = outer(); 9 outObj();//1,執行val += 1後,val還在 10 outObj();//2 11 outObj = null;//val 被回收 12 var outObj1 = outer(); 13 outObj1();//1 14 outObj1();//2
閉包會使變量始終保存在內存中,若是不當使用會增大內存消耗(若是上例中定義不少outer(),則內存中會保存不少val變量)。
javascript的垃圾回收原理:
(1)、在javascript中,若是一個對象再也不被引用,那麼這個對象就會被GC回收;
(2)、若是兩個對象互相引用,而再也不被第3者所引用,那麼這兩個互相引用的對象也會被回收。
那麼使用閉包有什麼好處呢?使用閉包的好處是:
1.但願一個變量長期駐紮在內存中
2.避免全局變量的污染
3.私有成員的存在java
二、回調
回調函數原理:我如今出發,到了通知你」。這是一個異步的流程,「我出發」這個過程當中(函數執行),「你」能夠去作任何事,「到了」(函數執行完畢)「通知你」(回調)進行以後的流程。
示例一:編程
1 function doSomething(callback){ 2 callback(1,2); 3 } 4 function numberAdd(a,b){ 5 document.write(a+b); 6 } 7 doSomething(numberAdd);//3
示例二:數組
function Thing(name){ this.name = name; }
//在Thing類里加入doSomething方法,這裏使用了構造器調用模式閉包
1 Thing.prototype.doSomething = function(callback){ 2 callback(this.name); 3 }; 4 function showName(name){ 5 document.write(name); 6 } 7 var t = new Thing("zhangsan"); 8 t.doSomething(showName);//zhangsan
若是你有一個數字組成的數組,你想寫個排序的公共方法,可是排序方式(從小到大或從大到小)是調用該排序方法的人決定。實現該排序方法能夠用回調來實現,固然你能夠寫2個方法,一個是從小到大的排序,一個是從大到小的排序方法。回調我的認爲就是將決定權交給了實際業務開發工程師,由他來決定怎麼去處理,這種思路跟咱們日常接觸的不一樣,有點不習慣,可是這種思路在異步編程中特別能看出它的好處,不知道我這麼理解是否正確。下面示例代碼就是回調的典型使用場合:異步
var arr = [25,13,33,8,23,32]; Array.prototype.sort = function(callback){ var arr = this; var i = 0;//i在這裏定義與在for循環的括號內(for(var i = 0; i < ...))定義是同樣的 for(; i < arr.length-1; i++){ var j = i + 1; for(; j < arr.length;j++){ if(callback(arr[i],arr[j])){ var temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } return arr; }; //a-b>0表示數組從小到大排序 arr.sort(function(a,b){ return a - b > 0; }); document.write(arr.join(",") + "<br />");//8,13,23,25,32,33 //b-a>0表示數組從大到小排序 arr.sort(function(a,b){ return b - a > 0; }); document.write(arr.join(","));//33,32,25,23,13,8