这个JavaScript模式叫什么?为什么使用它?

这个JavaScript模式叫什么?为什么使用它?,javascript,closures,iife,Javascript,Closures,Iife,我正在研究并注意到一种模式,其中函数的定义如下: var foo = ( function () { var bar = new Bar(); return function ( ) { //actual logic using bar from above. //return result; }; }()); (示例请参见光线投射方法) 这种方法的正常变化如下所示: var foo = function () { var ba

我正在研究并注意到一种模式,其中函数的定义如下:

var foo = ( function () {
    var bar = new Bar();

    return function ( ) {
        //actual logic using bar from above.
        //return result;
    };
}());
(示例请参见光线投射方法)

这种方法的正常变化如下所示:

var foo = function () {
    var bar = new Bar();

    //actual logic.
    //return result;
};
var tmpObject = new Bar();

function foo(){
    // Use tmpObject.
}
将第一个版本与正常变化进行比较,第一个版本的不同之处在于:

  • 它分配自执行函数的结果
  • 它在这个函数中定义了一个局部变量
  • 它返回包含使用局部变量的逻辑的实际函数
  • 因此,主要的区别在于,在第一个变体中,在初始化时,该条只被指定一次,而第二个变体每次调用时都会创建这个临时变量

    我对为什么使用它的最佳猜测是,它限制了bar的实例数(只有一个),从而节省了内存管理开销

    我的问题是:

  • 这个假设正确吗
  • 这个图案有名字吗
  • 为什么要用这个

  • 它限制了对象初始化成本,并另外确保所有函数调用使用相同的对象。例如,这允许将状态存储在对象中以供将来调用使用

    虽然它可能会限制内存使用,但GC通常会以任何方式收集未使用的对象,因此这种模式不太可能有多大帮助


    此模式是的一种特定形式。

    我不确定此模式是否有更正确的名称,但在我看来它像一个模块,使用它的原因是封装和维护状态

    闭包(由函数中的函数标识)确保内部函数可以访问外部函数中的变量


    在您给出的示例中,通过执行外部函数返回内部函数(并将其分配给
    foo
    ),这意味着
    tmpObject
    继续存在于闭包中,并多次调用内部函数
    foo()
    将在
    tmpObject

    的同一实例上运行。您的假设几乎是正确的。让我们先回顾一下这些

  • 它分配自执行函数的返回
  • 这称为or

  • 它在这个函数中定义了一个局部变量
  • 这是在JavaScript中使用私有对象字段的方法,因为它不提供
    private
    关键字或其他功能

  • 它返回包含使用局部变量的逻辑的实际函数
  • 同样,主要的一点是这个局部变量是私有的

    这个图案有名字吗

    好吧,你可以称之为这种模式。引述:

    模块模式使用闭包封装“隐私”、状态和组织。它提供了一种包装公共和私有方法和变量的混合方式,防止片段泄漏到全局范围,并避免与其他开发人员的接口发生意外冲突。使用此模式,只返回一个公共API,将闭包中的所有其他内容保持为私有

    比较这两个示例,我对为什么使用第一个示例的最佳猜测是:

  • 它正在实现单例设计模式
  • 使用第一个示例可以控制创建特定类型对象的方式。与这一点非常接近的匹配可以用有效的Java描述
  • 如果每次都需要相同的对象状态

  • 但是,如果每次只需要普通对象,那么此模式可能不会增加任何值。

    在提供的示例中,第一个代码段将在每次调用函数foo()时使用相同的tmpObject实例,其中与第二个代码段一样,tmpObject每次都是一个新实例

    使用第一个代码段的一个原因是,变量tmpObject可以在对foo()的调用之间共享,而不会将其值泄漏到foo()声明的范围中

    第一个代码段的非立即执行函数版本实际上如下所示:

    var foo = function () {
        var bar = new Bar();
    
        //actual logic.
        //return result;
    };
    
    var tmpObject = new Bar();
    
    function foo(){
        // Use tmpObject.
    }
    
    但是请注意,此版本的tmpObject与foo()在同一范围内,因此可以稍后对其进行操作

    实现相同功能的更好方法是使用单独的模块: 模块'foo.js':

    var tmpObject = new Bar();
    
    module.exports = function foo(){
        // Use tmpObject.
    };
    
    单元2:

    var foo = require('./foo');
    

    IEF和命名的foo creator函数的性能比较:

    您的代码和Three.js代码之间的关键区别在于,在Three.js代码中,变量
    tmpObject
    仅初始化一次,然后由返回函数的每次调用共享

    这将有助于在调用之间保持某些状态,类似于类C语言中如何使用
    静态
    变量

    tmpObject
    是一个私有变量,仅对内部函数可见


    它改变了内存的使用,但不是为了节省内存而设计的。

    我想通过扩展显示模块模式的概念,为这条有趣的线索做出贡献,它确保所有方法和变量在显式公开之前都是私有的


    在后一种情况下,加法方法将被称为Calculator.add()

    @ChrisHayes很公平。我将其标记为THREE.js,因为我认为THREE.js贡献者是最有资格回答这个问题的,但是的,这是一个通用的js问题。我相信它被称为闭包。你可以阅读它们。如果这是一个条被实例化的唯一地方,那么它就是一个模式。不一定是为了节省内存,但它可以保持状态invocations@wrongAnswer:不完全是。在这里,匿名函数(即闭包)被立即执行。在JS中,它通常被称为“模块”,我不会称它为“闭包的特定形式”。这是一种使用闭包的模式。这个图案的名字还没定下来。它真的需要名字吗?什么都做