詳解JavaScript中var和let的區(qū)別
變量
ECMAScript變量是松散類型,意思就是說變量可以保存任何類型的數(shù)據(jù),每個變量只不過是用于保存任意值的命名占位符。在JavaScript中,有3個關(guān)鍵字可以聲明變量:var、const和let,其中var在ECMAScript的所有版本中都可以使用,而const和let只能在ECMAScript 6及更晚的版本中使用
var 關(guān)鍵字
如果我們想定義變量,我們可以使用var操作符(這里要注意var也是一個關(guān)鍵字~),后跟變量名
var message;
這行代碼會定義一個名為message的變量,用于保存任何類型的值,如果在不初始化的情況下,默認(rèn)為undefined。ECMAScript實現(xiàn)變量初始化,因此可以同時定義變量并且設(shè)置它的值
var message = "hi";
通過上方代碼我們可以了解到,message被定義為一個保存字符串值hi的變量,像這樣初始化變量不會將它標(biāo)識為字符串類型,這僅僅是一個簡單的賦值而已,我們不僅可以改變保存的值,同時還可以改變值的類型
var message = "hi" message = 100 ;
通過上方代碼我們可以看到,message首先被定義為一個用于保存字符串值hi的變量,然后又被重寫為保存了數(shù)值100,雖然不推薦改變變量保存值的類型,但是這個在ECMAScript里面是非常有效的
var聲明作用域
我們在定義一個函數(shù)變量的時候,通常都會考慮他們的作用域,使用var操作符定義的變量將會成為包含它的函數(shù)的局部變量,比如用var在一個函數(shù)內(nèi)部定義一個變量,就意味著一旦出了這個區(qū)域,此定義無效
<script> function test() { var message = "hi"; } test(); console.log(message); </script>
從上方代碼我們可以看到,message變量是在函數(shù)內(nèi)部使用var定義的,函數(shù)名叫test() ,調(diào)用它會創(chuàng)建這個變量并且會給它賦值,調(diào)用結(jié)束之后這個變量就會被銷毀,因此上方代碼的倒數(shù)第二行會報語法錯誤,如果我們想要解決這個問題,把message定義成全局變量即可
<script> function test() { message = "hi"; } test(); console.log(message); </script>
去掉之前的var操作符之后,message就變成了全局變量,我們只需要調(diào)用一次函數(shù)test() ,就可以定義這個變量,并且在函數(shù)外部訪問
注意注意?。?!
我們雖然可以通過省略var操作符來定義全局變量,但是不推薦這么做,在局部作用域中定義的全局變量很難去維護(hù),也會給我們造成一定的困惑,因為我們不能確定這個var是不是有意而為之,如果像這樣給未聲明的變量賦值,則會導(dǎo)致拋出ReferenceError
如果我們需要定義多個變量,我們可以在一條語句中用逗號分隔每個變量(及可選的初始化)
<script> var message = "hi"; found = false; age = 29; </script>
這里我們定義了3個初始化變量,因為ECMAScript是松散類型的,所以使用不同數(shù)據(jù)類型初始化的變量可以用一條語句來聲明,插入換行和空格縮進(jìn)不是必需品(因為這里不是Python~)
小tip
在嚴(yán)格模式下,不能定義名為eval和arguments的變量,否則會導(dǎo)致語法錯誤
var聲明提升
我們在使用var的時候,下面的代碼不會報錯,因為使用這個關(guān)鍵字聲明的變量會自動提升到函數(shù)作用域的頂部
<script> function foo() { console.log(age); var age = 26; } foo(); </script>
之所以這個代碼不會報錯,是因為ECMAScript已經(jīng)幫我們解決啦~(它自己會自動調(diào)整閱讀順序),這就是所謂的提升,也就數(shù)把所有變量聲明都拉到函數(shù)作用域的頂部,此外,反復(fù)多次使用var聲明同一個變量也是沒有問題的
let聲明
let跟var的作用差不多,但是有著十分重要的區(qū)別,最明顯的區(qū)別就是,let聲明的范圍是塊作用域,而var聲明的范圍是函數(shù)作用域
<script> if(true){ var name = "Matt" console.log(name); //Matt } console.log(name); //Matt if(true){ let age = 26 ; console.log(age) //26 } console.log(age) //ReferenceError </script>
在這里,age變量之所以不能在if塊外部被引用,是因為它的作用域僅限于該塊內(nèi)部,塊作用域是函數(shù)作用于的子集,因此適用于var的作用域也適用于let
let也不允許同一個塊作用域中出現(xiàn)冗余聲明,這也會報錯
var name ; var name ; let age ; let age ; //SyntaxError 標(biāo)識符age已經(jīng)聲明過了
當(dāng)然,JavaScript引擎會記錄用于變量聲明的標(biāo)識符及其所在的塊作用域,因此嵌套相同的標(biāo)識符不會報錯, 這是因為在同一個塊中沒有重復(fù)聲明
<script> var name = "Nicholas"; console.log(name); // Nicholas if (true) { var name = "Matt"; console.log(name); // Matt } let age = 30; console.log(age); // 30 if (true) { let age = 26; console.log(age); // 26 } </script>
對聲明冗余報錯不會因混用let和var而受影響,這兩個關(guān)鍵字聲明的并不是不同類型的變量,它們只是指出變量在相關(guān)作用域如何存在
var name ; let name ; //SyntaxError let age ; var age ; //SynatxError
到此這篇關(guān)于詳解JavaScript中var和let的區(qū)別的文章就介紹到這了,更多相關(guān)JavaScript var let內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
- 使用js模擬類繼承小例子,學(xué)習(xí)js面向?qū)ο蟮呐笥芽梢詤⒖枷隆?/div> 2010-07-07
代碼短小的js div層拖動實現(xiàn)代碼[兼容IE與Firefox]
代碼短小的js div層拖動實現(xiàn)代碼[兼容IE與Firefox],需要的朋友可以參考下.2010-05-05JS+CSS實現(xiàn)網(wǎng)頁加載中的動畫效果
這篇文章主要為大家詳細(xì)介紹了JS+CSS實現(xiàn)網(wǎng)頁加載中的動畫效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10如何使用electron-builder及electron-updater給項目配置自動更新
這篇文章主要介紹了如何使用electron-builder及electron-updater給項目配置自動更新,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-12-12最新評論