vo ao 的解釋
1. 作用域
es5中只有全域性作用域和函式作用域,我們都知道他沒有塊級作用域。
es6中多了乙個let,他可以保證外層塊不受內層塊的影響。即內層塊形成了乙個塊級作用域,這是let的乙個特點。
var a=1;function f1()
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。這就是乙個作用域鏈。
函式的內部環境可以通過作用域鏈訪問到所有的外部環境,但是外部環境卻不可以訪問外部環境,這就是作用域的關鍵。但是我們要知道,作用域是在乙個函式建立時就已經形成的,而不是呼叫時。
var a=10;function fn();
}var g=fn();
g();
//20
此圖說明了作用域鏈向上查詢是尋找建立它的那個作用域。
2. 閉包
「閉包,允許使用內部函式(即函式定義和函式表示式位於另乙個函式的函式體內),而且,這些內部函式可以訪問他們所在的外部函式中的宣告的所有區域性變數丶引數和宣告的其他內部函式,當其中乙個這樣的內部函式在包含他們的外部函式之外被呼叫時,就會形成閉包。即內部函式會在外部函式返回後被執行。而當這個內部函式執行時,它仍然必須訪問其外部函式的區域性變數丶引數以及其他內部函式。這些區域性變數丶引數和函式宣告(最初時)的值是外部函式返回時的值,但也會受到內部函式的影響。」
簡單來說,就是在乙個函式a內部定義的另乙個函式b,當b在a之外被執行時,就會形成閉包。同時b函式仍然可以訪問到a函式中的區域性變數與函式。
function fn()}return
array;
}fn();
//[ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ]
閉包儲存的是定義它的那個函式內部的區域性變數丶引數和其他內部函式,也就是說儲存的是這個函式執行上下文中的整個vo,而不是乙個變數。上面**中的函式作用域鏈中都儲存著fn的活動物件,他們引用的都是乙個i,當fn返回時,i的值是10,所以每個函式都引用儲存i那個變數的同乙個變數。我們如果想得到原先想得到的那個結果,可以加上另乙個匿名函式改變他的父作用域(其實應該是建立它的作用域),將它包裹起來。
function fn();}(i);
}return
array;
}
這個匿名函式有乙個引數num,同時是返回值。在呼叫每個匿名函式時,傳入了變數i。由於引數是按值傳遞的,所以i就會複製給num,而這個匿名函式的內部又建立了乙個訪問num的閉包,返回後能夠訪問到該匿名函式中的vo變數物件(variable object)(包括引數),於是每個函式返回的都是num的乙個副本,所以可以得到不同的值。
閉包的兩個場景;
1. 函式作為函式的返回值
function f()}var g=f();
g();
//1;
2. 函式作為引數傳遞
function f()}var g=f();
g();
//1;
function f(fn)
f(g);
//1
上面兩個小例子也正好說明了閉包可以訪問定義它的那個函式作用域下的內部變數和內部函式。其實是整個vo變數物件(variable object),所以還包含引數。
作用域與閉包
執行上下文 範圍 一段或者乙個函式 全域性 變數定義 函式宣告 一段 函式 變數定義 函式宣告 this arguments 函式 ps 注意 函式宣告 和 函式表示式 的區別 console.log a var a 100 fn zhangsan function fn name this thi...
作用域與閉包
變數存在並產生作用的環境上下文。在es5規範中只有兩種作用域 函式可以巢狀,而每個函式都有自己的作用域,當進入乙個函式的時候,函式環境就會被壓入乙個環境棧當中,當函式執行完畢之後又會出棧,將控制權轉交給外面一層的函式。內部呼叫外部 var a 3 function add add console.l...
js 作用域和閉包
作用域應用的特色情況,有兩種表現 自由變數的查詢,在函式定義的地方,向上級作用域查詢不是在執行的地方 函式作為返回值 function create const fn create const a 200 fn 100 函式作為引數 function print fn const a 100 fun...