【问题标题】:Access to variables in scope from a function defined externally从外部定义的函数访问范围内的变量
【发布时间】:2014-05-29 03:32:42
【问题描述】:

有没有办法从在闭包外部定义但在闭包内引用的函数打印 temp(闭包变量)的值,而不将 temp 作为变量传递给 funcA?

var funcA, funcB;

funcA = function () {
   console.log(temp);
}

funcB = function () {var temp, funcC;
  temp = 1;
  funcC = funcA;
  funcC();
}
funcB();  // temp is undefined.

这可行,但只是因为 funcA 是在 funcB 中定义的:

funcB = function () {var temp, funcA, funcC;
  temp = 1;
  funcA = function () {
       console.log(temp);
  }
  funcC = funcA;
  funcC();
}
funcB(); // 1

我正在尝试找到一种方法,将一些函数定义从外部函数中提取出来,以简化变得有点复杂的代码。我可以在 funcB 之外定义 funcA 但仍然引用 temp 变量而无需传递参数吗?

我读到 javascript 没有动态运行时范围,它只是词法范围,但是通过在 funcB 中引用一个函数(通过 funcC 的 funcA),有没有办法满足词法范围要求并提供对范围的访问funcB 的变量?

【问题讨论】:

  • 函数只能访问定义在其作用域(函数作用域)内的变量和定义在全局作用域内的变量。 funcA 将无法在 funcB 中访问 temp,因为它不是闭包。如果您想从任何函数访问temp,请在全局范围内定义它。
  • 这似乎是一个 XY 问题。像这样的问题需要一个真实的例子来为你的实际问题提供一个好的解决方案。
  • @Akinkunle 你刚刚给了我一个解决方案的想法。我会发布它。我可以将整个东西包装在一个函数中并使用该函数的范围(就像一个全局范围,但仅限于我的应用程序)。
  • @ChrisG。是的,这就是模块的编写方式。您将整个代码封装在一个大函数范围内,这样全局范围就不会被污染。

标签: javascript


【解决方案1】:

使用 Akinkunle Allen 的评论,我想出了这个似乎解决了我的问题。

function funcB () {
  var funcA, funcB, temp;

  funcA = function () {
     console.log(temp);
  }

  funcB = function () {var funcC;
    temp = 1;
    funcC = funcA;
    funcC(); 
  }
  return funcB();
}

funcB(); // 1

【讨论】:

    【解决方案2】:

    是的,也不是。

    用于声明变量的关键字var 根据当前作用域的不同表现不同。当var 在全局范围内执行时,它是可选的。该变量成为全局对象的属性。在浏览器中执行时,这个全局对象是window

    所以下面在全局空间中的结果是一样的。

    var temp = 1;
    window.temp = 1;
    this.temp = 1;
    

    由于全局上下文,以上所有内容都只是window.temp

    当您在函数中使用var 时,变量会附加 到函数中。 Javascript 中的所有函数都是对象,因此只要父函数仍在某处使用,本地 var 变量就会存在。

    Javascript 将遍历执行范围的层次结构以查找变量标识符。因此,任何内部函数都可以访问它们的外部函数变量(如您的示例所示)。

    您可以做的是在函数中使用this 引用。

    Javascript 中的标识符this 是动态的(意味着您可以更改它)。我可以将变量传递给在调用函数之外声明的未知函数。由于this.temp 用于引用变量,因此函数funcA 能够显示该值。

    funcB = function(otherFunc)
    {
        this.temp = 1;
        otherFunc();
    }
    
    funcA = function()
    {
        alert(this.temp);
    }
    
    funcB(funcA);
    

    http://jsfiddle.net/thinkingmedia/dfLvj/

    参见上面的 jsfiddle 示例。

    您可以使用它来即时更改this 的含义。这是一个更好的例子。

    funcB = function(otherFunc)
    {
        var temp = {
            message: "Hello World!"
        };
        var foo = otherFunc.bind(temp);
        foo();
    }
    
    funcA = function()
    {
        alert(this.message);
    }
    
    funcB(funcA);
    

    http://jsfiddle.net/thinkingmedia/K5Pw6/

    动态更改this 可以带来很多好处,因为它允许函数接受将使用自定义this 引用执行的闭包引用。

    一个示例可能是点击事件处理程序,其中this 是触发事件的 DOM 元素。

    【讨论】:

    • 我明白你在做什么,但我试图避免传递参数(因为我将它用于其他事情)。我只想移动我的函数定义,但仍然保留这些函数访问原始函数中使用的变量的能力。示例 temp 用于 funcB 并在 FuncA 中引用。我想保留它,但我想将 funcA 的定义移出 funcB 以保持 funcB 更简单(里面的代码更少)。
    • @ChrisG。这听起来更像是对物品的需求。你学习过如何在 Javascript 中使用构造函数和原型设计吗?
    猜你喜欢
    • 2019-10-05
    • 2021-12-22
    • 1970-01-01
    • 2011-06-01
    • 2021-08-18
    • 1970-01-01
    • 2016-06-23
    • 2013-12-07
    • 2021-12-30
    相关资源
    最近更新 更多