【Day24】闭包(Closure)

今天我要讲解的是闭包(Closure),在进入之前我们先来看一段程序码,

首先准备一个随机生成字串的函式

function randomString(length) {
    let result = '';
    let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    for (let i = 0; i < length; i++) {
        result += characters.charAt(Math.floor(Math.random() * characters.length));
    }
    return result;
};

接着在全域中新增一个变数和函式,并且执行该函式

let demoData = [];

function getData() {    
    for (let i = 0; i < 1000; i++) {
        demoData.push(randomString(1000))
    }
};

getData();

我们能看见这段程序码占记忆体空间 20.6 MB,

接着我们将变数移到函式内,再看一次占多少记忆体空间

function getData() {    
    let demoData = [];
    for (let i = 0; i < 1000; i++) {
        demoData.push(randomString(1000))
    }
};

getData();

此时会看见程序码占记忆体空间 815 KB,

在此附上 KB 和 MB 的单位转换: 1 MB = 1024 KB

那麽为何所占的记忆体变少呢?

那是因为在函式中的变数所占的记忆体,

在函式执行结束後,此时函式内的变数没被参考,

所以该变数所储存的记忆体空间就被释放掉,

因此所占的记忆体就变少了

而当函式内的变数记忆体还保留时,这就是所谓的闭包(Closure)

闭包(Closure)

当函式内的变数其值被保留,而不被记忆体释放时,称为闭包(Closure)

范例:

function storeMoney(){
    let money = 1000;
    return function(price) {
        money += price;
        return money
    }
};

console.log(storeMoney);

console.log(storeMoney());

console.log(storeMoney()(100));

该范例中 storeMoney() 回传匿名函式,而匿名函式中则回传 money

在第一个 console.log() 中,会回传 storeMoney() 整个函式,

在第二个 console.log() 中,会回传匿名函式,

在第三个 console.log() 中,会回传 1100

那为何会回传 1100 呢?

那就跟它的作用域有关系了,

在匿名函式中因为没有变数 money 所以向外查找该变数,

也因为向外查找这个动作,就让 money 的值无法被释放,

所以 money 的值必须保存起来,匿名函式中才能取用该变数做使用,

因此才会回传 1100

接着我们将函式赋予到变数上

function storeMoney(){
    let money = 1000;
    return function(price) {
        money += price;
        return money
    }
};

const wei = storeMoney();

console.log(wei(100));  // 1100
console.log(wei(100));  // 1200
console.log(wei(100));  // 1300

我们能看到回传的结果会累加,

这是因为在 storeMoney() 中,

我们将 100 这个参数代入匿名函式进行相加,

而相加後的值也会保留起来不被释放,

因此当我们不断将参数带入时, money 的值也会不断累加,

还有因为我们是在函式中宣告变数,

因此这个范例中的 money 的值,只属於 wei 这个变数

当我们再宣告其他变数时,其值是互不相关的

function storeMoney(){
    let money = 1000;
    return function(price) {
        money += price;
        return money
    }
};

const wei = storeMoney();

console.log(wei(100));  // 1100
console.log(wei(100));  // 1200
console.log(wei(100));  // 1300

const ming = storeMoney();

console.log(ming(1000));  // 2000
console.log(ming(1000));  // 3000
console.log(ming(1000));  // 4000

以上就是今天闭包的解说,我们明天见!!


<<:  Day 09 - 继续加油

>>:  【把玩Azure DevOps】Day12 Artifacts应用:上传第一个nuget package

Day 28 | Unity游戏开发 - 介面设置及场景转换

在上一篇文章提到对话系统的管理,今天我们要来说明主画面设定及场景资料转换。 需要注意的是,介面的素材...

【Day 26】S3 on AWS Outpost 限制与建置流程

tags: 铁人赛 AWS S3 Outposts S3 Bucket 前言 昨天我们成功把 K8S...

企业使用高防服务器究竟有哪些好处?

企业网站没有攻击还需要租用高防服务器吗?其实网站并不是在搭建时就会有攻击的,很多企业都会选用高防服务...

Day 03: 面对 Design Pattern 该有的知识

Design Patterns(设计模式)的起点 一切都源自於 Erich Gamma、Richar...

Uva 10305. Ordering Tasks

      思路: 因为是看笔记教到Kahn's Algorithm,直接练习题,所以没什麽思路不...