Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript function name alt()

If the function name is "alt", I get the error: "alt is not a function". All other names work. Here is the code:

<!DOCTYPE HTML>
<html>
    <head>
    </head>
    <body>
        <input type="button" value="click me" onclick="alt('dato',28);"/>
        <script type="text/javascript">
            window.onload = function(){
                alt = function(name,age){
                    alert(name + "  " + age);
                }
            }
        </script>
    </body>
</html>

Please change function name from "alt" to anything else allowed, to see that it works.

Can anybody explain what is happening?

like image 528
ზურა კუპატაძე Avatar asked Feb 09 '23 21:02

ზურა კუპატაძე


2 Answers

The reason this is happening is that within the onclick attribute, this refers to the element that has the attribute attached. Now, alt is a standard attribute name, and it's going to start out as unset for your button since you didn't specify an alt attribute in your HTML (and an alt attribute is not needed for an input, so there's no need to add one).

In short, alt refers not to the global variable window.alt that you set in your script, but refers to the element's alt attribute, which starts out unset.

So when you run onclick="alt('dato',28);", it's implicitly being interpreted as this: onclick="this.alt('dato',28);".

To get the alt that you set in your global scope, instead of the alt that's a part of every HTML element, you need to explicitly reach into the global scope, like this:

onclick="window.alt('dato',28);"
like image 66
Maximillian Laumeister Avatar answered Feb 11 '23 14:02

Maximillian Laumeister


The problem is that, since you use an event handler content attribute, your global function window.alt is shadowed by HTMLInputElement.prototype.alt

This behavior is explained in step 10 of getting the current value of the event handler:

Lexical Environment Scope

  1. If H is an element's event handler, then let Scope be the result of NewObjectEnvironment(document, the global environment).

    Otherwise, H is a Window object's event handler: let Scope be the global environment.

  2. If form owner is not null, let Scope be the result of NewObjectEnvironment(form owner, Scope).

  3. If element is not null, let Scope be the result of NewObjectEnvironment(element, Scope).

Note: NewObjectEnvironment() is defined in ECMAScript edition 5 section 10.2.2.3 NewObjectEnvironment (O, E)

That means that the scope of the target element shadows the global scope.

Therefore, you can

  • Rename your function

    function alt__(name,age){
      alert(name + "  " + age);
    }
    <input type="button" value="click me" onclick="alt__('dato',28)" />
  • Use window.alt (assuming window has not been shadowed):

    <input type="button" value="click me" onclick="window.alt('dato',28)" />
    

    function alt(name,age){
      alert(name + "  " + age);
    }
    <input type="button" value="click me" onclick="window.alt('dato',28)" />
  • Use an event handler IDL attribute instead of a content attribute one:

    theInput.onclick = function(){ alt('dato',28); });
    

    function alt(name,age){
      alert(name + "  " + age);
    }
    document.querySelector('input').onclick = function(){
      alt('dato',28);
    };
    <input type="button" value="click me" />
  • Use an event listener instead of an event handler:

    theInput.addEventListener('click', function(){ alt('dato',28); });
    

    function alt(name,age){
      alert(name + "  " + age);
    }
    document.querySelector('input')
    
    
    ----------
    
    .addEventListener('click', function(){
      alt('dato',28);
    });
    <input type="button" value="click me" />
like image 27
Oriol Avatar answered Feb 11 '23 14:02

Oriol