不能在javascript中使用“下载”作为函数名

IT技术 javascript google-chrome
2021-02-15 18:09:15

我遇到了这个小片段的问题:

<script>
function download() {
    alert('Hi');
}
</script>
<a href="#" onClick="javascript:download();">Test</a>

单击 Chrome 14.0 中的链接后,我会得到一个

Uncaught TypeError: string is not a function

在 Firefox 和 IE 中它工作得很好。我通过重命名函数解决了这个问题,但我仍然很好奇 Chrome 中的“下载”是什么。据我所知,这不是保留关键字,那可能是什么?

2个回答

<a>元件具有一个download作为解释HTML5属性这里,用默认值""(空字符串)。

这意味着download === this.downloadonclick处理程序中(this属性中的元素onevent),因此download元素属性优于 的download属性window

这个小提琴列出了默认情况下存在的所有字符串属性。您可以看到download一个类似于 的属性innerHTML当用作函数时,它以完全相同的原因失败(即尝试引用window.innerHTML,而是执行elem.innerHTML())。

正如评论中所说, usingwindow不会混淆属性/属性变量将评估为什么。


这种作用域行为实际上似乎不是由于this值,而是由于正在构建的特定“作用域链”。

根据HTML5 规范

词法环境范围

Scope成为 的结果NewObjectEnvironment(the element's Document, the global environment)

如果该元素有一个表单所有者,那么 letScope是 的结果NewObjectEnvironment(the element's form owner, Scope)

Scope成为 的结果NewObjectEnvironment(the element's object, Scope)

即正在发生的事情是范围链是window-> document-> element(增加优势)。这意味着download评估为element.download而不是window.download从中也可以得出结论是,getElementById会冒泡到document.getElementById(给定elem.getElementById不存在)。

我设置了一个系统示例,以便您可以看到变量如何在作用域链中冒泡:

window.a   = 1;
document.a = 2;
elem.a     = 3;

window.b   = 4;
document.b = 5;

window.c   = 6;

然后,<a ... onclick="console.log(a, b, c)">日志356点击时。

@Felix Kling & @Ӫ_._Ӫ:抱歉,这看起来更接近:w3.org/TR/html5/webappapis.html#event-handler-attributes“让 Scope 成为 NewObjectEnvironment(元素的对象,Scope)的结果。” 所以这意味着元素本身在任何其他范围(例如窗口)之前被推送。这也是有道理的,因为document.xxx函数似乎也可以在不使用document处理程序属性的情况下使用document也根据那里的规则推送到作用域链中):jsfiddle.net/pimvdb/X5syU/1
2021-04-21 18:09:15
@Joe:this这不是问题所在。this指的是元素应该是已知的...问题是事件处理程序作用域不仅包含全局作用域,还包含元素本身作为作用域。就好像有人做了:with(theElement) { theElement.onclick = function() {...} }...这是令人困惑的部分。
2021-04-24 18:09:15
@FelixKling:这是一个参考。 “定义为 HTML 属性的事件处理程序具有更复杂的作用域链。作用域链的头部是调用对象……然而,事件处理程序作用域链中的下一个对象不是全局对象;它是调用对象的对象触发了事件处理程序。”
2021-04-28 18:09:15
我不喜欢这种奇怪的范围聚合的东西,或者不管你想怎么称呼它……表单也是如此。+1
2021-05-07 18:09:15
那么这是否表明可以通过将其更改为来解决此问题onClick="window.download()"
2021-05-11 18:09:15

一些函数名称只是保留或已经使用。另一个是“评估”。

我建议在您的所有函数和变量名称之前添加一些内容,以避免出现这种情况。示例:“sto_download”

如果我参加了函数定义出来的剧本,和console.log(download)console.log(download()),然后我得到download is not defined
2021-04-28 18:09:15
并没有真正解释 Chrome 中发生的事情,是吗?
2021-04-29 18:09:15