Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uncaught TypeError: lang is not a function [duplicate]

In my HTML I define the lang function in the script tag and add the "Test Fire!" button which has to call lang on click:

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title>Testing Functions</title>
  <script type="text/javascript">
    function lang() {
      alert("Hello, World! It's JavaScript this time");
    }
  </script>
</head>

<body>
  <form action="">
    <input type="button" value="Test Fire!" onclick="lang();">
  </form>
</body>

</html>

However, if I click the button I get this error:

Uncaught TypeError: lang is not a function

But if I change the function name from lang to anything else this code works fine.

like image 833
SanyamMishra Avatar asked Jul 08 '16 22:07

SanyamMishra


People also ask

How do I fix uncaught TypeError is not a function?

The TypeError: "x" is not a function can be fixed using the following suggestions: Paying attention to detail in code and minimizing typos. Importing the correct and relevant script libraries used in code. Making sure the called property of an object is actually a function.

How do I fix uncaught type error in jQuery?

We can fix this error by using jQuery() . We can use $() freely inside of our jQuery object after utilizing it. jQuery(document). ready(function($){ var allParagraphTags = $( 'p' ); });

Is not a function error JS?

This is a standard JavaScript error when trying to call a function before it is defined. This error occurs if you try to execute a function that is not initialized or is not initialized correctly. This means that the expression did not return a function object.


2 Answers

Consider this code:

<input type="button" value="Debugger Test" onclick="debugger;" />
<input type="button" value="Prototype Test" onclick="console.log(__proto__);" />

When you click on “Debugger Test” and open your debugger, you’ll see that there seems to be an implicit with scope wrapped around the onclick, making all the <input>’s properties accessible without needing to refer to the button.

Clicking on “Prototype Test” logs the prototype of the current scope. You’ll see that it’s the HTMLInputElement’s prototype, making all the scopable properties of this entire prototype chain available to the scope.

Interestingly, the scopable part of the prototype chain of the current HTMLDocument is included as well.

All this means that all global attributes (lang is one of them) and several others specific to buttons are overridden. E.g. value, type also wouldn’t work. Similarly, variables like createElement (from document) also wouldn’t work, but the unscopable append (from ParentNode.prototype) would.

All this is also explained in this answer to a related question about global variables clashing with window properties.


Your best bet is to use the standard way of adding event listeners: addEventListener.

<input type="button" value="Test" />
<script>
  function lang() {
    alert("Hello, World! It’s not an HTML event handler attribute this time");
  }

  document.querySelector("input").addEventListener("click", lang);
</script>
like image 126
Sebastian Simon Avatar answered Oct 15 '22 01:10

Sebastian Simon


There is no reason to complicate (I really do not know why it does not work), but you can use:

  • Add the alert directly in the input.

Result: https://jsfiddle.net/cmedina/h4m1qcoq/6/

or

Add listener to input

function lang() {
   alert("Hello, World! It's JavaScript this time");
}

document.getElementById('test').onclick = lang

Result: https://jsfiddle.net/cmedina/h4m1qcoq/7/

like image 40
CMedina Avatar answered Oct 15 '22 00:10

CMedina