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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

闭包详解一

發布時間:2025/4/16 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 闭包详解一 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在正式學習閉包之前,請各位同學一定要確保自己對詞法作用域已經非常的熟悉了,如果對詞法作用域還不夠熟悉的話,可以先看:

  • 深入理解閉包之前置知識---作用域與詞法作用域

前言

現在去面試前端開發的崗位,如果你對面試官也是個前端,并且不是太水的話,你有很大的概率會被問到JavaScript中的閉包。因為這個閉包這個知識點真的很重要,還非常難掌握。

什么是閉包

什么是閉包,你可能會搜出很多答案....

《JavaScript高級程序設計》這樣描述:

閉包是指有權訪問另一個函數作用域中的變量的函數;

《JavaScript權威指南》這樣描述:

從技術的角度講,所有的JavaScript函數都是閉包:它們都是對象,它們都關聯到作用域鏈。

《你不知道的JavaScript》這樣描述:

當函數可以記住并訪問所在的詞法作用域時,就產生了閉包,即使函數是在當前詞法作用域之外執行。

我最認同的是《你不知道的JavaScript》中的描述,雖然前面的兩種說法都沒有錯,但閉包應該是基于詞法作用域書寫代碼時產生的自然結果,是一種現象!你也不用為了利用閉包而特意的創建,因為閉包的在你的代碼中隨處可見,只是你還不知道當時你寫的那一段代碼其實就產生了閉包。

講解閉包

上面已經說到,當函數可以記住并訪問所在的詞法作用域時,就產生了閉包,即使函數是在當前詞法作用域之外執行。

看一段代碼

function fn1() {var name = 'iceman';function fn2() {console.log(name);}fn2(); } fn1(); 復制代碼

如果是根據《JavaScript高級程序設計》和《JavaScript權威指南》來說,上面的代碼已經產生閉包了。fn2訪問到了fn1的變量,滿足了條件“有權訪問另一個函數作用域中的變量的函數”,fn2本身是個函數,所以滿足了條件“所有的JavaScript函數都是閉包”。

這的確是閉包,但是這種方式定義的閉包不太好觀察。

再看一段代碼:

function fn1() {var name = 'iceman';function fn2() {console.log(name);}return fn2; } var fn3 = fn1(); fn3(); 復制代碼

這樣就清晰地展示了閉包:

  • fn2的詞法作用域能訪問fn1的作用域

  • 將fn2當做一個值返回

  • fn1執行后,將fn2的引用賦值給fn3

  • 執行fn3,輸出了變量name

我們知道通過引用的關系,fn3就是fn2函數本身。執行fn3能正常輸出name,這不就是fn2能記住并訪問它所在的詞法作用域,而且fn2函數的運行還是在當前詞法作用域之外了。

正常來說,當fn1函數執行完畢之后,其作用域是會被銷毀的,然后垃圾回收器會釋放那段內存空間。而閉包卻很神奇的將fn1的作用域存活了下來,fn2依然持有該作用域的引用,這個引用就是閉包。

總結:某個函數在定義時的詞法作用域之外的地方被調用,閉包可以使該函數極限訪問定義時的詞法作用域。

注意:對函數值的傳遞可以通過其他的方式,并不一定值有返回該函數這一條路,比如可以用回調函數:

function fn1() {var name = 'iceman';function fn2() {console.log(name);}fn3(fn2); } function fn3(fn) {fn(); } fn1(); 復制代碼

本例中,將內部函數fn2傳遞給fn3,當它在fn3中被運行時,它是可以訪問到name變量的。

所以無論通過哪種方式將內部的函數傳遞到所在的詞法作用域以外,它都回持有對原始作用域的引用,無論在何處執行這個函數都會使用閉包。

再次解釋閉包

以上的例子會讓人覺得有點學院派了,但是閉包絕不僅僅是一個無用的概念,你寫過的代碼當中肯定有閉包的身影,比如類似如下的代碼:

function waitSomeTime(msg, time) {setTimeout(function () {console.log(msg)}, time); } waitSomeTime('hello', 1000); 復制代碼

定時器中有一個匿名函數,該匿名函數就有涵蓋waitSomeTime函數作用域的閉包,因此當1秒之后,該匿名函數能輸出msg。

另一個很經典的例子就是for循環中使用定時器延遲打印的問題:

for (var i = 1; i <= 10; i++) {setTimeout(function () {console.log(i);}, 1000); } 復制代碼

在這段代碼中,我們對其的預期是輸出1~10,但卻輸出10次11。這是因為setTimeout中的匿名函數執行的時候,for循環都已經結束了,for循環結束的條件是i大于10,所以當然是輸出10次11咯。

究其原因:i是聲明在全局作用中的,定時器中的匿名函數也是執行在全局作用域中,那當然是每次都輸出11了。

原因知道了,解決起來就簡單了,我們可以讓i在每次迭代的時候,都產生一個私有的作用域,在這個私有的作用域中保存當前i的值。

for (var i = 1; i <= 10; i++) {(function () {var j = i;setTimeout(function () {console.log(j);}, 1000);})(); } 復制代碼

這樣就達到我們的預期了呀,讓我們用一種比較優雅的寫法改造一些,將每次迭代的i作為實參傳遞給自執行函數,自執行函數中用變量去接收:

for (var i = 1; i <= 10; i++) {(function (j) {setTimeout(function () {console.log(j);}, 1000);})(i); } 復制代碼

閉包的應用

閉包的應用比較典型是定義模塊,我們將操作函數暴露給外部,而細節隱藏在模塊內部:

function module() {var arr = [];function add(val) {if (typeof val == 'number') {arr.push(val);}}function get(index) {if (index < arr.length) {return arr[index]} else {return null;}}return {add: add,get: get} } var mod1 = module(); mod1.add(1); mod1.add(2); mod1.add('xxx'); console.log(mod1.get(2)); 復制代碼

關于閉包還有很多要講,這里先講解比較基礎的概念,接下來還會有更精彩的內容。

特別注意

可以關注我的公眾號:icemanFE,接下來持續更新技術文章!

總結

以上是生活随笔為你收集整理的闭包详解一的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 在线一区二区三区 | 成人污视频 | 玖玖爱在线精品视频 | 久久午夜国产精品 | 毛片在线免费观看视频 | аⅴ天堂中文在线网 | 操她视频在线观看 | 91精品国产麻豆国产自产在线 | 日日燥夜夜燥 | 奇米影视盒 | 日韩午夜av | 日韩视频精品在线 | 在线观看亚洲网站 | 性史性dvd影片农村毛片 | 日本一区二区在线观看视频 | 韩日一区二区三区 | 亚洲成人久久久久 | 人妻洗澡被强公日日澡 | 劲爆欧美第一页 | 久久久成人精品一区二区三区 | 成人免费看片网站 | 午夜性| 欧美爽爽爽| 一级一片免费播放 | 免费的毛片网站 | 国产成人午夜高潮毛片 | 波多野结衣视频网站 | 国产情侣自拍一区 | 一区二区三区亚洲 | 黄污视频在线观看 | 国产午夜一区二区三区 | 天堂av在线资源 | www.色香蕉 | 亚洲欧美综合网 | 火影忍者羞羞漫画 | 黄色a级片在线观看 | 疯狂做受xxxx国产 | 欧美精品久久久久久久久久 | 国产永久视频 | 伊人久久五月 | 日韩理论视频 | 97影院在线午夜 | 欧美偷拍视频 | 亚洲春色www | 亚洲人丰满奶水 | 日韩高清黄色 | 国产亚洲精品久久久久丝瓜 | 欧美亚洲二区 | 性高潮影院| 2021国产在线视频 | 日韩大片免费在线观看 | 亚洲精品乱码久久久久久黑人 | 国产视频一区二区三 | 成人开心网 | 国产初高中真实精品视频 | 一本大道av伊人久久综合 | 内射一区二区 | 在线中文字幕av | 国产精品国产三级国产aⅴ下载 | 激情爱爱网站 | 大肉大捧一进一出好爽视频 | 久久久久国产精品午夜一区 | 国产熟妇与子伦hd | 一区二区三区四区五区六区 | 亚洲一区二区成人 | 花房姑娘免费观看全集 | 91亚洲精华| 极品尤物魔鬼身材啪啪仙踪林 | 亚洲国产欧美在线 | 欧美疯狂做受 | 亚洲区中文字幕 | 日日日日日日bbbbbb | 欧美日韩一区二区不卡 | 日本东京热一区二区 | 波多野结衣操 | 国产成人手机视频 | 91丨porny丨露出| 国产叼嘿视频在线观看 | 国产精品国产三级国产aⅴ无密码 | av无码久久久久久不卡网站 | 天天操婷婷 | 久草播放| 夜夜操影视| 日韩精品免费播放 | 一个色综合网站 | www日本视频 | 伊人久久精品 | 看av的网址| 日本一区二区三区在线看 | 欧美18一19性内谢 | 日本一区中文 | 色婷婷一区二区 | 秘密基地免费观看完整版中文 | 紧身裙女教师三上悠亚红杏 | 久久er99热精品一区二区 | 国产主播一区 | 久久久中文字幕 | 免费在线观看高清影视网站 | 女人十八毛片嫩草av |