【问题标题】:Nested functions have access to the scope "above" them...but does it matter where they were defined?嵌套函数可以访问它们“上方”的范围......但是它们在哪里定义有关系吗?
【发布时间】:2016-06-17 21:14:48
【问题描述】:

我一直认为嵌套的函数调用可以访问它们上面的范围,而不管函数在哪里定义(在下面的示例中,我认为printsomething函数可以访问runeverything 函数中的“某物”变量)。根据下面的小提琴,情况并非如此。函数printsomething 是否必须在外部函数runeverything 中定义(而不仅仅是调用)才能访问在另一个函数runeverything 中定义的局部变量?

这对我来说很重要,因为节点模块在导入时会被提升到顶部。这给我带来了范围界定问题!

function foo(){
function printsomething() {
  $('#test').text(something || 'nothing');
};
  
var something = 'something';

function runeverything() {
  
  printsomething(); //returns "something is not defined"
}

runeverything();
};

foo();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 id="test"></h1>

【问题讨论】:

  • 有什么问题?您在测试中发现的是正确的:JavaScript 具有静态词法作用域。声明函数的代码点绝对重要。
  • 当模块导入被提升到顶部时,我可以在节点中做什么?当我从模块调用方法时,我必须将所有变量作为选项传递,因为该方法无法访问外部函数的变量。有什么解决办法吗?
  • 同样,JavaScript 具有静态词法范围。对此没有“解决方案” - 这是语言的基本性质。

标签: javascript closures local-variables node-modules scoping


【解决方案1】:

您需要将这些函数嵌入到另一个函数中才能做到这一点: 即:

function foo() {
    function printsomething() {
        $('#test').text(something || 'nothing');
    };

    function runeverything() {
        printsomething(); //returns "something"
    }

    var something = 'something';
    runeverything();
};
foo();

这样它就可以工作,因为变量 something 的范围是函数 foo,你的函数也在其中定义。

【讨论】:

  • 我在上面编辑了我的 sn-p。尝试运行它。外部“foo”函数不能解决问题。我也认为它会,这真的让我很困惑。
  • 你仍然在 runeverything 函数中定义了你的 var 东西。你需要在 foo 函数中定义它
  • 哦,你是对的。我的错。谢谢你抓住那个。不幸的是,看起来我通过“require”在节点中导入的代码总是被提升到任何外部函数的最顶部!不幸的是,在我工作的情况下,这行不通,但您仍然获得赞成票,因为这完全回答了我提出的问题。
  • 为什么不创建一个将所有变量作为对象属性的单个对象,并且只在调用函数时传递该对象?即 var obj={var1: 'abc',var2:'def'};调用函数(obj)
  • 是的,我希望我不必那样做 :)
【解决方案2】:

是的。

范围由定义函数的位置决定,而由调用它的位置决定。

要从调用函数的范围内访问数据:将其作为参数传递。

【讨论】:

  • 谢谢。当我从节点中的其他模块调用函数(来自我需要的其他脚本的函数)时,我已经厌倦了传递巨大的“选项”对象。您对这个问题有任何经验吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-13
  • 1970-01-01
  • 2014-04-12
相关资源
最近更新 更多