久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

JavaScript 學(xué)習(xí)-24.函數(shù)閉包(closure)

 上海悠悠 2022-05-25 發(fā)布于上海

前言

閉包是面試最喜歡問的一個問題了,,面試官最喜歡問:
1.什么是閉包,?2.閉包的作用是什么,?

什么是閉包?

閉包(closure)是一種保護(hù)私有變量的機(jī)制,,在函數(shù)執(zhí)行時形成私有的作用域,,保護(hù)里面的私有變量不受外界干擾,即形成一個不銷毀的棧環(huán)境,。

閉包的特性:

  • 函數(shù)嵌套函數(shù)

  • 內(nèi)部函數(shù)可以訪問外部函數(shù)的變量

  • 參數(shù)和變量不會被回收,。

先看一個典型的閉包, 實(shí)現(xiàn)計(jì)數(shù)器的功能

function myCounter() {
var counter = 0;

function add() {
counter += 1;
console.log(counter);
}
return add;
}

var myAdd = myCounter();
myAdd();
myAdd();
myAdd();// 計(jì)數(shù)器現(xiàn)在為 3

在弄清楚閉包之前,我們需要弄明白一個概念:私有的作用域

變量作用域

var 聲明的變量有2個作用域:全局作用域 和局部作用域,。
let 和 const 聲明的變量有3個作用域:全局作用域 和局部作用域,, 還有個塊作用域。塊作用域這里就不講了

全局作用域

在函數(shù)外部var 聲明的變量就是全局作用域

var count = 0

// 每次調(diào)用fun() count 加1
function fun() {
count += 1;
}

fun();
fun();
fun();
console.log(count); // 3

函數(shù)局部作用域

在函數(shù)內(nèi)部聲明的變量是函數(shù)局部作用域

var count = 0

// 每次調(diào)用fun() count 加1
function fun() {
var count = 0;
count += 1;
}

fun();
fun();
fun();
console.log(count); // 0

雖然函數(shù)內(nèi)部也聲明了一個count變量,,但是跟函數(shù)外部的count其實(shí)是2個不同的變量,,所以每次調(diào)用函數(shù),僅僅只是內(nèi)部變量count加1了,,但是外部的count還是0,。

計(jì)數(shù)器問題

如果我們想設(shè)置一個計(jì)數(shù)器,當(dāng)我們打開一個頁面,,只有5次點(diǎn)擊機(jī)會,,點(diǎn)完就不能再點(diǎn)擊了。

<body>
<button type="button" id="btn"></button>
<script>
var counter = 5;

// 每次調(diào)用fun() count -1
function fun() {
counter -= 1;
if (counter <= 0){
document.getElementById('btn').disabled = true;
return
}

}

// 設(shè)置初始值
document.getElementById('btn').innerHTML = '還剩' + counter + '次';
// 每點(diǎn)一次減1
document.getElementById('btn').onclick = function () {
fun();
document.getElementById('btn').innerHTML = '還剩' + counter + '次';
}
</script>
</body>

實(shí)現(xiàn)效果

每點(diǎn)一次會減1

最后為0時不可被點(diǎn)擊

看起來是沒什么問題,,但是這個會有一個安全隱患,,由于counter變量是全局的,所以在其它任何地方都可以改變?nèi)肿兞康闹怠?br>如果用戶在控制臺,,改變了全局變量counter的值,,比如我在console執(zhí)行var counter=100

當(dāng)我點(diǎn)一下按鈕,就會變成99次

閉包的作用

為了解決這種全局變量導(dǎo)致的問題,,所以我們需要在函數(shù)內(nèi)部設(shè)置一個私有變量

<body>
<button type="button" id="btn"></button>
<script>
// 每次調(diào)用fun() count -1
function fun() {
var counter = 5;
document.getElementById('btn').innerHTML = '還剩' + counter + '次';
function inner(){
counter -= 1;
if (counter <= 0){
document.getElementById('btn').disabled = true;
}
return counter
}
return inner
}
mycounter = fun();
// 每點(diǎn)一次減1
document.getElementById('btn').onclick = function () {
var x = mycounter();
document.getElementById('btn').innerHTML = '還剩' + x + '次';
}
</script>
</body>

或者把counter作為一個變量傳給函數(shù),,此時也不會影響

<body>
<button type="button" id="btn"></button>
<script>
// 每次調(diào)用fun() count -1
function fun(counter) {
document.getElementById('btn').innerHTML = '還剩' + counter + '次';
function inner(){
counter -= 1;
if (counter <= 0){
document.getElementById('btn').disabled = true;
}
return counter
}
return inner
}

var counter = 5;
mycounter = fun(counter);

// 每點(diǎn)一次減1
document.getElementById('btn').onclick = function () {
var x = mycounter();
document.getElementById('btn').innerHTML = '還剩' + x + '次';
}
</script>
</body>

因?yàn)?fun()函數(shù)只執(zhí)行一次,所以會鎖定局部變量counter,。

計(jì)數(shù)器

如果是從0開始,,每運(yùn)行一次函數(shù)加1,,那么可以優(yōu)化成以下代碼

<body>
<button type="button" onclick="myFunction()">計(jì)數(shù)!</button>
<p id="demo"></p>
<script>
// 自調(diào)用函數(shù)
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();

function myFunction(){
document.getElementById("demo").innerHTML = add();
}
</script>
</body>

每點(diǎn)一次按鈕會加1

閉包的作用

綜上所述,閉包的作用就是在外部a函數(shù)執(zhí)行后,,閉包使得Javascript的垃圾回收機(jī)制不會收回a所占用的資源,因?yàn)閍內(nèi)部函數(shù)的變量要給到內(nèi)部函數(shù)b繼續(xù)使用,。
那么閉包的好處有以下幾點(diǎn):

  • 保護(hù)函數(shù)內(nèi)的變量安全

  • 在內(nèi)存中維持一個變量(用的太多就變成了缺點(diǎn),,占內(nèi)存) ;

  • 邏輯連續(xù),,當(dāng)閉包作為另一個函數(shù)調(diào)用的參數(shù)時,,避免你脫離當(dāng)前邏輯而單獨(dú)編寫額外邏輯。

  • 方便調(diào)用上下文的局部變量,。

  • 加強(qiáng)封裝性,,可以達(dá)到對變量的保護(hù)作用。

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多