或更具体到我需要什么:
如果我从另一个函数中调用一个函数,它是从调用函数中还是从上面的级别中提取变量?前任:
myVar=0;
function runMe(){
myVar = 10;
callMe();
}
function callMe(){
addMe = myVar+10;
}
如果通过 runMe() 调用 callMe(),myVar 最终会是什么?
或更具体到我需要什么:
如果我从另一个函数中调用一个函数,它是从调用函数中还是从上面的级别中提取变量?前任:
myVar=0;
function runMe(){
myVar = 10;
callMe();
}
function callMe(){
addMe = myVar+10;
}
如果通过 runMe() 调用 callMe(),myVar 最终会是什么?
杰夫是对的。请注意,这实际上并不是对静态范围(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,因为警报不会从任一函数继承范围。
如果你的下一行是callMe(); ,则 addMe 将为 10,而 myVar 将为 0。
如果你的下一行是runMe(); ,那么 addMe 将是 20,而 myVar 将是 10。
请原谅我问 - 这与静态/动态绑定有什么关系?myVar 不只是一个全局变量吗,程序代码(将所有内容解包到调用堆栈上)不会确定值吗?
除非您使用关键字var
来定义变量,否则一切最终都会成为window
对象的属性。因此,您的代码将等效于以下内容:
window.myVar=0;
function runMe(){
window.myVar = 10;
window.callMe();
}
function callMe(){
window.addMe = window.myVar+10;
}
如果您牢记这一点,则应该始终清楚正在发生的事情。
我想补充一点,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关键字的变量都被视为global,它的局部范围为:
// This is a local scoped variable.
var local_var = "something";
// This is a global scoped variable.
global_var = "something_else";
作为一种良好的 JS 实践,建议始终添加var关键字。
myVar=0;
function runMe(){
myVar = 10;
callMe();
}
function callMe(){
addMe = myVar+10;
}
就输出而言,在这种情况下 myVar 和 addMe 都将是全局变量,就像在 javascript 中一样,如果您不使用 var 声明变量,那么它会隐式将其声明为全局变量,因此当您调用 runMe() 时 myVar 将具有值 10 和 addMe 将有 20 。