摘要:原文是這樣說(shuō)的不像那樣會(huì)發(fā)生變量提升現(xiàn)象。這就導(dǎo)致了所有變量聲明的語(yǔ)句都會(huì)被提升到代碼的最前面。這就是變量提升。注意提出的新指令和是不會(huì)發(fā)生變量提升現(xiàn)象的,所以在使用語(yǔ)法時(shí),一定要先聲明再調(diào)用。
場(chǎng)景
開(kāi)始讀es6的時(shí)候,一開(kāi)始介紹的是let和const指令,文章中就提到一個(gè)概念 => 變量提升。原文是這樣說(shuō)的:let不像var那樣會(huì)發(fā)生“變量提升”現(xiàn)象。對(duì)我這個(gè)菜鳥(niǎo)來(lái)說(shuō),what?什么是變量提升。經(jīng)過(guò)一番度娘以后,有了個(gè)大概的概念和自己的理解。
理解比較官方一點(diǎn)的解釋這樣的:JavaScript在工作時(shí)會(huì)先獲取所有變量,然后再一行一行地執(zhí)行代碼。這就導(dǎo)致了所有變量聲明的語(yǔ)句都會(huì)被提升到代碼的最前面。這就是變量提升。
栗子var a = 5; function fn(){ a = 3; console.log(a) var a; } fn()
很簡(jiǎn)單的一段代碼,最終輸出的是3。函數(shù)內(nèi)的a覆蓋了外面的變量a,var a;并沒(méi)有刷新a的值,因?yàn)檎嬲谶\(yùn)行時(shí)的順序應(yīng)該是這樣的
var a = 5; function fn(){ var a; a = 3; console.log(a) } fn()
我們可以看到,寫在下面的聲明a的語(yǔ)句被提前到了函數(shù)的最上面,所以最后輸出的是函數(shù)內(nèi)部的變量a而不是外面的a = 5
var a = 5; function fn(){ console.log(a) var a = 3;; } fn()
在這里又會(huì)發(fā)生什么呢?我們看一下運(yùn)行結(jié)果:
可能有人會(huì)說(shuō)為什么打印的不是5呢?這就是變量提升的神奇之處,使用var聲明的變量在運(yùn)行時(shí)該聲明語(yǔ)句會(huì)被放在當(dāng)前當(dāng)前作用域的最上面。這里又涉及到一個(gè)作用域的概念,暫時(shí)可以簡(jiǎn)單理解為一對(duì)大括號(hào)就是一個(gè)作用域。
所以上面的代碼在運(yùn)行時(shí)的順序應(yīng)該是這樣的:
var a = 5; function fn(){ var a; console.log(a) a = 3;; } fn()
變量提升只是把聲明語(yǔ)句提升上去,而賦值語(yǔ)句是不會(huì)被提升的。明顯可以看到在函數(shù)內(nèi)部還是新創(chuàng)建了一個(gè)變量a,但是在打印前都沒(méi)有給a賦值,所以最后打印出來(lái)的值是‘undefined’
函數(shù)除了變量提升意外,函數(shù)也是存在這樣的現(xiàn)象,我們來(lái)看一段代碼
// 代碼一 fn() function fn(){ console.log(0) } //代碼二 fn() var fn = function() { console.log(0) }
直接看結(jié)果:
代碼一運(yùn)行正常,代碼二就報(bào)錯(cuò)了。因?yàn)榇a二的實(shí)際運(yùn)行順序其實(shí)這樣的
var fn; fn(); fn = function() { console.log(0) }
很顯然,執(zhí)行fn();之前fn只是一個(gè)變量,以函數(shù)的方式調(diào)用變量肯定是錯(cuò)誤的用法。
注意:es6提出的新指令let和const是不會(huì)發(fā)生變量提升現(xiàn)象的,所以在使用es6語(yǔ)法時(shí),一定要先聲明再調(diào)用。
到此,本人知道的有關(guān)JavaScript的變量提升方面的知識(shí)就只有這么多,如果有幸這篇文章被你看到了,相信你看完以后也會(huì)對(duì)這個(gè)知識(shí)點(diǎn)有個(gè)大概的了解了。如果覺(jué)得有什么地方說(shuō)得不對(duì)的,歡迎指正。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/107978.html
摘要:如下代碼輸出的結(jié)果是代碼執(zhí)行分為兩個(gè)大步預(yù)解析的過(guò)程代碼的執(zhí)行過(guò)程預(yù)解析與變量聲明提升程序在執(zhí)行過(guò)程中,會(huì)先將代碼讀取到內(nèi)存中檢查,會(huì)將所有的聲明在此進(jìn)行標(biāo)記,所謂的標(biāo)記就是讓解析器知道有這個(gè)名字,后面在使用名字的時(shí)候不會(huì)出現(xiàn)未定義的錯(cuò)誤。 showImg(https://segmentfault.com/img/remote/1460000012922850); 如下代碼輸出的結(jié)果是...
摘要:函數(shù)作用域和塊作用域前面講了是詞法作用域,那么什么時(shí)候會(huì)創(chuàng)建作用域呢主要是基于函數(shù)級(jí)別的作用域,也就是每一個(gè)函數(shù)都會(huì)創(chuàng)建一個(gè)作用域。函數(shù)會(huì)被當(dāng)作函數(shù)表達(dá)式而不是一個(gè)標(biāo)準(zhǔn)的函數(shù)聲明來(lái)處理。 什么是作用域 來(lái)一段《你不知道的JavaScript-上卷》中的原話: 幾乎所有編程語(yǔ)言最基本的功能之一,就是能夠儲(chǔ)存變量當(dāng)中的值,并且能在之后對(duì)這個(gè) 值進(jìn)行訪問(wèn)或修改,這些變量住在哪里?換句話說(shuō),它...
摘要:作用域是代碼的不同部分在運(yùn)行期間的可見(jiàn)性。大多數(shù)開(kāi)發(fā)者想當(dāng)然地理解作用域,但毫無(wú)疑問(wèn),有它自己的說(shuō)明。變量可能是全局作用域的,或者是方法作用域的??偠灾?,不要重復(fù)聲明變量,使用良好命名,盡力避免在聲明前調(diào)用和執(zhí)行任何東西。 原文鏈接:https://hackernoon.com/unders... 什么是作用域? 就像JavaScript中的其他東西一樣,作用域并無(wú)特別之處。盡管大多...
摘要:依然持有對(duì)該作用域的引用,而這個(gè)引用就叫作閉包。循環(huán)和閉包正常情況下,我們對(duì)這段代碼行為的預(yù)期是分別輸出數(shù)字,每秒一次,每次一個(gè)。 一、作用域 作用域共有兩種主要的工作模型:第一種是最為普遍的,被大多數(shù)編程語(yǔ)言所采用的詞法作用域,另外一種叫作動(dòng)態(tài)作用域; JavaScript所采用的作用域模式是詞法作用域。 1.詞法作用域 詞法作用域意味著作用域是由書寫代碼時(shí)函數(shù)聲明的位置來(lái)決定...
閱讀 1269·2021-11-19 09:40
閱讀 3128·2021-11-02 14:47
閱讀 3102·2021-10-11 10:58
閱讀 3224·2019-08-30 15:54
閱讀 2678·2019-08-30 12:50
閱讀 1732·2019-08-29 16:54
閱讀 474·2019-08-29 15:38
閱讀 1243·2019-08-29 15:19