【Day25】闭包进阶:工厂模式及私有方法

我们先来看一段闭包程序码

function arrFunction() {
    const arr = [];
    for (var i = 0; i < 3; i++) {
        arr.push(function(){
            console.log(i);
        });
    };
    
    console.log(arr);
    
    return arr;
}

const fn = arrFunction();

fn[0]();
fn[1]();
fn[2]();

arrFunction() 是一个闭包,

我们在 arr 阵列中 push 三个函式,

那麽为何显示的结果都是 3 而不是 012 呢?

我们可以在 arrFunction() 中,

观察 for 回圈执行完後的 i 值为何

function arrFunction() {
    const arr = [];
    for (var i = 0; i < 3; i++) {
        arr.push(function(){
            console.log(i);
        });
    };
    
    console.log('i', i);
    
    return arr;
};

const fn = arrFunction();

从结果得知当我们将 arrFunction() 赋予到 fn 时,

此时的 i 值就已经是 3 了,

因为此时 arrFunction() 的作用域中 i 最後结果为 3

因此执行 arr 内的函式时,只会取得 3 这个值,

那如果要显示 012 的话,我们有两种方法可以使用

1. 立即函式

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

const fn = arrFunction();

fn[0]();
fn[1]();
fn[2]();

此时可看到结果确实显示 012

那是因为立即函式有自己的作用域,

当参数 i 代入立即函式时,

此时 arr 中的所取得的值就是作为参数带进来的值,

因此结果才会显示 012

2. 用 let 宣告 i

function arrFunction() {
    const arr = [];
    for (let i = 0; i < 3; i++) {
        arr.push(function(){
            console.log(j);
        });       
    };
    
    console.log(arr);
    
    return arr;
}

const fn = arrFunction();

fn[0]();
fn[1]();
fn[2]();

此时 i 的作用域在 for 回圈的 {}

所以显示结果为 012

工厂模式及私有方法

工厂模式

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

const mingMoney = storeMoney(300);

console.log(mingMoney(500));  // 800

const weiMoney = storeMoney(3000);

console.log(weiMoney(500));  // 3500

该范例我们透过闭包传入不同的值,来做相同的事情,称为工厂模式

私有方法

function storeMoney(initValue) {
    let money = initValue || 1000;
    return {
        increase: function(price){
            money += price
        },
        decrease: function(price){
            money -= price
        },
        value: function() {
            console.log(money);
        }
    };
};

const mingMoney = storeMoney(300);

mingMoney.increase(200);
mingMoney.increase(200);
mingMoney.increase(200);
mingMoney.decrease(300);

console.log(mingMoney.value());  // 600

在范例中我们在 return 中回传物件,

之後在物件中建立许多方法,

像这种使用闭包来回传各种方法的行为,称为私有方法


<<:  DAY 10 - 可爱小暴龙

>>:  每个人都该学的30个Python技巧|技巧 26:搜寻以及取代—find()和replace()(字幕、衬乐、练习)

[day14]Vue.js 网站基本建置

其实今年才刚学Vue.js ,目前的程度大概就是写几个简单的功能而已,要写一个比较完整的网站还是十分...

[Day4] 自我必备掌握力:了解公司的运作

公司的IT部门 IT不是超然於世的部门,而是运作於公司的一部分 甫加入公司的时候,已经有一个又一个的...

GCP loadbalanc(二)

GCP loadbalance (HTTP(S)) HTTP(S)负载平衡是一种全球性的基於代理的第...

Day 20 ATT&CK for ICS - Evasion(2)

T0858 Change Operating Mode 如同Day15 ATT&CK for...

第一次参加铁人赛

笔者在这几个事件的时间线上有点错乱,但没关系,大家当故事听听就好了 XDDD 还记得我第一次参加 I...