Javascript函数和表单名称冲突

Ton*_*orf 7 javascript

我有一个javascript函数,无法运行并抛出错误.花了大约一个小时才意识到我的表单与函数名称相同.表单名称与函数名称冲突似乎很奇怪,但我仍然更改名称,一切正常.有谁知道为什么会发生这种情况?

如果您运行此代码它将失败,但如果您更改表单名称它是有效的,非常奇怪.

<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script type="text/javascript">
function mytest(){alert("hello");}
</script>
</head>
<body>
<form name="mytest" ></form>
<a  href="#" onClick="mytest();">Click Me</a>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

我在IE6上运行它.对我来说奇怪的是,一个是Javascript代码,另一个是HTML的属性.

实时链接,你可以看到这种情况:
JSBin

Ant*_*nes 7

要在这里添加一些细节,你需要了解javascript的范围链.

范围对象

范围对象是在执行函数时创建的隐藏对象,其中声明的变量var作为属性放置,function执行函数内部的任何命名也都作为属性放置在范围对象上.

当诸如mytest请求的标识符javascript搜索附加到当前范围对象的那个名称时(btw,范围对象也称为"执行上下文").

范围链

在函数内声明函数时,当前作用域对象将附加到函数.当此内部函数正在执行时(因此具有自己的作用域对象),执行的代码不仅可以访问当前作用域对象,还可以访问创建当前正在执行的函数的作用域对象. 停在这里,重新阅读最后一句话. 这被称为范围链,链将与函数内部的函数一样深(当使用像JQuery这样的框架时会发生这种情况).

因此,当在当前范围对象上搜索标识符失败时,它会查看链上的下一个范围对象.它一直向上走,直到它到达全局对象(在全局级别声明的函数将全局对象作为其范围对象).

事件属性怪异

当浏览器在诸如onclick之类的属性的文本内执行代码时,它会将此代码视为一个函数.但是,浏览器会使用附加到此"功能"的明显范围链来执行奇怪的操作.通常,它们将当前元素和文档元素(以及其间的其他元素)注入到作用域链中,就好像它们是作用域对象一样.

例如,将示例中的onclick代码更改为"alert(href)".您将#在警告框中看到页面的路径.这是因为当前元素在作用域链中,因此href由其href属性解析.

在问题的情况下,代码到达document范围链(位于全局窗口对象上方)并找到标识符"mytest"(它是对表单的引用),因此尝试使用该值作为一个函数(并失败).


Guf*_*ffa 6

该函数是window对象中的成员,表单是对象中forms集合的成员document.当脚本查找标识符"mytest"的匹配时,它首先查找document对象,如果找不到它,则查找window对象.

如果您指定它在window对象中,则即使使用冲突的表单名称,也可以访问该函数:

<a href="#" onClick="window.mytest();">Click Me</a>
Run Code Online (Sandbox Code Playgroud)

  • 它还取决于浏览器.IE使用成员为页面上声明ID或NAME属性的每个元素污染全局命名空间.不用说它会导致很多问题.也就是说,由于在大多数情况下需要支持IE,因此最好尝试确保您的函数名称不会与页面中元素的名称/ id值冲突. (2认同)