var、let、constjavascript
1、varjava
一、聲明函數
一直以來咱們都是經過var
關鍵字定義JavaScript變量。spa
var a = 10;
咱們能夠在其餘函數內部訪問相同的變量code
function f() { var a = 10; return function g() { var b = a + 1; return b; } } var g = f(); g(); // returns 11;
g
能夠獲取到f
函數裏定義的a
變量。 每當g
被調用時,它均可以訪問到f
裏的a
變量。 即便當g
在f
已經執行完後才被調用,它仍然能夠訪問及修改a。
blog
function f() { var a = 1; a = 2; var b = g(); a = 3; return b; function g() { return a; } } f(); // returns 2
二、做用域規則ip
對於熟悉其它語言的人來講,var
聲明有些奇怪的做用域規則。作用域
function f(shouldInitialize: boolean) { if (shouldInitialize) { var x = 10; } return x; } f(true); // returns '10' f(false); // returns 'undefined'
變量x
是定義在if
語句裏面,可是咱們卻能夠在語句的外面訪問它。 這是由於var
聲明能夠在包含它的函數,模塊,命名空間或全局做用域內部任何位置被訪問(咱們後面會詳細介紹),包含它的代碼塊對此沒有什麼影響。 有些人稱此爲var
做用域或函數做用域。 函數參數也使用函數做用域。開發
這些做用域規則可能會引起一些錯誤。 其中之一就是,屢次聲明同一個變量並不會報錯:it
function sumMatrix(matrix: number[][]) { var sum = 0; for (var i = 0; i < matrix.length; i++) { var currentRow = matrix[i]; for (var i = 0; i < currentRow.length; i++) { sum += currentRow[i]; } } return sum; }
這裏很容易看出一些問題,裏層的for
循環會覆蓋變量i
,由於全部i
都引用相同的函數做用域內的變量。 有經驗的開發者們很清楚,這些問題可能在代碼審查時漏掉,引起無窮的麻煩。
2、let
let
let hello = "Hello!";
一、塊做用域
let聲明一個變量,它使用的是 詞法做用域 或 塊做用域。不一樣於使用 var 聲明的變量那樣能夠在包含它們的函數外訪問,塊做用域變量在包含它們的函數外訪問,塊做用域變量在包含它們的塊或者for循環以外是不能訪問的。
a++; // illegal to use 'a' before it's declared; let a;
二、重定義及屏蔽
使用var
聲明時,它不在意你聲明多少次;你只會獲得1個。
function f(x) { var x; var x; if (true) { var x; } }
let
聲明就不會這麼寬鬆
let x = 10; let x = 20; // 錯誤,不能在1個做用域裏屢次聲明`x`
function f(x) { let x = 100; // error: interferes with parameter declaration } function g() { let x = 100; var x = 100; // error: can't have both declarations of 'x' }
3、const
一、聲明
它們與let
聲明類似,可是就像它的名字所表達的,它們被賦值後不能再改變。 換句話說,它們擁有與let
相同的做用域規則,可是不能對它們從新賦值。