如何在JavaScript中提升名称解析顺序?

时间:2014-09-23 06:42:32

标签: javascript scope hoisting

我遇到了一个有趣的quiz

function bar() {
    return foo;
    foo = 10;
    function foo() {}
    var foo = '11';
}
alert(typeof bar());

我的解释是这样的(根据控制台错误:)):

var foo; // global variable
function bar(){
    function foo(){}
    var foo;  //  Here variable foo should override foo function 
    return foo; // (according to me foo should be variable with undefined value) What is going on here, How JavaScript resolve naming order ?
    foo = 10;
    foo = "11";
}

以下是我正在阅读this

的参考资料
  

在JavaScript中,名称以四种基本方式之一进入范围:    1.Language-defined:默认情况下,所有范围都给出了this和arguments的名称。    2.形式参数:函数可以具有命名形式参数,其范围限定为该函数的主体。    3.函数声明:它们的形式为函数foo(){}。    4.变量声明:它们采用var foo;

形式

他后来引述:

  

要记住的最重要的特殊情况是名称解析顺序。请记住,名称有四种方式可以输入给定的范围。我在上面列出的顺序是它们被解析的顺序。通常,如果已经定义了名称,则它永远不会被同名的另一个属性覆盖。这意味着函数声明优先于变量声明。这并不意味着对该名称的赋值不起作用,只是声明部分将被忽略。

这对我来说很困惑,有人可以参考上面的例子来简化这个吗? 我想知道的要点:

  • 函数中没有var的变量如何挂起?
  • 在吊装过程中是否发生变量覆盖?

2 个答案:

答案 0 :(得分:3)

让我们暂时离开函数foo。在函数内,如果在该函数内的任何位置声明变量,则声明将移动到函数的顶部。所以,它实际上是这样评估的

function bar() {
    var foo;
    return foo;
    foo = 10;
    foo = '11';
}

但是当你有一个用同一个名字声明的函数时,它将优先,并且它将被评估类似于这个

function bar() {
    var foo = function() {};
    return foo;
    foo = 10;
    foo = '11';
}

这就是您在警告框中收到function的原因。

答案 1 :(得分:0)

默认情况下,函数内没有var的任何变量都会变为全局变量。

当你在另一个函数中有一个函数声明时(比如你的例子),它首先被提升,然后是变量声明。

演示变量覆盖的示例。

function bar() {
    var foo = 10;
    function foo() {}
    return foo;
}

bar(); //--> returns 10;

function bar() {
   var foo;
   function foo() {}
   return foo;
}

bar(); //--> returns the function object foo.