With more than 1000 projects in the statistics database, we found that there were 10 errors that most commonly occurred in JavaScript. Here are some of the reasons why these errors occurred and how to prevent them.
For the number of times these errors occurred, we collected the data from the statistics obtained. Rollbar collects all the errors in each project, summarizes the number of occurrences of each error, and then groups them by the characteristics of each error.
is the top 10 JavaScript errors that occur most often:
Here's a dive into what happens to each error to determine what caused the error and how to avoid it.
1. uncaught Typeerror:cannot Read Property
This is the most common error that JavaScript developers encounter. This error is reported in Chrome when you read a property or call a method that does not have a defined object.
There are many reasons for this error to occur, and a common scenario is that the state is not initialized correctly when the UI component is rendered. Let's look at an example of this happening in a real application.
Class Quiz extends Component { componentwillmount () { axios.get ('/thedata '). Then (res = { This.setstate ({items:res.data});} ); Render () { return ( <ul> {this.state.items.map (item = <li key={item.id}>{ Item.name}</li> )} </ul> ); }}
The above code has two important aspects:
- The first is the state of the component (for example, This.state), which is the undefined state before the life cycle begins.
- The second is that when data is fetched asynchronously, whether in Componentwillmount in the constructor or in the constructor, the component is rendered at least once before the data is loaded. When the first rendering is detected, This.state.items is not defined. There will be an error-"uncaught typeerror:cannot Read Property ' map ' of undefined" in the Consol ".
The workaround is simple: use a reasonable default value for state initialization in the constructor.
Class Quiz extends Component { //Added this: constructor (props) { super (props); Assign State itself, and a default value for items this.state = { items: [] }; } Componentwillmount () { axios.get ('/thedata '). Then (res = { this.setstate ({items:res.data}); }); render () { return ( <ul> {this.state.items.map (item = <li key={item.id}> {item.name}</li> )} </ul> ); }}
2. TypeError: ' Undefined ' isn't an Object (evaluating ...)
This is the error that occurs when reading a property in Safari or calling a method on an undefined object, which is basically the same as Chrome's error, except that Safari uses a different error message.
3. Typeerror:null isn't an Object (evaluating ...)
This is an error that occurs when you read a property in Safari or call a method on an empty object.
Interestingly, in JavaScript, null and undefined are two different types, which is why there are two different error messages. Undefined is usually a variable that has not been allocated, and Null indicates that the value is empty. To verify that they are not equal, use the strict equality operator:
In reality, one of the reasons for this error is to try to use DOM elements in JavaScript before the element is loaded. This is because the DOM API returns null for blank object references.
Any JS code that executes and processes DOM elements should be executed after the DOM element is created. The JS code is interpreted from top to bottom according to the rules in HTML. Therefore, if a tag exists before the DOM element, the JS code within the script tag is executed when the browser parses the HTML page. This error can occur if the DOM element has not been created before the script is loaded.
In this example, we can solve this problem by adding an event listener that notifies us when the page is ready. Once AddEventListener is triggered, the init () method can use DOM elements.
<script> function init () { var MyButton = document.getElementById ("MyButton"); var MyTextField = document.getElementById ("MyTextField"); Mybutton.onclick = function () { var userName = mytextfield.value; } } Document.addeventlistener (' ReadyStateChange ', function () { if (document.readystate = = = "complete") { init (); } }); </script><form> <input type= "text" id= "MyTextField" placeholder= "Type your name"/> < Input type= "button" id= "MyButton" value= "Go"/></form>
4. (unknown): Script Error
Scripting errors occur when an uncaught JavaScript error violates the cross-border principle. For example, if you host JavaScript code on a CDN, any uncaught errors (errors that are made through the Window.onerror handler instead of the errors caught in Try-catch) will only be reported as "script errors." This is a security measure for browsers that are primarily used to prevent the occurrence of data passing across domains.
To get a real error message, you need to do the following:
1. access-control-allow-origin
Setting Access-control-allow-origin to * indicates that the resource can be accessed correctly from any domain. * If necessary, you can also use your own domain name to replace, for example:
Access-control-allow-origin:www.example.com.
The following are some examples of settings that are set up in various environments:
Apache
In the JavaScript folder, create a. htaccess file and include the following:
Header Add Access-control-allow-origin "*"
Nginx
Add the Add_header directive to the location block that provides the JavaScript file:
Location ~ ^/assets/{ add_header access-control-allow-origin *;}
HAProxy
Add the following to the static resource configuration backend that provides JavaScript files:
Rspadd access-control-allow-origin:\ *
2. Set crossorigin = "Anonymous" On the Script tab
In your HTML source code, set access-control-allow-origin for each script, and in the Set Script tab, set crossorigin= "anonymous". Before you add the Crossorigin property to the script label, make sure that you are sending the header to the script file. In Firefox, if the Crossorigin property exists but the Access-control-allow-origin title does not exist, the script does not execute.
5. Typeerror:object doesn ' t support property
This error occurs in IE when an undefined method is called.
This is equivalent to the "undefined is not a function" error in Chrome. For the same logic error, different browsers may have different error messages.
This is a common problem with the use of JavaScript namespaces in IE Web applications. Most of the reason this happens is that IE cannot bind methods in the current namespace to the This keyword. For example, if you have a namespace isawesome for the JS Rollbar method. In general, if you are in the Rollbar namespace, you can call the Isawesome method using the following syntax:
This.isawesome ();
Chrome, Firefox, and Opera accept this syntax, IE doesn't accept it. Therefore, the most secure way to use the JS namespace is to always prefix the actual namespace.
Rollbar.isawesome ();
6. TypeError: ' Undefined ' is not a Function
This error occurs in Chrome when a function is called that is undefined.
As JavaScript coding techniques and design patterns become more complex over the past few years, the self-referential scope in callbacks and closures has increased correspondingly, which is the main source of this confusion.
As the following sample code snippet:
function TestFunction () { this.clearlocalstorage (); This.timer = SetTimeout (function () { this.clearboard (); What is the "this"? }, 0);};
Executing the above code causes the following error: "Uncaught typeerror:undefined is not a function. "The reason for the above error is that when you call SetTimeout (), you are actually calling Window.settimeout (), and the anonymous function passed to SetTimeout () is defined in the context of the Window object, and the Window object is not Clearboa RD () method.
A solution that conforms to a legacy browser is to simply save the reference in this as a variable and then inherit from the closure. For example:
function TestFunction () { this.clearlocalstorage (); var = this; Save reference to ' this ' and while it ' s still this! This.timer = SetTimeout (function () { self.clearboard (); }, 0);};
Or, in a newer browser, use the Bind () method to pass the reference:
function TestFunction () { this.clearlocalstorage (); This.timer = SetTimeout (This.reset.bind (this), 0); Bind to ' this '};function testfunction () { this.clearboard (); Back in the context of the "this"!};
7. uncaught Rangeerror:maximum Call Stack
This is a bug in Chrome that happens when you call a recursive function that does not terminate.
This can also happen if you pass a value to a function that is out of range. Many functions only accept numeric input values in a specific range. For example, number.toexponential (digits) and number.tofixed (digits) accept parameters ranging from 0 to 20, while number.toprecision (digits) accepts numbers ranging from 1 to 21.
var a = new Array (4294967295); Okvar B = New Array (-1); Range Errorvar num = 2.555555;document.writeln (num.toexponential (4)); Okdocument.writeln (Num.toexponential (-2)); Range error!num = 2.9999;document.writeln (num.tofixed (2)); Okdocument.writeln (Num.tofixed ()); Range error!num = 2.3456;document.writeln (num.toprecision (1)); Okdocument.writeln (Num.toprecision ()); Range error!
8. Typeerror:cannot Read Property ' length '
This is an error that occurs in Chrome because a variable with an undefined length attribute is read.
The length of the definition is usually found in the array, but this error can occur if the array is uninitialized or the variable name is hidden in another context. Let's use the following example to explain this error.
var testarray= ["Test"];function testfunction (Testarray) {for (var i = 0; i < testarray.length; i++) { console . log (Testarray[i]);} } TestFunction ();
When a function is declared with a parameter, these parameters become local parameters. This means that even if you have a name variable Testarray, a parameter with the same name in the function will still be treated as a local parameter .
There are two ways to solve this problem:
1. Delete the parameters in the function declaration statement:
var testarray = ["Test"];/* precondition:defined testarray outside of a function */function testfunction (/* No params */) {for (var i = 0; i < testarray.length; i++) { console.log (testarray[i]);} } TestFunction ();
2. Call the array function passed to our declaration:
var testarray = ["Test"];function testfunction (Testarray) {for (var i = 0; i < testarray.length; i++) { Console.log (Testarray[i]);} } TestFunction (Testarray);
9. uncaught Typeerror:cannot Set Property
Undefined is always returned when attempting to access undefined variables. We also cannot get or set any properties of undefined. In this case, the application throws "Uncaught TypeError cannot set property of undefined".
For example, in a Chrome browser, this error occurs if the test object does not exist:
So you need to define the variables before accessing them.
Referenceerror:event is not Defined
This error is raised when attempting to access variables that are not defined or that are outside the current scope.
If you encounter this error while using the event-handling system, be sure to use the incoming event object as a parameter. Browsers such as IE provide global variable events, and Chrome automatically attaches event variables to handlers, and Firefox does not automatically add event variables.
Document.addeventlistener ("MouseMove", function (event) { Console.log (event);})
Conclusion
It turns out that many of these null or undefined errors are pervasive. A good static type checking system, similar to Typescript, can help developers avoid these errors when set to strict compilation options.
Finally, it is hoped that this article will help developers to avoid or deal with the above 10 errors.
Original link: https://dzone.com/articles/top-10-javascript-errors-from-1000-projects-and-ho-1
Top ten JavaScript errors in more than 1000 projects and how to avoid