我有两个功能:
doSomething = function() {
alert(this);
}
var doSomethingElse = function() {
alert(this);
}
这是我的HTML:
<div id="banner-message">
<p>Hello World</p>
<button id='button1' onclick='doSomething()'>Do Something</button>
<button id='button2' onclick='doSomethingElse()'>Do Something Else</button>
</div>
为什么doSomething()
函数调用不起作用,而doSomethingElse()
不起作用?
答案 0 :(得分:2)
有细微的差别。这将在全局范围内创建doSomething
:
doSomething = function()
这将在当前范围内创建doSomething
:
var doSomething = function()
后者之所以不起作用,是因为您正在范围内(闭包,window.onload = function() {}
,$(function() {})
等)内执行此代码,因此该变量在范围外不可用。在小提琴中,JavaScript代码包装在window.onload = function() { var doSomethingElse = ... }
中。
答案 1 :(得分:2)
为什么doSomething()函数调用起作用而doSomethingElse()不起作用?
仅当您显示的代码不在全局范围内时,这才是正确的(提琴中的代码包装在jsFiddle本身提供的onload
处理程序中,请参见JavaScript窗格上的选项-这是jsFiddle更为荒谬 令人惊讶的默认选项之一)。原因是我所说的The Horror of Implicit Globals。通过不在此代码中声明doSomething
:
doSomething = function() {
alert(this);
}
...您正在创建一个名为doSomething
的 global 变量。但是,通过在此代码中声明doSomethingElse
:
var doSomethingElse = function() {
alert(this);
}
...您正在该代码存在的范围内创建一个 local 变量。
为什么重要?因为您在旧的onXYZ
属性样式事件处理程序中调用的任何函数都必须是全局函数。
相反:
使用严格模式("use strict"
),以便将其分配给未声明的标识符是错误的,而不是创建自动全局标识符。
使用现代事件处理(addEventListener
等),而不是需要全局函数的onXYZ
属性类型的事件处理程序。
将script
标记放在文档正文的末尾,即</body>
结束标记的前面,以便在代码运行之前创建HTML定义的所有元素。 (然后,您不需要onload
或类似的处理程序。)
例如(堆栈片段为您在script
的末尾放置自动body
标签):
"use strict";
// Scoping function to avoid creating globals
(function() {
var doSomething = function() {
console.log("doSomething");
};
var doSomethingElse = function() {
console.log("doSomethingElse");
};
document.getElementById("button1").addEventListener("click", doSomething);
document.getElementById("button2").addEventListener("click", doSomethingElse);
})();
<div id="banner-message">
<p>Hello World</p>
<button id='button1'>Do Something</button>
<button id='button2'>Do Something Else</button>
</div>