欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

js中var、let、const之間的區(qū)別

 更新時間:2023年05月17日 09:31:07   作者:前端深情大男孩  
本文主要介紹了js中var、let、const之間的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、什么是變量

在讀這篇文章前,我們需要搞懂到底是什么變量,其實一句話就能概括:變量是一個可以保存任何數(shù)據(jù)類型值的命名占位符。本篇文章將會介紹以下知識點:

  • 什么是var、let、const
  • 變量聲明規(guī)則
  • 變量提升
  • 塊作用域
  • 暫時性死區(qū)

二、var關(guān)鍵字

2.1 初始化

初始化變量只需要在var關(guān)鍵字后面跟變量名即可:

var a;
var b = 2;

上面這段代碼聲明了a和b兩個變量,a變量只是單純的聲明,并沒有賦值,js引擎遇到未賦值的變量時,會自動為其賦值一個值,這個值就是undefined;變量b在聲明的時候我們給它賦值了一個數(shù)字2,所以當(dāng)獲取變量b的時候,會得到一個number類型的2。

說到number類型,這里就不得不提到一個概念:JavaScript中的變量屬于松散類型,也就是變量的值可以變更為任何數(shù)據(jù)類型的值,但并不建議這么做,隨意更改變量的數(shù)據(jù)類型會導(dǎo)致代碼可讀性降低。

// 翻譯后是var a = undefined;
var a;
var b = 2;
b = '2'; // 不建議這么做

在代碼開發(fā)過程中,有些場景需要創(chuàng)建多個變量,除了var a = 1; var b = 2;這種寫法,還可以使用,進行更便利的創(chuàng)建多個變量:

// 使用逗號創(chuàng)建多個變量
var a = 1,
    b = 2,
    c = 3;
// 等同于
var a = 1;
var b = 2;
var c = 3;

2.2 var聲明作用域

變量存在哪個作用域中是根據(jù)變量所聲明的場景位置決定,有兩種場景:全局、函數(shù)。在全局作用域中聲明var變量,該變量在任何地方都可以被訪問到,而且還可以通過window.變量名訪問。如果在函數(shù)內(nèi)部聲明變量,那么這個變量就只屬于這個函數(shù)自己的,外部訪問就會報錯,最后變量會在函數(shù)退出的時候被銷毀。

// 聲明全局變量
var a = 1;
// 訪問全局變量
console.log(a);  // 1
console.log(window.a);  // 1
// 聲明函數(shù)作用域內(nèi)的變量
function fun () {
    var b = 2;  // 只屬于fun函數(shù)的變量
    console.log(b);  // 2
};
fun();  // 2
console.log(b);  // 報錯:b is not defined(變量b未定義)

2.3 var的變量提升

變量提升其實就是在初始化的時候,var變量會提升到當(dāng)前作用域最頂部,并且每一個變量的值都是默認undefined,當(dāng)js引擎執(zhí)行到變量賦值的代碼后,變量的值才會是我們想要的那個值,根據(jù)這個理論,來看下面一段代碼,思考一下代碼執(zhí)行的結(jié)果是什么:

var a = 1,
    b = 2;
function fun (a) {
    console.log(b);
    var b = 6;
    var b = 5;
    console.log(a);
    console.log(b);
};
console.log(b);
fun(4);
console.log(b);

上面這段代碼其實并沒有復(fù)雜的交互,只是多次的訪問某些變量,會讓人有點眼花,沒關(guān)系,我們來一步一步的分解這些代碼,得到最終的結(jié)果,看是否和你的結(jié)果一樣:

  • 全局作用域中出現(xiàn)了三個變量:a、b、fun(函數(shù)名也是一個變量)
  • 在函數(shù)執(zhí)行前打印了全局作用域中的變量b,所以得到的是2
  • 調(diào)用函數(shù)并傳入?yún)?shù)值,開始執(zhí)行函數(shù)內(nèi)部代碼
  • 此時函數(shù)內(nèi)部變量a和b都提升到了函數(shù)作用域頂部,并且值都是undefined
  • 變量a被賦值4
  • 打印變量b,此時變量還沒有被賦值,所以得到的是undefined
  • 變量b開始被賦值,但遇到了兩個重名變量,最后一個變量會覆蓋之前的所有重名變量
  • 獲取變量a,還記得嗎?在執(zhí)行參數(shù)的時候給變量a賦值了4,所以我們獲得的也是4
  • 因為之前的變量b被后面的變量b覆蓋了,所以現(xiàn)在獲取變量b,獲得的是5
  • 函數(shù)內(nèi)部代碼執(zhí)行完畢,開始獲取變量b的值
  • 雖然函數(shù)內(nèi)部也有b變量,但那是屬于函數(shù)自己的,并且這個變量在函數(shù)執(zhí)行完后被銷毀了,所以我們只能獲取到全局作用域下的變量b,內(nèi)容是2

所以最終結(jié)果是:2、undefined、4、5、2。

全局變量

全局變量除了在最外層聲明,其實還有另外一種聲明方式,不過這種方式并不受推薦,所以了解就好:

var a = 1;  // 正常的聲明全局變量
function fun () {
    b = 2; // 變量名前面沒有寫var,默認成為全局作用域
};
// 因為函數(shù)還沒有執(zhí)行,所以這塊會報錯
console.log(b);  // b not defined
fun();
console.log(b);  // 2

三、let聲明

3.1 塊級作用域

相比于var變量,let顯得更加精致,因為它有自己的聲明準則,其中最大的區(qū)別就是let聲明的范圍是塊級作用域,那么什么是塊級作用域呢,其實很好理解:{}符號中的區(qū)域被稱為塊級作用域,需要注意的是這個區(qū)域?qū)ar并沒有影響。

塊級作用域和函數(shù)作用域相似,控制著內(nèi)部變量的讀取權(quán)限

{ // 塊級作用域
  let a1 = 2;
}
console.log(a1);  // 報錯:a1 is not defined

3.2 暫時性死區(qū)

在let創(chuàng)建之前的瞬間被稱為暫時性死區(qū),聽起來很高級,其實就是在暫時性死區(qū)階段訪問不到let變量的意思,因為let變量沒有變量提升這一說;let還有一個特點就是不能被重復(fù)聲明,也就是說let變量不會像var變量一樣可以聲明多個重名變量,在let變量這會報錯的。

{
    console.log(b);  // 因為沒有變量提升,所以在聲明前訪問不到該變量,報錯:annot access 'b' before initialization
    let b = 1;
}
let a = 1;
let a = 2;  // 重名變量會報錯:caught SyntaxError: Identifier 'a' has already been declared

let的全局作用域

雖然前面說let聲明的范圍是塊級作用域,但如果在最外層全局作用域里聲明let變量,也會被認為是合法的全局變量,與var變量不同的是let全局作用域不能通過window.變量名訪問。

for循環(huán)中的let和var

for循環(huán)過程中會不斷產(chǎn)生新的塊級作用域,這個時候var和let變量值迭代更新就有了不同的變化:

let arr = [1, 2, 3, 4, 5];
for (let i = 0; i < arr.length; i++) {};
console.log(i);  // 報錯:i is not defined
for (var i = 0; i < arr.length; i++) {};
console.log(i);  // 5

上面代碼中第一個循環(huán)內(nèi),使用let創(chuàng)建了一個變量,當(dāng)我們在循環(huán)體外訪問該變量時竟然報錯了!這是因為循環(huán)體使用了{},所以形成了塊級作用域,此時在塊作用域外訪問let變量肯定會報錯。當(dāng)我們訪問var變量的時候為什么沒有報錯呢?那是因為var變量不受塊級作用域影響,它成為了全局作用域。

四、const聲明

const聲明被稱為常量,為了更好理解,下文還是用變量進行介紹

const和let非常相似:不能聲明重名變量、存在暫時性死區(qū)、沒有變量提升、有塊級作用域限制。這些都是非常nice的規(guī)則,在此基礎(chǔ)上,const還增加了兩個規(guī)則:1、聲明時必須賦值;2、值不可修改;

聲明時必須賦值這個很好理解,就是在創(chuàng)建的時候必須給這個變量一個初始值。我們詳細說一下值不可修改這一點:

const a = '2';
a = 2; // 報錯a變量已經(jīng)聲明,不能重復(fù)創(chuàng)建:entifier 'a' has already been declared

上面代碼首先我們創(chuàng)建了const變量并為其賦值字符串類型的'2',在第二行代碼實際上是想把數(shù)字類型的2賦值給剛剛創(chuàng)建的const變量中,這時候確保錯了,由此可見const變量適合用在值不會變的場景。還有一種情況就是給const變量賦值數(shù)組和對象類型的值,因為這兩個數(shù)據(jù)類型屬于引用類型,所以只要在引用地址值不變的情況下,更改、新增、刪除對象或數(shù)組中的元素是不會報錯的。

總結(jié)

根據(jù)本篇文章的介紹,我們可以得出一個結(jié)論:盡量不用var,變量值需要變化的時候使用let,值不需要改變的時候使用const。

varletconst
變量提升××
重復(fù)聲明相同名稱變量××
是否可以更改變量值×
函數(shù)作用域××
塊作用域×

到此這篇關(guān)于js中var、let、const之間的區(qū)別的文章就介紹到這了,更多相關(guān)js var let const內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論