
JavaScript 中的作用域、預決議以及變數提升
作用域:變數的作用范圍
-
區域作用域:函式內部
在區域作用域宣告的變數稱為區域變數,區域變數只能在當前函式內部使用
1)函式在執行的時候會在記憶體中開辟新空間
2)當執行完畢函式之后,會關閉作用域空間(變數被銷毀)
注意:形參也是區域變數
function fn() { let b = 5 // 區域訪問 變數 b console.log(b) // 5 } fn() // 全域訪問 變數 b console.log(b) // 訪問不存在的變數,報錯在控制臺列印得到如下結果

-
全域作用域:函式外部
1)在全域作用域宣告的變數是全域變數,全域變數可以在任何地方使用
2)因為全域變數可以任何地方使用,所以要特別關注區域變數
let a = 2 function fn() { // 區域訪問 變數 a console.log(a) // 2 } fn() // 全域訪問 變數 a console.log(a) // 2在控制臺列印得到如下結果

函式內部之所以能夠訪問到變數 a ,是因為有一個作用鏈,函式內部訪問一個變數會先在自己的作用域內找,找不到會向上級作用域找,找不到就會報錯
例如 如下代碼
(找不到報錯的情況)
function fn() { function fn1() { function fn2() { // 區域訪問 變數 a console.log(a) // 2 } fn2() } fn1() } fn()控制臺列印

(全域變數區域訪問的情況)
let a = 'hello javascript'
function fn() {
function fn1() {
function fn2() {
// 區域訪問 變數 a
console.log(a) // hello javascript
}
fn2()
}
fn1()
}
fn()
控制臺列印

-
塊級作用域:類似區域作用域
1)用 {} 包裹一塊
2)let宣告變數具有塊級作用域,var宣告變數不具有塊級作用域
例如
(以字面量物件為例)
let obj = { uname: '法外狂徒-張三', age: 68 }想要訪問這個物件里面的屬性必須通過
obj.屬性,而不能直接訪問
預決議
預決議:在代碼執行之前把變數和函式會提前決議到當前作用域的最前面
任何作用域在執行之前都要預決議 (函式優于變數)
變數:帶有宣告的變數,只定義不賦值
1)變數在宣告之前被訪問,變數的值為 undefined
函式:帶有名字的函式,只定義不呼叫
1)函式優于變數
console.log(a) // undefined
fn() // hello javascript
function fn() {
console.log('hello javascript')
}
var a = 2
代碼是自上而下執行,但是在代碼執行前會先進行代碼的預決議,把變數以及函式 宣告 提升到當前作用域的最前面,如上代碼,console.log(a) 會列印 undefined
但是,注意!!!注意!!!
變數必須是 var 宣告的才可以,如果是 let 宣告的變數會報錯
圖 (var 宣告的 a)

圖 (let 宣告的 a)

變數提升
預決議會引起變數的提升
變數不宣告就輸出會報錯
console.log(a) // 報錯
控制臺列印

用 var 宣告
console.log(a) // undefined
var a = 'hello javascript'
控制臺列印 undefined ,我們知道變數定義不賦值會輸出 undefined,說明變數已經存在并且提升了,但是只提升了宣告沒有提升賦值,所以列印 undefined ,如果沒有提升的話,就會像上面一樣在執行 console.log(a) 的時候直接報錯
結論:var 存在變數提升
用 let 宣告
console.log(a) // 報錯
let a = 'hello javascript'
結論:let 不存在變數提升
補充:
申明變數:let \ var \ const
1)let 宣告的變數不在window內
2)var 宣告的變數相當于給window添加了個屬性,let不會
3)var 宣告的變數不具有塊級作用域,let具有塊級作用域
4)var 可以重復宣告,let只能宣告一次
5)const 用來定義常量,不可以改值
6)const 定義的常量必須初始化有值,let可以不設定值
建議:常量名字因為是不可以改動的值,所以常量名建議用大寫,一般用于定義固定不變的值
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/294737.html
標籤:其他
