var和let的區別

2021-09-11 01:29:02 字數 3216 閱讀 9815

在es6中新增了let命令,用來宣告變數。它的用法類似於var,但是所宣告的變數,只在let命令所在的**塊內有效。

let:

let所在的區域會形成塊級作用域 ;

let不存在變數提公升的情況 ;

let會形成暫時性的死區;

不可以在同一作用域下重複宣告變數 。

var

在es6之前 都是用var 宣告變數,只有函式作用域和全域性作用域;

用var宣告,變數會提公升;

可以在同一作用域下多次宣告變數。

// 用var在for迴圈中宣告變數

var arr = ;

for (var i = 0;i < 10;i++)

}arr[4]();//10

arr[7]();//10

console.log(i);//在全域性作用域可以訪問到

上面**中,變數i是var命令宣告的,在全域性範圍內都有效,所以全域性只有乙個變數i。每一次迴圈,變數i的值都會發生改變,

在每次迴圈中全域性變數中i都會被重新賦值,導致執行時輸出的是都是最後一輪的i的值,也就是 10。

//用let宣告變數

var arr= ;

for(let i = 0;i < 10;i++)

}arr[6]();//6

arr[8]();//8

上面**中,變數i是let宣告的,當前的i只在本輪迴圈有效,所以每一次迴圈的i其實都是乙個新的變數,所以第一次輸出的是6。

如果每一輪迴圈的變數i都是重新宣告的,在js引擎內部會記住上一輪迴圈的值,初始化本輪的變數i時會在上一輪迴圈的基礎上進行計算。

另外,for迴圈還有乙個特別之處,就是設定迴圈變數的那部分是乙個父作用域,而迴圈體內部是乙個單獨的子作用域。

for(let i = 0;i < 3;i++)

console.log(i);//報錯不在當前作用域

for(var i =0;i < 3;i++)

console.log(i);//nan不是乙個number,說明i的值被改變

let不存在變數提公升的情況

console.log(a);//undefined

var a = 1;

console.log(b); //報錯

let b = 1;

上面**中,變數a用var命令宣告,會發生變數提公升,即指令碼開始執行時,變數a已經存在了,但是沒有值,所以會輸出undefined。

變數b用let命令宣告,不會發生變數提公升。這表示在宣告它之前,變數b是不存在的,這時如果用到它,就會報錯。

暫時性死區

(1) 只要塊級作用域內存在let命令,它所宣告的變數就「繫結」這個區域,不再受外部的影響。

var a = 0;

if (true)

上面**中,存在全域性變數a,但是塊級作用域內let又宣告了乙個區域性變數a,導致後者繫結這個塊級作用域,所以在let宣告變數前,對a賦值會報錯。es6明確規定,如果區塊中存在let和const(常量)命令,這個區塊對這些命令宣告的變數,從一開始就形成了封閉作用域。

凡是在宣告之前就使用這些變數,就會報錯。總之,在**塊內,使用let命令宣告變數之前,該變數都是不可用的。這在語法上,稱為「暫時性死區」。

if (true)
上面**中,在let命令宣告變數tmp之前,都屬於變數tmp的「死區」。

(2)「暫時性死區」也意味著typeof不再是乙個百分之百安全的操作。

typeof x; // 報錯

let x;

上面**中,變數x使用let命令宣告,所以在宣告之前,都屬於x的「死區」,只要用到該變數就會報錯。因此,typeof執行時就會報錯。

作為比較,如果乙個變數根本沒有被宣告,使用typeof反而不會報錯。

console.log(typeof haha) // "undefined"
上面**中,haha是乙個不存在的變數名,結果返回「undefined」。所以,在沒有let之前,typeof運算子是百分之百安全的,永遠不會報錯。現在這一點不成立了。

變數一定要在宣告之後使用,否則就報錯。有些「死區」比較隱蔽,不太容易發現。

function bar(x = y, y=2) 

let a =bar(); //報錯

console.log(a);

// 上面**中,呼叫bar函式之所以報錯(某些實現可能不報錯),是因為引數x預設值等於另乙個引數y,而此時y還沒有宣告,屬於」死區「。

function bar(x = 2, y=x) 

let a =bar();

console.log(a);

如果y的預設值是x,就不會報錯,因為此時x已經宣告了。

另外,下面的**也會報錯,與var的行為不同。

var x = x;//x提公升到當前作用域的最頂端,為undefined,然後給x賦值

// 報錯

let x = x;// 報錯: x is not defined

上面**報錯,也是因為暫時性死區。使用let宣告變數時,只要變數在還沒有宣告完成前使用,就會報錯。上面這行就屬於這個情況,在變數x的宣告語句還沒有執行完成前,就去取x的值,導致報錯」x 未定義。「es6 規定暫時性死區和let、const語句不出現變數提公升,主要是為了減少執行時錯誤,防止在變數宣告前就使用這個變數,從而導致意料之外的行為。這樣的錯誤在 es5 是很常見的,現在有了這種規定,避免此類錯誤就很容易了。總之,暫時性死區的本質就是,只要一進入當前作用域,所要使用的變數就已經存在了,但是不可獲取,只有等到宣告變數的那一行**出現,才可以獲取和使用該變數。

let不允許在相同作用域內,重複宣告同乙個變數

var a = 0;

let a = 3;//報錯

function func()

// 因此,不能在函式內部重新宣告引數。

function fn(arg)

function fn(arg) 形成了乙個新的作用域}}

fn()

let 和 var 的區別

1 作用域只侷限於當前 塊 if true console.log str console.log str1 str1 is not defined2 let宣告的作用於不會被提公升 console.log str var str 1 console.log str1 str1 is not def...

var 和 let 的區別

var 和 let 都是存在 函式作用域以及全域性作用域的 但是 let 多了乙個 塊級作用域 而 var 則可以對同乙個變數重複多次定義,每次定義取最新值 函式作用域 指的是,在函式裡面定義的變數只能在函式裡面使用,出了函式外面就undefined 全域性作用域 指的是,在全域性範圍下定義 不在函...

var 和 const 和let的區別

es5中是不存在塊級作用域的。在es6增加了const和let,可以實現塊級作用 js中有兩種作用域,全域性作用域和方法作用域 function getdate getdate console.log date reference error date在外面方法中訪問不到但是有個問題,只要在方法中定...