做用域在js中是一個常常用到的概念,ES5中全局做用域和函數做用域。ES6中多了一個let,塊做用域。他能夠保證外層塊不受內層塊的影響。即內層塊造成了一個塊級做用域,這是let的一個特色。這樣即便函數或者類的內部和外部定義相同的變量,二者之間都不會影響。分析以前先看看下面的代碼:
var a=1;
function f1(){
var b=2;
function f2(){
var c=b;
b=a;
a=c;
console.log(a,b,c);
}
f2();
}
f1();//2,1,2閉包
上面的代碼,有三個執行上下文環境(EC),全局EC,f1EC,f2EC。全局環境下有一個變量a和一個函數f1(),在f1環境中,有一個變量b和一個函數f2(),在f2環境中有一個變量c。但在f2中,能夠訪問到f1環境中的b,也能夠訪問到全局環境中的a,在f1中,能夠訪問到全局環境下的a,但不能夠訪問f2中的c,在全局中,不能夠訪問f1中的b也不能夠訪問f2中的c.。這就是一個做用域鏈。ide
如今這個概念清晰了,做用域是函數的內部環境能夠經過做用域鏈訪問到全部的外部環境,可是外部環境卻不能夠訪問外部環境。函數
解釋完做用域,如今來解釋閉包,解釋以前先看一段代碼:作用域
var a=10;
function fn(){
var a=20;
return function b(){
console.log(a);
};
}
var g=fn();
g();//20it
閉包,容許使用內部函數(即函數定義和函數表達式位於另外一個函數的函數體內),並且,這些內部函數能夠訪問他們所在的外部函數中的聲明的全部局部變量丶參數和聲明的其餘內部函數,當其中一個這樣的內部函數在包含他們的外部函數以外被調用時,就會造成閉包。io
其實就是外部做用域要獲取內部做用域的變量或者方法。console