为什么有时在调用变量后定义变量并不给出undefined?

时间:2014-05-04 23:23:05

标签: javascript

我有两个片段,为什么第一个给出值,而第二个给出未定义

代码段1:

function sayAlice() {
    var sayAlert = function() { alert(alice); }
    var alice = 'Hello Alice';
    return sayAlert;
}
var hi = sayAlice() ;
hi();//alert Hello Alice

代码段2:

alert(i); // alert undefined
var i = 1; 

5 个答案:

答案 0 :(得分:1)

你的问题是:

  

为什么有时在调用变量后定义变量不会   给undefined?

然后你提供这个例子:

alert(i); // alert undefined
var i = 1; 

它会提醒undefined,因为您在定义alert()之前发出了i

在第一个例子中:

function sayAlice() {
    var sayAlert = function() { alert(alice); }
    var alice = 'Hello Alice';
    return sayAlert;
}
sayAlice()() //alert Hello Alice

同样的行为是可以预料到的,但似乎你用sayAlice调用()()的奇怪方式发生了两次。这基本上意味着它可能会很快发生,但第一次调用sayAlice()将设置alice变量,但alert很可能发生在第二次迭代中,调用时间为{{1} }}

等待。再看一遍,这就是第一个例子中发生的事情。这只是将sayAlice()()定义为一个函数,但实际上并没有运行它:

sayAlert

但是你这样做了:

var sayAlert = function() { alert(alice); }

var alice = 'Hello Alice'; 分配值。然后你终于这样做了:

alice

前两项后会发生这种情况。意思是,在第三行你定义了一个函数,然后定义了一个变量,但它只在最后一行汇总。

这对我有意义。但return sayAlert; 加倍sayAlice()()似乎很奇怪。

答案 1 :(得分:1)

在运行之前,所有变量声明都由javascript解释器移动到其作用域的顶部。这意味着这样的事情:

function sayAlice() {
    var sayAlert = function() { alert(alice); }
    var alice = 'Hello Alice';
    return sayAlert;
}
sayAlice()() //alert Hello Alice

相当于:

function sayAlice() {
    var sayAlert, alice;
    sayAlert = function() { alert(alice); }
    alice = 'Hello Alice';
    return sayAlert;
}
sayAlice()() //alert Hello Alice

当你致电sayAlice()()时,它首先会解析sayAlice(),它会返回函数sayAlert,绑定到变量alice,其值为'Hello Alice'。只要内部函数可以访问外部变量,该变量将保留其范围。因此,在分配sayAlert即alice = 'Hello Alice'之后的行修改了由sayAlert函数引用的变量。那么在调用时你会得到预期的结果“Hello Alice”。

答案 2 :(得分:1)

您拥有inside匿名函数closure。闭包有点带来他们的环境,并可以从中访问局部变量。

MDN article描述了一个与您非常相似的案例。

另请查看What exactly does “closure” refer to in JavaScript? SO帖子。

答案 3 :(得分:1)

发生这种情况是因为在第二个片段中,变量“i”未在警报执行时定义,但在第一个片段中,会发生的是行中的

var sayAlert = function() { alert(alice); }

您将'sayAlert'定义为函数,但此时此函数不会执行。之后,您定义变量'alice',之后返回'sayAlert',在那一刻,是执行警报的时候,变量'alice'已经有了值。

答案 4 :(得分:0)

尝试这段代码,你会得到完全不同的结果......

function sayAlice() {
    var sayAlert = function() { alert(alice); }
    return sayAlert;
    var alice = 'Hello Alice';
}

因为在调用函数时未定义alice。在您的示例中,alice已定义。