Why does this anchor say "search is not a function"?

I wrote a function with a name search

that I expected to be called when the link was clicked as shown below:

<script>
  function search() {
    console.log('Searching');
  }
</script>
<a href="#" onclick="search();">Click here</a>
      

Run codeHide result


However, the code doesn't work as I expected, resulting in this error (in Chrome) when clicking on a link:

Uncaught TypeError: search is not a function

I tried to login search

to understand why the error occurred:

<a href="#" onclick="console.log(search)">Click here</a>

      

<script>
  function search() {
    console.log('Searching');
  }
</script>
<a href="#" onclick="console.log(search);">Click here</a>
      

Run codeHide result


This time, the console was writing a blank line every time the link was clicked. What puzzles me is what is search

actually defined somewhere else as an empty string, which makes my function definition useless.

So I want to know what happens when the click event fires and when is it defined here search

?

+5


source to share


3 answers


It turns out search

to be referring to the a

element property search

, which is the property that controls the search parameters, which in this case is an empty string. This is because using HTMLAnchorElement

it is special in that it is used to create hyperlinks and navigate to other addresses, and thus the property is search

used to control the parameters of a hyperlink search (similar to a parameter Location

). Then setting the search

binding element property will set the global instance Location

window.location.search

. This also creates a naming conflict because the empty string is not the function that is causing the error.

Use a different name for the function to remove this conflict. Please note, if you don't use a

, you will see that it works fine:



<script>
  function search() { 
    alert("foo"); 
  }
</script>
<div onclick="search();">Click me!</div>

      

+4


source


Li357's answer explains most of what's going on, but just to add a point, the reason why

<a onclick="search();">Click me!</div>

      

The results of search

referencing the search

binding property are that inline handlers have an implicit environment with(this)

. For the interpreter, the above looks something like this:

<a onclick="
  with(this) {
    search();
  }
">Click me!</div>

      



And search

is a property HTMLAnchorElement.prototype

, so the property will be found first, before the interpreter HTMLAnchorElement.prototype

searches for window

the property name.

It's not intuitive at all. It is best to avoid built-in handlers, and also avoid using with

. You can add an event handler correctly using Javascript to solve the problem:

function search() {
  console.log('Searching');
}
document.querySelector('a').addEventListener('click', search);
      

<a href="#">Click here</a>
      

Run codeHide result


+2


source


Change the name of the function. Just tried my code and it worked as soon as I changed the function name.

<body>
<script type="text/javascript">    
    function test() {
        console.log('Searching');
    }
</script>
<a href="#" onclick="test()">Click here</a>  

      

0


source







All Articles