今天我要讲解的是闭包(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)
范例:
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
以上就是今天闭包的解说,我们明天见!!
>>: 【把玩Azure DevOps】Day12 Artifacts应用:上传第一个nuget package
在上一篇文章提到对话系统的管理,今天我们要来说明主画面设定及场景资料转换。 需要注意的是,介面的素材...
tags: 铁人赛 AWS S3 Outposts S3 Bucket 前言 昨天我们成功把 K8S...
企业网站没有攻击还需要租用高防服务器吗?其实网站并不是在搭建时就会有攻击的,很多企业都会选用高防服务...
Design Patterns(设计模式)的起点 一切都源自於 Erich Gamma、Richar...
思路: 因为是看笔记教到Kahn's Algorithm,直接练习题,所以没什麽思路不...