32

或更具体到我需要什么:

如果我从另一个函数中调用一个函数,它是从调用函数中还是从上面的级别中提取变量?前任:

myVar=0;

function runMe(){
    myVar = 10;
    callMe();
}

function callMe(){
   addMe = myVar+10;
}

如果通过 runMe() 调用 callMe(),myVar 最终会是什么?

4

7 回答 7

51

杰夫是对的。请注意,这实际上并不是对静态范围(JS 确实有)的一个很好的测试。更好的是:

myVar=0;

function runMe(){
    var myVar = 10;
    callMe();
}

function callMe(){
   addMe = myVar+10;
}

runMe();
alert(addMe);
alert(myVar);

在静态范围的语言(如 JS)中,警报 10 和 0。runMe 中的 var myVar(局部变量)会影响该函数中的全局 myVar。但是,它在 callMe 中不起作用,因此 callMe 使用仍为 0 的全局 myVar。

在动态范围的语言中(JS 不同),callMe 将从 runMe 继承范围,因此 addMe 将变为 20。请注意,在警报时 myVar 仍将为 0,因为警报不会从任一函数继承范围。

于 2009-06-06T05:11:16.330 回答
5

如果你的下一行是callMe(); ,则 addMe 将为 10,而 myVar 将为 0。

如果你的下一行是runMe(); ,那么 addMe 将是 20,而 myVar 将是 10。

请原谅我问 - 这与静态/动态绑定有什么关系?myVar 不只是一个全局变量吗,程序代码(将所有内容解包到调用堆栈上)不会确定值吗?

于 2009-06-06T04:21:49.913 回答
3

变量在 JavaScript 中是静态作用域的(动态作用域实际上是一个非常混乱的事情:你可以在Wikipedia上阅读更多关于它的信息)。

但是,在您的情况下,您使用的是全局变量,因此所有函数都将访问同一个变量。Matthew Flaschen 的回复显示了如何更改它,因此第二个 myVar 实际上是一个不同的变量。

本页解释了如何在 JavaScript 中声明全局变量和局部变量,以防您不太熟悉它。它与大多数脚本语言的做法不同。(总而言之:如果在函数内声明,“var”关键字使变量成为局部变量,否则变量是全局变量。)

于 2009-06-06T05:38:58.333 回答
1

除非您使用关键字var来定义变量,否则一切最终都会成为window对象的属性。因此,您的代码将等效于以下内容:

window.myVar=0;

function runMe(){
    window.myVar = 10;
    window.callMe();
}

function callMe(){
   window.addMe = window.myVar+10;
}

如果您牢记这一点,则应该始终清楚正在发生的事情。

于 2011-06-20T12:54:02.540 回答
1

我想补充一点,lambda 表达式在定义表达式的位置也是静态范围的。例如,

var myVar = 0;

function foo() {
    var myVar = 10;
    return { bar: function() { addMe = myVar + 10; }}
}

var myObj = foo();

var addMe = 6;
alert(addMe);

myVar = 42;
myObj.bar();

alert(addMe);

这将显示 6 和 20。

于 2015-01-08T19:09:13.887 回答
0

据我了解,任何没有var关键字的变量都被视为global,它的局部范围为:

// This is a local scoped variable.
var local_var = "something"; 

// This is a global scoped variable.
global_var = "something_else";

作为一种良好的 JS 实践,建议始终添加var关键字。

于 2009-06-06T06:07:59.680 回答
0
myVar=0;

function runMe(){
    myVar = 10;
    callMe();
}

function callMe(){
   addMe = myVar+10;
}

就输出而言,在这种情况下 myVar 和 addMe 都将是全局变量,就像在 javascript 中一样,如果您不使用 var 声明变量,那么它会隐式将其声明为全局变量,因此当您调用 runMe() 时 myVar 将具有值 10 和 addMe 将有 20 。

于 2017-07-01T21:54:13.703 回答