實(shí)例詳解JavaScript靜態(tài)作用域和動(dòng)態(tài)作用域
前言
在文章最開(kāi)始,先學(xué)習(xí)幾個(gè)概念:
- 作用域:《你不知道的js》中指出,作用域是一套規(guī)則,這套規(guī)則用來(lái)管理引擎如何在當(dāng)前作用域以及嵌套的子作用域中根據(jù)標(biāo)識(shí)符名稱(chēng)進(jìn)行變量查找。簡(jiǎn)單來(lái)說(shuō),作用域規(guī)定了如何查找變量。
- 靜態(tài)作用域:又稱(chēng)詞法作用域,函數(shù)的作用域在函數(shù)定義的時(shí)候就決定了,通俗點(diǎn)說(shuō)就是你在寫(xiě)代碼時(shí)將變量和塊作用域?qū)懺谀睦餂Q定的。
- 動(dòng)態(tài)作用域:函數(shù)的作用域在函數(shù)調(diào)用時(shí)才決定的。
靜態(tài)作用域與動(dòng)態(tài)作用域
JavaScript采用的是靜態(tài)作用域,函數(shù)定義的位置就決定了函數(shù)的作用域。
具體看一個(gè)例子,理解一下什么是靜態(tài)作用域與動(dòng)態(tài)作用域的區(qū)別
var val = 1; function test() { console.log(val); } function bar() { var val = 2; test(); } bar(); // 結(jié)果是???
上面代碼中:
- 我們首先定義全局變量 val,賦值為 1
- 聲明一個(gè)函數(shù) text,函數(shù)的功能是打印 val 這個(gè)變量的值
- 聲明一個(gè)函數(shù) bar,函數(shù)內(nèi)部定義局部變量 val,賦值為 2;并且函數(shù)內(nèi)部執(zhí)行 test() 函數(shù)
- 執(zhí)行 bar() 函數(shù)
靜態(tài)作用域執(zhí)行過(guò)程
當(dāng)執(zhí)行 test 函數(shù)時(shí),先從 test 函數(shù)內(nèi)部查找是否有變量 val,如果沒(méi)有,就沿定義函數(shù)的位置,查找上一層的代碼,查找到全局變量 val ,其值為 1。
作用域查找始終從運(yùn)行時(shí)所處的最內(nèi)層作用域開(kāi)始查找,逐級(jí)向外查找,直到遇見(jiàn)第一個(gè)匹配的標(biāo)識(shí)符為止。
無(wú)論函數(shù)在哪里被調(diào)用,無(wú)論如何被調(diào)用,它的作用域只由函數(shù)定義所處的位置決定。
動(dòng)態(tài)作用域執(zhí)行過(guò)程
執(zhí)行 test 函數(shù),首先從函數(shù)內(nèi)部查詢(xún) val 變量,如果沒(méi)有,就從調(diào)用函數(shù)的作用域,即 bar 函數(shù)的作用域內(nèi)部查找變量 val,所以打印結(jié)果 2
習(xí)題
我們來(lái)看三個(gè)習(xí)題,好好消化理解一下靜態(tài)作用域: 函數(shù)定義位置就決定了作用域。
習(xí)題一
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()
上面代碼中:
- 我們首先定義全局變量 a,賦值為 1
- 聲明一個(gè)函數(shù) fn1,函數(shù)的內(nèi)部分別聲明了函數(shù) fn3,定義局部變量 a,賦值為 2,返回值為 fn3 函數(shù)
- fn3 函數(shù)內(nèi)部定義局部變量 a,賦值為 4,執(zhí)行 fn2()
- 聲明函數(shù) fn2, 函數(shù)的功能是,打印 a 的值
- fn 賦值為 fn1() 的返回值
- 執(zhí)行 fn() (相當(dāng)于執(zhí)行 fn3 函數(shù))
做題之前,一定要理解 靜態(tài)作用域 的概念。該題 fn2 定義在全局上,當(dāng) fn2 中找不到變量 a 時(shí),它會(huì)去全局中尋找,與 fn1 和 fn3 毫無(wú)關(guān)系,打印 1.
習(xí)題二
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()
fn2 是定義在函數(shù) fn1 內(nèi)部,因此當(dāng) fn2 內(nèi)部沒(méi)有變量 a 時(shí),它會(huì)去 fn1 中尋找,跟函數(shù) fn3 毫無(wú)關(guān)系,如果 fn1 中尋找不到,會(huì)到 fn1 定義的位置的上一層(全局)尋找,直至尋找到第一個(gè)匹配的標(biāo)識(shí)符。本題可以在 fn1 中找到變量 a,打印 2
習(xí)題三
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()
該題 fn2 定義在函數(shù) fn3 中,當(dāng) fn2 中找不到變量 a 時(shí),會(huì)首先去 fn3 中查找,如果還查找不到,會(huì)到 fn1 中查找。本題可以在 fn3 中找到變量 a,但由于 fn2() 執(zhí)行時(shí),a 未賦值,打印 undefined。
總結(jié)
關(guān)于JavaScript 的靜態(tài)作用域,我們只需要記住一句話(huà):函數(shù)定義的位置就決定了函數(shù)的作用域,遇到題目時(shí)不要被別的代碼干擾到。
到此這篇關(guān)于JavaScript靜態(tài)作用域和動(dòng)態(tài)作用域的文章就介紹到這了,更多相關(guān)JS靜態(tài)作用域和動(dòng)態(tài)作用域內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用濾鏡設(shè)置透明導(dǎo)致 IE 6/7/8/9 解析異常的解決方法
使用濾鏡設(shè)置透明導(dǎo)致 IE 6/7/8/9 解析異常的解決方法,需要的朋友可以參考下。2011-04-04uni-app和web-view頁(yè)面相互傳參方法實(shí)例
web-view是一個(gè)web瀏覽器組件,可以用來(lái)承載網(wǎng)頁(yè)的容器,會(huì)自動(dòng)鋪滿(mǎn)整個(gè)頁(yè)面,下面這篇文章主要給大家介紹了關(guān)于uni-app和web-view頁(yè)面相互傳參的相關(guān)資料,需要的朋友可以參考下2023-06-06JavaScript 用cloneNode方法克隆節(jié)點(diǎn)的代碼
很多時(shí)候我們需要通過(guò)HTML DOM 的方式,用JavaScript 動(dòng)態(tài)生成很多相同的節(jié)點(diǎn),包括其子節(jié)點(diǎn)2012-10-10js實(shí)現(xiàn)json數(shù)據(jù)行到列的轉(zhuǎn)換的實(shí)例代碼
為了實(shí)現(xiàn)這樣的數(shù)據(jù)顯示出來(lái)三個(gè)序列,分別為鄭州、新鄉(xiāng)、安陽(yáng)的電量,就需要自己實(shí)現(xiàn)對(duì)這樣數(shù)據(jù)的轉(zhuǎn)換,轉(zhuǎn)換成如下的形式:2013-08-08js實(shí)現(xiàn)前面自動(dòng)補(bǔ)全位數(shù)的方法
今天小編就為大家分享一篇js實(shí)現(xiàn)前面自動(dòng)補(bǔ)全位數(shù)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-10-10js的繼承方法小結(jié)(prototype、call、apply)(推薦)
這篇文章主要介紹了js的繼承方法小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04微信jssdk在iframe頁(yè)面失效問(wèn)題的解決措施
這篇文章主要介紹了微信jssdk在iframe頁(yè)面失效問(wèn)題的解決措施 的相關(guān)資料,需要的朋友可以參考下2016-03-03用js實(shí)現(xiàn)預(yù)覽待上傳的本地圖片
用js實(shí)現(xiàn)預(yù)覽待上傳的本地圖片...2007-03-03JS apply用法總結(jié)和使用場(chǎng)景實(shí)例分析
這篇文章主要介紹了JS apply用法總結(jié)和使用場(chǎng)景,結(jié)合實(shí)例形式分析了JS apply的基本功能、原理、使用方法及操作注意事項(xiàng),需要的朋友可以參考下2020-03-03