Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/472.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript:How是什么;函数onload(){}";不同于;onload=function(){}";?_Javascript_Scope - Fatal编程技术网

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(){

}