david sharif做了一个JS测验,看起来很像 -
var foo=1;
function bar(){
return foo;
foo=10;
function foo(){}
var foo =5;
}
typeof bar();//?
根据我的理解,首先对函数进行托管,然后在内部声明变量。这个函数的主持形式就像是(如果我错了,请纠正我) -
var foo=1;
function bar(){
function foo(){}
var foo;
return foo;
foo=10;
foo =5;
}
typeof bar();//?
为什么typeof bar()函数未定义?
这是因为,在函数执行时,它找到第一个foo(这是一个函数)并且在没有继续搜索的情况下快乐地返回。或其他什么?
感谢您的时间。
答案 0 :(得分:1)
我在David Shariff博客中找到了答案。
“从他的博客中无耻地复制” -
即使foo被声明两次,我们从创建阶段就知道在变量之前在激活对象上创建了函数,如果激活对象上已存在属性名,我们只是绕过声明。
因此,首先在激活对象上创建对函数foo()的引用,当我们得到解释器到var foo时,我们已经看到属性名称foo存在,所以代码什么都不做并继续。
如果这听起来像希腊语,请阅读整个blog
答案 1 :(得分:0)
将其粘贴到您的控制台:
var foo = function(){}
var foo
typeof foo
这就是代码"的样子"编译时到解释器:
var bar = function bar(){
var foo = function foo(){}
foo
return foo;
// never reached
foo = 10;
foo = 5;
}
var foo;
foo = 1
typeof bar();//"function"
答案 2 :(得分:0)
在执行任何分步代码之前,在进入封闭范围时评估函数声明。函数的名称(foo)被添加到封闭范围(从技术上讲,函数定义的执行上下文的变量对象)。
示例1
从这个例子中我们可以看到,即使我们在return语句之后声明foo
,我们仍然可以返回foo。
function bar() {
return foo;
function foo() {} // this will get initialized before the return statement.
}
console.log(typeof bar()); // this will be function

示例2
从这个例子中我们可以看到,如果我们在return语句之后以正常方式声明我们的变量,它们就不会执行(赋值)。
返回后声明函数。
function bar() {
return foo;
var foo = function() {} // this will not get assigned
}
console.log(typeof bar()); // this will be undefined

返回后声明号码
function bar() {
return foo;
var foo = 12; // this will not get assigned
}
console.log(typeof bar()); // this will be undefined

示例3
现在让我们逐行浏览一个更加简洁的例子。
function bar() {
return foo;
function foo() {} // <-- initialize foo as a function
var foo = 11; // <-- this will not get assigned
}
console.log(typeof bar()); // function
&#13;
我希望上面的例子不仅可以回答你的问题,还可以让你更好地理解:
var foo = function() {}
vs function foo() {}