我有一个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
要在这里添加一些细节,你需要了解javascript的范围链.
范围对象
范围对象是在执行函数时创建的隐藏对象,其中声明的变量var作为属性放置,function执行函数内部的任何命名也都作为属性放置在范围对象上.
当诸如mytest请求的标识符javascript搜索附加到当前范围对象的那个名称时(btw,范围对象也称为"执行上下文").
范围链
在函数内声明函数时,当前作用域对象将附加到函数.当此内部函数正在执行时(因此具有自己的作用域对象),执行的代码不仅可以访问当前作用域对象,还可以访问创建当前正在执行的函数的作用域对象. 停在这里,重新阅读最后一句话. 这被称为范围链,链将与函数内部的函数一样深(当使用像JQuery这样的框架时会发生这种情况).
因此,当在当前范围对象上搜索标识符失败时,它会查看链上的下一个范围对象.它一直向上走,直到它到达全局对象(在全局级别声明的函数将全局对象作为其范围对象).
事件属性怪异
当浏览器在诸如onclick之类的属性的文本内执行代码时,它会将此代码视为一个函数.但是,浏览器会使用附加到此"功能"的明显范围链来执行奇怪的操作.通常,它们将当前元素和文档元素(以及其间的其他元素)注入到作用域链中,就好像它们是作用域对象一样.
例如,将示例中的onclick代码更改为"alert(href)".您将#在警告框中看到页面的路径.这是因为当前元素在作用域链中,因此href由其href属性解析.
在问题的情况下,代码到达document范围链(位于全局窗口对象上方)并找到标识符"mytest"(它是对表单的引用),因此尝试使用该值作为一个函数(并失败).
该函数是window对象中的成员,表单是对象中forms集合的成员document.当脚本查找标识符"mytest"的匹配时,它首先查找document对象,如果找不到它,则查找window对象.
如果您指定它在window对象中,则即使使用冲突的表单名称,也可以访问该函数:
<a href="#" onClick="window.mytest();">Click Me</a>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2311 次 |
| 最近记录: |