日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

详解var、let、const关键词声明变量的区别,以及变量提升、块级作用域的认识等。

發(fā)布時(shí)間:2025/3/12 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 详解var、let、const关键词声明变量的区别,以及变量提升、块级作用域的认识等。 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

首先回顧一下JavaScript中var聲明變量的基礎(chǔ)知識(shí):

? 在使用var關(guān)鍵詞聲明變量時(shí),變量在函數(shù)外則是全局變量,有全局作用域,全局變量在頁(yè)面關(guān)閉后銷毀;變量在函數(shù)內(nèi)則是局部變量,作用局部作用域(變量只能在該函數(shù)內(nèi)有效,函數(shù)執(zhí)行完將自動(dòng)銷毀)

? 我們使用var來(lái)創(chuàng)建變量,聲明后未賦值的變量輸出會(huì)提示 “undefined”。在方法函數(shù)外聲明的變量未使用var ,會(huì)報(bào)錯(cuò)“x is not defined”;

? 在函數(shù)內(nèi)未使用var聲明的變量自動(dòng)變?yōu)槿肿兞?/span>


開發(fā)背景(WHY)為什么要使用let、const關(guān)鍵詞來(lái)創(chuàng)建變量或常量

?解決ES5使用var初始化變量時(shí)會(huì)出現(xiàn)的變量提升問(wèn)題

?解決使用閉包時(shí)出錯(cuò)的問(wèn)題

?解決使用計(jì)數(shù)的for循環(huán)變量時(shí)候會(huì)導(dǎo)致泄露為全局變量的問(wèn)題,

?ES5只有全局作用域和函數(shù)作用域(對(duì)應(yīng)var聲明的全局變量和局部變量時(shí)),沒(méi)有塊級(jí)作用域(ES6中{}中的代碼塊)。同理只能在頂層作用域window中和函數(shù)中聲明函數(shù),不能在塊級(jí)作用域中聲明函數(shù);


那么先來(lái)理解一下什么是變量提升特性,會(huì)導(dǎo)致的問(wèn)題(比如內(nèi)層變量覆蓋外層變量)


?變量初始化時(shí)可以分為兩步:使用關(guān)鍵詞var聲明變量,以及賦值。變量提升就是將聲明變量這一步提升到該作用域的頭部。注意函數(shù)聲明也會(huì)類似var聲明出現(xiàn)提升特效,函數(shù)聲明提升在變量聲明提升上面;

參考網(wǎng)址:https://blog.csdn.net/recoluan/article/details/79253223

實(shí)例01

console.log(foo); console.log(foo2); var foo=2; let foo2=3;
//以上代碼var聲明變量后,相當(dāng)于如下 // var foo; // console.log(foo); //會(huì)提示‘undefined’ // foo=2; // let不存在變量提升,會(huì)報(bào)錯(cuò)

實(shí)例02

var a="我在外面"; function func(){ console.log(a); //undefined console.log(window.a); //我在外面 var a='我在里面'; console.log(a); //我在里面} //以上代碼var聲明變量后,相當(dāng)于如下 // var a="我在外面"; // function func(){ // var a; // console.log(a); // console.log(window.a); // a='我在里面'; // console.log(a); // }

注意:在使用let、const命令聲明的變量不具備變量提升效果;

????:函數(shù)聲明提升會(huì)在變量聲明提升上面

fuc2(); function fuc2(){ console.log(b); //undefined} var b=35; //相當(dāng)于 // function fuc2(){ // console.log(b); // } // var b; // func2(); // b=35;


為什么需要塊級(jí)作用域?

??用來(lái)計(jì)數(shù)的循環(huán)變量泄露為全局變量,如下:

for (var i = 0; i < s.length; i++) { console.log(s[i]); //會(huì)將字符串拆分為一個(gè)個(gè)的字符輸出}console.log(i); // 5


? let和const是ES6新增特性,都可生成塊級(jí)作用域(是指聲明在花括號(hào)內(nèi)的變量只在該區(qū)域內(nèi)有效)。let用來(lái)聲明變量,const用來(lái)聲明常量(不可修改變量值,數(shù)組和對(duì)象除外);如果區(qū)塊內(nèi)存在let或const命令,這個(gè)區(qū)塊對(duì)這些命令聲明的變量會(huì)形成封閉的區(qū)域,該區(qū)域外不能被使用,且變量聲明前使用變量會(huì)報(bào)錯(cuò)(又叫暫時(shí)性死區(qū)),更加嚴(yán)謹(jǐn)

var tmp = 123;if (true) { tmp = 'abc'; // ReferenceError,不能未聲明前使用這就是暫時(shí)性死區(qū) console.log(temp); let tmp; temp=666; console.log(temp);}


function bar(x = y, y = 2) { return [x, y];}bar(); // 報(bào)錯(cuò)


塊級(jí)作用域外不能訪問(wèn)該區(qū)塊內(nèi)的變量或者常量,子塊級(jí)作用域可以訪問(wèn)父塊級(jí)作用域的變量

{ const ss=99;{ console.log(ss); //可以在子塊內(nèi)訪問(wèn)父塊定義的常量}}console.log(ss); //b不可以在塊作用外訪問(wèn)let、const定義的變量或者常量

以上代碼中通過(guò)將let替換var就可以修復(fù)各種bug,所以,let是更完美的var”。


其他的let、const和var的用法及注意點(diǎn)

? let和var的區(qū)別:let聲明的變量只在其聲明的塊或子塊中可用,而var聲明的變量的作用域是整個(gè)封閉函數(shù)可用;

? let和const的特點(diǎn):

① let和const關(guān)鍵詞聲明的變量不具備變量提升的特效(第二步提到了的),存在暫時(shí)性的死區(qū),只能在聲明的位置后使用,同一塊級(jí)作用域中不能反復(fù)聲明同一變量名(子塊級(jí)可以重復(fù)聲明父塊級(jí)變量),var可以;

② let和const聲明只在最靠近的一個(gè)塊(花括號(hào)內(nèi))中有效;

③ 使用const聲明常量時(shí)候大寫,const在聲明時(shí)必須賦值;

注意1: const聲明的變量值并不是不能變的,而是變量指向的內(nèi)存地址是不能變的,對(duì)于數(shù)值、字符串等簡(jiǎn)單類型的數(shù)據(jù),值就保存在變量指向的內(nèi)存地址上,因此等同于常量;但對(duì)于符合類型的數(shù)據(jù)(如數(shù)組和對(duì)象),變量指向的內(nèi)存地址是一個(gè)指引,數(shù)據(jù)結(jié)構(gòu)是否可變就不能控制了,所以將對(duì)象聲明為常量必須非常小心;

const newArr=[23,43,22,66];newArr[0]=888;console.log(newArr); //[888, 43, 22, 66]

注意2:外層塊作用域不可以訪問(wèn)塊內(nèi)層作用域,內(nèi)層塊作用域可以獲取外層塊作用域變量,子塊可以重復(fù)定義外層塊作用域變量。函數(shù)在塊級(jí)作用域中聲明是行為類似let,不能被作用域外訪問(wèn),塊中的函數(shù)聲明存在變量提升,確實(shí)需要時(shí)候使用函數(shù)表達(dá)式的形式,而不是函數(shù)聲明語(yǔ)句形式;

function f() { console.log('I am outside!'); }(function () { if (false) { //函數(shù)提升后,這里重復(fù)聲明了該匿名函數(shù)外的函數(shù)f,所以會(huì)覆蓋外部函數(shù) function f() { console.log('I am inside!'); }} f();}());

注意3: ?Let不允許在相同作用域中使用與其他let或const,重復(fù)聲明同一個(gè)變量,所以不能在有參函數(shù)聲明中重復(fù)聲明函數(shù)參數(shù),如function func(arg){let arg}會(huì)報(bào)錯(cuò)

var message = "Hello!";let age = 25;// 以下兩行都會(huì)報(bào)錯(cuò)const message = "Goodbye!";const age = 30;


注意4: 在ES5中頂層對(duì)象(在瀏覽器指的是window對(duì)象),頂層對(duì)象屬性和全局變量是等價(jià)的。屬性也可以動(dòng)態(tài)創(chuàng)建變量,頂層對(duì)象的屬性可以被隨處讀寫不利于模塊化編程;而在ES6中,var命令和function命令聲明的全局變量,依舊是頂層對(duì)象的屬性;另一方面規(guī)定,let命令、const命令、class命令聲明的全局變量,不屬于頂層對(duì)象的屬性。也就是說(shuō),從 ES6 開始,全局變量將逐步與頂層對(duì)象的屬性脫鉤。

var aaa=1;console.log(window.aaa); //輸出1let bbb=2;console.log(window.bbb ); //輸出undefined


總結(jié)

以上是生活随笔為你收集整理的详解var、let、const关键词声明变量的区别,以及变量提升、块级作用域的认识等。的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。