本文涉及知識點
- 什么是閉包组贺?
- 閉包有什么用?
什么是閉包祖娘?
!function(){
var local = '變量'
function foo(){
console.log('local')
}
}()
ok失尖,這三行代碼就是一個閉包。在這三行代碼中渐苏,有一個局部變量local掀潮,有一個函數(shù)foo,foo里面可以訪問到local變量琼富。就形成了閉包仪吧,就是這么簡單:
「函數(shù)」和「函數(shù)內(nèi)部能訪問到的變量」(也叫環(huán)境)的總和,就是一個閉包鞠眉。
顯然可見薯鼠,閉包就是函數(shù)作用域的產(chǎn)物:
- 函數(shù)在執(zhí)行的過程中,先從自己內(nèi)部找變量
- 如果找不到械蹋,再從創(chuàng)建當(dāng)前函數(shù)所在的作用域去找, 以此往上
- 注意找的是變量的當(dāng)前的狀態(tài)
也就是在執(zhí)行foo函數(shù)的時候出皇,現(xiàn)在自己內(nèi)部找local變量;內(nèi)部沒有l(wèi)ocal變量哗戈,于是乎就從創(chuàng)建foo函數(shù)所在的作用域去找恶迈,也就是立即執(zhí)行函數(shù)中,local='變量'
谱醇。
但是很多時候,我們見到的閉包是函數(shù)套函數(shù)步做,比如這樣:
function foo(){
var local = 1
function bar(){
local++
return local
}
return bar
}
var func = foo()
func()
其實跟上方的代碼沒有多大區(qū)別副渴,在上方代碼中,bar函數(shù)與local變量也形成了一個閉包(Closure).
為什么要函數(shù)套函數(shù)全度?
是因為需要一個局部變量煮剧,所以才把 local 放在一個函數(shù)里,如果不把 local 放在一個函數(shù)里将鸵,local 就是一個全局變量了勉盅,達(dá)不到使用閉包的目的——隱藏變量。
為什么要 return bar 呢顶掉?
因為如果不 return草娜,你就無法使用這個閉包。把 return bar 改成 window.bar = bar 也是一樣的痒筒,只要讓外面可以訪問到這個 bar 函數(shù)就行了宰闰。
所以 return bar 只是為了 bar 能被使用茬贵,也跟閉包無關(guān)。
閉包的作用
閉包用來間接訪問一個變量移袍,也就是隱藏變量解藻。通俗來講就是我把我家的鑰匙給你,你有了我家鑰匙就可以進(jìn)入我家干任何事葡盗,但是你沒有我家鑰匙就進(jìn)不了我家螟左,干不了任何事。
用代碼來說:
假設(shè)我們在做一個游戲觅够,在寫其中關(guān)于「還剩幾條命」的代碼胶背。
如果不用閉包,你可以直接用一個全局變量:
window.lives = 30 // 還有三十條命
這樣看起來很不妥蔚约。萬一不小心把這個值改成 -1 了怎么辦奄妨。所以我們不能讓別人「直接訪問」這個變量。怎么辦呢苹祟?
用局部變量砸抛。
但是用局部變量別人又訪問不到,怎么辦呢树枫?
暴露一個訪問器(函數(shù))直焙,讓別人可以「間接訪問」。
代碼如下:
!function(){
var lives = 50
window.獎勵一條命 = function(){
lives += 1
}
window.死一條命 = function(){
lives -= 1
}
}()
簡明起見砂轻,用了中文
那么在其他的 JS 文件奔誓,就可以使用 window.獎勵一條命() 來漲命,使用 window.死一條命() 來讓角色掉一條命搔涝。
看到閉包在哪了嗎厨喂?