2

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 (也就是一个函数),没有继续搜索就愉快的返回了。或者是其他东西?

珍惜你的时间。

4

3 回答 3

1

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

“无耻抄袭他的博客”——

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

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

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

于 2013-12-01T03:00:21.677 回答
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"
于 2016-02-07T12:53:24.650 回答
0

在执行任何分步代码之前,在进入封闭范围时对函数声明进行评估。函数的名称 (foo) 被添加到封闭范围(从技术上讲,是定义函数的执行上下文的变量对象)。

示例 1

从这个例子中我们可以看到,即使我们foo在 return 语句之后声明,我们仍然可以得到 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

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

var foo = function() {}对比function foo() {}

于 2017-02-24T08:06:24.387 回答