JavaScript:How是什么;函数onload(){}";不同于;onload=function(){}";?
在对的回答中,我们看到JavaScript:How是什么;函数onload(){}";不同于;onload=function(){}";?,javascript,scope,Javascript,Scope,在对的回答中,我们看到函数f(){}在本地定义名称,而[var]f=function(){}在全局定义名称。这对我来说很有道理,但是两个声明之间有一些奇怪的行为是不同的 我用脚本制作了一个HTML页面 onload = function() { alert("hello"); } 这一切都如期而至。当我把它改成 function onload() { alert("hello"); } 什么也没发生。(Firefox仍然发起了这一事件,但WebKit、Opera和Intern
函数f(){}
在本地定义名称,而[var]f=function(){}
在全局定义名称。这对我来说很有道理,但是两个声明之间有一些奇怪的行为是不同的
我用脚本制作了一个HTML页面
onload = function() {
alert("hello");
}
这一切都如期而至。当我把它改成
function onload() {
alert("hello");
}
什么也没发生。(Firefox仍然发起了这一事件,但WebKit、Opera和Internet Explorer没有,尽管坦率地说,我不知道哪一个是正确的。)
在这两种情况下(在所有浏览器中),我都可以验证window.onload
和onload
是否都设置为该函数。在这两种情况下,全局对象this
被设置为窗口,无论我如何编写声明,window
对象都能很好地接收属性
这是怎么回事?为什么一个声明与另一个不同?这是JavaScript语言、DOM的怪癖还是两者之间的交互
var onload = function() {
alert("hello");
}
也会在当地申报
我建议您阅读这篇非常有用的文章:许多人都正确地指出了两者之间的全球/本地差异(更新:这些答案现在大多已被作者删除) 及 但这并没有真正回答你的具体问题,因为你实际上并没有做第一个问题 在您的示例中,两者之间的区别是:
// Adds a function to the onload event
onload = function() {
alert("hello");
}
鉴于
// Declares a new function called "onload"
function onload() {
alert("hello");
}
根据Tim Down的有益评论和与Jonathan Penn的简短讨论,以下是我认为正在发生的事情: 当JavaScript解释器分配给
window.onload
属性时,它正在与浏览器提供给它的对象对话。它调用的setter注意到该属性被称为onload
,因此转到浏览器的其余部分,并连接适当的事件。所有这些都超出了JavaScript的范围——脚本只看到属性已设置
当您编写声明
函数onload(){}
时,setter不会以完全相同的方式被调用。由于声明导致赋值发生在解析时,而不是计算时,脚本解释器将继续创建变量,而不告诉浏览器;或者窗口对象未准备好接收事件。不管它是什么,浏览器都没有机会看到赋值,就像您编写通过常规setter例程的onload=function(){}
时一样。没有绑定
function onload() { ... }
此代码段将函数分配给当前作用域中名为“onload”的属性/变量/字段:
onload = function() { ... }
Firefox执行绑定并在第一个代码段上引发onload事件,而其他人没有这样做的原因可能是因为Firefox chrome(其用户界面)本身是使用JavaScript编写和自动化的——这就是为什么它如此灵活且易于在其上编写扩展的原因。不知何故,当您以这种方式声明本地作用域的
onload
函数时,当其他浏览器将声明正确地“沙盒”到另一个作用域时,Firefox“替换”了窗口的实现(最有可能是当时的本地上下文)(例如,global
或其他内容)。这会生成一个错误:
foo();
var foo = function(){};
这并不是:
foo();
function foo(){}
因此,当您使用函数模块化和组织代码时,第二种语法更好,而第一种语法更适合作为数据范例的函数。最简单的解释是:
function aaaaaaa(){
可在声明之前使用:
aaaaaaa();
function aaaaaaa(){
}
但这不起作用:
aaaaaaa();
aaaaaaa=function(){
}
这是因为在第三段代码中,您将aaaaaaa分配给匿名函数,而不是将其声明为函数。这是一篇很棒的文章,但它没有回答问题。可能是因为后者在解析时得到评估,所以窗口
对象还没有准备好接受事件?真的吗?将函数分配给<根据我的经验,code>window.onload
工作得很好。根据ECMAScript 3规范,var x=function(){…};
和function x(){…}
应该设置同一个变量对象的属性,在全局代码的情况下,这个变量对象是全局对象,在大多数浏览器中,它或多或少等同于窗口
,因此您的答案并不能真正回答这个问题。@Sohnee:我的观点是var x=function(){…}之间没有“全局/局部差异”;
和函数x(){…}
在同一范围内声明。我开始怀疑这是Webkit/Opera中的一个bug,并且Firefox具有正确的行为。两者本身都不正确。全局对象(窗口引用的对象)可能具有主机定义的属性(例如onload
)ECMAScript 3实现可以自由实现它认为合适的属性的行为,包括内部[[Put]]
方法,该方法在指定属性值时调用。在Firefox 3.5.5中,如果使用onload=function(){…};
但不使用var onload=function(){…},我会看到警告
我不确定是否会出现奇迹,但基于观察到的不一致性,我当然建议不要使用var-onload=…
和function-onload(){…}
表单。window.onload=function(){…};
不是任何当前标准的一部分,但与
一样,跨浏览器几乎普遍支持。window.addEventListener
和window.attachEvent
的组合将允许您在所有主要浏览器中添加多个事件处理程序,但请注意两者之间的差异。这与您无关你的问题,但是你
function aaaaaaa(){
aaaaaaa();
function aaaaaaa(){
}
aaaaaaa();
aaaaaaa=function(){
}