JavaScript中的保留函数名称

时间:2018-10-01 22:15:48

标签: javascript event-handling reserved-words

重命名我的函数后,代码停止工作。这个新名称scrollIntoView似乎与element.scrollIntoView()方法冲突。

<div onmousedown="scrollIntoView('id001')"/>

function scrollIntoView(id) {
    alert(id);
}

我创建了一个简单的测试用例https://jsfiddle.net/mgtn215y/,表明我的功能甚至被element.scrollIntoView()忽略了

  • 未在元素上调用
  • 属性不匹配

解决方案很明显-使用不同的函数名称。由于此行为在主要浏览器之间是一致的,因此我希望在某处指定该行为。但是,我找不到任何相关的东西,例如JavaScript lexical grammar。这种行为有背景吗?

3 个答案:

答案 0 :(得分:2)

出于某些奇怪的原因,内联处理程序似乎在运行时隐式使用with(this),其中this引用触发事件的元素。每当您尝试引用某物时,如果某物作为this的属性存在,则该属性将最终被引用,而不是同名的外部变量:

console.log(typeof className); // Undefined in standard global scope
console.log(typeof scrollIntoView); // Undefined in standard global scope
.mydiv {
  width: 100px;
  height: 100px;
  background-color: red;
  cursor: pointer;
}
<div class="mydiv" onclick="
  console.log(typeof className); // Defined inside inline handler
  console.log(typeof scrollIntoView); // Defined inside inline handler
">

对于解释器来说,onclick实际上 看起来更像:

onclick="with(this) {
  console.log(typeof className);
  console.log(typeof scrollIntoView);
}"

这很奇怪。但是内联事件处理程序无论如何都是很糟糕的做法,可能不应该使用;使用addEventListeneronkeydown正确分配处理程序:

document.querySelector('.mydiv').onmousedown = () => scrollIntoView("id001");
function scrollIntoView(id) {
  console.log(id);
}
.mydiv {
  width: 100px;
  height: 100px;
  background-color: red;
  cursor: pointer;
}
    <div class="mydiv"></div>

答案 1 :(得分:2)

问题是从HTML源中声明的HTML元素属性值编译的函数的作用域链。形式为Pool.map myfiles.output_file的属性表现出这种行为。

出于历史原因(目前尚不存在DOM,on_eventName=functionBodyCode尚未出现……),此类函数是使用范围链编译的,该范围链包含提供了事件处理程序属性的对象,该元素所在的任何document.getElementByID元素以及form对象。 但是在模拟Netscape行为时,不同的浏览器采用了不同的方法。某些浏览器包含提供事件处理程序属性的元素的所有父对象,而其他浏览器则省略了诸如document之类的一些相关对象。

技术细节可以在“ Javascript权威指南” O'Reilly的“ 19.1.6。事件处理程序的范围”部分中找到。

主要建议是避免以HTML提供事件处理程序-而是使用document在JavaScript中添加事件处理程序。如果出于某种原因必须在HTML属性值中编码函数调用,请避免使用作为DOM对象方法的函数名称。

请注意,事件处理程序的自定义范围链仅适用于从HTML属性生成的函数。它不适用于使用JavaScript创建并使用addEventListeneraddEventListener添加到元素的函数。


以下代码段演示了在HTML中定义的事件处理程序作用域链中外部元素的属性名称::

element.onEventName=aFunctionObject

  • 在第一种形式中,<form name="formName1" action=""> <p> Try to access the elements collection of the form: <button type="button" onclick="console.log( elements);">elements </button> </p> </form> <form name="formName2" action="" onsubmit="return false"> <p> Try to access form name as form.name: <button type="button" onclick="console.log( 'form.name: %s', form.name);">form.name </button> </p> </form> <form name="formName3" action="" onsubmit="return false"> <p>Access document.write as "write" <button type="button" onclick="console.log( 'write: %s', write);">write </button> </p> </form>是周围表单元素的属性。

  • 在第二种形式中,elements是HTMLButtonElement的属性。

  • 在第三种形式中,formwrite的方法。

答案 2 :(得分:0)

要覆盖,只需尝试:

Element.prototype.scrollIntoView = function(id) {
    alert(id);
}

但是请注意,它可以与addEventListener一起使用:

var element = document.getElementById("element");

function scrollIntoView(id) {
    alert(id);
}

element.addEventListener("mousedown", function() {
    scrollIntoView("id001");
});
div {
  width: 100px;
  height: 100px;
  background-color: red;
  cursor: pointer;
}
<div id="element"></div>