摘要:作用域是門動(dòng)態(tài)語言,跟不一樣,可以隨意定義全局變量和局部變量,變量會(huì)在該作用域下提升,而且沒有塊級(jí)作用域。一預(yù)處理作用域解析的作用域只用兩種,一個(gè)是全局的,一個(gè)是函數(shù)的,也稱為全局作用域和局部作用域局部作用域可以訪問全局作用域。
作用域
JavaScript是門動(dòng)態(tài)語言,跟Java不一樣,JavaScript可以隨意定義全局變量和局部變量,變量會(huì)在該作用域下提升,而且JavaScript沒有塊級(jí)作用域。一、預(yù)處理 + 作用域解析
全局變量就是定義在全局的變量了,局部變量是定義在函數(shù)里的變量,每一個(gè)函數(shù)都是一個(gè)作用域,當(dāng)函數(shù)執(zhí)行時(shí)會(huì)優(yōu)先查找當(dāng)前作用域,然后逐級(jí)向上。定義在
if 和 for 語句里的變量,在大括號(hào)外面也能訪問到,這就是沒有塊級(jí)作用域。
JavaScript 的作用域只用兩種,一個(gè)是全局的,一個(gè)是函數(shù)的,也稱為 全局作用域 和 局部作用域 ;局部作用域 可以訪問 全局作用域 。但是 全局作用域 不能訪問 局部作用域
有這樣一段代碼
var a = 1; function fn1(){ alert(a); var a = 2; } fn1(); alert(a);
這里先揭曉答案:
第一個(gè) alert(a) 彈出 undefined 第二個(gè) alert(a) 彈出 1
1. 預(yù)解析(預(yù)編譯) 全局作用域 (全局詞法環(huán)境)
// 全局詞法環(huán)境 // 第1行,遇到 var 關(guān)鍵字,解析到全局的頭部 a = undefined // 第2行,遇到 function 關(guān)鍵字,解析到全局的頭部 fn1 = function fn1(){ alert(a); var a = 2; } // 第3行,沒有遇到關(guān)鍵字,不解析 // 第4行,沒有遇到關(guān)鍵字,不解析
2. 開始執(zhí)行代碼
第1行,遇到表達(dá)式 a = 1, a 被賦值成 1 第6行,遇到函數(shù)調(diào)用 fn1() , ---- 開始 預(yù)解析(預(yù)編譯) 局部-----
3. 預(yù)解析(預(yù)編譯) 局部作用域 (函數(shù)詞法環(huán)境)
// 第3行,沒有遇到關(guān)鍵字,不解析 // 第4行,遇到 var 關(guān)鍵字,解析到局部 a = undefined
4. 開始執(zhí)行 局部 代碼
第3行,彈出 undefined 第4行,遇到表達(dá)式,把局部 a 改成 2
5. 局部執(zhí)行完成,繼續(xù)執(zhí)行全局
第7行,彈出 1 ,因?yàn)槿趾途植渴莾蓚€(gè)獨(dú)立的作用域二、作用域疑惑之處
1. js沒有塊作用域
2. js不是動(dòng)態(tài)作用域,js是靜態(tài)作用域
function f(){ alert(x); } function f1() { var x = 6; f(); } function f2() { var x = 10; f(); } f1(); // 執(zhí)行會(huì)報(bào)錯(cuò),因此js不是動(dòng)態(tài)作用域哦二、作用域鏈
var a = 10; function f() { var x = 100; function g () { // } g(); } f();
作用域鏈解析
1. 創(chuàng)建詞法環(huán)境(window) 2. 加入 a 以及 f函數(shù) ,這時(shí)候 【f.scope === window】 3. 進(jìn)入f函數(shù),創(chuàng)建f函數(shù)的詞法環(huán)境 【f.le => f.scope】 4. 創(chuàng)建f 的詞法環(huán)境 5. 添加x和 g函數(shù) 到f函數(shù)的詞法環(huán)境 【g.scope === f.le】 6. 進(jìn)入g函數(shù),創(chuàng)建g函數(shù)的詞法環(huán)境 【g.le => g.scope】
g.le -> g->scope -> f.le -> f.scope -> window三、作用域的本質(zhì)
var a = 10; function f() { var x = 100; function g () { // alert(a); } g(); } f();
我們?cè)趃內(nèi)部使用了變量a,想要找到a,
首先在g的詞法環(huán)境中查找,如果沒找到
到g.scope 也就是 f的詞法環(huán)境中查找,如果依舊沒找到
到f.scope 也就是 全局詞法環(huán)境中查找。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/96754.html
摘要:使用上一篇文章的例子來說明下自由變量進(jìn)階期深入淺出圖解作用域鏈和閉包訪問外部的今天是今天是其中既不是參數(shù),也不是局部變量,所以是自由變量。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開始前端進(jìn)階的第二期,本周的主題是作用域閉包,今天是第7天。 本計(jì)劃一共28期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了解本進(jìn)階計(jì)...
摘要:閉包面試題解由于作用域鏈機(jī)制的影響,閉包只能取得內(nèi)部函數(shù)的最后一個(gè)值,這引起的一個(gè)副作用就是如果內(nèi)部函數(shù)在一個(gè)循環(huán)中,那么變量的值始終為最后一個(gè)值。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開始前端進(jìn)階的第二期,本周的主題是作用域閉包,今天是第8天。 本計(jì)劃一共28期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了...
摘要:開篇作用域是每種計(jì)算機(jī)語言最重要的基礎(chǔ)之一,因此要想深入的學(xué)習(xí)作用域和作用域鏈就是個(gè)繞不開的話題。這樣由多個(gè)執(zhí)行上下文的變量對(duì)象構(gòu)成的鏈表就叫做作用域鏈。這時(shí)候執(zhí)行上下文的作用域鏈,我們命名為至此,作用域鏈創(chuàng)建完畢。 開篇 作用域是每種計(jì)算機(jī)語言最重要的基礎(chǔ)之一,因此要想深入的學(xué)習(xí)JavaScript,作用域和作用域鏈就是個(gè)繞不開的話題。 在《深入學(xué)習(xí)js之—-執(zhí)行上下文?!分形覀兲岬?..
摘要:下面,讓我們以一個(gè)函數(shù)的創(chuàng)建和激活兩個(gè)時(shí)期來講解作用域鏈?zhǔn)侨绾蝿?chuàng)建和變化的。這時(shí)候執(zhí)行上下文的作用域鏈,我們命名為至此,作用域鏈創(chuàng)建完畢。 JavaScript深入系列第五篇,講述作用鏈的創(chuàng)建過程,最后結(jié)合著變量對(duì)象,執(zhí)行上下文棧,讓我們一起捋一捋函數(shù)創(chuàng)建和執(zhí)行的過程中到底發(fā)生了什么? 前言 在《JavaScript深入之執(zhí)行上下文棧》中講到,當(dāng)JavaScript代碼執(zhí)行一段可執(zhí)行代...
摘要:在中的應(yīng)用采用詞法作用域,也就是靜態(tài)作用域。那什么又是詞法作用域或者靜態(tài)作用域呢請(qǐng)繼續(xù)往下看靜態(tài)作用域與動(dòng)態(tài)作用域因?yàn)椴捎玫氖窃~法作用域函數(shù)的作用域在函數(shù)定義的時(shí)候就決定了。 開篇 當(dāng)我們?cè)陂_始學(xué)習(xí)任何一門語言的時(shí)候,都會(huì)接觸到變量的概念,變量的出現(xiàn)其實(shí)是為了解決一個(gè)問題,為的是存儲(chǔ)某些值,進(jìn)而,存儲(chǔ)某些值的目的是為了在之后對(duì)這個(gè)值進(jìn)行訪問或者修改,正是這種存儲(chǔ)和訪問變量的能力將狀態(tài)給...
閱讀 3591·2021-11-24 10:19
閱讀 3730·2021-09-30 09:47
閱讀 1293·2019-08-30 15:56
閱讀 790·2019-08-29 15:11
閱讀 905·2019-08-29 13:43
閱讀 3570·2019-08-28 18:25
閱讀 2160·2019-08-26 13:27
閱讀 1439·2019-08-26 11:44