摘要:這里一共說了三種作用域,其實(shí)可以說是兩種一種是全局作用域,而是局部作用域函數(shù)作用域塊級(jí)作用域,塊級(jí)作用域概念又包括了函數(shù)作用域。
作用域:
變量所在的上下文,指的是變量在哪些地方可以訪問
對(duì)于JavaScript來說有全局作用域但是沒有塊級(jí)作用域,在ES6中引入了關(guān)鍵字let可以生成塊作用域.見以下代碼:
var value = true if (value) { var age = 18 console.log(`我今年${age}歲了`) } console.log (`我也是${age}歲了哦`) //輸出 "我今年18歲了" "我也是18歲了哦" // 可見在if()中不存在塊級(jí)作用域
在這里if()里的變量具有全局作用域,全局皆可使用
var value = true if (value) { let age = 18 console.log(`我今年${age}歲了`) } console.log (`我也是${age}歲了哦`) /*輸出 "我今年18歲了" "error" "ReferenceError: age is not defined*/
在這里使用關(guān)鍵字let 使 if () 塊里的變量age產(chǎn)生了塊級(jí)作用域,使得它只在這個(gè)塊里生效.
JS中有函數(shù)作用域,指的是作用域在函數(shù)內(nèi)部。這里一共說了三種作用域,其實(shí)可以說是兩種:一種是全局作用域,而是局部作用域(函數(shù)作用域、塊級(jí)作用域),塊級(jí)作用域概念又包括了函數(shù)作用域。
全局作用域:在所有函數(shù)外部使用var語句聲明變量或者在聲明變量時(shí)忽略var則會(huì)隱式轉(zhuǎn)化為全局變量
函數(shù)作用域: 需要在函數(shù)內(nèi)部使用var 聲明變量才行
塊級(jí)作用域: 在變量名前添加let語句聲明(ES6)
作用域鏈var a = "你好,我是a"; function scopeChain(a) { var b =1; function inScope(a) { var c = "螞蟻" console.log(`大象愛${c}`) console.log(`我是最內(nèi)層的函數(shù),這里也可以使用a: ${a}`) } console.log(`能使用a嗎?${a}`) inScope(a) } scopeChain(a)
這里a是全局作用域下的變量,b是函數(shù)scopeChain()作用域下的變量,而c是函數(shù)scopeChain()里的inScope()函數(shù)作用域下的變量。
作用域鏈的前端始終是當(dāng)前環(huán)境作用域下變量對(duì)象,逐層往外作用域鏈接,最后端是全局變量環(huán)境下的變量,這些變量時(shí)鏈接在一起,在解析一個(gè)變量時(shí)從鏈前端往后端搜索(從內(nèi)不找外部找),但是有一點(diǎn)值得注意:每個(gè)變量的作用域總是從自身聲明的作用域往外找,而不是調(diào)用它的地方 :
var a = 1 function fn1(){ function fn3(){ var a = 4 fn2() } var a = 2 return fn3 } function fn2(){ console.log(a) } var fn = fn1() fn() //輸出1
這里就是當(dāng)fn1() 執(zhí)行后調(diào)用 fn2() 時(shí),發(fā)現(xiàn)fn3()作用域下沒有,也就是作用域鏈前端沒有,往外找一層也就是fn1()作用域下進(jìn)行查找,作用域也就往后端前進(jìn)了一步,發(fā)現(xiàn)還是沒有,繼續(xù)往外層作用域查找找到了全局作用域,也就是作用域鏈的最后端,找到了后調(diào)用它。
但是對(duì)于fn2()來說它需要調(diào)用a這個(gè)變量,這里也就出現(xiàn)了誤區(qū):在fn3()里有變量a,那么是用的是這個(gè)變量a嗎?
但其實(shí)fn2()是發(fā)現(xiàn)不了這個(gè)變量a的,因?yàn)閒n2()聲明的地方并不在fn3()里,同理fn1()也不是fn2()聲明的地方,所以對(duì)于fn2()來說它只發(fā)現(xiàn)了全局下的 var a =1 所以調(diào)用它并輸出a時(shí)也就等于1.
var a = 1 function fn1(){ function fn2(){ console.log(a) } function fn3(){ var a = 4 fn2() } var a = 2 return fn3 } var fn = fn1() fn() //輸出多少?
由以上的論述可以分析出這段代碼,當(dāng)fn1()被調(diào)用時(shí)也就是 return fn3 ,也就調(diào)用了fn3(),然后fn3()里又是調(diào)用fn2(),而fn() 是在fn1()里聲明的,自然也就使用了fn1()里的變量a,又因?yàn)閍變量在調(diào)用前聲明并賦值了,故此輸出為2
var a = 1 function fn1(){ function fn3(){ function fn2(){ console.log(a) } var a fn2() a = 4 } var a = 2 return fn3 } var fn = fn1() fn() //輸出多少?
分析這段代碼,發(fā)現(xiàn)與上面代碼不同之處在于先聲明了 ` var a 后沒有里脊賦值,在調(diào)用了fn2()后再進(jìn)行的賦值,那么這里應(yīng)該是多少呢?
這里也就牽涉到了聲明前置,對(duì)于fn3()下,當(dāng)聲明 var a時(shí),也就是執(zhí)行到了fn3()代碼前,函數(shù)聲明和變量聲明會(huì)提前至代碼前端,所以這里聲明并沒有影響到輸出值得改變,但是賦值操作是按照程序順序執(zhí)行的,當(dāng)調(diào)用前,a只聲明沒有賦值,則會(huì)輸出undefined。 而具體變量查找是符合作用域鏈的順序來的.
總結(jié)如下:
函數(shù)在執(zhí)行的過程中,先從自己內(nèi)部找變量
如果找不到,再從創(chuàng)建當(dāng)前函數(shù)所在的作用域去找, 以此往上
注意找的是變量的當(dāng)前的狀態(tài)
個(gè)人學(xué)習(xí)備忘,如有謬誤,歡迎指正。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/94373.html
摘要:示例當(dāng)一個(gè)函數(shù)創(chuàng)建后,它的作用域鏈會(huì)被創(chuàng)建此函數(shù)的作用域中可訪問的數(shù)據(jù)對(duì)象填充。每一個(gè)運(yùn)行期上下文都和一個(gè)作用域鏈關(guān)聯(lián)。此時(shí),作用域鏈中函數(shù)的所有局部變量所在的作用域?qū)ο髸?huì)被推后,訪問代價(jià)變高了。 作用域 作用域就是變量與函數(shù)的可訪問范圍,即作用域控制著變量與函數(shù)的可見性和生命周期。在JavaScript中,變量的作用域有全局作用域和局部作用域兩種。 作用域鏈 函數(shù)對(duì)象有一個(gè)內(nèi)部屬性[...
摘要:作用域與作用域鏈每個(gè)函數(shù)都有自己的執(zhí)行環(huán)境。這是初步了解作用域,如想更深入了解作用域,請(qǐng)看下面鏈接作用域原理作用域鏈由一道題圖解的作用域或者看權(quán)威指南和高級(jí)程序設(shè)計(jì) 本文是我學(xué)習(xí)JavaScript作用域整理的筆記,如有不對(duì),請(qǐng)多指出。 作用域 一個(gè)變量的作用域是程序源代碼中定義這個(gè)變量的區(qū)域。 而在ES5中只分為全局作用域和函數(shù)作用域,也就是說for,if,while等語句是不會(huì)創(chuàng)建...
前言 JavaScript中有一個(gè)被稱為作用域(Scope)的特性。雖然對(duì)于許多新手開發(fā)者來說,作用域的概念并不是很容易理解,本文我會(huì)盡我所能用最簡單的方式來解釋作用域和作用域鏈,希望大家有所收獲! 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客 作用域(Scope) 1.什么是作用域 作用域是在運(yùn)行時(shí)代碼中的某些特定部分中變量,函數(shù)和對(duì)象的可訪問性。換句話說,作用域決定了代碼區(qū)塊中變量和其他資源的可見...
前言 JavaScript中有一個(gè)被稱為作用域(Scope)的特性。雖然對(duì)于許多新手開發(fā)者來說,作用域的概念并不是很容易理解,本文我會(huì)盡我所能用最簡單的方式來解釋作用域和作用域鏈,希望大家有所收獲! 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客 作用域(Scope) 1.什么是作用域 作用域是在運(yùn)行時(shí)代碼中的某些特定部分中變量,函數(shù)和對(duì)象的可訪問性。換句話說,作用域決定了代碼區(qū)塊中變量和其他資源的可見...
摘要:注意由于閉包會(huì)額外的附帶函數(shù)的作用域內(nèi)部匿名函數(shù)攜帶外部函數(shù)的作用域,因此,閉包會(huì)比其它函數(shù)多占用些內(nèi)存空間,過度的使用可能會(huì)導(dǎo)致內(nèi)存占用的增加。 作用域和作用域鏈?zhǔn)莏avascript中非常重要的特性,對(duì)于他們的理解直接關(guān)系到對(duì)于整個(gè)javascript體系的理解,而閉包又是對(duì)作用域的延伸,也是在實(shí)際開發(fā)中經(jīng)常使用的一個(gè)特性,實(shí)際上,不僅僅是javascript,在很多語言中都...
閱讀 2005·2023-04-25 16:53
閱讀 1446·2021-10-13 09:39
閱讀 611·2021-09-08 09:35
閱讀 1645·2019-08-30 13:03
閱讀 2126·2019-08-30 11:06
閱讀 1835·2019-08-30 10:59
閱讀 3193·2019-08-29 17:00
閱讀 2293·2019-08-23 17:55