javascript
2017/5 JavaScript基础9 --- 闭包、作用域
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
一、理解閉包
1、閉包的例子
//一般函數(shù) function outer(){var localVal = 30; //局部變量 函數(shù)調(diào)用完成后,局部變量釋放return localVal; } outer(); //30/***********閉包**************/function outer(){var localVal = 30;return function(){ //返回一個(gè)匿名函數(shù)return localVal;} } // 函數(shù)調(diào)用完成后,匿名函數(shù)不能被釋放, var func = outer();//在函數(shù) outer調(diào)用結(jié)束之后,func()函數(shù)調(diào)用時(shí),匿名函數(shù)仍能訪問(wèn)到外函數(shù) outer的局部變量 func(); //302、閉包的作用
1、在瀏覽器里處理事件的點(diǎn)擊,要訪問(wèn)外層局部變量
!function(){var localData = "localData";document.addEventListener('click',function(){ //綁定 事件console.log(localData)}) }(); //調(diào)用/* 有一個(gè)異步請(qǐng)求,用jquery的 ajax方法在 success的回調(diào)函數(shù)里面,用到外層變量,因?yàn)殚]包的原因, 在外層匿名函數(shù)調(diào)用完成后,回調(diào)函數(shù)仍可以訪問(wèn)到外層引用的 localData,或者是url*/!function(){var localData = "localData here";var url = "http://www.baidu.com/";$ajax({url :url,success:function(){//do sthconsole.log(localData);}}) }(); //調(diào)用3、常見錯(cuò)誤之循環(huán)閉包
1)錯(cuò)誤操作
document.body.innerHTML = "<div id='div1'>aaa</div>" + "<div id = 'div2'>bbb</div>" + "<div id = 'div3'>bbb</div>"for(var i = 1; i<4; i++){document.getElementById('div' + i);addEventListener('click', function(){ //增加點(diǎn)擊事件alert(i); //每次點(diǎn)擊彈出的都是4}) }//想要得到點(diǎn)擊第幾個(gè)div就彈出第幾號(hào)數(shù)字,但其實(shí)在初始化完成后 i已經(jīng)是4了。之后每次點(diǎn)擊標(biāo)簽輸出的都是42)正確操作
document.body.innerHTML = "<div id='div1'>aaa</div>" + "<div id = 'div2'>bbb</div>" + "<div id = 'div3'>bbb</div>" ;for(var i = 1; i< 4; i++){!function(i){document.getElementById('div' + i);addEventListener('click',function(){alert(i); // 1,2,3})}(i); //立即執(zhí)行的匿名函數(shù),將遍歷的 i傳入 匿名函數(shù) }//這樣每次點(diǎn)擊時(shí),就會(huì)獲取不同閉包環(huán)境下,在不同循環(huán)賦值得到的i4、閉包 - 封裝
//定義函數(shù)局部變量,外部是無(wú)法訪問(wèn)的 (function(){var _userId = 23492;var _typeId = 'item';var export = {};function converter(userId){return +userId;}export.getUserId = function(){return coverter(_userId);}export.getTypeId = function(){return _typeId;}window.export = export; //把想輸出的對(duì)象輸出出去} ());export.getUserId(); //23492 閉包: 通過(guò)對(duì)象函數(shù)獲取局部變量值 export.getTypeId(); //item export._userId ; //undefined 無(wú)法訪問(wèn)5、閉包的概念
在計(jì)算機(jī)科學(xué)中,閉包(也稱為詞法閉包或函數(shù)閉包)是指一個(gè)函數(shù),或函數(shù)的引用,與一個(gè)引用環(huán)境綁定在一起,這個(gè)引用環(huán)境是一個(gè)存儲(chǔ)該函數(shù)每個(gè)非局部變量(也叫自由變量)的表。
閉包,不同于一般函數(shù),他允許一個(gè)函數(shù)在立即詞法作用域外調(diào)用時(shí),仍可訪問(wèn)非本地變量。
二、作用域
1、作用域分類
2、作用域鏈
function outer2(){var local2 =1;function outer1(){var local1 =1; //局部變量//visit local1 or local2(閉包、自由變量) or global3}outer1(); }var global3 = 1; outer2();function outer(){var i=1;//使用 new Functions構(gòu)造器 構(gòu)造函數(shù),訪問(wèn)不到 ivar func = new Function("console.log(type of i)");func(); //undefined }3、利用函數(shù)作用域封裝
//防止出現(xiàn)大量全局變量 (function(){var a,b; //把函數(shù)內(nèi)部變量變?yōu)榫植孔兞?#xff0c;而不是全局變量 })() ;//使用嘆號(hào),把函數(shù)聲明變?yōu)楹瘮?shù)表達(dá)式 //省略嘆號(hào),會(huì)理解為函數(shù)聲明,會(huì)前置處理,沒有名字會(huì)報(bào)錯(cuò) !function(){ var a,b; }();三、ES3執(zhí)行上下文(執(zhí)行上下文機(jī)制)
函數(shù)聲明,變量聲明會(huì)被前置。
每一次函數(shù)調(diào)用時(shí)都會(huì)有一個(gè)對(duì)應(yīng)的執(zhí)行環(huán)境:執(zhí)行上下文。同樣一個(gè)每次調(diào)用都會(huì)產(chǎn)生不同的上下文
一些抽象概念:
執(zhí)行上下文,變量對(duì)象,在ECMA-262第三版標(biāo)準(zhǔn)規(guī)范中定義
1、執(zhí)行上下文
類似棧結(jié)構(gòu),一層一層嵌套。
當(dāng)調(diào)用funcEC1時(shí)控制權(quán),從全局EC0到EC1的執(zhí)行上下文,Ec3執(zhí)行結(jié)束后退回到EC2,EC2結(jié)束后退回到EC1....EC0
2、變量對(duì)象
JS解釋器如何找到我們定義的函數(shù)和變量
變量對(duì)象(Variable Object,縮寫為 VO) 是一個(gè)抽象概念中的“對(duì)象”,他用于存儲(chǔ)執(zhí)行上下文中的
函數(shù)聲明 test()
?
轉(zhuǎn)載于:https://my.oschina.net/u/2991733/blog/904351
總結(jié)
以上是生活随笔為你收集整理的2017/5 JavaScript基础9 --- 闭包、作用域的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 自然语言交流系统 phxnet团队 创新
- 下一篇: JSP中访问数据库