【问题标题】:How hoisting name resolution order works in JavaScript?提升名称解析顺序在 JavaScript 中如何工作?
【发布时间】:2014-11-17 06:31:56
【问题描述】:

我遇到了一个有趣的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. 语言定义:默认情况下,所有范围都给定名称 this 和 arguments。 2. 形参:函数可以具有命名形参,其作用域为该函数的主体。 3. 函数声明:这些是函数 foo() {} 的形式。 4. 变量声明:形式为 var foo;

他后来引用了:

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

这让我很困惑,任何人都可以参考上面的例子来简化这个? 我想知道的要点:

  • 函数内没有var的变量如何提升?
  • 在提升过程中是否发生变量覆盖?

【问题讨论】:

标签: javascript scope hoisting


【解决方案1】:

让我们暂时离开函数foo。在函数内,如果在该函数内的任何位置声明了变量,则该声明将移至函数顶部。所以,其实是这样评价的

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

但是当你有一个同名的函数声明时,它会优先,并且它会被类似地评估

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

这就是为什么您会在警告框中收到function

【讨论】:

  • 谢谢,所以你的意思是说在函数作用域对象中只有一个名为 'foo' 的属性会被创建?
  • @pandit 没错...您将在不同的时间点将不同的对象分配给同一个局部变量。
【解决方案2】:

函数内没有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.

【讨论】:

  • 感谢您的招待,但我认为 thefourtheye 的答案更准确。
猜你喜欢
  • 2015-03-30
  • 2012-03-22
  • 2011-08-26
  • 1970-01-01
  • 2019-11-27
  • 2021-02-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多