[JavaScript]JavaScript中的函數(2)
阿新 • • 發佈:2018-08-27
ron 總結 href 尋找 tro http cal con 如果
承接上一篇博文的總結,這篇博文是利用代碼+畫圖的形式,梳理一下對於函數作用域和閉包的理解。
函數中的作用域
在 JavaScript 中, 對象和函數同樣也是變量。
在 JavaScript 中, 作用域為可訪問變量,對象,函數的集合。
首先我們聲明一個函數,然後在函數內部聲明並賦值一個變量:
function fn(){
var x = 3
console.log(x)
}
fn.call() //3
在函數fn中就產生了一個作用域,要求打印x的值時,函數就會在自身內部尋找這個x,然後把結果打出來。
在函數內部再次聲明一個函數的話,情況會變成什麽樣呢:
function fn(){ var x = 3 // console.log(x) function fn1(){ var x = 4 console.log(x) } fn1.call() } fn.call() //4
函數fn1在fn作用域內創造了一個子作用域,打印的時候不使用fn中的變量x,而是使用了這個子作用域內的變量x。
如果fn1中沒有聲明變量x,他會打印出什麽呢?
function fn(){
var x = 3
function fn1(){
console.log(x)
}
fn1.call()
}
fn.call() //3
他會去尋找fn中的x,然後把他打印出來。
如果函數fn作用域內也不存在這個變量呢?
var x = 5 function fn(){ function fn1(){ console.log(x) } fn1.call() } fn.call() //5
由此可以看出:在調用函數作用域(fn1)中的某個變量(x)時,他會先在自身作用域中尋找這個變量;如果這個變量沒有找到,那麽這個函數可以訪問上一級作用域(fn)中的變量(x);如果這個變量還沒有找到,那麽這個函數可以訪問更上一級,即全局作用域(window)中的x。
註意
在理解作用域的同時,我們要十分註意變量提升的問題。
比如:
function fn(){
function fn1(){
console.log(x)
var x = 5
}
fn1.call()
}
fn.call() //undefined
為什麽會打印出了undefined呢?
因為這段代碼實際上表達的意思是這樣:
function fn(){
function fn1(){
var x
console.log(x)
x = 5
}
fn1.call()
}
fn.call() //undefined
變量x只是做出了聲明,但是並沒有賦值,所以打印出來是undefined。
閉包
既然理解了函數作用域,就能理解閉包了。
「函數」和「函數內部能訪問到的變量」(也叫環境)的總和,就是一個閉包。
比如上文這張圖:
函數fn1加上他可以訪問的位於函數fn的作用域內的變量x,就是一個閉包。
關於閉包的更詳細的解釋,可以看看方應杭方老師的這篇文章,我們充分理解,學以致用,就可以了。
[JavaScript]JavaScript中的函數(2)