摘要:全局作用域局部作用域局部作用域全局作用域局部作用域塊語句沒有塊級作用域塊級聲明包括和,以及和循環,和函數不同,它們不會創建新的作用域。局部作用域只在該函數調用執行期間存在。
一、什么是作用域?
作用域是你的代碼在運行時,各個變量、函數和對象的可訪問性。(可產生作用的區域)二、JavaScript中的作用域
在 JavaScript 中有兩種作用域
全局作用域
局部作用域
當變量定義在一個函數中時,變量就在局部作用域中,而定義在函數之外的變量則從屬于全局作用域。每個函數在調用的時候會創建一個新的作用域。
1.全局作用域當你在文檔中(document)編寫 JavaScript 時,你就已經在全局作用域中了。JavaScript
文檔中(document)只有一個全局作用域。定義在函數之外的變量會被保存在全局作用域中。
// 作用域默認為全局作用域 var name = "andy";
全局作用域里的變量能夠在其他作用域中被訪問和修改。
var name = "andy"; console.log(name); // 輸出 "andy" function logName() { console.log(name); // "name" 變量可以在這里和其他地方訪問 } logName(); // 輸出 "andy"2.局部作用域
定義在函數中的變量就在局部作用域中。并且函數在每次調用時都有一個不同的作用域。這意味著同名變量可以用在不同的函數中。因為這些變量綁定在不同的函數中,擁有不同作用域,彼此之間不能訪問。
// 全局作用域 function someFunction() { // 局部作用域 ##1 function someOtherFunction() { // 局部作用域 ##2 } } // 全局作用域 function anotherFunction() { //局部作用域 ##3 }3.塊語句(JS沒有塊級作用域)
塊級聲明包括if和switch,以及for和while循環,和函數不同,它們不會創建新的作用域。在塊級聲明中定義的變量從屬于該塊所在的作用域。也就是說在for、if、while等語句內部的聲明的變量與在外部聲明是一樣的,在這些語句外部也可以訪問和修改這些變量的值。
if (true) { //這里的if條件不會創建一個新的作用域 var name = "Hammad"; // name 這個變量仍在全局作用域 } console.log(name); // logs "Hammad"
ECMAScript 6 引入了let和const關鍵字。這些關鍵字可以代替var。
var name = "Hammad"; let likes = "Coding"; const skills = "Javascript and PHP";
和var關鍵字不同,let和const關鍵字支持在塊級聲明中創建使用局部作用域。(塊級作用域)
if (true) // 這個 "if" 塊語句沒有創建一個塊級作用域 // name 變量處于全局作用域,因為由var關鍵字聲明 var name = "Hammad"; // likes 變量處于塊級作用域因為由let關鍵字聲明 let likes = "Coding"; // skills 變量處于塊級作用域因為由const關鍵字聲明 const skills = "JavaScript and PHP"; } console.log(name); // 輸出 "Hammad" console.log(likes); // Uncaught ReferenceError: likes is not defined console.log(skills); // Uncaught ReferenceError: skills is not defined
一個應用中全局作用域的生存周期與該應用相同。局部作用域只在該函數調用執行期間存在。
4.詞法作用域所謂的 詞法( 代碼 )作用域, 就是代碼在編寫過程中體現出來的作用范圍. 代碼一旦寫好, 不用執行, 作用范圍就已經確定好了.
這個就是所謂詞法作用域.這意味著函數運行在定義它的作用域中,而不是在調用它的作用域中。
在 js 中詞法作用域規則:
函數允許訪問函數外的數據.
整個代碼結構中只有函數可以限定作用域.
作用規則首先使用提升規則分析
如果當前作用規則中有名字了, 就不考慮外面的名字
詞法作用域var用來將變量定義在詞法作用域中(也就是function中)
function someFunc(){ var a; }
a就被函數someFunc框在了詞法作用域中
塊級作用域let和const用來將變量定義在塊級作用域中(也就是花括號中)
if(true){ let b; }
b就被if的花括號框在了塊級作用域中
5.作用域鏈可以發現只有函數可以制造作用域結構. 那么只要是代碼, 至少有一個作用域, 即全局作用域. 凡是代碼中有函數,那么這個函數就構成另一個作用域. 如果函數中還有函數, 那么再這個作用域中就 又可以誕生一個作用域. 那么將這樣的所有的作用域列出來,可以有一個結構: 函數內指向函數外的鏈式結構.作用域嵌套
作用域是可以嵌套的,任務一中提到的詞法作用域和塊級作用域都可以嵌套其他作用域
(塊級作用域僅對ES6而言)
function someFunc(){ function inner(){ } }
inner就是嵌套在someFunc(詞法作用域)中的詞法作用域
if(true){ while(false){ } }
while就是嵌套在if(塊級作用域)中的塊級作用域
function someFunc(){ if(true){ } }
if就是嵌套在someFunc(詞法作用域)中的塊級作用域
作用域中的變量訪問所有的嵌套作用域都遵循以下規則:
內部作用域有權訪問外部作用域,反之不成立。
栗子:
function someFunc(){
var outerVar = 1; function inner(){ var innerVar = 2; }
}
inner有權訪問innerVar和outerVar,但是someFunc只能訪問到outerVar
作用域是可以任意嵌套的,但是都要遵循上面的規則。
再附加一個規則:
兄弟作用域不可相互訪問
栗子:
function someFunc(){ function inner(){ } function inner2(){ } }
inner和inner2都是someFunc中的作用域,正如someFunc不能訪問inner們的作用域一樣,inner們之間也不能相互訪問。
作用域樹從上向下看這個嵌套作用域,就是棵樹!
看代碼:
function someFunc() { function inner() { } function inner2() { function foo() { } } }
看樹:
someFunc() | / / / ↓ ↓ inner() inner2() | ↓ foo()
要記住的是:inner作用域可以訪問外部作用域,但是反之不成立; foo()可以訪問inner2()中的變量,inner2()可以訪問someFunc()中的變量,這棵樹倒過來似乎更有意義,就成了鏈!!
作用域鏈從最里面看到最外面就構成了作用域鏈
someFunc() ↑ inner2() ↑ | foo()
如果你覺得這篇文章對你有所幫助,那就順便點個贊吧,點點關注不迷路~
黑芝麻哇,白芝麻發,黑芝麻白芝麻哇發哈!
前端哇發哈
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101783.html
摘要:閉包面試題解由于作用域鏈機制的影響,閉包只能取得內部函數的最后一個值,這引起的一個副作用就是如果內部函數在一個循環中,那么變量的值始終為最后一個值。 (關注福利,關注本公眾號回復[資料]領取優質前端視頻,包括Vue、React、Node源碼和實戰、面試指導) 本周正式開始前端進階的第二期,本周的主題是作用域閉包,今天是第8天。 本計劃一共28期,每期重點攻克一個面試重難點,如果你還不了...
摘要:使用上一篇文章的例子來說明下自由變量進階期深入淺出圖解作用域鏈和閉包訪問外部的今天是今天是其中既不是參數,也不是局部變量,所以是自由變量。 (關注福利,關注本公眾號回復[資料]領取優質前端視頻,包括Vue、React、Node源碼和實戰、面試指導) 本周正式開始前端進階的第二期,本周的主題是作用域閉包,今天是第7天。 本計劃一共28期,每期重點攻克一個面試重難點,如果你還不了解本進階計...
摘要:在中,通過棧的存取方式來管理執行上下文,我們可稱其為執行棧,或函數調用棧。因為執行中最先進入全局環境,所以處于棧底的永遠是全局環境的執行上下文。 一、什么是執行上下文? 執行上下文(Execution Context): 函數執行前進行的準備工作(也稱執行上下文環境) JavaScript在執行一個代碼段之前,即解析(預處理)階段,會先進行一些準備工作,例如掃描JS中var定義的變量、...
摘要:由此可知閉包是函數的執行環境以及執行環境中的函數組合而構成的。此時產生了閉包。二閉包的作用閉包的特點是讀取函數內部局部變量,并將局部變量保存在內存,延長其生命周期。三閉包的問題使用閉包會將局部變量保持在內存中,所以會占用大量內存,影響性能。 一、什么是閉包 1.閉包的定義 閉包是一種特殊的對象。它由兩部分構成:函數,以及創建該函數的環境(包含自由變量)。環境由閉包創建時在作用域中的任何...
摘要:本期推薦文章從作用域鏈談閉包,由于微信不能訪問外鏈,點擊閱讀原文就可以啦。推薦理由這是一篇譯文,深入淺出圖解作用域鏈,一步步深入介紹閉包。作用域鏈的頂端是全局對象,在全局環境中定義的變量就會綁定到全局對象中。 (關注福利,關注本公眾號回復[資料]領取優質前端視頻,包括Vue、React、Node源碼和實戰、面試指導) 本周開始前端進階的第二期,本周的主題是作用域閉包,今天是第6天。 本...
閱讀 4928·2023-04-25 18:47
閱讀 2680·2021-11-19 11:33
閱讀 3450·2021-11-11 16:54
閱讀 3105·2021-10-26 09:50
閱讀 2545·2021-10-14 09:43
閱讀 672·2021-09-03 10:47
閱讀 675·2019-08-30 15:54
閱讀 1504·2019-08-30 15:44