分享的 HTML 與上圖內容一樣,需要修改的小伙伴可以自行修改內容。 <style><!-- @import url("https://fonts.googleapis.com/css?family=Share+Tech+Mono|Montserrat:700"); * { margin: 0; p ...
在介紹閉包之前,我們先看看是什麼全局變數和局部變數
全局變數和局部變數
局部變數:定義在函數內部的變數(只能在內部被訪問) 形參也是一種局部變數
全局變數:不在函數內部定義的變數, 就稱為全局變數,全局變數在任何函數內都可以被訪問和修改
假如我們在函數內部 定義了一個和外部相同名字的變數, 那麼在函數內部是用的哪個變數呢?
<script>
var ccc = 5;
function inner() {
var ccc = 4;
console.log(ccc);
}
inner();
</script>
以上結果會輸出4 , 因為在執行過程中, 會由內向外尋找變數的定義,所以局部變數在函數內部比全局變數更有優先被使用的權力
再看一個例子, 假如我們列印外部的ccc變數會輸出什麼?
<script>
var ccc = 5;
function inner() {
var ccc = 4;
}
inner();
console.log(ccc);
</script>
上面的例子會輸出 5, 因為函數內部定義的變數無法被外部看到
我們再來看一個比較奇葩的例子
<script>
var ccc = 5;
function inner() {
ccc += 1;
var ccc = 4;
console.log(ccc);
}
inner();
</script>
這個例子第一次列印會輸出 NaN , 第二次列印會輸出 4
第二次列印好理解, 因為我們已經知道局部變數優先被使用。
第一次比較奇怪, 按道理講, 在函數內部也應該能引用到外部的全局變數ccc,但是程式的運行結果和我們的推斷相反,這是因為js語言有個比較坑的知識點;即在函數執行前,語法規定把變數的定義提升到 函數的前面。
上面的例子在運行的時候瀏覽器是這麼理解的
<script>
var ccc = 5;
function inner() {
var ccc = undefined;
ccc += 1;
ccc = 4;
console.log(ccc);
}
inner();
</script>
這種特性就叫做函數變數提升, 把一個後面定義變數, 提升到前面,因為前面有這個地方的引用。
局部函數
一個函數內部也可以定義另一個函數內部
<script>
function outer() {
function inner() {
console.log("innser函數")
}
inner()
}
outer();
</script>
上面的inner() 函數只能再 outer() 函數內部調用
特別註意
如果不加修飾詞定義一個變數的話, 此變數將被視為全局變數,即使它定義在了函數內部
<script>
function fa() {
quanju = 10;
}
fa();
console.log(quanju);
</script>
閉包
概念
從概念上講,閉包就是一個函數以及捆綁在此函數周圍環境狀態的引用組合, 每創建一個函數都會產生一個閉包
這個定義比較抽象,下麵,我們舉個慄子
<script>
function outter(){
var cons = '常量小常'
return function() {
return cons;
}
}
// 得到外部函數的內部函數
var consFun= outter(1,2);
// 執行內部函數
consFun();
</script>
這個例子最終會輸出 ‘常量小常’, 雖然內部函數是在外部執行的, 但它依然能夠找到定義時候的一些常量值。這個就是一種閉包的表現形式
換句話說,就是函數在執行的時候,能夠還原它定義時所處的環境,能夠按照定義時候的樣子去執行
模擬私有變數
很多語言都支持私有變數, 就是將一個變數或者方法聲明為私有,只能被內部使用,外部要想使用只能通過定義的一些公共方法訪問
Js原生不支持這種語法,但可以通過閉包模擬這種私有變數的特性
下麵就是一個閉包模擬私有變數的例子 , privateCounter 變數不能直接被外部訪問,只能通過特定的方法操作。這個例子來源於此:
用閉包模擬私有變數
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures#用閉包模擬私有方法
<script>
var Counter = (function () {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function () {
changeBy(1);
},
decrement: function () {
changeBy(-1);
},
value: function () {
return privateCounter;
},
};
})();
console.log(Counter.value()); /* logs 0 */
Counter.increment();
Counter.increment();
console.log(Counter.value()); /* logs 2 */
Counter.decrement();
console.log(Counter.value()); /* logs 1 */
</script>
請關於一下啦^_^
微信公眾號