最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺析JavaScript中的變量提升

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

前言:

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

sayHi() // Hi there!

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

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

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

在編譯階段階段,代碼真正執(zhí)行前的幾毫秒,會(huì)檢測(cè)到所有的變量和函數(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!')
}

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

lexicalEnvironment = {
  sayHi: < func >
}

var變量提升

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

上面的代碼實(shí)際上分為兩個(gè)部分:

  • var name表示聲明變量name
  • = 'John Doe'表示的是為變量name賦值為'John Doe'。
var name    // 聲明變量
name = 'John Doe' // 賦值操作

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

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

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

所以函數(shù)表達(dá)式也不會(huì)被“提升”。helloWorld是一個(gè)默認(rèn)值是undefined的變量,而不是一個(gè)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

為什么會(huì)報(bào)一個(gè)ReferenceError錯(cuò)誤,難道letconst聲明的變量沒有被“提升”嗎?

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

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

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

舉例:

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

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

lexicalEnvironment = {
  a: <uninitialized>
}

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

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

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

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

Class提升

letconst一樣,class在JavaScript中也是會(huì)被“提升”的,在被真正賦值之前都不會(huì)被初始化值, 同樣受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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Echarts橫向堆疊柱狀圖和markLine實(shí)例詳解

    Echarts橫向堆疊柱狀圖和markLine實(shí)例詳解

    一些柱形圖在數(shù)據(jù)量比較多的時(shí)候,橫向排列受到擠壓,導(dǎo)致柱形圖,變的非常細(xì),影響整體的效果,所以應(yīng)該將柱形圖堆疊起來,這樣就會(huì)好很多,下面這篇文章主要給大家介紹了關(guān)于Echarts橫向堆疊柱狀圖和markLine的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • JS+Canvas繪制抽獎(jiǎng)轉(zhuǎn)盤

    JS+Canvas繪制抽獎(jiǎng)轉(zhuǎn)盤

    這篇文章主要為大家詳細(xì)介紹了JS+Canvas繪制抽獎(jiǎng)轉(zhuǎn)盤,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • js原生輪播圖插件制作

    js原生輪播圖插件制作

    這篇文章主要為大家詳細(xì)介紹了js原生輪播圖插件制作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • Js與下拉列表處理問題解決

    Js與下拉列表處理問題解決

    這篇文章主要介紹了Js與下拉列表處理問題,需要的朋友可以參考下
    2014-02-02
  • js 動(dòng)態(tài)生成json對(duì)象、時(shí)時(shí)更新json對(duì)象的方法

    js 動(dòng)態(tài)生成json對(duì)象、時(shí)時(shí)更新json對(duì)象的方法

    下面小編就為大家?guī)硪黄猨s 動(dòng)態(tài)生成json對(duì)象、時(shí)時(shí)更新json對(duì)象的方法。小編覺的挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-12-12
  • 微信小程序頁面滑動(dòng)屏幕加載數(shù)據(jù)效果

    微信小程序頁面滑動(dòng)屏幕加載數(shù)據(jù)效果

    這篇文章主要為大家詳細(xì)介紹了微信小程序頁面滑動(dòng)屏幕加載數(shù)據(jù)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • 玩轉(zhuǎn)JavaScript OOP - 類的實(shí)現(xiàn)詳解

    玩轉(zhuǎn)JavaScript OOP - 類的實(shí)現(xiàn)詳解

    下面小編就為大家?guī)硪黄孓D(zhuǎn)JavaScript OOP - 類的實(shí)現(xiàn)詳解。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-06-06
  • js字符串去重復(fù)id的實(shí)現(xiàn)代碼

    js字符串去重復(fù)id的實(shí)現(xiàn)代碼

    最近由于需要我們將相關(guān)id的重復(fù)的去掉,一個(gè)是客戶端一個(gè)后臺(tái)程序把關(guān),這里分享下js的去重復(fù)id的實(shí)現(xiàn)代碼
    2013-07-07
  • 關(guān)于JavaScript中的數(shù)組方法和循環(huán)

    關(guān)于JavaScript中的數(shù)組方法和循環(huán)

    這篇文章主要介紹了關(guān)于JavaScript中的數(shù)組方法和循環(huán),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 微信小程序地圖繪制線段并且測(cè)量(實(shí)例代碼)

    微信小程序地圖繪制線段并且測(cè)量(實(shí)例代碼)

    這篇文章主要介紹了微信小程序地圖繪制線段并且測(cè)量,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-01-01

最新評(píng)論

绥阳县| 喀喇| 芮城县| 盐边县| 竹山县| 射阳县| 义马市| 江源县| 三都| 凉城县| 满洲里市| 资溪县| 尼勒克县| 喀什市| 大城县| 潜山县| 吴江市| 彭泽县| 孟津县| 康保县| 翼城县| 桓台县| 从化市| 石景山区| 信丰县| 宁德市| 韶关市| 醴陵市| 武宁县| 中西区| 辰溪县| 湖州市| 武强县| 绥宁县| 白城市| 台中市| 从江县| 芦溪县| 淳安县| 比如县| 黄冈市|