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 adownloadattribute in HTML5 as explained here, with a default value of""(an empty string).This means that
download === this.downloadin theonclickhandler (thisis the element inoneventattributes), and therefore thedownloadattribute of the element is superior to thedownloadproperty ofwindow.This fiddle lists all string attributes that are present by default. You can see
downloadis 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
windowmakes for no confusion as to what property/attribute variables will evaluate to.This scope behaviour does actually not seem to due to the
thisvalue 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 thatdownloadevaluates toelement.downloadand notwindow.download. What also can be concluded from this is thatgetElementByIdwill bubble up todocument.getElementById(givenelem.getElementByIddoes 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,6when clicked.