Javascript变量和函数提升

时间:2013-12-01 02:55:35

标签: javascript hoisting

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(这是一个函数)并且在没有继续搜索的情况下快乐地返回。或其他什么?

感谢您的时间。

3 个答案:

答案 0 :(得分:1)

我在David Shariff博客中找到了答案。

“从他的博客中无耻地复制” -

即使foo被声明两次,我们从创建阶段就知道在变量之前在激活对象上创建了函数,如果激活对象上已存在属性名,我们只是绕过声明。

因此,首先在激活对象上创建对函数foo()的引用,当我们得到解释器到var foo时,我们已经看到属性名称foo存在,所以代码什么都不做并继续。

如果这听起来像希腊语,请阅读整个blog

答案 1 :(得分:0)

功能声明"阴影" var语句。

将其粘贴到您的控制台:

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;
&#13;
&#13;

我希望上面的例子不仅可以回答你的问题,还可以让你更好地理解:

var foo = function() {} vs function foo() {}