“清除”是 Javascript 中的保留字吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7165570/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 23:09:43  来源:igfitidea点击:

Is "clear" a reserved word in Javascript?

javascript

提问by Uncle Vinny

I just spent a long time figuring out that I shouldn't use clear() as the name of a function in Javascript:

我花了很长时间才弄清楚我不应该在 Javascript 中使用 clear() 作为函数的名称:

<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>

Here's Array.js:

这是 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";
}

Symptoms: Clicking the 'add' and 'check' buttons gives me the result I expect, but clicking the 'clear' button does nothing.

症状:单击“添加”和“检查”按钮会得到我期望的结果,但单击“清除”按钮什么也没做。

If I rename clear()to clearxyz(), it works fine.

如果我将clear()重命名为clearxyz(),它工作正常。

My questions:

我的问题:

  1. Is "clear" a reserved word? I don't see it on the list: https://developer.mozilla.org/en/JavaScript/Reference/Reserved_Words
  2. Is there a debugging trick I should be using to figure this kind of thing out in the future? It took me a long time (I'm a noob!) to figure out that the name of the function was my problem.
  1. “clear”是保留字吗?我没有在列表中看到它:https: //developer.mozilla.org/en/JavaScript/Reference/Reserved_Words
  2. 我将来是否应该使用调试技巧来解决此类问题?我花了很长时间(我是菜鸟!)才发现函数的名称是我的问题。

Many thanks. Edit: I'm using Firefox 6.0, and I added a line break to show where Array.js starts.

非常感谢。编辑:我使用的是 Firefox 6.0,我添加了一个换行符来显示 Array.js 的开始位置。

回答by Felix Kling

As the others said, clearis nota reserved keyword. It seems that the called function is document.clear[MDN]. Invoking

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

console.log(clear === document.clear);

inside the event handler returns true.

在事件处理程序中返回true

DEMO

演示

So it seems, documentis in the scope chain of the event handler.... the question now is why.

所以看起来,document在事件处理程序的作用域链中......现在的问题是为什么。

JavaScript: The Definitive Guidesays:

JavaScript:权威指南说:

In an event handler as HTML attribute, the Document object is in the scope chain before the Window object (...)

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

As your method is global, meaning it is a property of the windowobject, it is not found in the scope chain, as document.clearcomes earlier in the scope chain.

由于您的方法是全局的,这意味着它是window对象的一个属性,因此在作用域链中找不到它,就像document.clear在作用域链中一样。

I haven't found any specification for this. The guide also says that one should not rely on that, so I assume this is nothing official.

我还没有找到任何规范。该指南还说人们不应该依赖它,所以我认为这不是官方的。

If you have form elements inside a form, then even the corresponding formelement will be in the scope chain (not sure whether this holds for all browsers though). This is another reason for confusion.

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



There are two (not exclusive) ways to avoid such situations:

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

  • Don't use inline event handlers.It is considered bad practice as it is mixing logic and presentation. There are otherwaysto attach event handlers.

  • Don't pollute the global namespace.Create one object in global scope (with a name you are sure of does not collide with any windowor documentproperties or ids of HTML elements) and assign the functions as properties of this object. Whenever you call a function, you reference it through this object. There also other waysto namespace your code.

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

  • 不要污染全局命名空间。在创建全球范围内一个对象(一个名字你肯定不会有任何碰撞windowdocument属性或HTML元素的IDS)和分配功能,因为这对象的属性。每当你调用一个函数时,你就是通过这个对象来引用它的。还有其他方法可以命名您的代码。

回答by bejonbee

Not according to the MDN.

不是根据MDN

Edit:

编辑:

You got me curious, so I threw together this little jsfiddle.

你让我好奇,所以我把这个小 jsfiddle放在一起。

function clear() {
    alert("you cleared just fine");
}

$('clear').addEvent('click', clear);

Having a function named clearseems to work just fine.

有一个命名的函数clear似乎工作得很好。

回答by rosscj2533

Good question. I think the problem is a scoping issue - your onClick="clear()"is not going to the clearfunction you defined, but I'm not sure where it's going. Changing it to window.clear()or a new function that simply calls your clearworks.

好问题。我认为这个问题是一个范围问题 - 你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>

回答by Oriol

No, clearis not a reserved keyword.

不,clear不是保留关键字。

The problem is that, since you use an event handler content attribute, your global function window.clearis shadowed by the obsolete document.clear.

问题是,由于您使用事件处理程序内容属性,您的全局函数window.clear被过时的document.clear.

This behavior is explained in step 10of getting the current value of the event handler:

此行为在获取事件处理程序的当前值的第 10 步中进行解释:

Lexical Environment Scope

  1. If His an element's event handler, then let Scopebe the result of NewObjectEnvironment(document, the global environment).

    Otherwise, His a Windowobject's event handler: let Scopebe the global environment.

  2. If form owneris not null, let Scopebe the result of NewObjectEnvironment(form owner, Scope).

  3. If elementis not null, let Scopebe the result of NewObjectEnvironment(element, Scope).

Note: NewObjectEnvironment() is defined in ECMAScript edition 5 section 10.2.2.3 NewObjectEnvironment (O, E)

词法环境范围

  1. 如果H是元素的事件处理程序,则让Scope成为 NewObjectEnvironment( document全局环境) 的结果。

    否则,H是一个Window对象的事件处理程序:让 Scope成为全局环境

  2. 如果表单所有者不为空,则让Scope为 NewObjectEnvironment( form owner, Scope) 的结果。

  3. 如果element不为 null,则令Scope为 NewObjectEnvironment( element, Scope) 的结果。

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

That means that the global scope is shadowed by

这意味着全局范围被

  1. The document
  2. The form owner, if any
  3. The element
  1. 文件
  2. 表单所有者(如果有)
  3. 元素

Therefore, you can

因此,您可以

  • Rename your function.

    function clear__() { document.body.style.background = 'green'; }
    <button type="button" onclick="clear__()">Click me</button>

    This approach is not completely reliable because some browser could implement a non-standard feature which shadows your variables. Or a future spec could introduce that feature (example).

  • Call your function as a method of the global object.

    For example, assuming windowis not shadowed, you can use window.clear.

    function clear() { document.body.style.background = 'green'; }
    <button type="button" onclick="window.clear()">Click me</button>

  • Avoid event handler content attributes.

    Instead, you can use event handler IDL attributes or event listeners.

    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>

  • 重命名您的函数。

    function clear__() { document.body.style.background = 'green'; }
    <button type="button" onclick="clear__()">Click me</button>

    这种方法并不完全可靠,因为某些浏览器可能会实现隐藏变量的非标准功能。或者未来的规范可以引入该功能(示例)。

  • 调用您的函数作为全局对象的方法。

    例如,假设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>