中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript中的變量提升實例分析

發布時間:2022-06-01 11:07:07 來源:億速云 閱讀:117 作者:zzz 欄目:開發技術

這篇文章主要介紹“JavaScript中的變量提升實例分析”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“JavaScript中的變量提升實例分析”文章能幫助大家解決問題。

前言:

JavaScript中奇怪的一點是你可以在變量和函數聲明之前使用它們。就好像是變量聲明和函數聲明被提升了代碼的頂部一樣。

sayHi() // Hi there!

function sayHi() {
    console.log('Hi there!')
}
name = 'John Doe'
console.log(name)   // John Doe
var name

然而JavaScript并不會移動你的代碼,所以JavaScript中“變量提升”并不是真正意義上的“提升”。

JavaScript是單線程語言,所以執行肯定是按順序執行。但是并不是逐行的分析和執行,而是一段一段地分析執行,會先進行編譯階段然后才是執行階段。

在編譯階段階段,代碼真正執行前的幾毫秒,會檢測到所有的變量和函數聲明,所有這些函數和變量聲明都被添加到名為Lexical Environment的JavaScript數據結構內的內存中。所以這些變量和函數能在它們真正被聲明之前使用。

函數提升

sayHi() // Hi there!

function sayHi() {
    console.log('Hi there!')
}

因為函數聲明在編譯階段會被添加到詞法環境(Lexical Environment)中,當JavaScript引擎遇到sayHi()函數時,它會從詞法環境中找到這個函數并執行它。

lexicalEnvironment = {
  sayHi: < func >
}

var變量提升

console.log(name)   // 'undefined'
var name = 'John Doe'
console.log(name)   // John Doe

上面的代碼實際上分為兩個部分:

  • var name表示聲明變量name

  • = 'John Doe'表示的是為變量name賦值為'John Doe'。

var name    // 聲明變量
name = 'John Doe' // 賦值操作

只有聲明操作var name會被提升,而賦值這個操作并不會被提升,但是為什么變量name的值會是undefined呢?

原因是當JavaScript在編譯階段會找到var關鍵字聲明的變量會添加到詞法環境中,并初始化一個值undefined,在之后執行代碼到賦值語句時,會把值賦值到這個變量。

// 編譯階段
lexicalEnvironment = {
  name: undefined
}
// 執行階段
lexicalEnvironment = {
  name: 'John Doe'
}

所以函數表達式也不會被“提升”。helloWorld是一個默認值是undefined的變量,而不是一個function

helloWorld();  // TypeError: helloWorld is not a function
var helloWorld = function(){
  console.log('Hello World!');
}

let & const提升

console.log(a)  // ReferenceError: a is not defined
let a = 3

為什么會報一個ReferenceError錯誤,難道letconst聲明的變量沒有被“提升”嗎?

事實上所有的聲明(function, var, let, const, class)都會被“提升”。但是只有使用var關鍵字聲明的變量才會被初始化undefined值,而letconst聲明的變量則不會被初始化值。

只有在執行階段JavaScript引擎在遇到他們的詞法綁定(賦值)時,他們才會被初始化。這意味著在JavaScript引擎在聲明變量之前,無法訪問該變量。這就是我們所說的Temporal Dead Zone,即變量創建和初始化之間的時間跨度,它們無法訪問。

如果JavaScript引擎在letconst變量被聲明的地方還找不到值的話,就會被賦值為undefined或者返回一個錯誤(const的情況下)。

舉例:

let a
console.log(a)  // undefined
a = 5

在編譯階段,JavaScript引擎遇到變量a并將它存到詞法環境中,但因為使用let關鍵字聲明的,JavaScript引擎并不會為它初始化值,所以在編譯階段,此刻的詞法環境像這樣:

lexicalEnvironment = {
  a: <uninitialized>
}

如果我們要在變量聲明之前使用變量,JavaScript引擎會從詞法環境中獲取變量的值,但是變量此時還是uninitialized狀態,所以會返回一個錯誤ReferenceError

在執行階段,當JavaScript引擎執行到變量被聲明的時候,如果聲明了變量并賦值,會更新詞法環境中的值,如果只是聲明了變量沒有被賦值,那么JavaScript引擎會給變量賦值為undefined

tips: 我們可以在letconst聲明之前使用他們,只要代碼不是在變量聲明之前執行:

function foo() {
    console.log(name)
}
let name = 'John Doe'
foo()   // 'John Doe'

Class提升

letconst一樣,class在JavaScript中也是會被“提升”的,在被真正賦值之前都不會被初始化值, 同樣受Temporal Dead Zone的影響。

let peter = new Person('Peter', 25) // ReferenceError: Person is not defined
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}
let John = new Person('John', 25); 
console.log(John) // Person { name: 'John', age: 25 }

關于“JavaScript中的變量提升實例分析”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

武威市| 绍兴县| 元谋县| 雅江县| 玉溪市| 德化县| 长海县| 恭城| 天等县| 福鼎市| 横山县| 博爱县| 科技| 通化市| 即墨市| 温宿县| 尉氏县| 北川| 石柱| 德庆县| 灵川县| 咸丰县| 沙湾县| 乌拉特后旗| 邵东县| 进贤县| 林西县| 巨鹿县| 韩城市| 深圳市| 舒兰市| 巴彦淖尔市| 正镶白旗| 拉萨市| 威海市| 邯郸市| 吴堡县| 东阿县| 格尔木市| 缙云县| 古丈县|