JavaScript中作用,作用域鏈和閉包詳解
成都創(chuàng)新互聯(lián)公司專注于鶴壁網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供鶴壁營銷型網(wǎng)站建設(shè),鶴壁網(wǎng)站制作、鶴壁網(wǎng)頁設(shè)計(jì)、鶴壁網(wǎng)站官網(wǎng)定制、成都小程序開發(fā)服務(wù),打造鶴壁網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供鶴壁網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
一、作用域
在js中有全局變量和局部變量之分:
比如
var a = 1;
function sum(){
var b=1
console.log(b) //1
console.log(a) //2
}
sum()
console.log(a) //3
console.log(b) //4
例子中 a 是全局變量,b是局部變量(定義在函數(shù)內(nèi)部,只能在函數(shù)內(nèi)部訪問)所以第1行正確
函數(shù)內(nèi)部也能訪問全局變量 a所以第2行也能正確 第三行也正確。第4行有外部不能訪問
內(nèi)部變量。變量聲明的時(shí)候初始化,局部變量在函數(shù)調(diào)用完時(shí)候銷毀,全局變量在頁面關(guān)閉時(shí)候銷毀
(注意如何b沒有用var修飾,就默認(rèn)是全局變量)
二、js函數(shù)
1、function 函數(shù)名(){
}
2、匿名函數(shù) function(){}
3、立即執(zhí)行函數(shù)又名表達(dá)式函數(shù)
(function(i){
//dosometing
})(i)
4、私有函數(shù)
function a(){
function b(){ ====私有函數(shù)
}
}
5、var 發(fā)=new Function(//dosomething)
6、變量的提升 函數(shù)提升
函數(shù)的生命周期
1、在函數(shù)創(chuàng)建階段,JS解析引擎進(jìn)行預(yù)解析,會(huì)將函數(shù)聲明提前,同時(shí)將該函數(shù)放到全局作用域中(js中函數(shù)是一等公民優(yōu)先考慮)或當(dāng)前函數(shù)的上一級(jí)函數(shù)的局部作用域中。
在函數(shù)
執(zhí)行階段,會(huì)創(chuàng)建該函數(shù)的執(zhí)行上下文并且JS引擎會(huì)將當(dāng)前函數(shù)的局部變量和內(nèi)部函數(shù)進(jìn)行聲明提前,然后再執(zhí)行業(yè)務(wù)代碼,當(dāng)函數(shù)執(zhí)行完退出時(shí),釋放該函數(shù)的執(zhí)行上下文,并注銷該函數(shù)
的局部變量。
2、函數(shù)聲明大于變量聲明()
三、作用域鏈
1、在JS中運(yùn)行中 當(dāng)某個(gè)函數(shù)第一次被調(diào)用時(shí) ,就會(huì)創(chuàng)建一個(gè)執(zhí)行環(huán)境(execution context)以及相應(yīng)的作用域鏈在js中將聲明的變量、參數(shù)、私有函數(shù)封裝在一個(gè)結(jié)構(gòu)體內(nèi) ,對(duì)外界來
說不可見的 并把作用域鏈賦值給一個(gè)特殊的內(nèi)部屬性([scope])。然后使用this.arguments(arguments在全局環(huán)境中不存在)和其他命名參數(shù)的值來初始化函數(shù)的活動(dòng)對(duì)象(activation
object)。當(dāng)前執(zhí)行環(huán)境的變量對(duì)象始終在作用域鏈的第0位
例子
function a(){
var a;
function b(){
return a
}
return b
}
var fun=a()
fun()
在JS運(yùn)行上面機(jī)制 a函數(shù)作用鏈(scope chain ) b作用域鏈(b是內(nèi)部函數(shù))[scope chain] 會(huì)生成執(zhí)行上下文變量 當(dāng)代碼在一個(gè)環(huán)境中執(zhí)行時(shí),會(huì)創(chuàng)建變量對(duì)象的一個(gè)作用域
鏈。作用域鏈的用途是保證對(duì)執(zhí)行環(huán)境(執(zhí)行上下文)有權(quán)訪問的所有變量和函數(shù)的有序訪問。
變量對(duì)象(VO):變量對(duì)象即包含變量的對(duì)象,變量對(duì)象我們無法訪問,除此之外和普通對(duì)象沒什么區(qū)別。變量對(duì)象存儲(chǔ)了在上下文中定義的變量和函數(shù)聲明
活動(dòng)對(duì)象(AO):是在進(jìn)入函數(shù)執(zhí)行
環(huán)境時(shí)刻被創(chuàng)建的,它通過函數(shù)的 arguments 屬性初始化。
變量對(duì)象和活動(dòng)對(duì)象的關(guān)系
未進(jìn)入執(zhí)行階段之前,變量對(duì)象(VO)中的屬性都不能訪問,只是聲明但是進(jìn)入執(zhí)行階段
之后,變量對(duì)象(VO)轉(zhuǎn)變?yōu)榱?/code>
活動(dòng)對(duì)象(AO),里面的屬性都能被訪問了,然后開始進(jìn)行執(zhí)行階段的操作。它們其實(shí)都是同一個(gè)對(duì)象,只是處于執(zhí)行環(huán)境的不同生命周期。AO 實(shí)際上是包含了 VO 的。因?yàn)槌?VO 之外,AO
還包含函數(shù)的 parameters,以及 arguments 這個(gè)特殊對(duì)象。也就是說 AO 的確是在進(jìn)入到執(zhí)行階段的時(shí)候被激活,但是激活的除了 VO 之外,還包括函數(shù)執(zhí)行時(shí)傳入的參數(shù)
和 arguments 這個(gè)特殊對(duì)象。
四、 JavaScript閉包
在js私有函數(shù)對(duì)外部函數(shù)產(chǎn)生引用或者變量依賴就會(huì)產(chǎn)生閉包 通俗的講函數(shù)是可以嵌套函數(shù)的,內(nèi)部function可以訪問外部function的變量;通過引用訪問函數(shù)內(nèi)的函數(shù),實(shí)現(xiàn)內(nèi)存的
保留;訪問函數(shù)內(nèi)的函數(shù),突破變量作用域限制
var a=function(){
var a的變量
function b(){
a++;
}
return b
}
var s=a()
1、信息保留就是引用存在,空間不會(huì)因?yàn)楹瘮?shù)(內(nèi)部函數(shù))銷毀,而消失,
c.add1();