掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢(xún)/運(yùn)營(yíng)咨詢(xún)/技術(shù)建議/互聯(lián)網(wǎng)交流
作用域是指在程序中定義變量的區(qū)域,該位置決定了變量的生命周期。簡(jiǎn)言之作用域就是變量與函數(shù)的可訪(fǎng)問(wèn)范圍,即作用域控制著變量和函數(shù)的可見(jiàn)性和生命周期。

讓客戶(hù)滿(mǎn)意是我們工作的目標(biāo),不斷超越客戶(hù)的期望值來(lái)自于我們對(duì)這個(gè)行業(yè)的熱愛(ài)。我們立志把好的技術(shù)通過(guò)有效、簡(jiǎn)單的方式提供給客戶(hù),將通過(guò)不懈努力成為客戶(hù)在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名注冊(cè)、網(wǎng)站空間、營(yíng)銷(xiāo)軟件、網(wǎng)站建設(shè)、獨(dú)山網(wǎng)站維護(hù)、網(wǎng)站推廣。
在ES6階段之前,作用域分為兩種:全局作用域和函數(shù)作用域;進(jìn)行ES6之后,作用域分為:全局作用域、函數(shù)作用域和塊級(jí)作用域。
全局作用域
在該作用域中的對(duì)象在代碼的任何地方都能訪(fǎng)問(wèn),其生命周期伴隨著頁(yè)面的生命周期。例如以下內(nèi)容均在全局作用域中。
(1)window上的屬性(在瀏覽器中)
- console.log(window.location.href); // 頁(yè)面地址
(2)最外層的函數(shù)
- function testFun() {
- console.log('testFun');
- }
- testFun();
(3)最外層定義的變量
- let val1 = 10;
- const val2 = 20;
- var val3 = 30;
(4)未定義直接賦值的變量
- val4 = 40;
(5)js規(guī)定的全局對(duì)象的屬性,三個(gè)值(Infinity、NaN、undefined)、九個(gè)函數(shù)(parseInt、parseFloat、decodeURI、encodeURI……)、一些構(gòu)造器(Date、Array等)、四個(gè)用于當(dāng)做命名空間的對(duì)象(Atomics、JSON、Math、Reflect)。
- Math.sin(Math.PI / 2);;
- const date = new Date();
函數(shù)作用域
在函數(shù)內(nèi)部定義的變量或者函數(shù),并且定義的變量或者函數(shù)只能在函數(shù)內(nèi)部被訪(fǎng)問(wèn)。在函數(shù)執(zhí)行結(jié)束之后,函數(shù)內(nèi)部定義的變量會(huì)被銷(xiāo)毀。
- function test() {
- var val1 = 10;
- function fun1() {
- console.log('fun1');
- }
- console.log(val1); // 10
- fun1(); // fun1
- }
- test();
- // console.log(val1); // val1 is not defined
- // fun1(); // fun1 is not defined
塊級(jí)作用域
在ES6階段,出現(xiàn)了塊的概念,新增了塊級(jí)作用域,同時(shí)新增了let、const命令。塊級(jí)作用域簡(jiǎn)言之就是使用一對(duì)大括號(hào){}包裹的一段代碼,通過(guò)單獨(dú)的大括號(hào)、if塊、while塊、for塊、try/catch/finallyd等都會(huì)產(chǎn)生塊級(jí)作用域。(對(duì)于let和const在塊級(jí)作用域的特征可見(jiàn)前端百題斬【002】)
- // 單一括號(hào)包括的塊
- {}
- // if語(yǔ)句
- if (flag) {
- }
- // for語(yǔ)句
- for (let i = 0; i < 10; i++) {
- }
- // ……
在每個(gè)執(zhí)行上下文的變量環(huán)境中,都包含一個(gè)外部引用(成為outer),用來(lái)指向外部的指向上下文。當(dāng)在查找一個(gè)變量的時(shí)候,如果在當(dāng)前的變量環(huán)境中沒(méi)有找到,js引擎會(huì)繼續(xù)在outer所指向的執(zhí)行上下文中查找,把這個(gè)查找的鏈條稱(chēng)為作用域鏈。(作用域鏈可以理解為一組對(duì)象列表,包含 父級(jí)和自身的變量對(duì)象,因此我們便能通過(guò)作用域鏈訪(fǎng)問(wèn)到父級(jí)里聲明的變量或者函數(shù)。)
作用域鏈由兩部分組成,分別是[[scope]]屬性和AO。
[[scope]]屬性:指向父級(jí)變量對(duì)象和作用域鏈,也就是包含了父級(jí)的[[scope]]和AO
AO:自身活動(dòng)對(duì)象,也就是該執(zhí)行上下文中的變量對(duì)象。
擴(kuò)展:如此 [[scope]]包含[[scope]],便自上而下形成一條 鏈?zhǔn)阶饔糜颉?/p>
下面用一個(gè)簡(jiǎn)單的例子來(lái)演示該作用域鏈,以進(jìn)一步理解作用域鏈。
- var val1 = 10;
- function fun1() {
- var val2 = 20;
- function fun2() {
- var val3 = 30;
- console.log(val1 + val2 + val3);
- }
- fun2();
- }
- fun1();
結(jié)合代碼和上述執(zhí)行上下文的流程圖,當(dāng)執(zhí)行到console.log(val1 + val2 + val3);時(shí)會(huì)在fun2函數(shù)作用域中找到val3變量,在fun1函數(shù)作用域中找到變量val2,在全局作用域中找到變量val1,最終與該語(yǔ)句相關(guān)的三個(gè)變量均獲取到。其中fun2函數(shù)作用域、fun1函數(shù)作用域、全局作用域就構(gòu)成了一條作用域鏈。
本文轉(zhuǎn)載自微信公眾號(hào)「執(zhí)鳶者」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系執(zhí)鳶者公眾號(hào)。

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢(xún)/運(yùn)營(yíng)咨詢(xún)/技術(shù)建議/互聯(lián)網(wǎng)交流