例如:
function example() {
console.log("outside the if block above function b declaration"+b());
function a() {
return "you invoked function a";
}
if (true) {
console.log("inside the if block"+a());
console.log("inside the if block above function b declaration"+b());
function b() {
return "you invoked function b";
}
}
}
当我调用这个example()函数时,我得到一个错误,b是未定义的,但当我删除第二行调用if块中定义的函数b时它是否一切正常?
答案 0 :(得分:6)
是和否。关键字let
确实支持块中的本地范围。关键字function
和var
适用于功能级别范围。它们在执行之前编译块时定义一个标识符。所以你通常可以调用声明之上的函数。
在您的示例中,函数是有条件声明的。它将在评估条件后声明,并且在执行内部块之前声明。但是当它被声明时,它在整个函数的范围内是有效的。尝试移动if-block下面的invokation,它将被知道并执行。
答案 1 :(得分:2)
不,它没有。如果块仍然限制在其容器中。您的函数B未定义,因为定义它的代码在被if语句阻止时永远不会被执行。但是,一旦删除了if语句,就会执行定义函数的代码,定义函数。
这是jsfiddle demonstrating the concept。
function defining() {
ifstmt = true;
if(ifstmt) {
var ifscope;
ifscope = "yes";
}
console.log(ifscope); // logs "yes"
}
function notDefining () {
ifstmt = false;
if(ifstmt) {
var ifscope;
ifscope = "no";
}
console.log(ifscope); // logs undefined
}
defining()
notDefining()
defining()
中的变量ifscope
已定义,但显然不限于if语句的范围。在notDefining()
中,将跳过定义ifscope
的代码,因此console.log
将返回undefined。
答案 2 :(得分:0)
正如Michael.Lumley在答案中指出的那样,通常需要代码来定义在执行代码之前发生的事情。但是,Javascript支持" hoisting",它使编码器能够在定义之前调用一段代码。(更多关于提升 - https://developer.mozilla.org/en-US/docs/Glossary/Hoisting) 因此,以下代码可以正常工作:
example()
function example() {
console.log("outside the if block above function b declaration"+b());
if (true) {
console.log("inside the if block"+a());
console.log("inside the if block above function b declaration"+b());
}
}
function a() {
return "you invoked function a";
}
function b() {
return "you invoked function b";
}
这是jsfiddle - https://jsfiddle.net/px2ghrgy/
但是,你的代码显然不会起作用,因为似乎条件似乎不支持吊装。原因是范围,即,虽然函数在一个封闭范围(全局或函数内)中提升,但它不会发生在条件(if / else)中。 您会发现此答案也相关 - > https://stackoverflow.com/a/35250887/7374117