Original text: rollbar.com/blog/top-10… Disclaimer: The original text has been slightly modified to make it easier to read

preface

After looking at thousands of projects, I found 10 of the most common JavaScript errors. We tell you what causes these errors and how to prevent them from happening. If you can avoid falling into these “traps”, you’ll be a better developer.

Top 10 Common JavaScript mistakes:

Each error description has been shortened for ease of reading. Next, let’s dive into each error to determine what causes it and how to avoid creating it.

1, Uncaught TypeError: Cannot read property

If you’re a JavaScript developer, you’ve probably seen this error more times than you’d dare admit. This error occurs in Chrome when you read an undefined object’s properties or call its methods. You can easily test it in the Chrome developer console.

There are many reasons for this, but a common one is poor initialization of state when rendering UI components.

Let’s take a look at an example that happens in a real application: we chose React, but the same applies to Angular, Vue, or any other framework.

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> ); }}Copy the code

There are two important processes:

  1. A component’s state (such as this.state) begins with undefined.
  2. When data is retrieved asynchronously, whether it is in the constructorcomponentWillMountorcomponentDidMountThe component is rendered at least once before the data is loaded, whenQuizWhen it was first presented,this.state.itemsIs undefined.

This is easy to fix. The simplest way is to initialize state 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> ); }}Copy the code

The specific code in your application may be different, but we hope we’ve given you enough clues to solve or avoid this problem in your application. If not, read on, because we’ll cover more examples of related errors below.

TypeError: ‘undefined’ is not an object

This is an error that occurs when reading a property or calling a method on an undefined object in Safari. You can easily test it in the Safari Developer Console. This is basically the same error for Chrome as mentioned in point 1, but Safari uses a different error message prompt.

TypeError: null is not an object

This is an error that occurs when reading a property or calling a method on an empty object in Safari. You can easily test it in the Safari Developer Console.

Interestingly, null and undefined are not the same in JavaScript, which is why we see two different error messages.

Undefined is usually an unassigned variable, while null indicates that the value is null. To verify that they are not equal, try using the strict equality operator ===

One scenario where this error can occur in our work is if we try to use elements in JavaScript before loading them. The DOM API returns null for a blank object reference.

Any JS code that executes and processes A DOM element should be executed after the DOM element is created.

JS code is interpreted from top to bottom as specified in HTML. So, if a DOM element is preceded by a tag, the JS code inside the script tag will be executed when the browser parses the HTML page. This error occurs if the DOM element has not been created before the script is loaded.

In this case, we can solve this problem by adding an event listener that will notify us when the page is ready. Once the 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>Copy the code

(unknown): Script error

This type of scripting error occurs when uncaught JavaScript errors (errors raised through the window.onerror handler, rather than caught in a try-catch) are restricted by the browser’s cross-domain policy. For example, if you host your JavaScript code on a CDN, any uncaught errors will be reported as “script errors” rather than containing useful stack information. This is a browser security measure designed to prevent the transfer of data across domains that would otherwise not allow communication.

To get a real error message, do the following:

1. Set the access-Control-allow-Origin header

Setting the access-Control-allow-Origin header to * indicates proper Access to resources from any domain.

In Nginx, the Settings are as follows:

Add the add_header directive to the location block that provides the JavaScript file:

location ~ ^/assets/ {
    add_header Access-Control-Allow-Origin *;
}
Copy the code

In 2.<script>Set in thecrossorigin="anonymous"

In your HTML code, for each script for which you set Access-Control-Allow-Origin, set Crossorigin = “anonymous” on the script tag. Before adding the Crossorigin attribute to the script tag, be sure to verify that the above headers are sent correctly.

In Firefox, if the Crossorigin attribute exists, but the Access-Control-Allow-Origin header does not, the script will not execute.

TypeError: Object doesn’t support property

This is an error that occurs in IE when you call an undefined method. You can test it in the IE developer console.

This is equivalent to “TypeError:” undefined “is not a function” error in Chrome.

Yes, different browsers may have different error messages for the same logical error.

This is a common problem with Internet Explorer for Web applications that use JavaScript namespaces. In this case, 99.9% of the reason is that IE cannot bind methods in the current namespace to the this keyword.

For example, if you have a namespace Rollbar in JS and the method isAwesome. In general, if you are inside the Rollbar namespace, the isAwesome method can be called using the following syntax:

this.isAwesome();
Copy the code

Chrome, Firefox, and Opera will embrace this syntax. Internet Explorer doesn’t. Therefore, the safest choice when using A JS namespace is to always prefix it with the actual namespace.

Rollbar.isAwesome();
Copy the code

TypeError: ‘undefined’ is not a function

This is a Chrome error when you call an undefined function. You can test it in the Chrome developer console and Mozilla Firefox Developer console.

function clearBoard(){ alert("Cleared"); } document.addEventListener("click", function(){ this.clearBoard(); // What is "this"? });Copy the code

Executing the above code results in the following error:

Uncaught TypeError: this.clearBoard is not a function.

The cause should be clear, that is, a pointing error caused by an incomprehension of the execution context.

7、 Uncaught RangeError

This error occurs when you call a recursive function that does not terminate. You can test it in the Chrome developer console.

In addition, this can happen if you pass values to functions that are out of scope.

Many functions only accept a specific range of numbers from their input values. Such as:

  1. toExponential(digits)toFixed(digits)Accept 0 to 100
  2. toPrecision(digits)Accept 1 to 100
Var num = 2.555555; console.log(num.toExponential(4)); //OK console.log(num.toExponential(-2)); //range error! console.log(num.toFixed(2)); //OK console.log(num.toFixed(105)); //range error! console.log(num.toPrecision(1)); //OK console.log(num.toPrecision(0)); //range error!Copy the code

8, TypeError: Cannot read property ‘length’

This is an error that occurred in Chrome because the length attribute of an undefined variable was read. You can test it in the Chrome developer console.

You will usually find the defined length in the array, but you may encounter this error if the array is not initialized or if the variable is in a different context. Let’s use the following example to understand this mistake.

var testArray = ["Test"];
function testFunction(testArray) {
    for (var i = 0; i < testArray.length; i++) {
        console.log(testArray[i]);
    }
}
testFunction();
Copy the code

An error occurs when executing the above code:

Cannot read property ‘length’ of undefined

There are two ways to solve this problem:

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();
Copy the code

or

var testArray = ["Test"];
function testFunction(testArray) {
   for (var i = 0; i < testArray.length; i++) {
      console.log(testArray[i]);
    }
}
testFunction(testArray);
Copy the code

9、 Uncaught TypeError: Cannot set property

When we try to access an undefined variable, it always returns undefined, and we cannot get or set any undefined properties. In this case “Uncaught TypeError: Cannot set Property” will be thrown.

10. ReferenceError: event is not defined

This error is raised when you try to access an undefined variable or a variable that is out of current scope. You can test it in Chrome.

If you encounter this error when using event, be sure to use the event object passed in as a parameter. Older browsers like Internet Explorer provide a global variable event, but not all browsers support it.

document.addEventListener("mousemove", function (event) {
  console.log(event);
})
Copy the code

conclusion

We looked at the 10 most common mistakes above, but it’s not that difficult. By the time you’ve read the first volume of JavaScript You Don’t Know, these errors are almost never repeated.

The bottom line is that the basic knowledge of JavaScript is not solid.

Vue related article output plan

Recently, some friends always ask me questions about Vue, so I will output 10 articles about Vue, hoping to be of some help to you. I will keep it updated every 7 to 10 days.

  1. Vuex injection into the Vue lifecycle (done)
  2. Learn the necessary knowledge of Vue source code (Done)
  3. Brief Analysis of Vue response Type Principle (completed)
  4. Patch is performed on old and new VNodes
  5. How do I develop functional components and upload NPM
  6. Optimize your Vue project in these areas
  7. The development of front-end routing is discussed from vue-Router design
  8. How to use Webpack properly in a project
  9. Vue server render
  10. How to choose between Axios and Fetch

I suggest you pay attention to my public number, the first time you can receive the latest article.