在声明之前引用JavaScript值 – 有人可以解释这一点
我希望有人能向我解释为什么当在浏览器中查看HTML时,下面的JavaScript / HTML将显示“门#2”:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <script type="text/javascript"> function testprint() { alert('door #1'); }; window.onload = testprint; function testprint() { alert('door #2'); }; testprint = function() { alert('door #3'); }; </script> <script type="text/javascript"> function testprint() { alert('door #4'); }; </script> </head> <body> </body> </html>
由于在window.onload
设置为testprint
之前只有声明testprint
,所以我期望window.onload
原因'door#1'出现。 其实,onload会导致“2号门”。 请注意,无论是否包含testprint
的第一个声明,都testprint
。
testprint
的第三个和第四个声明使用不同的方式来分配函数,我试着看看它是否会覆盖window.onload
的行为,同样是testprint
的第二个声明。 它没有。 请注意,如果将testprint
的第四个声明移动到第一个脚本块的末尾,它将被window.onload
调用。
函数声明是提升的对象,并且在parsing时被评估,通过提升意味着它们可以被声明在整个范围内,例如:
foo(); // alerts foo foo = function () { alert('bar')}; function foo () { alert('foo');} foo(); // alerts bar
foo
的第一个调用将执行函数声明 ,因为在parsing时它是可用的, foo
的第二个调用将执行在运行时声明的函数expression式 。
有关函数expression式和函数声明之间差异的更详细的讨论,请查看这个问题和这篇文章 。
原因#3不会改变window.onload是函数被引用调用,而不是名称。 当您设置window.onload = testprint
,它将对testprint
的当前值(门#2,如CMS所解释)分配给window.onload
。 稍后更改testprint
的值不会影响window.onload
的值。
4号门不会覆盖2号门(除非,如你所说,将其移动到第一个脚本块),因为它位于不同的脚本块中,所以在第一个块完成之后将被parsing。
函数testprint是全局的页面。 testprint = function …指定了一个variables,我不能确定整个范围,但是我发现它并没有像第一个那样添加到函数表字典中。