您的代码实际上是很好,你只是选择了一个不幸的名称为全球:name
。如果将其更改为其他(如foo
),它的工作原理:http://jsfiddle.net/6nuCx/1/
造成这种情况的原因是有点模糊。全局变量成为window
对象的属性。但window
对象已经有一个名为name
的属性,它是该窗口的名称。我很惊讶地发现你的代码没有工作,因为我希望你的代码覆盖窗口的名字。但显然不是。 (这就是为什么它是最好避免全局变量一个伟大例子。)无论如何,选择不同变量名,一个不与现有name
财产冲突,梳理出来。
但是你没有在你的代码的东西,可能是不明显的,所以让我们深入到多一点深深的(在这里我使用了foo
版本,以避免混乱):
// Here, you're defining a global variable called `foo`
var foo ='John';
// Here you have a global function, `displayName`, which accepts an
// *argument* named `foo`
function displayName(foo)
{
// Here, within the function, the symbol `foo` refers to the
// *argument*, not to the global. The global is *hidden* by
// the argument (this is called "shadowing" -- the local
// "shadows" the global).
alert('Hi I am '+foo);
}
,并在你的HTML:
<!-- Here, `foo` refers to the global variable -->
<button type="button" onclick="displayName(foo)">Display Name</button>
如果我们改变参数的名称可能是清晰的:
var foo ='John';
function displayName(f)
{
alert('Hi I am '+f);
}
和HTML是不变的:
<!-- Here, `foo` refers to the global variable -->
<button type="button" onclick="displayName(foo)">Display Name</button>
在上面,我说,这是最好的避免全局变量,你的问题是,为什么一个很好的例子。那么我们该怎么做?那么,主要是通过避免DOM0处理程序(如您的onclick
中的那个)。这里是你会如何改写你的提琴:Live copy
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<button id="theButton" type="button">Display Name</button>
<script type="text/javascript">
// Start a "scoping function"
(function() {
// Everything within this function is local to the function,
// not global
var name = 'John';
function displayName(n)
{
alert('Hi I am ' + n);
}
// Instead of the onclick= in the markup, hook up here in
// the code
document.getElementById("theButton").onclick = function() {
displayName(name);
};
})();
</script>
</body>
</html>
注意我们是如何自由使用name
,因为我们没有创造或全局交互。另外请注意,我在代码之后的这个按钮,因为代码假定按钮已经存在。
更好的是,使用addEventListener
或attachEvent
来连接处理程序。
var btn = document.getElementById("theButton");
if (btn.addEventListener) {
btn.addEventListener("click", handler, false);
}
else if (btn.attachEvent) {
btn.attachEvent("onclick", handler);
}
else {
// Punt!
btn.onclick = handler;
}
function handler() {
display(name);
}
正如你所看到的,我们必须同时处理,因为旧版本的IE(或“兼容模式”较新的)不具有addEventListener
。这是使用像jQuery这样的库的一个原因,但我知道你试图扩大你的理解,没有一个,并有充分的理由。最好的!
最后,你问:
我知道,我可以把我的变量在我的功能修复它,但有一个方法来调用我的函数外声明我的第一个变量(变量就在脚本类型之后)?
以上都没有答案。 :-)答案是:是的,你可以参考它直接,通过去除阴影,全球的说法:Live example
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var foo ='John';
// Note: No argument declared
function displayName()
{
// Because the argument doesn't shadow it, we can refer
// to foo, because foo is declared in an *enclosing
// context*
alert('Hi I am '+foo);
}
</script>
</head>
<body>
<!-- Note we don't pass any argument ------v -->
<button type="button" onclick="displayName()">Display Name</button>
</body>
</html>
@Crowder辉煌 – codingbiz 2012-07-28 17:52:53
非常好的答案!我很感激THX! – 2012-07-28 17:54:34
这很好!另一件事是OP不能访问全局变量,因为它被本地变量所影响。但是,由于他通过函数调用传递了全局变量,它本应该起作用。 – 2012-07-28 17:56:37