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

您的位置:首頁技術文章
文章詳情頁

深入淺出JavaScript之閉包(Closure)

瀏覽:9日期:2023-11-16 17:23:59

閉包(closure)是掌握Javascript從人門到深入一個非常重要的門檻,它是Javascript語言的一個難點,也是它的特色,很多高級應用都要依靠閉包實現。下面寫下我的學習筆記~

深入淺出JavaScript之閉包(Closure)

閉包-無處不在

在前端編程中,使用閉包是非常常見的,我們經常有意無意,直接或間接用到了閉包。閉包可以使傳遞數據更加靈活(比如處理一些點擊事件)

!function() {var localData = "localData here"; document.addEventListener('click', //處理點擊事件時用到了外部局部變量,比如這里的localData function(){ console.log(localData); }); }();

又比如下面這個例子:(是不是很親切~~)

!function() {var localData = "localData here";var url = "http://www.baidu.com/";$.ajax({ url : url, success : function() { // do sth... console.log(localData); } }); }();

再來看一個例子~~這種情況就是我們通常所說的閉包

function outer() { var localVal = 30; return function(){ return localVal; } } var func = outer(); func(); // 30

這個例子中調用outer()返回匿名函數function(),這個匿名函數中可以訪問outer()的局部變量localVal,在outer()調用結束后,再次調用func()的時候,仍然能訪問到outer()的局部變量localVal

閉包的概念

閉包,不同于一般的函數,它允許一個函數在立即詞法作用域外調用時,仍可訪問非本地變量。 --維基百科

閉包就是能夠讀取其他函數內部變量的函數。 --阮一峰

由于在Javascript語言中,只有函數內部的子函數才能讀取局部變量,因此可以把閉包簡單理解成"定義在一個函數內部的函數"。

所以,在本質上,閉包就是將函數內部和函數外部連接起來的一座橋梁

閉包的用途

這部分轉自這篇博文

閉包可以用在許多地方。它的最大用處有兩個,一個是前面提到的可以讀取函數內部的變量,另一個就是讓這些變量的值始終保持在內存中。

function f1(){var n=999;nAdd=function(){n+=1}function f2(){alert(n);}return f2;}var result=f1();result(); // 999nAdd();result(); // 1000

在這段代碼中,result實際上就是閉包f2函數。它一共運行了兩次,第一次的值是999,第二次的值是1000。這證明了,函數f1中的局部變量n一直保存在內存中,并沒有在f1調用后被自動清除。

為什么會這樣呢?原因就在于f1是f2的父函數,而f2被賦給了一個全局變量,這導致f2始終在內存中,而f2的存在依賴于f1,因此f1也始終在內存中,不會在調用結束后,被垃圾回收機制(garbage collection)回收。

這段代碼中另一個值得注意的地方,就是"nAdd=function(){n+=1}"這一行,首先在nAdd前面沒有使用var關鍵字,因此nAdd是一個全局變量,而不是局部變量。其次,nAdd的值是一個匿名函數(anonymous function),而這個匿名函數本身也是一個閉包,所以nAdd相當于是一個setter,可以在函數外部對函數內部的局部變量進行操作。

閉包-封裝

(function() { var _userId = 23492; var _typeId = 'item'; var export = {};function converter(userId) { return +userId; } export.getUserId = function() {return converter(_userId);} export.getTypeId = function() {return _typeId; } window.export = export; //通過此方式輸出}()); export.getUserId(); // 23492 export.getTypeId(); // item export._userId; // undefined export._typeId; // undefined export.converter; // undefined

利用閉包的特性能讓我們封裝一些復雜的函數邏輯,在這個例子中調用export上的方法(getUserId,getTypeId)間接訪問函數里私有變量,但是直接調用export._userId是沒法拿到_userId的。這也是Node里面常用到特性吧~

常見錯誤之循環閉包

下面這個案例,我們添加3個div,值分別為aaa,bbb,ccc,我們想實現的是點擊aaa輸出1,點擊bbb輸出2,點擊ccc輸出3

document.body.innerHTML = "<div id=div1>aaa</div>" + "<div id=div2>bbb</div><div id=div3>ccc</div>"; for (var i = 1; i < 4; i++) {document.getElementById('div' + i). addEventListener('click', function() { alert(i); // all are 4! }); }

深入淺出JavaScript之閉包(Closure)

結果點擊aaa,bbb還是ccc都是alert(4)~~

產生這樣的問題在于這個i的值在初始化完成的時候就已經是4了

要達到我們想要的點擊aaa輸出1,點擊bbb輸出2,點擊ccc輸出3,要用到閉包的技巧,在每次循環的時候,用立即執行的匿名函數把它包裝起來,這樣子做的話,每次alert(i)的值就取自閉包環境中的i,這個i來自每次循環的賦值i就能輸出1,2,3了

document.body.innerHTML = "<div id=div1>aaa</div>" + "<div id=div2>bbb</div>" + "<div id=div3>ccc</div>"; for (var i = 1; i < 4; i++) { !function(i){ //②再用這個參數i,到getElementById()中引用 document.getElementById('div' + i). addEventListener('click', function() { alert(i); // 1,2,3 }); }(i); //①把遍歷的1,2,3的值傳到匿名函數里面}

深入淺出JavaScript之閉包(Closure)

思考題

如果你能理解下面兩段代碼的運行結果,應該就算理解閉包的運行機制了。(來自阮老師)這題目總結得真秒~~

代碼片段一。

var name = "The Window";var object = {name : "My Object",getNameFunc : function(){return function(){return this.name;};}};alert(object.getNameFunc()());

代碼片段二。

var name = "The Window";var object = {name : "My Object",getNameFunc : function(){var that = this;return function(){return that.name;};}};alert(object.getNameFunc()());

標簽: JavaScript
相關文章:
主站蜘蛛池模板: 微水泥_硅藻泥_艺术涂料_艺术漆_艺术漆加盟-青岛泥之韵环保壁材 武汉EPS线条_EPS装饰线条_EPS构件_湖北博欧EPS线条厂家 | 信阳网站建设专家-信阳时代网联-【信阳网站建设百度推广优质服务提供商】信阳网站建设|信阳网络公司|信阳网络营销推广 | 火锅加盟_四川成都火锅店加盟_中国火锅连锁品牌十强_朝天门火锅【官网】 | 薄壁轴承-等截面薄壁轴承生产厂家-洛阳薄壁精密轴承有限公司 | Eiafans.com_环评爱好者 环评网|环评论坛|环评报告公示网|竣工环保验收公示网|环保验收报告公示网|环保自主验收公示|环评公示网|环保公示网|注册环评工程师|环境影响评价|环评师|规划环评|环评报告|环评考试网|环评论坛 - Powered by Discuz! | 深圳市宏康仪器科技有限公司-模拟高空低压试验箱-高温防爆试验箱-温控短路试验箱【官网】 | 车牌识别道闸_停车场收费系统_人脸识别考勤机_速通门闸机_充电桩厂家_中全清茂官网 | 磁力轮,磁力联轴器,磁齿轮,钕铁硼磁铁-北京磁运达厂家 | 气弹簧定制-气动杆-可控气弹簧-不锈钢阻尼器-工业气弹簧-可调节气弹簧厂家-常州巨腾气弹簧供应商 | 购买舔盐、舔砖、矿物质盐压块机,鱼饵、鱼饲料压块机--请到杜甫机械 | 华夏医界网_民营医疗产业信息平台_民营医院营销管理培训 | 二手光谱仪维修-德国OBLF光谱仪|进口斯派克光谱仪-热电ARL光谱仪-意大利GNR光谱仪-永晖检测 | 卫生人才网-中国专业的医疗卫生医学人才网招聘网站! | 欧洲MV日韩MV国产_人妻无码一区二区三区免费_少妇被 到高潮喷出白浆av_精品少妇自慰到喷水AV网站 | 刹车盘机床-刹车盘生产线-龙口亨嘉智能装备 | 东莞喷砂机-喷砂机-喷砂机配件-喷砂器材-喷砂加工-东莞市协帆喷砂机械设备有限公司 | 房在线-免费房产管理系统软件-二手房中介房屋房源管理系统软件 | 智能终端_RTU_dcm_北斗星空自动化科技 | 中直网_行业门户-行业人专业的交流平台!| 焊接烟尘净化器__焊烟除尘设备_打磨工作台_喷漆废气治理设备 -催化燃烧设备 _天津路博蓝天环保科技有限公司 | 四探针电阻率测试仪-振实密度仪-粉末流动性测定仪-宁波瑞柯微智能 | 深圳市东信高科自动化设备有限公司 | TwistDx恒温扩增-RAA等温-Jackson抗体-默瑞(上海)生物科技有限公司 | 吸污车_吸粪车_抽粪车_电动三轮吸粪车_真空吸污车_高压清洗吸污车-远大汽车制造有限公司 | 贵阳用友软件,贵州财务软件,贵阳ERP软件_贵州优智信息技术有限公司 | 坏男孩影院-提供最新电影_动漫_综艺_电视剧_迅雷免费电影最新观看 | 硅胶管挤出机厂家_硅胶挤出机生产线_硅胶条挤出机_臣泽智能装备 贵州科比特-防雷公司厂家提供贵州防雷工程,防雷检测,防雷接地,防雷设备价格,防雷产品报价服务-贵州防雷检测公司 | 「钾冰晶石」氟铝酸钾_冰晶石_氟铝酸钠「价格用途」-亚铝氟化物厂家 | 南京精锋制刀有限公司-纵剪机刀片_滚剪机刀片_合金刀片厂家 | 数显水浴恒温振荡器-分液漏斗萃取振荡器-常州市凯航仪器有限公司 | 潍坊青州古城旅游景点攻略_青州酒店美食推荐-青州旅游网 | 山东钢格板|栅格板生产厂家供应商-日照森亿钢格板有限公司 | 防水套管_柔性防水套管_刚性防水套管-巩义市润达管道设备制造有限公司 | 青岛球场围网,青岛车间隔离网,青岛机器人围栏,青岛水源地围网,青岛围网,青岛隔离栅-青岛晟腾金属制品有限公司 | 新能源汽车电池软连接,铜铝复合膜柔性连接,电力母排-容发智能科技(无锡)有限公司 | 山东led显示屏,山东led全彩显示屏,山东LED小间距屏,临沂全彩电子屏-山东亚泰视讯传媒有限公司 | ET3000双钳形接地电阻测试仪_ZSR10A直流_SXJS-IV智能_SX-9000全自动油介质损耗测试仪-上海康登 | 干粉砂浆设备_干混砂浆生产线_腻子粉加工设备_石膏抹灰砂浆生产成套设备厂家_干粉混合设备_砂子烘干机--郑州铭将机械设备有限公司 | 联系我们-腾龙公司上分客服微信19116098882 | 液压油缸生产厂家-山东液压站-济南捷兴液压机电设备有限公司 | 盘式曝气器-微孔曝气器-管式曝气器-曝气盘-斜管填料 | 郑州市前程水处理有限公司 |