ES6 之前 JS 沒(méi)有塊級(jí)作用域。例如
創(chuàng)新互聯(lián)專(zhuān)業(yè)成都做網(wǎng)站、成都網(wǎng)站建設(shè),集網(wǎng)站策劃、網(wǎng)站設(shè)計(jì)、網(wǎng)站制作于一體,網(wǎng)站seo、網(wǎng)站優(yōu)化、網(wǎng)站營(yíng)銷(xiāo)、軟文營(yíng)銷(xiāo)等專(zhuān)業(yè)人才根據(jù)搜索規(guī)律編程設(shè)計(jì),讓網(wǎng)站在運(yùn)行后,在搜索中有好的表現(xiàn),專(zhuān)業(yè)設(shè)計(jì)制作為您帶來(lái)效益的網(wǎng)站!讓網(wǎng)站建設(shè)為您創(chuàng)造效益。
從上面的例子可以體會(huì)到作用域的概念,作用域就是一個(gè)獨(dú)立的 地盤(pán) ,讓變量不會(huì)外泄、暴露出去。上面的name就被暴露出去了,因此, JS 沒(méi)有塊級(jí)作用域,只有全局作用域和函數(shù)作用域 。
全局作用域就是最外層的作用域 ,如果我們寫(xiě)了很多行 JS 代碼,變量定義都沒(méi)有用函數(shù)包括,那么它們就全部都在全局作用域中。這樣的壞處就是很容易撞車(chē)、沖突。
這就是為何 jQuery、Zepto 等庫(kù)的源碼,所有的代碼都會(huì)放在 (function(){....})() 中。因?yàn)榉旁诶锩娴乃凶兞浚?不會(huì)被外泄和暴露 ,不會(huì)污染到外面,不會(huì)對(duì)其他的庫(kù)或者 JS 腳本造成影響。這是函數(shù)作用域的一個(gè)體現(xiàn)。
附:ES6 中開(kāi)始加入了塊級(jí)作用域,使用let定義變量即可,如下:
首先認(rèn)識(shí)一下什么叫做 自由變量 。如下代碼中,console.log(a)要得到a變量,但是在當(dāng)前的作用域中沒(méi)有定義a(可對(duì)比一下b)。當(dāng)前作用域沒(méi)有定義的變量,就稱(chēng)為 自由變量 。自由變量如何得到 —— 向 父級(jí) 作用域?qū)ふ摇?/p>
如果父級(jí)也沒(méi)呢? 再一層一層向上尋找,直到找到全局作用域還是沒(méi)找到,就宣布放棄 。這種一層一層的關(guān)系,就是 作用域鏈 。
通過(guò)例子來(lái)理解閉包。
自由變量將從作用域鏈中去尋找,但是 依據(jù)的是函數(shù)定義時(shí)的作用域鏈,而不是函數(shù)執(zhí)行時(shí) ,以上這個(gè)例子就是閉包。閉包主要有 兩個(gè) 應(yīng)用場(chǎng)景:
1.函數(shù) 作為 返回值 ,上面的例子就是
2.函數(shù) 作為 參數(shù) 傳遞,看以下例子
[img]在ES6以前,js一般只有全局作用域和函數(shù)作用域(ES6新增了塊級(jí)作用域)。全局作用域的鏈表不用多說(shuō),就是包括了所有的全局變量和window的屬性(瀏覽器環(huán)境下)。函數(shù)作用域鏈簡(jiǎn)單的說(shuō)就是在該函數(shù)內(nèi)部,能夠訪問(wèn)到的所有變量的集合鏈表,包括所有的全局變量、函數(shù)內(nèi)部的局部變量,如果有外層函數(shù)的話,還包括外層函數(shù)定義的變量。
JavaScript中所有的量都是存在于某一個(gè)作用域中的
除了全局作用域,?每一個(gè)作用域都是存在於某個(gè)作用域中的
在試圖訪問(wèn)一個(gè)變量時(shí)JS引擎會(huì)從當(dāng)前作用域開(kāi)始向上查找直到Global全局作用域停止
例如
var?A;//全局作用域
function?B()
{
var?C;//C位于B函數(shù)的作用域
function?D()
{
var?E;//E位于D函數(shù)的作用域
alert(A)
}
}
當(dāng)alert(A)時(shí),?JS引擎沿著D的作用域,?B的作用域,?全局作用域的順序進(jìn)行查找.
這三個(gè)作用域組成的有序集合就成為作用域鏈
至于為什么叫鏈,?你可以理解和鏈表有相似之處,?深層的作用域會(huì)能夠訪問(wèn)到上層作用域,?就如同鏈表中兩個(gè)連續(xù)節(jié)點(diǎn)能夠單向訪問(wèn)一樣
最近在學(xué)習(xí)JavaScript的過(guò)程中,先由明了,再到困惑,現(xiàn)在又步入了明了的階段。
那么就說(shuō)說(shuō)原型鏈和作用域鏈的問(wèn)題,剛學(xué)習(xí)的時(shí)候,這兩者是分開(kāi)學(xué)的,并沒(méi)有
在這兩者之間有困擾,但是當(dāng)回過(guò)頭來(lái)綜合學(xué)習(xí)的時(shí)候,卻在這兩者之間產(chǎn)生了困惑,
后來(lái)經(jīng)過(guò)學(xué)習(xí),發(fā)現(xiàn)原來(lái)這兩者完全屬于不同的范圍,只不過(guò)名字相似而已,發(fā)生
困惑的就是他們尋找目標(biāo)的方式幾乎一樣,都是有鏈頂?shù)芥溛驳捻樞颉?/p>
其實(shí)區(qū)分他們的關(guān)鍵就是,作用域鏈的目的是用來(lái)尋找變量的機(jī)制,而原型鏈?zhǔn)沁M(jìn)行
對(duì)象屬性的查找的機(jī)制。之所以發(fā)生困惑,是因?yàn)楹芏嘟坛躺隙加羞@么一句話:其實(shí)
全局變量就是全局對(duì)象的屬性,這句話本身并沒(méi)有錯(cuò),在這個(gè)意義上來(lái)說(shuō)確實(shí)一樣,但
這也容易讓我們發(fā)生迷惑。
總之,javascript中作用域鏈?zhǔn)亲兞康牟檎覚C(jī)制,而原型鏈?zhǔn)菍?duì)象屬性的查找機(jī)制,分清
即可