Js中var,let,const的區(qū)別你知道嗎
一:區(qū)別:
1、var聲明的變量屬于函數(shù)作用域,而let和const聲明的變量屬于塊級作用域;(js作用域在上篇文章)
2、var聲明的變量存在變量提升,而let和const沒有
3、var聲明的變量可以重復(fù)聲明,而在同一塊級作用域,let變量不能重新聲明,const常量不能修改(對象的屬性和方法,數(shù)組的內(nèi)容可以修改)
二:var聲明的作用域
1. 使用var聲明的變量,這個變量屬于當(dāng)前的函數(shù)作用域,如果變量的聲明在任何函數(shù)外,那么這個變量就屬于全局作用域
var a = 1; //此處聲明的變量a為全局變量 function foo(){ var a = 2;//此處聲明的變量a為函數(shù)foo的局部變量 console.log(a);//2 } foo(); console.log(a);//1
2.如果在聲明變量時,省略 var 的話,該變量就會變成全局變量,如全局作用域中存在該變量,就會更新其值
var a = 1; //此處聲明的變量a為全局變量 function foo(){ a = 2;//此處的變量a也是全局變量 console.log(a);//2 } foo(); console.log(a);//2
三:var聲明的變量提升
1.var的聲明會在js預(yù)解析時把var的聲明提升到當(dāng)前作用域的最前面,意思是是指無論 var 出現(xiàn)在一個作用域的哪個位置,這個聲明都屬于當(dāng)前的整個作用域,在其中到處都可以訪問到。只有變量聲明才會提升,對變量賦值并不會提升
console.log(a);//undefined var a = 1;
相當(dāng)于執(zhí)行以下代碼
var a; console.log(a);//undefined a = 1;
四、let聲明
1.let 聲明的變量具有塊作用域的特征。
2.在同一個塊級作用域,不能重復(fù)聲明變量。
function foo(){ let a = 1; let a = 2;//Uncaught SyntaxError: Identifier 'a' has already been declared }
3.let 聲明的變量不存在變量提升,換一種說法,就是 let 聲明存在暫時性死區(qū)(TDZ)。
let a = 1; console.log(a);//1 console.log(b);//Uncaught ReferenceError: b is not defined let b = 2;
(此時變量b的聲明不會提升到當(dāng)前作用域的前面)
五:徹底區(qū)分var和let聲明變量(作用域區(qū)別)
1.var聲明
for (var i = 0; i < 10; i++) { setTimeout(function(){ console.log(i); },100) };
(1.此時的var聲明的變量i屬于函數(shù)作用域,聲明又不在函數(shù)里,所以i屬于全局變量
2.此時的定時器函數(shù)屬于異步函數(shù),隔100毫秒才會執(zhí)行,而這100毫秒的時間內(nèi),for循環(huán)已經(jīng)循環(huán)結(jié)束,全局變量i已經(jīng)為10
3.相當(dāng)于代碼執(zhí)行
{ var i = 0; // 第一次循環(huán) { setTimeout(() => { //延時器屬于異步函數(shù),不會立即執(zhí)行, //經(jīng)過1s后,循環(huán)已經(jīng)結(jié)束,全局變量i已經(jīng)變成10 console.log(i); }, 1000) i++ } // 第二次循環(huán) { setTimeout(() => { //var聲明的變量i沒有塊級作用域,所以可以訪問第一次循環(huán)體內(nèi)的變量i, //同樣,1s后,循環(huán)已經(jīng)結(jié)束,全局變量i已經(jīng)變成10 console.log(i); }, 1000) i++ } ..... }
最后代碼的執(zhí)行后,會在控制臺打印出10個10)
ps:主要的原因是var聲明的變量的沒有塊級作用域
2.let 聲明
使用閉包原理解決上例中var聲明變量的不具有塊級作用域的問題:
for (var i = 1; i <= 5; i++) { //i=0 第一輪循環(huán) (function (i) { // 立即執(zhí)行函數(shù)執(zhí)行,形成一個私有的函數(shù)上下文 //形參i是屬于立即執(zhí)行函數(shù)的局部變量,第一輪循環(huán)時相當(dāng)于let i=0 //由于立即執(zhí)行函數(shù)的參數(shù)i被下一級的延時器回調(diào)函數(shù)上下文所引用,所以會產(chǎn)生閉包, // 從而形成塊級作用域,保護(hù)了每一次循環(huán)的i,也就是閉包的特點:變量私有化 setTimeout(() => { // 延時器回調(diào)函數(shù)執(zhí)行,也會形成一個私有的函數(shù)上下文 console.log(i);//由于當(dāng)前延時器回調(diào)函數(shù)上下文引用了 // 上一級立即執(zhí)行函數(shù)的參數(shù)i(立即執(zhí)行函數(shù)的局部變量), //所以此時會產(chǎn)生閉包,立即執(zhí)行函數(shù)的參數(shù)i會一直保存在內(nèi)存中供延時器回調(diào)函數(shù)使用 }, 5000) })(i)//把每一輪循環(huán)全局的i的值作為實參傳遞給立即執(zhí)行函數(shù)的私有上下文,第一輪傳遞的是0 }
使用let聲明的變量具有塊級作用域
for (let i = 0; i < 10; i++) { // 每一輪都會形成一個私有的塊級作用域,并且有一個私有的變量i,分別存儲每一輪循環(huán)的索引 setTimeout(function(){ console.log(i); },100) };
PS:這是因為閉包的機(jī)制,但是因為let的塊作用域是瀏覽器底層機(jī)制實現(xiàn)的,比我們自己創(chuàng)建的閉包性能要好一些
代碼執(zhí)行后,則該代碼運(yùn)行后,就會在控制臺打印出0-9. )
六:const 聲明
1.const 聲明方式,除了具有 let 的上述特點外,其還具備一個特點,即 const 定義的變量,一旦定義后,就不能修改,即 const 聲明的為常量。
const a = 1; console.log(a);//1 a = 2; console.log(a);//Uncaught TypeError: Assignment to constant variable.
2.但是,并不是說 const 聲明的變量其內(nèi)部內(nèi)容不可變,如:
const obj = {a:1,b:2}; console.log(obj.a);//1 obj.a = 3; console.log(obj.a);//3
所以準(zhǔn)確的說,是 const 聲明創(chuàng)建一個值的只讀引用。但這并不意味著它所持有的值是不可變的,只是變量標(biāo)識符不能重新分配。
(我的理解是如果是簡單數(shù)據(jù)類型,const聲明的變量保存的值就是變量的值,是不可以修改,但如果是復(fù)雜數(shù)據(jù)類型(對象,數(shù)組等)const只是保存的是復(fù)雜數(shù)據(jù)類型的地址,只是確保地址不可變,但地址指向的內(nèi)容是可以變的)
總結(jié)
最后,因為let和const是es6的新特性,let和const的出現(xiàn)就是為了解決var的各種問題,強(qiáng)烈建議大家寫js代碼都用let和const聲明變量和常量!
到此這篇關(guān)于Js中var,let,const區(qū)別的文章就介紹到這了,更多相關(guān)Js中var,let,const區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Javascript?中?var?和?let?、const?的區(qū)別及使用方法
- javascript中var與let、const的區(qū)別詳解
- JavaScript變量中var,let和const的區(qū)別
- 淺談JS中var,let和const的區(qū)別
- JavaScript變量聲明的var、let、const詳解
- javascript?變量聲明?var,let,const?的區(qū)別
- 面試官常問之說說js中var、let、const的區(qū)別
- JavaScript?ES6語法中l(wèi)et,const?,var?的區(qū)別
- javascript的var與let,const之間的區(qū)別詳解
- JavaScript中var let const的用法有哪些區(qū)別
- JavaScript es6中var、let以及const三者區(qū)別案例詳解
- 詳解javascript中var與ES6規(guī)范中l(wèi)et、const區(qū)別與用法
- 了解javascript中l(wèi)et和var及const關(guān)鍵字的區(qū)別
- 5分鐘快速掌握J(rèn)S中var、let和const的異同
- JavaScript中var、let、const區(qū)別淺析
- JavaScript變量聲明var,let.const及區(qū)別淺析
- JavaScript ES6中const、let與var的對比詳解
- JS變量中有var定義和無var定義的區(qū)別以及es6中l(wèi)et命令和const命令
- JavaScript中const、var和let區(qū)別淺析
- JavaScript聲明變量的這四兄弟(var、let、function、const)
相關(guān)文章
當(dāng)鼠標(biāo)滑過文本框自動選中輸入框內(nèi)容的JS代碼分享
這篇文章主要介紹了當(dāng)鼠標(biāo)滑過文本框自動選中輸入框內(nèi)容的JS代碼,有需要的朋友可以參考一下2013-11-11egg.js的基本使用和調(diào)用數(shù)據(jù)庫的方法示例
這篇文章主要介紹了egg.js的基本使用和調(diào)用數(shù)據(jù)庫的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05基于JavaScript實現(xiàn)網(wǎng)頁倒計時自動跳轉(zhuǎn)代碼
這篇文章主要介紹了基于JavaScript實現(xiàn)網(wǎng)頁倒計時自動跳轉(zhuǎn)代碼 的相關(guān)資料,需要的朋友可以參考下2015-12-12js中對函數(shù)設(shè)置默認(rèn)參數(shù)值的3種方法
這篇文章主要介紹了js中對函數(shù)設(shè)置默認(rèn)參數(shù)值的3種方法嗎,3種方法都具有一定的參考價值,感興趣的小伙伴們可以參考一下2015-10-10JavaScript利用canvas實現(xiàn)炫酷的碎片切圖效果
這篇文章主要和大家分享一個炫酷的碎片式切圖效果,本文主要利用canvas來實現(xiàn),代碼量不多,但有些地方還是需要花點時間去理解的,感興趣的可以學(xué)習(xí)一下2022-10-10