这是javascript关闭的有效用例吗?

时间:2012-07-16 00:21:40

标签: javascript closures application-design

我已经查看了SO上的所有其他(优秀)答案(尤其是:How do JavaScript closures work?),但我想要您对我对该概念的理解的反馈。

我理解一个用例是隐藏私有方法的实现,不受公共访问的影响。

我想到的另一个是它作为工厂发电机:

<script>

function carFactory( make ) {

    var m = make;
    return { manufacture: function ( model ) 

        {console.log("A " + m + " " + model + " has been created");}

    }
}

toyotaFactory = carFactory("toyota");
hondaFactory = carFactory("honda");

toyotaFactory.manufacture("corolla");
toyotaFactory.manufacture("corolla");
hondaFactory.manufacture("civic");

</script>

输出:

A toyota corolla has been create
A toyota corolla has been created
A honda civic has been created 

那么您认为它是闭包的有效用例(即使用相同的代码库创建多个工厂)吗?或者我能用更好的东西来实现同样的目标吗?

请注意,问题不在于闭包的技术实现,而在于应用程序设计/开发中的有效用例。

感谢。

4 个答案:

答案 0 :(得分:3)

是的,保持变量私有是闭包的有效用法。它允许您私有访问变量而不使其成为公共成员。

有关其他示例,请参阅此参考:http://www.crockford.com/javascript/private.html

答案 1 :(得分:1)

如果我正确理解您的问题,您不关心将make财产保密吗?如果是这样的话,那么关闭并不是必需的,你可以使用原型实现相同的功能......

function carFactory(model){
  this.m = make;
}

carFactory.prototype.manufacture = function(model){
  console.log('A ' + this.m + ' ' + model + ' has been created');
}

根据this question,它具有相关的性能优势(减少内存和提高速度)。

答案 2 :(得分:0)

闭包是非常强大的构造,具有许多有用的用途。你在那里使用的那个实际上是一种“黑客”。闭包最常见的用途是,当你实现了一些在中间“做某事”的功能......并且“做某事”可以配置成或多或少你想要的任何东西......例如jQuery ajax功能当请求有错误或成功时,可以“做某事”等等...... 如果你没有闭包,你只能传递一个“静态定义”的函数,它可能需要从全局变量中收集你想要它做任何事情所需的上下文,或者你必须对所有函数使用相同的签名,例如在C或C ++中使用的函数(customData){} ... Closures允许您在运行时“动态构建函数”,重新创建它们创建时所具有的上下文,因此您可以以非常简单的方式传递给需要“做某事”几乎任何事情的模块(在合同中)你在c或c ++或没有闭包的情况下做的事情,它是丑陋的,容易出错的,也是一个黑客攻击。)

因此,无论何时必须在某些内容中“配置”一些自定义功能,您都将使用闭包......

答案 3 :(得分:0)

我正在尝试提出一个信息隐藏/封装的实际例子,这是我到目前为止的尝试

'use strict';

const bank = (accountHolderName, initialDeposit) => {
    let balance = initialDeposit;
    const add = (amount) => {
        balance += amount;
    }

    let subtract = (amount) => {
        balance -= amount
    }

    let printBalance = () => {
        console.log(accountHolderName, "has balance of", balance, "dollars");
    }

    return {
        credit: add,
        debit: subtract,
        balance: printBalance
    }
}

let amy = bank("Amy", 1000);
amy.balance();
amy.credit(100);
amy.balance();
amy.debit(10);
amy.balance();

let sam = bank("Sam", 50);
sam.balance();
sam.credit(50);
sam.balance();
sam.debit(100);
sam.balance();

一旦运行,您将获得以下输出

Amy has balance of 1000 dollars
Amy has balance of 1100 dollars
Amy has balance of 1090 dollars
Sam has balance of 50 dollars
Sam has balance of 100 dollars
Sam has balance of 0 dollars

好处?

  • balance变量不可直接访问。
  • 使用闭包,每个调用者都获得自己的数据。艾米的balance不干扰Sam's数据
  • 调用方(AmySam等)拥有一个不错的API,可用来处理bank的内部细节。

我想念其他东西吗?