var與ES6中const、let宣告的變數的區別
好久以前的研究,今天再來回顧一下。
首先我們比較一下使用var宣告的變數和不使用var宣告的變數的區別:
- 使用var宣告的變數宣告前呼叫,那麼該變數的值為undefined;不使用var宣告的變數宣告前呼叫直接報錯Uncaught ReferenceError:xxx is not difined;
- 使用var宣告的變數不可delete,不使用var宣告則可以delete掉釋放空間。(實則瀏覽器的垃圾回收機制也會清理掉用var宣告但是不再使用的的變數,比如某個僅執行一次的函式中被呼叫的某個var 宣告的變數)
- 未使用var宣告的變數實際上是window的一個物件,而使用var宣告的變數只是一個本地變數而已。
- 在使用'use strict'的模式之下,不使用var 宣告變數的語法是不被允許的,報錯:Uncaugth SyntaxError;
console.log(a); //undefined,這裡還涉及變數提升的概念
console.log(b); //報錯 Uncaught ReferenceError: b is not defined
var a = 1;
b = 2;
console.log(a); //1
console.log(b); //2
console.log(window.a); //undefined
console.log(window.b); //2
delete a;
delete b;
console.log(a); //1
console.log(b); //報錯 Uncaught ReferenceError: b is not defined,可見b在宣告前使用和宣告後delete再使用是一樣的結果
再來看下let,var,const宣告的變數的區別:- 看意思就知道,const是常量的意思,就是說只能被定義一次,且不可再改變,否則就會報錯:Uncaught TypeError: Assignment to constant variable.另外宣告前使用也會報錯:Uncaught ReferenceError: a is not defined;看一個例子:
這裡const定義一個foo之後,對其新增了屬性prop,隨後又對該屬性進行了修改,為什麼沒有報錯?那是因為常量foo本身儲存的是一個地址,該地址指向一個物件,不可變的是foo這個地址,即不能把foo指向另一個地址,但物件本身是可變的,所以依然可以為foo新增新屬性,改變新屬性值,而最後一行中嘗試改變foo的地址,就會報錯,如果要徹底將物件凍結,應該使用Object.freeze(obj)方法。同理,陣列也是一樣的:const foo = {}; foo.prop = 123; console.log(foo.prop); //123 foo.prop = 456; console.log(foo.prop); //456 const foo = {}; //Identifier 'foo' has already been declared
const group = []; group.push('Bob'); console.log(group[0]); //Bob group = ["Tom"];//Uncaught TypeError: Assignment to constant variable.
- var 和 let 就有意思了,let宣告的變數宣告前使用也會報錯,這個與const一致;最重要的一點是let宣告瞭一個塊級作用域的變數在一個塊的“}”結束的時候,該變數消失。例子:
(function(x,y){ var b = x; let c = y; if (true) { var b = 5; let c = 6; console.log(b); //5 console.log(c); //6,這裡的let c在下一行的"}"之後消失 } console.log(b); //5 console.log(c); //3 ,這裡仍然是第三行的let c; }(2,3));
- 再看一個例子:
所以說let是一個比較保守的變數。這裡變數為i的for迴圈中,i是一個全域性變數,array1[i]是一個console.log(i)的函式,而i的最終結果為10,故而每次呼叫array1[i],實際上都是console.log(10);而let作為僅在其程式碼塊有效的變數,當前的j僅在本輪的迴圈中有效,就是說每一次迴圈,j其實都是一個新產生的變數。所以let變數適合用於迴圈體中。var array1 = [],array2 = []; for(var i=0;i<10;i++){ array1[i] = function(){ console.log(i); }; } for(let j=0;j<10;j++){ array2[j] = function(){ console.log(j); }; } array1[6](); //10 array2[6](); //6
- 再看一個例子:
這個例子中tmp=2的賦值會報錯,因為if中的let對tmp變數的宣告,導致該tmp繫結了這個作用域,而let不會像var那樣“變數提升”,所以未宣告賦值會報錯。ES6中明確規定:如果區塊中存在let和const命令,則這個區塊對這些命令宣告的變數從一開始就形成了封閉做作用域,只要在宣告之前做任何使用,都會報錯。這在語法上稱為“暫時性死區”(temporal dead zone ,簡稱TDZ)。var tmp = 1; if(true){ tmp = 2; //ReferenceError let tmp; }
- 還有一點要注意,var宣告的變數為全域性變數,而let,const宣告的變數不為全域性變數,使用window訪問不到,如下:
var a = 1; console.log(window.a); //1 let b = 2; console.log(window.b) //undefined
相關文章
- var、let、const宣告變數的區別變數
- var、let、const變數宣告的區別及特點變數
- var與let宣告變數的區別變數
- es6 let const與var 的區別
- ES6中var,let,const的區別
- 變數和函式宣告提升,let和var const區別變數函式
- ES6中let和var和const的區別
- JavaScript中let、const、var 的區別JavaScript
- var、const、let 的區別
- ES6 --- 新的變數宣告方式 let 與 const 解析變數
- ES6中的let與var的區別
- JavaScript中的var、let 及 const 區別JavaScript
- 【ES6】var、let、const三者的區別
- var和let/const的區別
- var、let和const的區別
- var let const區別
- let const var 區別
- let,const,var區別
- 變數宣告帶var與不帶var的區別變數
- ES5 和 ES6:let const var 區別
- 深入理解ES6之var,let,const區別
- JavaScript 高階—— ES6新增語法 const(let const var區別)JavaScript
- 1.變數:var,let,const變數
- JavaScript 中的 Var,Let 和 Const 有什麼區別JavaScript
- JavaScript變數宣告帶var與不帶var區別JavaScript變數
- js中 let 與 var 的區別JS
- let與var的區別
- let var與const
- ES6之var、let、const
- 【前端面試】(四)JavaScript var let const的區別前端面試JavaScript
- TypeScript let與var的區別TypeScript
- let與const區別
- ES6 let和var的區別是什麼?
- var、let和const三者有哪些區別?
- var 和 let 的區別
- 1分鐘帶你瞭解var let 和 const 的區別
- js中var和let的快速區別JS
- 關於es6 let var const 以及Symbol的總結Symbol
- ES6-----for迴圈中setimeout,var與let的區別