【问题标题】:How to return a value from within closure to external scope?如何将一个值从闭包内返回到外部范围?
【发布时间】:2012-08-22 02:06:14
【问题描述】:

我遇到了从一个函数向另一个函数返回值的需求,当这个简单的任务不起作用时,我一度困惑地挠了挠头。然后我意识到我在一个闭包函数(或匿名函数?)中操作,并且找不到关于如何将变量释放到此类函数范围之外的文档。

例如,这不起作用:

function aFunc()
{
   var result;
   object.event = function(){
      result = true;
   }
   return result;
}

也不会从闭包内部返回。我需要两者都做吗?我尝试在可能的最大范围内(所有函数之外)使用全局变量,但这也不起作用。我错过了什么?

我不确定我是否正确使用了闭包这个词,我指的是匿名函数。

谢谢。

【问题讨论】:

    标签: javascript scope closures


    【解决方案1】:

    你可以将一个对象传递给闭包,它的属性“result”会在函数被调用时设置。

    function aFunc (foo) {
        object.event = function() {
            foo.result = true;
        }
    }
    

    问题在于result 的值是由aFunc 返回的,而不是对它的引用,这意味着在闭包内部发生的result 的任何后续更改都不会影响result之前被退回了。

    【讨论】:

    • 上面的例子是我遇到问题的函数的简化。结果在闭包(?)内确定,并且取决于几个条件可能是也可能不是真的。所以我无法将结果的预定值传递给它。
    • 没关系。关键是您分配给已知对象的属性并且可以访问结果。
    • 如果在函数 aFunc 在 aFunc 完成执行后将结果赋值给局部变量,则检索值的机会很小
    • 传递一个对象似乎是最简单的想法,但考虑到时间问题,这可行吗?
    • 嗯,它会在执行闭包时为 'foo' 的字段 'result' 分配必要的值。您必须在此之前存储对象。
    【解决方案2】:

    你需要调用闭包:

    function aFunc() {
       var result;
       object.event = function() {
          result = true;
       };
       object.event();
       return result;
    }
    

    或者,如果它在其他地方运行,这是一个时间问题。你可以有类似promise的东西:

    function aFunc() {
       var promise = { hasRun: false, result: null };
       object.event = function() {
          result.hasRun = true;
          result.result = true; // or something else...
       };
       return promise;
    }
    
    // check if it has run and get the result:
    
    if (promise.hasRun) {
      // access promise.result
    }
    

    但是,一个简单的回调就足够了。既然您提到了XMLHttpRequest 对象,您应该能够将回调附加到其onreadystatechange 事件,或者将回调传递给aFunc:

    function aFunc(callback) {
       object.event = function() {
          var result = true;
          callback(result);
       };
    }
    

    然后在结果可用时调用您的回调。

    【讨论】:

    • 闭包确实运行了,所讨论的对象和事件是 xmlhttp 就绪状态,也许我的示例有一些混淆。
    • 那是时间问题,在你返回结果之前它肯定不会运行。那么你需要的是返回一个promise,你可以稍后检查;或者干脆使用回调。
    • 啊,我明白了。承诺是什么样的?
    • 谢谢,我最终使用了自己的回叫,这很管用 :)
    【解决方案3】:

    这是不可能的;代码

    object.event = function(){
        result = true;
    }
    

    实际上并不执行result = true;,它只是定义了一个将result 设置为true 的函数。在调用函数之前使用result 会产生未定义的值。

    有两种解决方案:

    1. 您可以使用容器(按照 Qnan 的建议)

    2. 您可以使用回调。

    第二种方法的意思是:不要马上使用result,而是让object.event后面的函数在result有一些有用的值时调用你的一些代码:

    object.event = function(){
        result = true;
        callback(result);
    }
    

    【讨论】:

    • 这是有道理的。在 C# 中使用回调后,我对回调很熟悉。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-13
    • 2016-06-23
    • 2020-02-14
    • 1970-01-01
    相关资源
    最近更新 更多