“明确”是Javascript中的保留字吗?

时间:2011-08-23 18:08:45

标签: javascript

我花了很长时间搞清楚我不应该使用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(),则可以正常使用。

我的问题:

  1. “清楚”是一个保留字吗?我没有在列表中看到它: https://developer.mozilla.org/en/JavaScript/Reference/Reserved_Words
  2. 我是否应该使用调试技巧来计算这种情况 未来的事情?我花了很长时间(我是一个菜鸟!) 弄清楚函数的名称是我的问题。
  3. 非常感谢。 编辑:我正在使用Firefox 6.0,我添加了换行符以显示Array.js的启动位置。

4 个答案:

答案 0 :(得分:35)

正如其他人所说,clear 是保留关键字。似乎被调用的函数是document.clear [MDN]。调用

console.log(clear === document.clear);
事件处理程序内的

返回true

DEMO

看来,document位于事件处理程序的范围链中......现在的问题就是原因。

JavaScript: The Definitive Guide说:

  

在作为HTML属性的事件处理程序中,Document对象位于Window对象(...)之前的作用域链中

由于您的方法是全局的,意味着它是window对象的属性,因此在范围链中找不到它,因为document.clear在范围链的早期出现。

我还没有找到任何规范。该指南还说,不应该依赖于此,所以我认为这不是正式的。

如果表单中有表单元素,那么即使相应的form元素也会在作用域链中(不确定这是否适用于所有浏览器)。这是混淆的另一个原因。


有两种(非排他性)方法可以避免这种情况:

  • 不要使用内联事件处理程序。它被认为是不好的做法,因为它混合了逻辑和表示。有other ways附加事件处理程序。

  • 不要污染全局命名空间。在全局范围内创建一个对象(您确定的名称不会与任何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 10getting the current value of the event handler中解释:

  

词汇环境范围

     
      
  1. 如果 H 是元素的event handler,那么让 Scope 成为NewObjectEnvironment( document 全球环境)。

         

    否则, H Window对象的event handler:让   范围全球环境

  2.   
  3. 如果表单所有者不为null,请将作用域作为NewObjectEnvironment的结果(表单所有者作用域< / em>的)。

  4.   
  5. 如果元素不为null,请将范围作为NewObjectEnvironment(元素,范围)的结果。

  6.         

    注意: NewObjectEnvironment()在ECMAScript第5版第10.2.2.3 NewObjectEnvironment (O, E)部分中定义

这意味着全局范围被

遮蔽
  1. 文件
  2. 表单所有者(如果有)
  3. 元素
  4. 因此,你可以

    • 重命名您的功能。

      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>