追求JS小姊姊系列 Day23 -- 头等工具人也看安眠书店? 认识闭包让你独占变数

前情提要

工具人竟敢透露了一些身份的秘密。

:打断一下,所以为何你们三个工具人出现的瞬间,JS姐妹们就突然消失了?
方函式:喔~终於想起来了吗?因为一直让你接触他们不是很好,所以我使用我的能力:闭包,把他们关起来了。


闭包怎麽做到关人的?

在了解闭包能力之前,你应该要先知道为何会需要闭包?

假设今天我们要计算一个值,但我们把初始值宣告在全域

let balance = 1000;
function caculatePrice(cost){
    balance = balance - cost;
    console.log(balance);
}
//花了100元
caculatePrice(100)
console.log(balance); //900
//再花100元
caculatePrice(100)
console.log(balance); //800

我们可以将它放入函式内,让它成为区域变数,这样就不会被大家共用

let balance = 1000;

//开销计算
function caculateCost(cost){
    balance = balance - cost;
    return balance;
}
//花了100元
caculateCost(100)
console.log(balance,"第一次支出开销"); //900
//再花100元
caculateCost(100)
console.log(balance,"第二次支出开销"); //800

//书本开销计算
function caclateCostOfBook(bookPrice){
    balance = balance - bookPrice;
    return balance;
};
caclateCostOfBook(200);

//然後我们再看一次我们的余额
console.log(balance,"预期应该为800");

你会发现因为它们共用同一个变数值,所以不论我们执行caclateCostOfBook或是caculateCost时,都会影响balance的值,进而造成计算结果不如预期。

怎麽办呢?放入函式内


放入函式

因为此时变数读取有了所谓区域性,这样就能避免储存金额的变数,在全域被误调值。

function caculatePrice(cost){
    let balance = 1000;
    balance = balance - cost;
    console.log(balance);
}
//花了100元
caculatePrice(100)
console.log(balance); //900
//再花100元
caculatePrice(100)
console.log(balance); //800

但另一个问题出现了,不论你执行几次caculatePrice,都是从最初的金额$1000开始扣除,因为每次呼叫时,balance都会被重新宣告

这时候就是闭包(closure)上场的时刻!


闭包(closure)

先说笔者目前所知闭包最大的功能就是:私有化变数

function caculatePrice(cost){
    let balance = 1000;
    return function (){
     balance = balance - cost;
     console.log(balance);
    }
}
//将匿名函式存入变数
let x = caculatePrice(100);

x();//扣100
x();//再扣100

我们将caculatePrice(100)存入变数x这个动作,实际上你可以视为:将匿名函式存入变数x

x = function (){
     balance = balance - cost;
     console.log(balance);
    }

但不同的是,这个匿名函式保留了对caculatePrice字汇环境的参照,所以能透过 scope chain去读取内部的值如:balance,cost ,并且在每次执行时去影响数值。


方函式若你把变数想像成姐妹

  1. 当你放在全域:就很像随时在开放空间的人,随便想攀谈都很正常。
  2. 当你放在函式内:就很像进到一个空间内,只是在那个空间她们不管怎麽活动,都在我的眼皮下,我能随时关注。
  3. 闭包内:当情况进展太快,你想要断绝他们关系,就能用闭包

:所以只有这三种区别?

-- to be continued --


那今天就到这边搂!
每天的休息,是为了後面的追求,明天见。


reference:

你懂 JavaScript 吗?#15 闭包(Closure)
所有的函式都是闭包:谈 JS 中的作用域与 Closure
D10 - 点一笼热呼呼的小笼闭包 Closure


<<:  [Day 27] 中场休息 - 换边发球,heroku布署完整步骤

>>:  EP 30: Archive and Publish TopStore App for iOS in Visual Studio

[铁人12:Day 29] 「AI 的未来十年」摘要 5:固有知识框架

知识表达 符号处理其中的一个关键技术是「知识表达 (knowledge representation...

【Day20】:Servo控制-By PWM输出

Servo 对於简单的角度控制,大家第一个想到的就是伺服马达了吧,大小也适中,非常适合用在机器人上。...

Day09 建造APP(3)

经过昨天的介绍後,相信大家对App都有更一步的了解了,是吧!(应该有吧) 那我们今天就来做一点小小的...

[Day15] 第十五章-建立skill的model跟migration

前言 昨天我们把使用者的API 做了一个阶段的完结 今天我们来见使用者技能的资料模型跟migrati...

Day14 Let's ODOO: Security(3) Record rules

如果说Access right是针对model的CURD,那麽Record rules就是针对每笔资...