總結下var、let 和 const 的區別

前言

var 和 let 的區別是老生常談,看到網上一些文章的總結,有的不太全面,甚至有的描述不太準確,在這裏儘可能全面的總結下這三者的區別。es6


let 是 ES6新增的變量類型,用來代替 var 的一些缺陷,跟 var 相比主要有如下區別:瀏覽器

1. let 使用塊級做用域

在 ES6以前,ES5中js只有全局做用域和函數做用域,例如:ide

if(true) {
   var a = 'name'
}
console.log('a',a) // name

做用域是一個獨立的地盤,讓變量不外泄出去,可是上例中的變量就外泄了出去,因此此時 JS 沒有塊級做用域的概念。函數

var a = 1;
function fn() {
   var a = 2;
   console.log('fn',a);
}
console.log('global',a);
fn();

全局做用域就是最外層的做用域,若是咱們寫了不少行 JS 代碼,變量定義都沒有用函數包括,那麼它們就所有都在全局做用域中。這樣的壞處就是很容易衝突。
ES6中加入塊級做用域以後:設計

if(true) {
   let a = 'name'
}
console.log('a',a) // Uncaught ReferenceError: a is not defined

塊做用域內用 let 聲明的變量,在塊外是不可見的,若是引用的話就會報錯。code

2. let 約束了變量提高而不是沒有變量提高

在 js 中變量和函數都會提高:對象

function fn() {
   console.log('a',a);
   var a = 1;  // undefind
}
fn()

a其實已經在調用前被聲明瞭,只是沒有被初始化。JavaScript會把做用域裏的全部變量和函數提到函數的頂部聲明,至關於:ip

function fn() {
   var a;
   console.log('a',a);
   a = 1;  // undefind
}
fn()

JavaScript會使用undefined缺省值建立變量a,事實上瀏覽器並無把聲明語句放到做用域的頂部,在編譯階段,控制流進入域,該域全部的變量和函數的聲明先進入內存,文中代碼的相對位置不會變更。內存

變量提高指的是變量聲明的提高,不會提高變量的初始化和賦值。作用域

而且函數的提高優先級大於變量的提高:

function fn() {
            console.log('a', a);
            var a = 1;
            function a () {
                console.log('I am a function');
            }
        }
        fn() // ƒ a () {console.log('I am a function');}

在上例中, let 聲明的變量的做用域以外引用該變量會報錯,可是否可理解爲 let 沒有變量提高?

let a = 'outside';
if(true) {
   console.log(a);//Uncaught ReferenceError: a is not defined
    let a = "inside";
}

報出錯誤 a 沒有被定義,而不是引用了全局做用域裏的 a,說明 let 聲明的 a 也被提高了。

緣由是 let 設計中的暫時性死區:
當前做用域頂部到該變量聲明位置中間的部分,都是該let變量的死區,在死區中,禁止訪問該變量。由此,咱們給出結論,let聲明的變量存在變量提高, 可是因爲死區咱們沒法在聲明前訪問這個變量。

3. let 禁止重複聲明變量

使用 var 能夠重複聲明變量,可是 let 不容許在同一塊做用域內重複聲明同一個變量:

function fn (){
   var a = 1;
   let a = 2;
   console.log(a); //SyntaxError
}

function fn (){
   let a = 1;
   let a = 2;
   console.log(a); //SyntaxError
}

function fn (a){
   let a = 2;
   console.log(a); //SyntaxError
}

上述代碼會報語法錯誤;

4. let不會成爲全局對象的屬性

咱們在全局範圍內聲明一個變量時,這個變量自動成爲全局對象的屬性(在瀏覽器和Node.js環境下,這個全局對象分別是windowglobal),但let是獨立存在的變量,不會成爲全局對象的屬性:

var a = 1;
console.log(window.a); //1

let b = 2;
console.log(window.b); // undefined

5. const 聲明的常量

以上 let 的規則一樣適用於 const,可是跟 let 的區別是 const 聲明的變量不能從新賦值,因此 const 聲明的變量必須通過初始化

const a = 1;

a = 2; // // Uncaught TypeError: Assignment to constant variable
const b; // Uncaught SyntaxError: Missing initializer in const declaration

最後

以上大概是總結後的內容,看來,仍是多用 let 、const 吧。

參考資料: http://es6.ruanyifeng.com/#do...
相關文章
相關標籤/搜索