我花了很长时间搞清楚我不应该使用clear()作为Javascript函数的名称:
<head>
<script type="text/javascript" src="Array.js"></script>
</head>
<body>
Hello!!!!<br>
<button type="button" onClick="clear()" id="ppp">Shoo!</button><br>
<button type="button" onClick="add()" id="add">Add a few elements</button><br>
<button type="button" onClick="check()" id="check">Check the array</button><br>
<p id="results">Results will appear here.</p>
<script type="text/javascript">
initialize();
</script>
</body>
这是Array.js:
var results;
function initialize(){
results = document.getElementById("results");
}
function add() {
results.firstChild.data="add";
}
function clear() {
results.firstChild.data = "Hello?";
}
function check() {
results.firstChild.data = "check";
}
症状:点击“添加”和“检查”按钮可以得到我期望的结果,但点击“清除”按钮不会产生任何效果。
如果我将 clear()重命名为 clearxyz(),则可以正常使用。
我的问题:
非常感谢。 编辑:我正在使用Firefox 6.0,我添加了换行符以显示Array.js的启动位置。
答案 0 :(得分:35)
正如其他人所说,clear
不是保留关键字。似乎被调用的函数是document.clear
[MDN]。调用
console.log(clear === document.clear);
事件处理程序内的返回true
。
看来,document
位于事件处理程序的范围链中......现在的问题就是原因。
JavaScript: The Definitive Guide说:
在作为HTML属性的事件处理程序中,Document对象位于Window对象(...)之前的作用域链中
由于您的方法是全局的,意味着它是window
对象的属性,因此在范围链中找不到它,因为document.clear
在范围链的早期出现。
我还没有找到任何规范。该指南还说,不应该依赖于此,所以我认为这不是正式的。
如果表单中有表单元素,那么即使相应的form
元素也会在作用域链中(不确定这是否适用于所有浏览器)。这是混淆的另一个原因。
有两种(非排他性)方法可以避免这种情况:
不要污染全局命名空间。在全局范围内创建一个对象(您确定的名称不会与任何window
或{{1}发生冲突HTML元素的属性或ID)并将函数指定为此对象的属性。无论何时调用函数,都可以通过此对象引用它。还有other ways来命名您的代码。
答案 1 :(得分:2)
不符合MDN。
编辑:
你让我很好奇,所以我把this little jsfiddle放在了一起。
function clear() {
alert("you cleared just fine");
}
$('clear').addEvent('click', clear);
拥有一个名为clear
的函数似乎工作正常。
答案 2 :(得分:2)
好问题。我认为这个问题是一个范围问题 - 你的onClick="clear()"
没有进入你定义的clear
函数,但我不确定它的发展方向。将其更改为window.clear()
或仅调用clear
的新功能。
<body>
Hello!!!!<br>
<button type="button" onClick="clear()" id="ppp">Shoo!</button><br>
<button type="button" onClick="window.clear()" id="ppp">window.clear!</button><br>
<button type="button" onClick="clear2()" id="ppp">clear2!</button><br>
<button type="button" onClick="add()" id="add">Add a few elements</button><br>
<button type="button" onClick="check()" id="check">Check the array</button><br>
<p id="results">Results will appear here.</p>
<script type="text/javascript">
var results;
function initialize(){
results = document.getElementById("results");
}
function add() {
results.firstChild.data="add";
}
function clear() {
results.firstChild.data = "Hello";
}
function clear2() {
clear();
}
function check() {
results.firstChild.data = "check";
}
initialize();
</script>
</body>
答案 3 :(得分:1)
不, clear
不是保留关键字。
问题是,由于您使用的是event handler content attribute,因此您的全局函数window.clear
会被过时的document.clear
所遮蔽。
此问题在step 10的getting the current value of the event handler中解释:
词汇环境范围
如果 H 是元素的event handler,那么让 Scope 成为NewObjectEnvironment( document , 全球环境)。
否则, H 是
Window
对象的event handler:让 范围是全球环境。如果表单所有者不为null,请将作用域作为NewObjectEnvironment的结果(表单所有者,作用域< / em>的)。
- 醇>
如果元素不为null,请将范围作为NewObjectEnvironment(元素,范围)的结果。
注意: NewObjectEnvironment()在ECMAScript第5版第10.2.2.3 NewObjectEnvironment (O, E)部分中定义
这意味着全局范围被
遮蔽因此,你可以
重命名您的功能。
function clear__() { document.body.style.background = 'green'; }
<button type="button" onclick="clear__()">Click me</button>
这种方法并不完全可靠,因为某些浏览器可能会实现影响变量的非标准功能。或者未来的规范可能会引入该功能(example)。
将您的函数作为全局对象的方法调用。
例如,假设window
未加阴影,您可以使用window.clear
。
function clear() { document.body.style.background = 'green'; }
<button type="button" onclick="window.clear()">Click me</button>
避免事件处理程序内容属性。
相反,您可以使用事件处理程序IDL属性或事件侦听器。
function clear() { document.body.style.background = 'green'; }
document.querySelector('button').onclick = clear;
<button type="button">Click me</button>
function clear() { document.body.style.background = 'green'; }
document.querySelector('button').addEventListener('click', clear);
<button type="button">Click me</button>