關(guān)于JS管理作用域的問題
理解JavaScript如何管理作用域和作用域鏈很重要。因?yàn)樵谧饔糜蜴溨幸檎业淖兞繉ο蟮膫€數(shù)直接影響標(biāo)識符解析的性能。標(biāo)識符在作用域鏈中的位置越深,查找和訪問它所需的時(shí)間越長;如果作用域管理不當(dāng),就會給腳本的執(zhí)行時(shí)間帶來負(fù)面影響。
當(dāng)執(zhí)行JavaScript代碼時(shí),JavaScript引擎會創(chuàng)建一個執(zhí)行上下文(Execution Context)。執(zhí)行上下文(有時(shí)被稱為作用域)設(shè)定了代碼執(zhí)行時(shí)所處的環(huán)境。JavaScript引擎會在頁面加載后創(chuàng)建一個全局的執(zhí)行上下文,然后每執(zhí)行一個函數(shù)時(shí)都會創(chuàng)建一個對應(yīng)的執(zhí)行上下文,最終建立一個執(zhí)行上下文的堆棧,當(dāng)前起作用的執(zhí)行上下文在堆棧的最頂端。
每個執(zhí)行上下文都有一個與之關(guān)聯(lián)的作用域鏈,用于解析標(biāo)識符。作用域鏈包含一個或多個變量對象,這些對象定義了執(zhí)行上下文作用域內(nèi)的標(biāo)識符。全局執(zhí)行上下文的作用域鏈中只有一個變量對象,它定義了JavaScript中所有可用的全局變量和函數(shù)。當(dāng)函數(shù)被創(chuàng)建(不是執(zhí)行)時(shí),JavaScript引擎會把創(chuàng)建時(shí)執(zhí)行上下文的作用域鏈賦給函數(shù)的內(nèi)部屬性[[Scope]]。然后,當(dāng)函數(shù)被執(zhí)行時(shí),JavaScript引擎會創(chuàng)建一個活動對象(Activetion Object),并在初始化時(shí)給this、arguments、命名參數(shù)和該函數(shù)的所有局部變量賦值?;顒訉ο髸霈F(xiàn)在執(zhí)行上下文作用域鏈的頂端,緊接其后的是函數(shù)[[scope]]屬性中的對象。
在執(zhí)行代碼時(shí),JavaScript引擎通過搜索執(zhí)行上下文的作用域鏈來解析諸如變量和函數(shù)名這樣的標(biāo)識符。解析標(biāo)識符的過程從作用域的頂端開始,按照自上而下的順序進(jìn)行。
驗(yàn)證理論function add(num1, num2) {
return num1 + num2;
}
當(dāng)這段代碼執(zhí)行開始時(shí),add函數(shù)擁有一個僅包含全局變量對象的[[scope]]屬性。如下圖:
在執(zhí)行add函數(shù)時(shí),JavaScript引擎會創(chuàng)建一個新的執(zhí)行上下文和一個包含this、arguments、num1、num2的活動對象,并把活動對象添加到作用域鏈中。在add()函數(shù)內(nèi)部運(yùn)行時(shí),JavaScript引擎需要解析函數(shù)里的num1和num2標(biāo)識符。var total = add(5, 10);
解析過程是從作用域鏈中的第一個對象開始,這個對象就是包含該函數(shù)局部變量的活動對象。如果在該對象中沒有找到標(biāo)識符,就會繼續(xù)在作用域鏈中下一個對象里查找標(biāo)識符。一旦找到標(biāo)識符,查找就結(jié)束。
高效的數(shù)據(jù)存取局部變量是JavaScript中讀寫最快的標(biāo)識符。
一個好的經(jīng)驗(yàn):任何非局部變量在函數(shù)中的使用超過一次時(shí),都應(yīng)該將其存儲為局部變量。
對于數(shù)組和對象,始終將那些需要頻繁存取的值存儲到局部變量中。
實(shí)際上每次存取HTMLCollection對象屬性,都會對DOM文檔進(jìn)行動態(tài)查詢。
如果需要對HTMLCollection對象的成員反復(fù)存取,高效的方式是將它們復(fù)制到數(shù)組里。
- 詳解JavaScript的AngularJS框架中的作用域與數(shù)據(jù)綁定
- JavaScript的作用域和塊級作用域概念理解
- 深入理解Javascript中this的作用域
- 深入理解JavaScript高級之詞法作用域和作用域鏈
- javascript 函數(shù)及作用域總結(jié)介紹
- javascript中的變量作用域以及變量提升詳細(xì)介紹
- 淺析js封裝和作用域
- 深入Javascript函數(shù)、遞歸與閉包(執(zhí)行環(huán)境、變量對象與作用域鏈)使用詳解
- js作用域及作用域鏈概念理解及使用
- js變量以及其作用域詳解
- js使用函數(shù)綁定技術(shù)改變事件處理程序的作用域
- JavaScript作用域示例詳解
相關(guān)文章
JavaScript中的prototype原型學(xué)習(xí)指南
這篇文章主要介紹了JavaScript中的prototype原型學(xué)習(xí)指南,包括原型鏈與原型繼承等重要知識,需要的朋友可以參考下2016-05-05<script defer> defer 是什么意思
好多朋友不知道 script后面加個defer是什么意思有什么作用。2009-05-05為JS擴(kuò)展Array.prototype.indexOf引發(fā)的問題及解決辦法
這篇文章主要介紹了為JS擴(kuò)展Array.prototype.indexOf引發(fā)的問題及解決辦法,需要的朋友可以參考下2015-01-01VB倒計(jì)時(shí)器和JS當(dāng)前時(shí)間
VB倒計(jì)時(shí)器和JS當(dāng)前時(shí)間...2006-11-11