或更具体地我需要什么:
如果我从另一个函数中调用一个函数,它将从调用函数中还是从上一级拉出变量? 例如:
myVar=0;
function runMe(){
myVar = 10;
callMe();
}
function callMe(){
addMe = myVar+10;
}
如果通过runMe()调用callMe(),myVar最终会变成什么?
你为什么不运行它并找出答案?
记录问题是否更好,这样其他人也可以看到?
答案实际上是开始理解词汇与动态范围恕我直言的一个好方法,因此可以很好地听到,但是Sasha提醒初学者,运行和试验始终是一个好策略,这并没有错。
杰夫是对的。请注意,这实际上不是对静态作用域的良好测试(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,因为警报不会从任何一个函数继承作用域。
例外是this关键字,其行为类似于动态范围的变量
如果您的下一行是callMe();,则addMe将为10,而myVar将为0。
如果您的下一行是runMe();,则addMe将为20,而myVar将为10。
请原谅我问-这与静态/动态绑定有什么关系? myVar不仅是一个全局变量,而且程序代码(将所有内容都包装到调用堆栈中)不会确定这些值吗?
我的意思是范围界定...
变量在JavaScript中是静态作用域的(动态作用域确实是一件非常麻烦的事情:您可以在Wikipedia上阅读有关它的更多信息)。
但是,就您而言,您正在使用全局变量,因此所有函数都将访问同一变量。 Matthew Flaschen的回复显示了如何更改它,因此第二个myVar实际上是一个不同的变量。
如果您不太熟悉此页,则说明如何在JavaScript中声明全局变量与局部变量。它与大多数脚本语言执行此操作的方式不同。 (总之:如果在函数内声明," var"关键字使变量成为局部变量,否则该变量为全局变量。)
除非使用关键字var定义变量,否则所有内容最终都是window对象的属性。因此,您的代码将等效于以下内容:
window.myVar=0;
function runMe(){
window.myVar = 10;
window.callMe();
}
function callMe(){
window.addMe = window.myVar+10;
}
如果您牢记这一点,应该始终清楚发生了什么。
myVar=0;
function runMe(){
myVar = 10;
callMe();
}
function callMe(){
addMe = myVar+10;
}
就输出而言,在这种情况下,myVar和addMe都将是全局变量,例如在javascript中,如果您不使用var声明变量,则它将隐式声明为全局变量,因此当您调用runMe()时,myVar将具有值10和addMe将具有20。
我想补充一下,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。
据我了解,任何不带var关键字的变量都被视为全局变量,其局部作用域是这样,所以:
// This is a local scoped variable.
var local_var ="something";
// This is a global scoped variable.
global_var ="something_else";
作为一种好的JS做法,建议始终添加var关键字。