欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺析JavaScript中的變量提升

 更新時間:2022年06月01日 11:54:22   作者:??哎嘿咬我呀????  
這篇文章主要介紹了淺析JavaScript中的變量提升,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下

前言:

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

sayHi() // Hi there!

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

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

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

在編譯階段階段,代碼真正執(zhí)行前的幾毫秒,會檢測到所有的變量和函數(shù)聲明,所有這些函數(shù)和變量聲明都被添加到名為Lexical Environment的JavaScript數(shù)據(jù)結(jié)構(gòu)內(nèi)的內(nèi)存中。所以這些變量和函數(shù)能在它們真正被聲明之前使用。

函數(shù)提升

sayHi() // Hi there!

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

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

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呢?

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

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

所以函數(shù)表達式也不會被“提升”。helloWorld是一個默認(rèn)值是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關(guān)鍵字聲明的變量才會被初始化undefined值,而letconst聲明的變量則不會被初始化值。

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

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

舉例:

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

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

lexicalEnvironment = {
  a: <uninitialized>
}

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

在執(zhí)行階段,當(dāng)JavaScript引擎執(zhí)行到變量被聲明的時候,如果聲明了變量并賦值,會更新詞法環(huán)境中的值,如果只是聲明了變量沒有被賦值,那么JavaScript引擎會給變量賦值為undefined。

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

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 }

到此這篇關(guān)于淺析JavaScript中的變量提升的文章就介紹到這了,更多相關(guān)JS變量提升內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 微信小程序列表中item左滑刪除功能

    微信小程序列表中item左滑刪除功能

    這篇文章主要介紹了微信小程序列表中item左滑刪除功能,本文分步驟給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-11-11
  • JavaScript異步調(diào)用定時方法并停止該方法實現(xiàn)代碼

    JavaScript異步調(diào)用定時方法并停止該方法實現(xiàn)代碼

    JavaScript異步調(diào)用定時方法并停止該方法實現(xiàn)代碼 ,需要的朋友可以參考下
    2012-03-03
  • js簡單粗暴的發(fā)布訂閱示例代碼

    js簡單粗暴的發(fā)布訂閱示例代碼

    這篇文章主要給大家介紹了js簡單粗暴的發(fā)布訂閱的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • JavaScript中的函數(shù)(二)

    JavaScript中的函數(shù)(二)

    函數(shù)是由事件驅(qū)動的或者當(dāng)它被調(diào)用時執(zhí)行的可重復(fù)使用的代碼塊。本文給大家介紹介紹javascript中的函數(shù)(二),對javascript函數(shù)相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧
    2015-12-12
  • JavaScript基礎(chǔ)之流程控制語句的用法

    JavaScript基礎(chǔ)之流程控制語句的用法

    下面就為大家?guī)硪黄狫avaScript基礎(chǔ)之流程控制語句的用法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • JS實現(xiàn)json的序列化和反序列化功能示例

    JS實現(xiàn)json的序列化和反序列化功能示例

    這篇文章主要介紹了JS實現(xiàn)json的序列化和反序列化功能,結(jié)合具體實例形式分析了javascript針對json的序列化與反序列化相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2017-06-06
  • layer.js open 隱藏滾動條的例子

    layer.js open 隱藏滾動條的例子

    今天小編就為大家分享一篇layer.js open 隱藏滾動條的例子,具有很好的參考價值,希望對大家有所幫助。 一起跟隨小編過來看看吧
    2019-09-09
  • Echarts繪制氣泡圖的示例代碼

    Echarts繪制氣泡圖的示例代碼

    Echarts是一款基于JavaScript的數(shù)據(jù)可視化庫,它提供了豐富的圖表類型,本文將詳細(xì)介紹如何使用Echarts來繪制氣泡圖,并介紹氣泡圖相關(guān)的配置,需要的可以參考下
    2023-12-12
  • 微信小程序嵌入H5頁面(web-view)的方法詳解

    微信小程序嵌入H5頁面(web-view)的方法詳解

    使用<web-view>標(biāo)簽?zāi)茉谛〕绦蛑写蜷_外部網(wǎng)頁,但是要打開的網(wǎng)頁的域名必須跟小程序的業(yè)務(wù)域名(業(yè)務(wù)域名可以在小程序的后臺管理界面添加)一致,否則在真機上是打不開的,下面這篇文章主要給大家介紹了關(guān)于微信小程序嵌入H5頁面(web-view)的相關(guān)資料,需要的朋友可以參考下
    2022-09-09
  • js中document.referrer實現(xiàn)移動端返回上一頁

    js中document.referrer實現(xiàn)移動端返回上一頁

    本文主要介紹了document.referrer實現(xiàn)移動端返回上一頁的方法,具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02

最新評論