电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

詳解JavaScript作用域 閉包

瀏覽:130日期:2023-10-19 15:57:58

JavaScript閉包,是JS開(kāi)發(fā)工程師必須深入了解的知識(shí)。3月份自己曾撰寫(xiě)博客《JavaScript閉包》,博客中只是簡(jiǎn)單闡述了閉包的工作過(guò)程和列舉了幾個(gè)示例,并沒(méi)有去刨根問(wèn)底,將其弄明白!

現(xiàn)在隨著對(duì)JavaScript更深入的了解,也剛讀完《你不知道的JavaScript(上卷)》這本書(shū),所以乘機(jī)整理下,從底層和原理上去刨一下。

JavaScript并不具有動(dòng)態(tài)作用域,它只有詞法作用域。詞法作用域是在寫(xiě)代碼或者說(shuō)定義時(shí)確定的,而動(dòng)態(tài)作用域是在運(yùn)行時(shí)確定的。了解閉包前,首先我們得知道什么是詞法作用域(作用域是由書(shū)寫(xiě)代碼時(shí)函數(shù)聲明的位置來(lái)決定的)。

一、何為閉包

示例1:

function foo(){var a = 2;function bar(){console.log(a);}return bar;}var baz = foo();bzz(); //2

在foo()執(zhí)行后,通常認(rèn)為垃圾回收機(jī)制會(huì)將foo()的整個(gè)內(nèi)部作用域都被銷毀;而閉包可以阻止這樣事情發(fā)生,讓其內(nèi)部作用域依然存在。因?yàn)閎ar()處于foo()內(nèi)部,它擁有涵蓋foo()作用域的閉包,使得該作用域能夠一直存活,以供bar()在之后任何時(shí)間進(jìn)行引用。

bar()依然持有對(duì)該作用域的引用,而這個(gè)引用就叫作閉包。

簡(jiǎn)言之:當(dāng)函數(shù)可以記住并訪問(wèn)所在的詞法作用域,即使函數(shù)是在當(dāng)前詞法作用域之外執(zhí)行,這時(shí)就產(chǎn)生了閉包。

示例2:

無(wú)論使用何種方式對(duì)函數(shù)類型的值進(jìn)行傳遞,當(dāng)函數(shù)在別處被調(diào)用時(shí)都可以觀察到閉包。

function foo(){var a = 2;function baz(){console.log(a);}bar(baz);}function bar(fn){fn();// 這就是閉包}

示例3:

將一個(gè)內(nèi)部函數(shù)(timer)傳遞給setTimeout。timer具有涵蓋wait()作用域的閉包,保有對(duì)變量message的引用。

wait()執(zhí)行1000毫秒后,它的作用域并不會(huì)消失,timer依然保有wait()作用域的閉包。

function wait(message){setTimeout( function timer(){console.log(message);},1000);}wait('Hello,ligang');

示例4:

下述activator()具有涵蓋setupBot()作用域的閉包!

function setupBot(name, selector){$(selector).click(function activator(){console.log('Activating: '+ name);});}setupBot('Closure Bot 1', '#bot_1');setupBot('Closure Bot 2', '#bot_2');

二、循環(huán)和閉包

for(var i=1; i<=5; i++){setTimeout(function timer(){console.log(i);}, i*1000);}// 期望:每秒一次的頻率輸出1~5// 結(jié)果:每秒一次的頻率輸出五次6

先解釋一下:“i*1000”,5個(gè)定時(shí)分別在1s、2s、3s、4s、5s后執(zhí)行,并不是1s、3s、6s、10s、15s。也就是頻率為1s,不是每次間隔增加1s。如果去掉i寫(xiě)成“1000”,會(huì)在for執(zhí)行完1s后直接輸出五次6。

回調(diào)函數(shù)在循環(huán)結(jié)束后才被執(zhí)行,因此輸出的是循環(huán)終止條件是i值。事實(shí)上,當(dāng)定時(shí)器運(yùn)行時(shí)即使每個(gè)迭代中執(zhí)行的是setTimeout(..., 0),所有的回調(diào)函數(shù)依然是在循環(huán)結(jié)束后才被執(zhí)行。

根據(jù)作用域的工作原理,盡管五個(gè)函數(shù)是在各個(gè)迭代中分別定義的,但是它們都被封閉在一個(gè)共享的全局作用域中,因此實(shí)際上只有一個(gè)i。

解決方案1:

for(var i=0; i<=5; i++){(function(j){setTimeout(function timer(){console.log(j);}, j*1000 );})(i);}// 結(jié)果:每秒一次的頻率輸出1~5

每個(gè)迭代都生成一個(gè)新的作用域,使得延遲函數(shù)的回調(diào)可以將新的作用封閉在每個(gè)迭代內(nèi)部,每個(gè)迭代中都會(huì)含有一個(gè)具有正確值的變量供我們?cè)L問(wèn)。

解決方案2(ES6):

for(var i=0; i<=5; i++){let j = i;setTimeout(function timer(){console.log(j);}, j*1000 );}// 結(jié)果:每秒一次的頻率輸出1~5for(let i=0; i<=5; i++){setTimeout(function timer(){console.log(i);}, i*1000 );}// 結(jié)果:每秒一次的頻率輸出五次6

三、模塊

模塊需要具備兩個(gè)必要條件:

(1)必須有外部的封閉函數(shù),該函數(shù)必須至少被調(diào)用一次(每次調(diào)用都會(huì)創(chuàng)建一個(gè)新的模塊實(shí)例)。

(2)封閉函數(shù)必須返回至少一個(gè)內(nèi)部函數(shù),這樣內(nèi)部函數(shù)才能在私有作用域中形成閉包,并且可以訪問(wèn)或者修改私有的狀態(tài)。

典型的模塊化:

function CoolMoudle(){var something = 'cool';var doSomething = function(){console.log(something);}return{doSomething: doSomething};}var foo = CoolMoudle();//如果不執(zhí)行外部函數(shù)CoolMoudle(),內(nèi)部作用域和閉包都無(wú)法創(chuàng)建foo.doSomething();//cool

單例模式:

var foo = (function CoolModule(id){function change(){// 修改公共APIpublicAPI.identify = identify2;}function identify1(){console.log(id);}function identify2(){console.log(id.toUpperCase());}var publicAPI = {change: change,identify: identify1};return publicAPI;})('foo module');foo.identify();//foo modulefoo.change();foo.identify(); //FOO MODULE

以上就是詳解JavaScript作用域 閉包的詳細(xì)內(nèi)容,更多關(guān)于JavaScript作用域 閉包的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: 福尔卡(北京)新型材料技术股份有限公司| 大型果蔬切片机-水果冬瓜削皮机-洗菜机切菜机-肇庆市凤翔餐饮设备有限公司 | 冷库安装厂家_杭州冷库_保鲜库建设-浙江克冷制冷设备有限公司 | 皮带输送机-大倾角皮带输送机-皮带输送机厂家-河南坤威机械 | 电磁流量计_智能防腐防爆管道式计量表-金湖凯铭仪表有限公司 | pos机办理,智能/扫码/二维码/微信支付宝pos机-北京万汇通宝商贸有限公司 | 菲希尔FISCHER测厚仪-铁素体检测仪-上海吉馨实业发展有限公司 | 兰州牛肉面加盟,兰州牛肉拉面加盟-京穆兰牛肉面 | 驾驶式洗地机/扫地机_全自动洗地机_工业洗地机_荣事达工厂官网 | 大型多片锯,圆木多片锯,方木多片锯,板材多片锯-祥富机械有限公司 | WF2户外三防照明配电箱-BXD8050防爆防腐配电箱-浙江沃川防爆电气有限公司 | 气力输送设备_料封泵_仓泵_散装机_气化板_压力释放阀-河南锐驰机械设备有限公司 | 飞利浦LED体育场灯具-吸顶式油站灯-飞利浦LED罩棚灯-佛山嘉耀照明有限公司 | 软瓷_柔性面砖_软瓷砖_柔性石材_MCM软瓷厂家_湖北博悦佳软瓷 | 高低温万能试验机_拉力试验机_拉伸试验机-馥勒仪器科技(上海)有限公司 | 杭州顺源过滤机械有限公司官网-压滤机_板框压滤机_厢式隔膜压滤机厂家 | 精密线材测试仪-电线电缆检测仪-苏州欣硕电子科技有限公司 | 小威小说网 - 新小威小说网 - 小威小说网小说搜索引擎 | 盘式曝气器-微孔曝气器-管式曝气器-曝气盘-斜管填料 | 郑州市前程水处理有限公司 | 撕碎机,撕破机,双轴破碎机-大件垃圾破碎机厂家 | 杭州代理记账多少钱-注册公司代办-公司注销流程及费用-杭州福道财务管理咨询有限公司 | 安平县鑫川金属丝网制品有限公司,声屏障,高速声屏障,百叶孔声屏障,大弧形声屏障,凹凸穿孔声屏障,铁路声屏障,顶部弧形声屏障,玻璃钢吸音板 | b2b网站大全,b2b网站排名,找b2b网站就上地球网 | 顺景erp系统_erp软件_erp软件系统_企业erp管理系统-广东顺景软件科技有限公司 | 铝镁锰板厂家_进口钛锌板_铝镁锰波浪板_铝镁锰墙面板_铝镁锰屋面-杭州军晟金属建筑材料 | 河南中整光饰机械有限公司-抛光机,去毛刺抛光机,精密镜面抛光机,全自动抛光机械设备 | 德国GMN轴承,GMN角接触球轴承,GMN单向轴承,GMN油封,GMN非接触式密封 | 非甲烷总烃分析仪|环控百科| 海尔生物医疗四川代理商,海尔低温冰箱四川销售-成都壹科医疗器械有限公司 | 盐城网络公司_盐城网站优化_盐城网站建设_盐城市启晨网络科技有限公司 | 至顶网| 国际船舶网 - 船厂、船舶、造船、船舶设备、航运及海洋工程等相关行业综合信息平台 | 考勤系统_人事考勤管理系统_本地部署BS考勤系统_考勤软件_天时考勤管理专家 | 自清洗过滤器_全自动过滤器_全自动反冲洗过滤器_量子过滤器-滑漮滴 | 爆破器材运输车|烟花爆竹运输车|1-9类危险品厢式运输车|湖北江南专用特种汽车有限公司 | 华东师范大学在职研究生招生网_在职研究生招生联展网 | 河南mpp电力管_mpp电力管生产厂家_mpp电力电缆保护管价格 - 河南晨翀实业 | 深圳展厅设计_企业展馆设计_展厅设计公司_数字展厅设计_深圳百艺堂 | 沈飞防静电地板__机房地板-深圳市沈飞防静电设备有限公司 | 品牌广告服务平台,好排名,好流量,好生意。 | 香港新时代国际美容美发化妆美甲培训学校-26年培训经验,值得信赖! |