# let、const、var的區别 ###### tags:`javascript` 不要用var,如果該變數會變,就用let,不變就用const。 ### var * 變數宣告 * 宣告時沒指定初始值也不會抱錯 * 可以重複宣告改值 * 容易被覆蓋 * 函式作用域(function scope):只能以函式為變數作用域的分界,在一些使用了區塊語句(用花括號的語句)的像if, else, for, while等等區塊語句中,會讓變數曝露到全域之中可被存取 * 變數提升:會替即將宣告的變數保留記憶體位置,若未宣告該變數,==會回傳undefind== * 用var宣告全域變數,會成為window的屬性,但let和const不會。 ```javascript= var star="**" var arr=3 var star="***"//可以重複宣告改值 ``` --- ### let * 變數宣告,用在for迴圈 * let 在宣告的時候可以不用給值,若無初始值預設會給undefine * 不允許重複宣告 * ==區塊作用域(block scope)== :以區塊語句為分界的作用域,它會比較明確而且不易發生錯誤。 * 變數提升:==宣告前不允許使用(暫時性死區)== 不讓開發者在「提升之後」到「賦值之前」的這段期間提取變數。==若未宣告該變數,會回傳錯誤== ```javascript= let star="**" let arr=3 let star="***"//Uncaught SyntaxError: Identifier 'fruit' has already been declared翻譯:let的"變數"不能定義兩次 ``` --- ### const數字(常數) * 常數宣告,用在function解構=賦值 * ==⼀開始宣告時⼀定要給初始值== * ==不允許重複宣告給值==但==物件跟陣列跟函式==的宣告,因為裡⾯記錄的是「地址」,類似於某⼤樓的地址,如果改變裡⾯的成員並不會更動到地址,所以==可以改變裡面的值==,所以對於物件、陣列、函式來說,使用const常數來宣告 * 區塊作用域(block scope):以區塊語句為分界的作用域,它會比較明確而且不易發生錯誤。 * 變數提升==宣告前不允許使用(暫時性死區)== 不讓開發者在「提升之後」到「賦值之前」的這段期間提取變數。==若未宣告該變數,會回傳錯誤== ```javascript const pi=3.14; console.log(pi); pi=3.1422; //x const變數只能給一次值且一定要給值 console.log(pi); const a = [] a[0] = 1//可以改變裡面的值 const b = {} b.foo = 123//可以改變裡面的值 ``` ==函式表達式只能使⽤const宣告== ```javascript= const foo = function() { } ``` --- ## var 與 let 的差別 var 與 let 的差別 1. 塊級區域function scope&block scope 1. 變數提升 1. 不允許重複宣告 ### 塊級區域scope 是變數可以被取用的區域 * var是函式作用域function scope: 函式會建立自己的作用域,其內的識別字(不管是變數、函式)僅能在這個函式裡面使用。 ```javascript var a=1; if(true){ var b=2; } console.log("a",a)//a 1 console.log("b",b)//b 2 ``` ==變數 b使用var宣告,var是函式作用域,所以拿得到值== * let與const是區塊作用域block scope: 由一組大括號包起來的範圍,變數範圍只會存在大括號裡 ```javascript let a=1; if(true){ let b=2;//block scope console.log("a",a)//a 1 console.log("b",b)//b 2 } console.log("a",a)//a 1 console.log("b",b)//undefined,變數b在大括號內定義有值,在大括號外定義是沒有值的 ``` ==變數 b使用let宣告,b的變數範圍只會存在這個大括號裡,所以在區塊作用域外拿不到值== ### 變數提升(hoisting) 在JavaScript 中另一件有關變數不常見的事, 是你可引用一個較晚宣告的變數並且不會有異常。這個概念被稱為「提升(hoisting)」; 變數在 JavaScript 中是「被提升(hoisted)」或「被抬至(lifted)」到函式(function)或陳述式(statement)的頂部。 然而,==被提升(hoisted)的變數將返回一個未定義的值(undefined)==。所以即使你在使用或者引用這個變數之後才宣告和初始化它,它仍然會返回它是一個未定義的值(undefined)。 * var 如果我們是後定義,==var會自動幫我們定義undefined== ```javascript console.log("a",a)//undefined //如果我們是後定義,var會自動幫我們定義var a; console.log("c",c)//not defined //沒有定義這個變數c var a=1; if(true){ var b=2; } ``` * let比較嚴謹 不能先執行才定義這個變數,變數要先定義才能執行 ```javascript console.log("a",a)//Cannot access 'a' before initialization //我還沒執行這一段之前你不能使用這個變數 console.log("c",c)//not defined //沒有定義這個變數 let a=1; if(true){ let b=2; } ``` ### 不允許重複宣告 * var可以重複宣告 ```javascript var a=1; var a=5; if(true){ var b=2; } console.log("a",a)//a 5後面宣告的5把前面宣告的值蓋掉了 console.log("b",b)//b 2 ``` * let不可以重複宣告 ```javascript let a=1; let a=5; if(true){ let b=2; } console.log("a",a)//Identifier 'a' has already been declared不允許重複宣告 console.log("b",b)//undefined,不再作用域裡 ``` (5)暂时性死区: 在使用let、const命令==声明变量之前,该变量都是不可用的==。这在语法上,称为暂时性死区。使用==var不存在暂时性死区==。 (6)初始值设置: 在变量声明时,==var 和 let 可以不用设置初始值==。而==const声明变量必须设置初始值==。 (7)指针指向: let和const都是ES6新增的用于创建变量的语法。 let创建的变量是可以更改指针指向(==可以重新赋值==)。但const声明的变量是不允许改变指针的指向(==不可以重新赋值==)。 作者:CUGGZ 链接:https://juejin.cn/post/6940945178899251230 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 --- ## 作用域 ### var函式作用域: 超過function就不會作用 ```javascript var a=1; var a=5; if(true){ var b=2; } function showVar(){ var c=3 console.log("c",c)//c 3 } showVar()呼叫 console.log("a",a)//a 5 var可以重複宣告 console.log("b",b)//b 2 function作用域 console.log("c",c)//c not defined函式作用域var只要超過函式function的範圍就無法執行 ``` ### let區塊作用域: 超過區域的大括號就不會作用 ```javascript let a=1; if(true){ let b=2; console.log("a",a)//1 console.log("b",b)//2 } function showVar(){ let c=3 console.log("c",c)//3 } showVar() console.log("a",a)//1 console.log("c",c) c is not defined ``` * 全域變數global variable * 區域變數local variable ```javascript var a=1;//global variable var c=5;//global variable if(true){ var b=2;//local variable } function showVar(){ var c=3//function scope console.log("inside c",c)//inside c 3 } showVar() console.log("a",a)//1 console.log("b",b)//2 console.log("outside c",c)//outside c 5 ``` ```javascript let a=1;//global variable let c=5;//global variable if(true){ let b=2;//local variable console.log("a",a)//1 console.log("b",b)//2 } function showVar(){ let c=3;//function scope console.log("inside c",c)//inside c 3 } showVar() console.log("a",a)//1 //console.log("b",b) console.log("outside c",c)//outside c 5 //let在同一個作用欲下不可以使用同一個變數,在不同作用愈可以使用同一個變數 不用擔心全域變數去影響到區域變數 ``` 前面沒有var.let的d ```javascript var a=1; var c=5; var d=9; if(true){ var b=2; } function showVar(){//函式作用域function scope var c=3;//區域變數//local variable d=12;//全域變數前面沒有var.let console.log("inside c",c)//印出inside c 3 console.log("inside d",d)//印出inside d 12 } showVar() console.log("a",a)//a 1 console.log("b",b)//b2 console.log("outside c",c)//印出outside c 5 console.log("outside d",d)//印出outside d 9變成12 d12前面沒有var.let是全域變數,所以這個值會去覆蓋存取前面的全域變數的d ``` [JavaScript基本功修練:Day5 - 宣告變數 - let、const、var](https://ithelp.ithome.com.tw/articles/10240708)