I've had a problem with this little snippet:
<script>
function download() {
alert('Hi');
}
</script>
<a href="#" onClick="javascript:download();">Test</a>
Once I click on the link in Chrome 14.0, I get a
Uncaught TypeError: string is not a function
in Firefox and IE it works just fine. I solved the problem by renaming the function but I'm still curious what's with the "download" thing in Chrome. It's not a reserved keyword as far as I know so what might it be?
<a>
elements have adownload
attribute in HTML5 as explained here, with a default value of""
(an empty string).This means that
download === this.download
in theonclick
handler (this
is the element inonevent
attributes), and therefore thedownload
attribute of the element is superior to thedownload
property ofwindow
.This fiddle lists all string attributes that are present by default. You can see
download
is an attribute just likeinnerHTML
, which also fails with the exact same reason when used as a function (i.e. trying to refer towindow.innerHTML
, but instead executingelem.innerHTML()
).As said in the comments, using
window
makes for no confusion as to what property/attribute variables will evaluate to.This scope behaviour does actually not seem to due to the
this
value but rather a specific "scope chain" that is being constructed.As per the HTML5 specification:
I.e. what is happening is the scope chain is
window
->document
->element
(increasing superiority). This means thatdownload
evaluates toelement.download
and notwindow.download
. What also can be concluded from this is thatgetElementById
will bubble up todocument.getElementById
(givenelem.getElementById
does not exist).I set up a systematic example so that you can see how variables bubble up the scope chain:
Then,
<a ... onclick="console.log(a, b, c)">
logs3
,5
,6
when clicked.Some function names are simply reserved or already used. Another would be "evaluate".
I recommend prepending something to all of your function and variable names to avoid this kinds of situations. Example: "sto_download"