如果函数在全局范围内声明,但在本地范围内定义,它属于哪个范围?我问,因为我知道它可以访问本地函数的范围(在其中定义),但声明让我感到困惑。
示例:
var funcDef;
function a() {
var msg = "Hello, world!";
funcDef = function() {
return msg;
}
}
a();
console.log(funcDef()); // prints Hello, world!
我的理解是变量,funcDef本身绑定到全局范围,其函数声明仍然绑定在()的范围内。有人可以证实吗?
答案 0 :(得分:1)
忘记这是一个功能并将其视为变量的事实。假设您更改了函数a(请在下次选择更好的名称)将字符串值赋给funcDef。
console.log(funcDef);
会在执行a()
之前打印未定义,之后会打印字符串值。
这是类似的,funcDef
的值在执行a()
之前是未定义的,之后它会分配一个函数。
当然,以上是对实际情况的简化,但你可以这样思考。实际上,由于关闭,msg将在a()
返回后保持不变并保持活动状态。
阅读本文以获取更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures
答案 1 :(得分:1)
function() { return msg; }
只是funcDef
的值,如5,true,依此类推,funcDef
在全局范围内声明(因此在任何地方都可见)。
函数可以访问创建它们的执行范围(以及外部范围)。如果您再次调用a()
,funcDef
的值将是一个不同的函数,可以访问不同的执行范围(因为它是在a
的另一个调用中创建的)。
var funcDef;
function a(msg) {
funcDef = function() {
return msg;
}
}
a("foo");
a("bar");
console.log(funcDef()); // bar
在创建它们的范围内可以看到函数。
var funcDef;
function a() {
function f() { console.log(1); }
funcDef = f;
}
a();
funcDef(); // works
f(); // fails, not visible
顺便说一句,经验法则:
/* function declaration */
f(); // works
function f() { console.log(1); }
/* function expression */
g(); // fails
var g = function () { console.log(2); };
/* function expression */
namedFunc(); // fails
var h = function namedFunc() { console.log(1); };
答案 2 :(得分:1)
这是一个非常好的问题。
正如@AlliterativeAlice所说,范围是直观的,预期的,全球化的。
现在funcDef
知道msg
的原因是其中最有趣的部分。
确实,正如@Ameen告诉你的那样,当你拨打a()
时,你只是应用了一个闭包。
那时,funcDef
“冻结”了对父范围和变量的引用。
因此,当您致电funcDef
时,其范围msg
的价值为Hello, world!
。