JavaScript閉包和回調(diào)詳解
一、閉包
閉包(closure)是Javascript語言的一個難點,也是它的特色,很多高級應用都要依靠閉包實現(xiàn)。
閉包有三個特性:
1.函數(shù)嵌套函數(shù);
2.函數(shù)內(nèi)部可以引用外部的參數(shù)和變量;
3.參數(shù)和變量不會被垃圾回收機制回收。
閉包是指有權訪問另一個函數(shù)作用域中的變量的函數(shù),創(chuàng)建閉包的最常見的方式就是在一個函數(shù)內(nèi)創(chuàng)建另一個函數(shù),通過另一個函數(shù)訪問這個函數(shù)的局部變量。使用閉包有一個優(yōu)點,也是它的缺點,就是可以把局部變量駐留在內(nèi)存中,可以避免使用全局變量。全局變量在每個模塊都可調(diào)用,這勢必將是災難性的。所以推薦使用私有的,封裝的局部變量。一般函數(shù)執(zhí)行完畢后,局部活動對象就被銷毀,內(nèi)存中僅僅保存全局作用域。但閉包的情況不同!
示例一:
//閉包就是一個函數(shù)的返回值為另外一個函數(shù),在outer外部可以通過這個返回的函數(shù)訪問outer內(nèi)的局部變量.
function outer(){
var val = 0;
return function (){
val += 1;
document.write(val + "<br />");
};
}
var outObj = outer();
outObj();//1,執(zhí)行val += 1后,val還在
outObj();//2
outObj = null;//val 被回收
var outObj1 = outer();
outObj1();//1
outObj1();//2
閉包會使變量始終保存在內(nèi)存中,如果不當使用會增大內(nèi)存消耗(如果上例中定義很多outer(),則內(nèi)存中會保存很多val變量)。
javascript的垃圾回收原理:
(1)、在javascript中,如果一個對象不再被引用,那么這個對象就會被GC回收;
(2)、如果兩個對象互相引用,而不再被第3者所引用,那么這兩個互相引用的對象也會被回收。
那么使用閉包有什么好處呢?使用閉包的好處是:
1.希望一個變量長期駐扎在內(nèi)存中
2.避免全局變量的污染
3.私有成員的存在
二、回調(diào)
回調(diào)函數(shù)原理:我現(xiàn)在出發(fā),到了通知你”。這是一個異步的流程,“我出發(fā)”這個過程中(函數(shù)執(zhí)行),“你”可以去做任何事,“到了”(函數(shù)執(zhí)行完畢)“通知你”(回調(diào))進行之后的流程。
示例一:
function doSomething(callback){
callback(1,2);
}
function numberAdd(a,b){
document.write(a+b);
}
doSomething(numberAdd);//3
示例二:
function Thing(name){
this.name = name;
}
//在Thing類里加入doSomething方法,這里使用了構造器調(diào)用模式
Thing.prototype.doSomething = function(callback){
callback(this.name);
};
function showName(name){
document.write(name);
}
var t = new Thing("zhangsan");
t.doSomething(showName);//zhangsan
如果你有一個數(shù)字組成的數(shù)組,你想寫個排序的公共方法,但是排序方式(從小到大或從大到?。┦钦{(diào)用該排序方法的人決定。實現(xiàn)該排序方法可以用回調(diào)來實現(xiàn),當然你可以寫2個方法,一個是從小到大的排序,一個是從大到小的排序方法?;卣{(diào)個人認為就是將決定權交給了實際業(yè)務開發(fā)工程師,由他來決定怎么去處理,這種思路跟我們平常接觸的不同,有點不習慣,但是這種思路在異步編程中特別能看出它的好處,不知道我這么理解是否正確。下面示例代碼就是回調(diào)的典型使用場合:
var arr = [25,13,33,8,23,32];
Array.prototype.sort = function(callback){
var arr = this;
var i = 0;//i在這里定義與在for循環(huán)的括號內(nèi)(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表示數(shù)組從小到大排序
arr.sort(function(a,b){
return a - b > 0;
});
document.write(arr.join(",") + "<br />");//8,13,23,25,32,33
//b-a>0表示數(shù)組從大到小排序
arr.sort(function(a,b){
return b - a > 0;
});
document.write(arr.join(","));//33,32,25,23,13,8
相關文章
JavaScript中document.forms[0]與getElementByName區(qū)別
在很多情況下JavaScript中document.forms[0]與getElementByName這兩種用法沒有區(qū)別,這片文章詳細的解釋了兩者的區(qū)別和用法,有興趣的朋友可以參考一下。2015-01-01
JavaScript使用readAsDataUrl方法預覽圖片
這篇文章主要為大家詳細介紹了JavaScript使用readAsDataUrl方法預覽圖片,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05
JS實現(xiàn)網(wǎng)頁頂部向下滑出的全國城市切換導航效果
這篇文章主要介紹了JS實現(xiàn)網(wǎng)頁頂部向下滑出的全國城市切換導航效果,涉及javascript鼠標事件及頁面元素顯示的實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-08-08
JavaScript中創(chuàng)建字典對象(dictionary)實例
這篇文章主要介紹了JavaScript中創(chuàng)建字典對象(dictionary)實例,本文直接給出了實現(xiàn)的源碼,并給出了使用示例,需要的朋友可以參考下2015-03-03

