一看就懂的var、let、const三者區別

哈嘍你們好,又見面啦,我依舊是那個可愛的蛙人。java

今天又週五了啊,划水人的一天,開心。安全

話很少說哈,直接摟代碼函數

var 變量提高機制

咱們在全局做用域中或仍是在局部做用域中,使用var關鍵字聲明的變量,都會被提高到該做用域的最頂部,這就是咱們常說的變量提高。指針

function person(status) {
    if (status) {
        var value = "蛙人" 
    } else {
        console.log(value) // undefined
    }
    console.log(value) // undefined
}
person(false)

上面example中,if代碼塊中的var聲明的變量就被提高到了函數的頂端,有的小夥伴就會疑惑了,if代碼塊裏的都沒執行,怎麼會提高到頂端了呢?,這是由於javaScript引擎,在代碼預編譯時,javaScript引擎會自動將全部代碼裏面的var關鍵字聲明的語句都會提高到當前做用域的頂端, 所以上面的代碼就會被解析爲下面。code

function person(status) {
    var value;
    if (status) {
        value = "蛙人" 
    } else {
        console.log(value) // undefined
    }
    console.log(value) // undefined
}
person(false)

因爲javaScript存在變量提高,這讓不少開發者初學起來這門語言,還得花很多時間研究變量提高,也有時在工做中由於一個變量提高致使出bug。所以Escript6中爲咱們帶了塊級聲明,那麼什麼是塊級聲明呢?對象

  • 只在當前函數下聲明的變量有效
  • 在代碼塊和{ }括號以內有效

let聲明

let聲明和var聲明用法是同樣,都是定義變量,使用let聲明的變量沒有var那樣的變量提高,let聲明的變量只在當前做用域中有效。咱們來把上面的example重寫一下。ip

function person(status) {
    if (status) {
        let value = "蛙人" 
    } else {
        console.log(value) // 報錯
    }
    console.log(value) // 報錯
}
person(false)

let是塊級做用域,全部外面的語句塊訪問不到,let是沒有變量提高的,下面咱們來演示一下。作用域

console.log(value) // 報錯
let value = "蛙人"

禁止重複聲明

若是在同一個做用域中某個變量已經存在,再次使用let關鍵字聲明的話會報錯。開發

var value = "蛙人"
let value = "蛙人" // 報錯

// 再來看一下不一樣做用域的狀況

var value = "蛙人" // 全局做用域
if(true) {
	let value = "蛙人" // 代碼塊中聲明,毫無影響
}

上面example中,能夠徹底看到,只有在相同做用域中重複聲明變量纔會報錯。io


const聲明

ECMAscript6中還提供了const關鍵字聲明,const聲明指的是常量,常量就是一旦定義完就不能修改的值。還有一點須要注意的是,常量定義必須初始化值,若是不初始化值就會報錯。

const value = "蛙人"
const age; // 報錯 常量未初始化

const 與 let

const與let也沒什麼大不一樣,都是塊級做用域,const常量也只會在當前代碼塊內有效,也不能在當前做用域中重複定義相同的變量,也不存在變量提高。

if (true) {
    const name = "蛙人"
}
console.log(name) // 報錯 訪問不到內部變量
console.log(value) // 報錯 const聲明的變量也不存在變量提高
const value = "蛙人"
let value = "蛙人"
const value = "蛙人" // 報錯 重複聲明

const聲明對象

雖然const變量不能修改指針,可是能夠修改值,好比咱們定義一個對象,咱們就能夠修改對象裏的屬性值,可是不能夠重寫整個對象。

const person = {
    name: "蛙人",
    age: 23
}
person.age = 18 // 沒問題
person = {} // 報錯 不能修改對象指針

暫時死區

跟var相比,let和const定義變量不會被提高到做用域頂端,即使是用相對安全的typeof也會出現錯誤。

console.log(typeof value)
let value = "蛙人"

上面example中,console.log(typeof value)會拋出錯誤是由於用let定義並初始化變量語句是不會執行的。此時的value仍是處於在JavaScript所謂的暫時死區(temporal dead zone)簡稱爲TDZ 中,雖然JavaScript沒有明確標準TDZ,可是人們經常使用它描述let和const定義的變量不會提高。<br>

咱們來講一下TDZ工做原理,JavaScript引擎在掃描代碼時發現變量聲明時,若是遇到var就會將它們提高到當前做用域的頂端,若是遇到let或const就會將聲明放到TDZ中,若是訪問TDZ中的變量就會拋出錯誤,只有執行完TDZ中的變量纔會將它移出,而後就能夠正常方法。這機制只會在當前做用域生效。咱們來看下不一樣做用域案例

console.log(typeof value)  // "undefined"
if (true) {
    let value = "蛙人"
}

上面說的若是變量是let和const聲明的就會被放到TDZ中,前提是隻會針對當前做用域內有效。因此上面代碼中console.log(typeof value)不會拋出錯誤,let聲明只會在當前的語句中有效。

var let const 最大的區別

var在全局做用域聲明的變量有一種行爲會掛載在window對象上,它會建立一個新的全局變量做爲全局對象的屬性,這種行爲說不定會覆蓋到window對象上的某個屬性,而let const聲明的變量則不會有這一行爲。來看下面例子。

var value1 = "張三"
let value2 = "李四"
const value3 = "王五"
console.log(window.value1) // 張三
console.log(window.value2) // undefined
console.log(window.value3) // undefined

咱們的講解就到這裏,下次見。

以爲寫得不錯的話,請用大家發財的小手點個贊叭!

相關文章
相關標籤/搜索