function myFunction() {
function myInternalFunction() {
return 10;
}
return myInternalFunction();
function myInternalFunction() {
return 20;
}
}
alert(myFunction()); // What will this alert?
答案是20。
function myFunction() {
var myInternalFunction = function() {
return "Hello World.";
}
return myInternalFunction();
var myInternalFunction = function() {
return "Second Definition.";
}
}
alert(myFunction()); // What will this alert?
答案是" Hello Wold"。
为什么????为什么不"第二定义" ????
答案 0 :(得分:3)
因为,在第一种情况下,在编译时本身,第二个myInternalFunction
替换当前范围中的第一个myInternalFunction
。这意味着,myInternalFunction
范围内仅存在第二个myFunction
函数。
但在第二种情况下,函数仅在执行期间创建。在执行alert
时,只创建了第一个myInternalFunction
函数,根本没有创建第二个myInternalFunction
。这就是Hello World
被警告的原因。
答案 1 :(得分:3)
提升变量的声明,但不是定义。所以你的第二个例子相当于:
function myFunction() {
var myInternalFunction
myInternalFunction = function() {
return "Hello World."
}
return myInternalFunction()
myInternalFunction = function() {
return "Second Definition."
}
}
很明显,myInternalFunction
无法访问,因此使用第一个定义,因为它在调用时是myInternalFunction
的值。 JSLint正确地抱怨(使用您的原始代码):
var
之后无法访问return
。
与第一个示例相比较,其中函数声明被提升,因此您的代码相当于:
function myFunction() {
function myInternalFunction() {
return 10
}
function myInternalFunction() {
return 20
}
return myInternalFunction()
}
正如我们在此处所见,myInternalFunction
会立即重新声明,因此最后一个获胜。在调用函数本身之前,两个声明都发生。
那么,为什么这个表达式最后警告称为变量:
var a = "one"; var a = "two"; alert(a); // alerts two ???? shouldn't be "one" if expressions?
这不等同于你的函数示例;一个等效的例子是:
var a = "one"
alert(a)
var a = "two"
并期望它提醒“两个”。我认为很明显它不会。变量的值,无论是函数,字符串还是其他任何东西都不相关。
答案 2 :(得分:0)
函数声明和变量声明总是被JavaScript解释器无形地移动(“提升”)到其包含范围的顶部。
请注意,它必须是函数声明,这意味着只会挂起function foo() {}
的语法。
第一个代码等于:
function myFunction() {
function myInternalFunction() {
return 10;
}
function myInternalFunction() {
return 20;
}
return myInternalFunction();
}
第二个代码等于:
function myFunction() {
var myInternalFunction;
myInternalFunction = function() {
return "Hello World.";
}
return myInternalFunction();
myInternalFunction = function() {
return "Second Definition.";
}
}