研究闭包实例

来源:互联网 发布:51单片机有什么用 编辑:程序博客网 时间:2024/05/17 09:47
继续讨论闭包~
要想更好地理解闭包,研究一些实例是比不可少的,那么用什么语言来举例呢?
我最初认识闭包是在学习SICP这本计算机经典教材的时候,SICP的教学语言是Scheme,我现在也认为用Scheme来构造一个闭包的例子的确很简洁优雅。但是根据国内的计算机教育的情况,有多少人会在意Scheme呢?
我也曾经认为python是一个不错的选择,可是当我在构造一个实际的例子的时候突然发现闭包不是python强调的一个概念!python可以支持闭包,但是由于python在处理简单类型(如整形)对象时候的一些特点,在python中构造一个很简单的闭包反而更加复杂,不优雅。
最近由于工作的原因,做了一些javascript方面的研究,在对javascript的传统印象(只能用来产生弹出式广告)发生改变之后,忽然发现javascript是我可以用来演示闭包的一种通俗易懂的语言。
下面请看例子
function bank_account(init_balance){
    var balance = init_balance;
    function deposit(amount){
        balance += amount;
        return balance;
    }
    function withdraw(amount){
        if (balance < amount)
            return "there isn't enought money, there is only " + balance + " in your account";
        else
        {
            balance -= amount;
            return balance;
        }
    }
    return [deposit, withdraw];
}
//create a bank account with the initial balance of 100
acc1 = bank_account(100);
//get deposit function
deposit = acc1[0];
//get withdraw function
withdraw = acc1[1];
//start to do some bank account operation
deposit(100);    //returns 200
deposit(100);    //returns 300
withdraw(100);    //returns 200
withdraw(100);    //returns 100
withdraw(100);    //returns 0
withdraw(100);    //returns "there isn't enought money, there is only 0 in your account"
这是一个模拟银行账户的例子,bank_account会创建一个帐户,在bank_account内部定义了存钱(deposit)和取钱( withdraw)函数,然后把这两个函数返回,在外部用同名的deposit和withdraw来对应。
对deposit和withdraw的调用过程展示了这样一个现象,虽然每次调用deposit和withdraw的参数都是相同的,但每次的结果都不同。这是因为bank_account返回了内部函数deposit和withdraw,而deposit和withdraw的功能对bank_account内部的变量balance的引用构成了闭包,构成了一个隐含的保存特定状态(balance)的对象。对deposit和withdraw的每次调用都会改变这个闭包的状态,因此尽管参数相同,但是返回值依然不同。
这个例子的原型来自SICP的3.1节Assignment and Local State,前一段时间我曾想过用python去重写SICP中的一些例子,结果现在却用更简单的javascript实现了,看来简单的东西功能却不一定简单,这也是当时学习SICP时通过Scheme懂得的一个道理~
原创粉丝点击