咱們首先來回顧一下,咱們在客戶端瀏覽器學的關于作用域的東西,回憶一下,作用域有幾種當時學的?恩,對,有二種,一種叫全局作用域,一種叫函數(shù)作用域,也叫局部作用域:
<script>
var a = 123;//這個變量a是全局級別的作用域
var fn = function(){//函數(shù)fn屬于全局作用域級下面的函數(shù)
//這里是屬于局部作用域,下面的a,b變量是屬于當前這個局部作用域的變量
var a = 234;
var b = 344;
}
</script>
關于全局作用域的變量或函數(shù)使用原則是:'''代碼從上往下執(zhí)行,只要在上面的代碼定義過某全局變量或函數(shù),那么在任何地方都可以使用這個全局的變量或函數(shù)'''。
關于局部作用域的變量或函數(shù)使用原則是:'''當前這個函數(shù)被調(diào)用或叫被使用的時候,在當前局部作用域里定義的變量可以在當前作用域被使用,超出這個作用域范圍之后是訪問不到這個變量或函數(shù)的'''。
<script>
var a = 100;
var fn = function(){
console.log("fn函數(shù)被調(diào)用");
}
var fn1 = function(){
var b = 123;
console.log(b);//b是屬于當前這個函數(shù)級作用域
console.log(a);//在函數(shù)級作用域里也可以使用全局變量a
fn();//在函數(shù)級作用域里也可以使用全局函數(shù)fn
}
fn1();
console.log(b);//會報錯,因為我們只有在fn1函數(shù)級作用域里定義過變量b
</script>
另外,不是說在局部作用域里定義的變量或函數(shù)就一定是屬于當前這個作用域,我們還可以通過代理global的全局最大對象window來在局部作用域里面定義全局變量或函數(shù):
<script>
var fn = function(){
window.a = 123;
window.fn1 = function(){
console.log("fn1函數(shù)被調(diào)用");
}
}
fn();
console.log(a);//結(jié)果是123
fn1();
</script>
當然,作用域嵌套作用域的情況又會產(chǎn)生一個好玩的東西叫閉包:
<script>
function fn(a){
var b = 100;
var fn1 = function(){
b++;
console.log(a + b);
}
return fn1;
}
var myFn = fn(100);
myFn();
myFn();
</script>
到此為止咱們就復習完了咱們的客戶端瀏覽器端學習的作用域的知識,現(xiàn)在咱們再繼續(xù)學一些其他類型的作用域的知識:
咱們來看一下咱們的node.js,在咱們的node.js里面學過一個東西叫模塊,模塊的思想其實是來源于生活的,咱們在平時的情況下有時候處理一個東西太復雜了,不太好研究,咱們會習慣性的把這個事物這個東西分成一塊一塊的來研究,最常見的就是比如人,咱們就會把一個人分為免疫系統(tǒng)、血液系統(tǒng)等各個系統(tǒng),或者像咱們的汽車,咱們會把它分成發(fā)動機啊、車胎啊之類的。在咱們的node.js這個平臺里面,咱們會把一個js文件(node文件、json文件)當成一個模塊。這時候就會出現(xiàn)一種新的作用域叫模塊級別的作用域。
然后,除了模塊級作用域之外,在ES3和ES5里面,咱們想定義一個變量一般會采用的是:
var a = 100;
但是這樣定義一個變量會有問題的,什么情況下會出現(xiàn)問題呢?咱們可以看一下面的這段代碼:
"use strict";
if(false){
var a = 1;
}
console.log(a);
雖然if里的條件表達式的值是false,但是咱們打印a卻不會報錯,結(jié)果是undefined,這個原因在這里也不細究了(大家可以復習一下預解析相關的知識點的內(nèi)容)。
所以,為了避免這個問題,在ES6中就有了一個新的用來定義一個變量的關鍵字叫l(wèi)et,比如下面的這段代碼:
"use strict";
if(false){
let a = 1;
}
console.log(a);
這個時候就會報錯,因為這時候不會有一個變量叫a,因為不存在變量作用域提升了。不但如此,咱們再看一段代碼如下:
"use strict";
if(true){
let a = 1;
}
console.log(a);
這段代碼 也是報錯,這個原因就是因為如果用了let關鍵字以后呢,就會出現(xiàn)一種新的作用域叫塊級作用域,塊級作用域只會存在于當前這個花括號內(nèi)部。
塊級作用域和let個人覺得最有用的應該是在好多情況下本來需要閉包,現(xiàn)在不需要了,可以簡化代碼:
"use strict";
for(let i=0;i<5;i++){
setTimeout(function(){
console.log(i);
},100);
}