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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

首先回顧一下JavaScript中var聲明變量的基礎知識:

? 在使用var關鍵詞聲明變量時,變量在函數外則是全局變量,有全局作用域,全局變量在頁面關閉后銷毀;變量在函數內則是局部變量,作用局部作用域(變量只能在該函數內有效,函數執行完將自動銷毀)

? 我們使用var來創建變量,聲明后未賦值的變量輸出會提示 “undefined”。在方法函數外聲明的變量未使用var ,會報錯“x is not defined”;

? 在函數內未使用var聲明的變量自動變為全局變量


開發背景(WHY)為什么要使用let、const關鍵詞來創建變量或常量

?解決ES5使用var初始化變量時會出現的變量提升問題

?解決使用閉包時出錯的問題

?解決使用計數的for循環變量時候會導致泄露為全局變量的問題,

?ES5只有全局作用域和函數作用域(對應var聲明的全局變量和局部變量時),沒有塊級作用域(ES6中{}中的代碼塊)。同理只能在頂層作用域window中和函數中聲明函數,不能在塊級作用域中聲明函數;


那么先來理解一下什么是變量提升特性,會導致的問題(比如內層變量覆蓋外層變量)


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

參考網址:https://blog.csdn.net/recoluan/article/details/79253223

實例01

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

實例02

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

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

????:函數聲明提升會在變量聲明提升上面

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


為什么需要塊級作用域?

??用來計數的循環變量泄露為全局變量,如下:

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


? let和const是ES6新增特性,都可生成塊級作用域(是指聲明在花括號內的變量只在該區域內有效)。let用來聲明變量,const用來聲明常量(不可修改變量值,數組和對象除外);如果區塊內存在let或const命令,這個區塊對這些命令聲明的變量會形成封閉的區域,該區域外不能被使用,且變量聲明前使用變量會報錯(又叫暫時性死區),更加嚴謹

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


function bar(x = y, y = 2) { return [x, y];}bar(); // 報錯


塊級作用域外不能訪問該區塊內的變量或者常量,子塊級作用域可以訪問父塊級作用域的變量

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

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


其他的let、const和var的用法及注意點

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

? let和const的特點:

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

② let和const聲明只在最靠近的一個塊(花括號內)中有效;

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

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

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

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

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

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

var message = "Hello!";let age = 25;// 以下兩行都會報錯const message = "Goodbye!";const age = 30;


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

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


總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。