admin管理员组

文章数量:1208155

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?

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?

Share Improve this question asked Oct 21, 2011 at 16:12 AmatiAmati 1,5321 gold badge18 silver badges30 bronze badges 5
  • Do you have any extensions installed? – user542603 Commented Oct 21, 2011 at 16:14
  • 4 Confirmed. Even removing the javascript: that shouldn't be there doesn't help. Weird! – Lightness Races in Orbit Commented Oct 21, 2011 at 16:15
  • 1 Don't use global functions. Place your functions in a namespace and bind the event handler programmatically. – Šime Vidas Commented Oct 21, 2011 at 16:15
  • @Muu, I have plenty but even if I start an incognito window (which apparently disables extensions) I still get the error. Also, as Tomalak pointed below, console.log(download) gives undefined. – Amati Commented Oct 21, 2011 at 16:24
  • @Amati: Where are you doing this? If you created a jsFiddle, note that the actual code is run in an iframe and global variables are not accessible from the console. – Felix Kling Commented Oct 21, 2011 at 16:27
Add a comment  | 

2 Answers 2

Reset to default 21

<a> elements have a download attribute in HTML5 as explained here, with a default value of "" (an empty string).

This means that download === this.download in the onclick handler (this is the element in onevent attributes), and therefore the download attribute of the element is superior to the download property of window.

This fiddle lists all string attributes that are present by default. You can see download is an attribute just like innerHTML, which also fails with the exact same reason when used as a function (i.e. trying to refer to window.innerHTML, but instead executing elem.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:

Lexical Environment Scope

Let Scope be the result of NewObjectEnvironment(the element's Document, the global environment).

If the element has a form owner, let Scope be the result of NewObjectEnvironment(the element's form owner, Scope).

Let Scope be the result of NewObjectEnvironment(the element's object, Scope).

I.e. what is happening is the scope chain is window -> document -> element (increasing superiority). This means that download evaluates to element.download and not window.download. What also can be concluded from this is that getElementById will bubble up to document.getElementById (given elem.getElementById does not exist).

I set up a systematic example so that you can see how variables bubble up the scope chain:

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

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

window.c   = 6;

Then, <a ... onclick="console.log(a, b, c)"> logs 3, 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"

本文标签: google chromeCan39t use quotdownloadquot as a function name in javascriptStack Overflow