1. let聲明變量只在let命令所在的代碼區內有效。html
1 "use strict"; 2 /*若是不加"use strict";會報錯:Uncaught SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode*/ 3 { 4 5 let a=10;//let 聲明變量,只在let命令所在的代碼塊內有效。 6 var b=66; 7 } 8 alert(b); 9 alert(a);//Uncaught ReferenceError: a is not defined
2. es6
1 for //循環計數器,很適合使用let命令。 2 3 for(let i=0;i<10;i++){ 4 //... 5 } 6 console.log(i);//Uncaught ReferenceError: i is not defined 7 //上面代碼中,計數器i只在for循環體內有效,在循環體外引用就會報錯。 8 9 var a=[]; 10 //變量i時var聲明的,在全局範圍內有效,每次循環,變量i的值都會發生改變,而循環內被賦給數組a的函數內部的console.log(i),這裏的i指向的就是全局的i,全部數組a的成員裏面的i,指向的都是同一個i,致使運行時輸出的是最後一輪i的值,也就是10. 11 for(var i=0;i<10;i++){ 12 a[i]=function(){ 13 console.log(i); 14 }; 15 } 16 a[6](); 17 18 19 20 var a=[]; 21 for(let i=0;i<10;i++){ 22 // 變量i是用let聲明的,當前的i只在本輪循環有效,全部每一次循環的i其實都是一個新的變量,全部最後輸出是6.每輪循環的變量的i都是從新聲明的,JavaScript引擎內部會記住上一輪循環的值,初始化本輪的變量i時,就是上一輪循環的基礎上進行計算。 23 a[i]=function(){ 24 console.log(i); 25 }; 26 } 27 a[6]();//6 28 29 30 //for循環的特別之處,設置循環變量的那一部分是一個父做用域,而循環體內部是一個單獨的子做用域。 31 for(let i=0;i<3;i++){ 32 let i='abc'; 33 console.log(i);//輸出三次abc。這代表函數內部的變量i與循環體變量i不在同一個做用域,有各自單獨的做用域。 34 }
3. 不存在變量提高。數組
1 console.log(foo);//undefined 2 var foo=2; 3 4 console.log(foo); 5 let foo=2;//Uncaught ReferenceError: foo is not defined 6 7 //暫時性死區:在代碼塊內,使用let命令聲明變量以前,該變量都是不可用的,這在語法上,成爲「暫時性死區(temporal dead zone,TDZ)」,暫時性死區的本質就是,只要一進入當前做用域,所要使用的變量就已經存在了,可是不可獲取,只有等到聲明變量的那一行出現,才能夠獲取和使用該變量。 8 9 //只要塊級做用域內存在let命令,它所聲明的變量就"綁定"這個區域,再也不受外部的影響。 10 var tmp=123; 11 if(true){ 12 tmp='abc'; 13 let tmp;//Uncaught ReferenceError: tmp is not defined,ES6明確規定,若是在區塊中存在let和const命令,這個區塊對這些命令聲明的變量從一開始就造成了封閉做用域。凡是在聲明以前就使用這些變量,就會報錯。 14 } 15 16 if (true) { 17 // TDZ開始 18 tmp = 'abc'; // ReferenceError 19 console.log(tmp); // ReferenceError 20 21 let tmp; // TDZ結束 22 console.log(tmp); // undefined 23 24 tmp = 123; 25 console.log(tmp); // 123 26 } 27 28 //較隱蔽的暫時性死區。 29 function bar(y = x, x = 2 ) { 30 return [x, y]; 31 } 32 bar(); // es6.html:89 Uncaught ReferenceError: x is not defined 33 console.log(bar()); 34 35 function bar(x=2,y=x){ 36 return [x,y]; 37 } 38 bar(); 39 console.log(bar());//[2, 2] 40 41 var x=x;//不報錯 42 43 let x=x;//es6.html:103 Uncaught ReferenceError: x is not defined
4. 不容許在相同做用域內,重複聲明同一個變量ide
1 //let不容許在相同做用域內,重複聲明同一個變量 2 //所以,不能再函數內部從新聲明參數。 3 4 //報錯 5 function(){ 6 let a=10; 7 var a=1; 8 } 9 10 // 報錯 11 function(){ 12 let a=10; 13 let a=1; 14 } 15 16 function func(arg){ 17 let arg;//報錯,identifier top has already been declared標識符頂部已被聲明 18 } 19 func(4); 20 21 function func(arg){ 22 { 23 let arg; 24 console.log(arg);//沒有報錯,undefined 25 } 26 } 27 func(4);
5. ES6的塊級做用域函數
1 //ES6的塊級做用域 2 function f1(){ 3 let n=5; 4 if(true){ 5 let n=10; 6 } 7 console.log(n);//5 8 } 9 f1(); 10 11 12 //ES5只有全局做用域和函數做用域,沒有塊級做用域。 13 function f1(){ 14 var n=5; 15 if(true){ 16 var n=10; 17 } 18 console.log(n);//10 19 } 20 f1(); 21 22 //塊級做用域的出現,實際上使得得到普遍應用的當即執行函數表達式(IIFE)再也不必要了。 23 // IIFE 寫法 24 (function () { 25 var tmp = ...; 26 ... 27 }()); 28 29 // 塊級做用域寫法 30 { 31 let tmp = ...; 32 ... 33 } 34 35 36 function f() { console.log('I am outside!'); } 37 38 (function () { 39 function f() { console.log('I am inside!'); } 40 if (false) { 41 } 42 f(); 43 }());