JS 闭包(Closure) DAY63

闭包(Closure)

可以让资源的记忆体不被释放,让外部能重复执行

function storeMoney(){
    var money = 100;
    // 这里子函式我们假设名称 func
    return function(price){
        money = money + price;
        return money;
    }
}
// 因 func 的 money 会因范围练而像外层寻找
// 所以 storeMoney() 的 money变数会保留,不会释放记忆体
console.log(storeMoney()); // 子函式
console.log(storeMoney()(100)); // 200 (执行完就结束了,直接释放记忆体)
console.log(storeMoney()(100)); // 200 (执行完就结束了,直接释放记忆体)
console.log(storeMoney()(100)); // 200 (执行完就结束了,直接释放记忆体)
function storeMoney(){
    var money = 100;
    return function(price){
        money = money + price;
        return money;
    }
}
// 因 子函式 的 money 会因范围练而像外层寻找
// 所以 storeMoney() 的 money变数会保留,不会释放记忆体
console.log(storeMoney()); // 子函式
console.log(storeMoney()(100)); // 200 (执行完就结束了,直接释放记忆体)
console.log(storeMoney()(100)); // 200 (执行完就结束了,直接释放记忆体)
console.log(storeMoney()(100)); // 200 (执行完就结束了,直接释放记忆体)

// 为什麽可以一直累加??
// MingMoney变数 接收子函式结果,而子函式会一直取用父函式(storeMoney)的 money 
// 导致 storeMoney 函式里第 2 行的 money 不断地改变数字

// 而为什麽 storeMoney 函式里第 2 行的 money 不会被记忆体释放??
// MingMoney变数 会因范围练而像外层寻找 , 所以"参照" storeMoney 函式里第 2 行的 money 
// 故串连起来,外界跟外层 storeMoney 变的有关联
var MingMoney = storeMoney(); 
console.log(MingMoney(1000)); // 1100
console.log(MingMoney(1000)); // 2100
console.log(MingMoney(1000)); // 3100

var JayMoney = storeMoney(); 
console.log(JayMoney(1000)); // 1100
console.log(JayMoney(1000)); // 2100
console.log(JayMoney(1000)); // 3100




工厂模式及私有方法

我们先来看一个例子


function arrFunction(){
    var arr = [];
    for(var i = 0 ; i < 3 ; i++){
        arr.push(function(){
            console.log(i); // 是取函式作用域的 i ,但这时 i 为 3 
        })
    }
    console.log('i' + i); // 3 
    return arr;
}
var fn = arrFunction();
fn[0]();
fn[1]();
fn[2]();

解决方法(2种)
利用 立即函式 限制作用域

function arrFunction(){
    var arr = [];
    for(var i = 0 ; i < 3 ; i++){
        (function(j){
            arr.push(function(){
                console.log(j); // 0 1 2
            })
        }(i))
    }
    return arr;
}
var fn = arrFunction();
fn[0]();
fn[1]();
fn[2]();

JS ES6 let

function arrFunction(){
    var arr = [];
    for(let i = 0 ; i < 3 ; i++){
        arr.push(function(){
            console.log(i); // 0 1 2
        })
    }
    return arr;
}
var fn = arrFunction();
fn[0]();
fn[1]();
fn[2]();

函式工厂

function storeMoney(init){
    var money = init || 100;
    return function(price){
        money = money + price;
        return money;
    }
}
var myMoney = storeMoney(100);
console.log(myMoney(500)); // 600

私有方法

function storeMoney(init){
    var money = init || 100;
    return {
        increase: function(price){
            money += price ;
        },
        decrease: function(price){
            money -= price;
        },
        value: function(){
            return money
        }
    }
}
var myMoney = storeMoney(500);
myMoney.increase(1000);
myMoney.increase(1000);
myMoney.increase(1000);
myMoney.decrease(500);
myMoney.decrease(500);
console.log(myMoney.value()); // 2500

那今天的介绍就到这里
若有任何问题 或 内容有误
都可以跟我说唷/images/emoticon/emoticon41.gif


<<:  字母呈现大小写混合转换的波浪型态之C#写法(墨西哥波浪舞)

>>:  [鼠年全马] W37 - Vue出一个旅馆预约平台(11)

[FGL] 服务简单收 - IMPORT 3 利用http与XML套件取 Web资源

没有人能一次做好所有的事情,也不可能有一套系统收尽所有资料。既然如此,如何适当且适时的抓取外部资料...

[Day10] CH07:站在巨人的肩膀上——方法

先来公布一下昨天的解答吧,应该画一下图就知道为什麽要这样了,这里就不再说明,因为今天要讲解一个新的概...

12 - Metrics - 观察系统的健康指标 (6/6) - 使用 Metricbeat 掌握 Infrastructure 的健康状态 AWS 篇

Metrics - 观察系统的健康指标 系列文章 (1/6) - Metrics 与 Metricb...

Day20 Analysis of Algorithms(Ⅱ)

假如说今天有一个问题,有三种不同的解法,必须选择指数越小的,时间复杂度越小! 所以以下这个例子可以知...

[经典回顾]未知病毒入侵金融业事件纪录

防毒软件不断推陈出新,病毒也变化多端... 站在 Blueteam 位置,守住资讯安全防线的难度也飞...