日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

好程序员前端教程之JavaScript闭包和匿名函数的关系详解...

發布時間:2025/3/15 javascript 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 好程序员前端教程之JavaScript闭包和匿名函数的关系详解... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

好程序員前端教程之JavaScript閉包和匿名函數的關系詳解
本文講的是關于JavaScript閉包和匿名函數兩者之間的關系,從匿名函數概念到立即執行函數,最后到閉包。下面一起來看看文章分析,希望你會喜歡。
前面講了一篇在for循環中加setTimeout輸出內容,我們用到了一個閉包,但同時也可以說是匿名函數,到底匿名函數和閉包有沒有關系呢?【答案是它們之間沒有關系】
匿名函數
匿名函數,顧名思義,就是沒有名字的函數,與之對應的就是有名字的函數,也叫具名函數。
//匿名函數
function (){

console.log('匿名函數');

}
//具名函數
function myFn(){

console.log('具名函數');

}
//變量a就是匿名函數的名字
var a = function(){

console.log('a就是匿名函數的名字');

}
如果我們直接在控制臺中運行匿名函數,會發現報錯,無法執行。匿名函數是無法執行的,一般用到匿名函數的時候都是立即執行,也叫自執行匿名函數或者自調用匿名函數,一般人都叫立即執行函數。
立即執行函數
比較常見的立即執行函數如下:
;(function(){

console.log('caibaojian.com');

})()

;(function(){

console.log('caibaojian.com');

}());
上面這兩種都是典型的立即執行函數寫法,兩者的區分就是一個執行在匿名函數括號外面,另外一個發起執行的括號在匿名函數里面。比較常見的是第一種寫法,括號在匿名函數的括號外面。
步驟分解:
1.首先聲明一個匿名函數 function(){alert('我是匿名函數')}。
2.然后在匿名函數后面接一對括號 (),調用這個匿名函數。
那為什么還要用一個括號包起來呢?其實是為了兼容JS的語法,如果我們不加括號,直接寫成
function (){alert('我是匿名函數')}()
瀏覽器會報語法錯誤,想要通過瀏覽器的語法檢查,必須加點小東西,比如下面幾種
(function(){alert('我是匿名函數')} ()) // 用括號把整個表達式包起來
(function(){alert('我是匿名函數')}) () //用括號把函數包起來
!function(){alert('我是匿名函數')}() // 求反,我們不在意值是多少,只想通過語法檢查。
+function(){alert('我是匿名函數')}()
-function(){alert('我是匿名函數')}()
~function(){alert('我是匿名函數')}()
void function(){alert('我是匿名函數')}()
new function(){alert('我是匿名函數')}()
實際上,立即執行函數的作用只有一個:創建一個獨立的作用域,在這個作用域里面,外面訪問不到,避免變量污染。比如我們前面的一篇文章,setTimeout的第三個參數里面講到的一道題目。
for(var i=0;i<6;i++){

setTimeout(function(){console.log(i); //為什么輸出的總是 6,而不是0,1,2,3,4,5 },i*1000);

}
我們發現上面這個定時器總是輸出6,因為setTimeout里面的執行函數是異步的,執行的時候,i的值是貫穿整個作用域的,而不是單獨一個給每個定期器分配了一個i,for運行完的值是6,此時輸出就總是6了。
那怎么解決呢?用立即執行函數給每個定時器創造一個獨立作用域即可。
for(var i=0;i<6;i++){

(function(j){setTimeout(function(){console.log(j);},j*1000); })(i);

}
在for循環執行時,立即執行函數就已經有了結果了。而每個立即執行函數里面的j值就是獨立的一個,不會受后面影響。所以會分別執行5次定時器。
//第一個立即執行函數
(function(0){

setTimeout(function(){console.log(0); })

})(0);
//第二個立即執行函數
(function(1){

setTimeout(function(){console.log(1); })

})(1);
//……
//第六個立即執行函數
(function(5){

setTimeout(function(){console.log(5); })

})(5);

i 的值從 0 變化到 5,對應 6 個立即執行函數,這 6 個立即執行函數里面的 j 「分別」是 0、1、2、3、4、5。
上面說了這么多關于匿名函數和立即執行函數的,相信你對這兩個概念已經很清楚,那么閉包跟匿名函數有關系嗎?
閉包
js閉包是指有權訪問另一個函數作用域中的變量的函數,個人認為js閉包最大的用處就是防止對全局作用域的污染。閉包最神奇的地方就是能在一個函數外訪問函數中的局部變量,把這些變量用閉包的形式放在函數中便能避免污染。
我們可以分離出上面的第一個立即執行函數
function box(i){

setTimeout(function(){console.log(i); },i*1000);

}
box(1);

//或者這樣
function box(i){

function inner(){console.log(i); } return inner;

}
var outer = box(1);
outer();
結論
很明顯這是一個閉包,然后我們再看看我們最前面的匿名函數代碼和立即執行函數代碼,可以看出匿名函數和閉包兩者并沒有關系。閉包既可以在匿名函數也可以在具名函數中使用。
這個for循環中的閉包怎么理解以及自執行匿名函數的作用:
這個for循環產生的閉包其實是定時器的回調函數,這些回調函數的執行環境是window,類似剛才例子中的引用inner的全局outer的執行環境,匿名函數則相當于剛才例子中的box函數。
Stackoverflow網站上的一個提問跟我們今天分析的類似。有一個回答挺好。
閉包機制適用于所有JavaScript函數,無論是否匿名。
我認為這兩個概念之間的混淆來自于使用術語“閉包”,其中作者已經說過“下面的代碼創建一個閉包”,然后給出了一個恰好使用匿名函數的例子。 在這種情況下,閉包機制通常是使特定代碼段按預期工作的重要因素,而使用匿名函數而不是命名函數恰好是編碼它的便捷方式。 閱讀這些例子并且第一次看到“閉包”的人然后誤解了這個術語,并繼續在他們自己的Stack Overflow或博客文章中錯誤地使用它,因此混亂傳播。
一開始我以為匿名函數跟閉包有關系,那是因為恰好這個定時器使用了閉包和匿名函數,讓我們誤認為兩者之間有關系,其實還有很多種方法可以解決這個問題,比如我們之前說到的setTimeout的第三個參數,同樣可以得到跟使用立即執行函數同樣的效果。
所以說匿名函數和閉包之間沒有什么關系,只不過很多時候在用到匿名函數解決問題的時候恰好形成了一個閉包,就導致很多人分不清楚匿名函數和閉包的關系。

總結

以上是生活随笔為你收集整理的好程序员前端教程之JavaScript闭包和匿名函数的关系详解...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。