我有两个片段,为什么第一个给出值,而第二个给出未定义?
代码段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;
答案 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
已定义。