let和var一樣也是用來定義變數,不同之處在於let是塊級作用域,只在所定義的塊級作用域中生效,乙個花括號便是乙個塊級作用域
console.log(a);
//我是var定義的
console.log(b); //
b is not defined
可以看出let定義的變數在全域性作用域內並沒有生效
如果我們在全域性作用域中定義,試一下看在函式或者流程控制語句中是否會輸出
let a="我是let定義的"var b=0;
while(b<5)//
⑤我是let定義的變數
if(true)//
我是let定義的變數
我們發現這樣可以輸出
如果我們反向來一下呢
for(let i=0;i<5;i++)//0,1,2,3,4
console.log(a);
//a is not defined
console.log(b);
//流程控制語句中的var
for(var j=0;j<1;j++)//0
console.log(j);
//1
我們發現let定義的變數不會被提公升,只要有塊級括號存在,它就只在該塊級中有意義
如果在函式中呢
function test()() //報錯
我們發現並不能輸出
我們可以得出結論,流程控制語句中的變數均屬於全域性變數,但是在流程控制語句中的括號中定義則為塊級,不會提公升為全域性變數
for迴圈還有乙個特別之處,就是設定迴圈變數的那部分是乙個父作用域,而迴圈體內部是乙個單獨的子作用域
for(let i=0;i<3;i++)//abc,abc,abc
let在for迴圈宣告的變數每一次迴圈的值都會被引擎內部記下,但是var宣告的變數則會重新整理覆蓋掉上一次的值
var a=;for(var i=0;i<10;i++);}
console.log(a)
//[f,f,f,f,f,f,f,f,f,f]
a.foreach((e)=>)
//⑩10
我們可以看出,這種方式其實將未執行的函式push進陣列了,當每次呼叫時候發現此刻的i早已經被迴圈覆蓋掉,最終輸出都為此刻的i值10
var a=;for(let i=0;i<10;i++);}
console.log(a)
//[f,f,f,f,f,f,f,f,f,f]
a.foreach((e)=>)
//0,1,2,3,4,5,6,7,8,9
但是對於let宣告的變數,每一次引擎都會自動儲存記錄i的值,而不會覆蓋掉,因此每次輸出都是push當時的i值
let不存在變數提公升,只有在定義後再使用才不會報錯
console.log(a);var a=1;//undefined
console.log(b);let b=2;//
報錯
let具有強制性繫結變數的能力,原先var宣告的變數,當被let重新宣告的時候會被強制性繫結,原先var宣告的所有被let所管轄的塊級作用域裡的變數均被let強制為自己宣告的值,形成暫時性死區,let所處塊級作用域中let宣告之前的該變數均報錯
var a=1;//a is not defined
var a=1;
;console.log(a)//1
var a=1;
console.log(a);//1
;
let不允許在相同作用域內,重複宣告同乙個變數。
//報錯
//報錯
//報錯
//報錯
上面的最後乙個例子可以看出當再次宣告該變數之前呼叫的變數都會炸掉
我們可以看到let宣告的變數可以引用塊級作用域外面的函式
let a=f();function
f()console.log(a)//1
const宣告的變數為永恆變數,不能更改,而且宣告以後必須初始化
const a;//報錯const b=1;
b=2//
報錯
const的作用域與let命令相同:只在宣告所在的塊級作用域內有效。
const命令宣告的常量也是不提公升,同樣存在暫時性死區,只能在宣告的位置後面使用。
const宣告的常量,也與let一樣不可重複宣告。
const實際上保證的,並不是變數的值不得改動,而是變數指向的那個記憶體位址不得改動。對於簡單型別的資料(數值、字串、布林值),值就儲存在變數指向的那個記憶體位址,因此等同於常量。但對於復合型別的資料(主要是物件和陣列),變數指向的記憶體位址,儲存的只是乙個指標,const只能保證這個指標是固定的,至於它指向的資料結構是不是可變的,就完全不能控制了。因此,將乙個物件宣告為常量必須非常小心。
常量foo儲存的是乙個位址,這個位址指向乙個物件。不可變的只是這個位址,即不能把foo指向另乙個位址,但物件本身是可變的,所以依然可以為其新增新屬性。
const foo={};foo.prop=123;
console.log(foo.prop)
//123
常量a是乙個陣列,這個陣列本身是可寫的,但是如果將另乙個陣列賦值給a,就會報錯。
const a=;a.push(1);
console.log(a)
//[1]
console.log(a.length)//
1a=//
報錯
再來驗證以下引用
var a=1;b=a;
console.log(b);//1
a=2;
console.log(b)//1
b=3;
console.log(a)
//2
可以看出var定義的變數,b=a時候,是直接複製了乙份a,並不是a的引用
let a=1;b=a;
console.log(b);//1
a=2;
console.log(b);//1
b=3;
console.log(a);//2
console.log(b);//
3var b=4;
console.log(b)
//4
可以看出let也一樣
const也是複製乙份
const a=1;b=a;
console.log(b);//1
b=3;
console.log(a);//1
console.log(b);//
3var b=4;
console.log(b)
//4
ES6中let和const命令
es6中新增了 let 命令,用於宣告變數,關於let有以下幾個特點 1 用法類似於var,但是所宣告的變數只在 let 命令所在的 塊內有效,實現了塊級作用域且不會汙染全域性變數。2 不存在變數提公升 3 暫時性死區 4 同乙個變數在相同作用域內不允許重複宣告 下面圍繞這四個特點進行詳細的分析 l...
ES6學習 let和const命令
1.let命令 所宣告的變數命令所在 塊有效 a referenceerror a is not defined.b 1for迴圈的計數器,就很適合let命令 for let i 0 i arr.length i console.log i referenceerror i is not defin...
ES6 一 let和const命令
在js中是沒有塊級作用域的,var 宣告的變數作用域是整個函式體,而let可以起到這一作用 console.log b 2 console.log a a is not defind 而let可以起到這一作用啊在js中變數和函式的宣告會提公升到當前作用域最頂部執行。這樣就會出現問題。var a 函式...