7

在阅读有关 Javascript 提升的信息时,我尝试了以下方法。我不确定为什么第一个和第二个输出不同。提前致谢。(我什至不确定这与吊装有关。)

var me = 1;
function findme(){
   if(me){
    console.log( me );//output 1
    }
  console.log( me ); //output 1
}
findme();

但是,以下输出未定义。

var me = 1;
function findme(){
 if(me){
    var me = 100;
    console.log(me); 
    }
  console.log(me); 
}
findme();
// undefined
4

4 回答 4

8

变量声明被提升到每个函数的顶部,但值分配保持在原处。所以第二个例子是这样运行的:

var me = 1;
function findme () {
    var me;  // (typeof me === 'undefined') evaluates to true
    if (me) { // evaluates to false, doesn't get executed
        me = 100;
        console.log(me); 
    }
    console.log(me); 
}
findme();
于 2013-01-13T01:19:22.707 回答
3

在第二个示例中的块中对局部变量的声明if被提升到整个函数。

因此,me在函数中总是指局部变量,而不是全局变量。

但是,变量的没有被提升,所以它总是undefined并且if永远不会输入。

于 2013-01-13T01:17:52.070 回答
2

提升 avar不会提升分配,只是提升声明。所以它被这样解析:

function findme(){
  var me;
  if(me){
    me = 100;
    console.log(me); 
  }
  console.log(me); 
}

if语句运行时,me被标记为函数的局部变量,但是是undefined(没有值)。undefined是假的,所以你的条件永远不会是真的。

这就是为什么习惯上总是在函数的顶部声明局部变量的原因,因为不管你喜欢与否,这就是它们的去处。

于 2013-01-13T01:22:31.153 回答
0

我觉得这个问题的真正答案通常被“提升机”这个词抽象出来。这是真正发生的事情。

每次在 JavaScript 中运行函数时,都会为该函数创建一个新的执行上下文,并将其推送到执行堆栈中。所以在你的第二个例子中,你有以下代码:

 var me = 1;
 function findme(){
    if(me){
       var me = 100;
       console.log(me); 
    }
    console.log(me); 
 }
 findme();
 // undefined

在这段代码执行的最开始(假设这是整个 JavaScript),首先发生的是 JavaScript 引擎创建一个全局执行上下文。在创建过程中,它为该上下文中的所有函数和变量分配内存。函数按照您想象的方式分配和初始化,但变量只是首先分配(未正确初始化)。

因此,在此示例中创建全局执行上下文之后,函数 findme() 将被完整地分配到内存中,但变量“me”将被分配一个未定义的初始值。在创建全局执行上下文之后,然后运行代码。它发现 var me = 1; 并将“me”变量从 undefined 更新为 1。它实际上并没有对函数定义做任何事情,但是,它找到了“findme();”的函数调用。

此时,我们进入 findme() 函数。真的,同样的事情再次发生。为这个函数创建一个执行上下文,它被推到全局执行堆栈上,这成为运行代码。如果你理解我讨论的第一部分,我想你会意识到“console.log(me);” 在“if”语句未定义之后调用。为什么?因为在创建 findme() 函数执行上下文时,它最初创建了“me”变量,因为它在其上下文中看到了“var me = 100;” 陈述。但是,就全局执行堆栈而言,“if”语句不会获得专用的执行上下文。因此,当“console.log(me);” 在 if 之外运行 me 变量 IS 在函数的总体上下文中定义。

如果您遵循了所有这些,您现在了解了 JavaScript 引擎如何工作的主要部分。

于 2015-10-11T20:20:44.113 回答