您的代碼實際上是很好,你只是選擇了一個不幸的名稱爲全球: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