Top 10 JavaScript errors for 1000+ projects

 Source: Full stack front-end selection

In order to make it easier to read, each error has been shortened. Let's study each problem in more depth to determine what caused these problems and how to avoid them.

1. Uncaught TypeError: Cannot read property

If you are a JavaScript developer, you may have seen this error. This happens in Chrome when you read properties or call methods on undefined objects. You can easily test it in the Chrome Developer Console.

There are many reasons for this, but the common reason is improper state initialization when rendering UI components. Let's look at an example of how this happens in a real application. We will choose React, but the same principle of incorrect initialization also 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>
    );
  }
}

There are two important things to be aware of here:

  • The state of the component (for example  this.stateundefined starts using the state.

  • When you get data asynchronously, regardless of whether the data is obtained in the constructor componentWillMount or  in the constructor  componentDidMount , the component will be rendered at least once before the data is loaded. When Quiz rendered for the first time, this.state.items yes  undefined. This in turn means that ItemList will get undefined items, and you will get an error in the console-"UncaughtTypeError: Cannot read property'map' of undefined ".

This is easy to solve, and the simplest method: initialize the state with reasonable default values ​​in the constructor.

class Quiz extends Component {
  // 添加了这个:
  constructor(props) {
    super(props);
    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>
    );
  }
}

The actual code in your application may be different, but I hope I have given you enough clues for you to fix or avoid this problem in your application. If not, please continue reading as I will introduce more examples of related errors below.

2. TypeError: ‘undefined’ is not an object (evaluating

This is undefinedan error that occurs when reading properties or calling methods on objects in Safari. You can test it very easily in the Safari Developer Console. This is basically the same as the above error for Chrome, but Safari uses a different error message.

3. TypeError: null is not an object (evaluating

This is nullan error that occurs when reading properties or calling methods on objects in Safari. You can test it very easily in the Safari Developer Console.

Interestingly, in JavaScript, null and undefined are not the same, which is why we see two different error messages. Undefined is usually a variable that has not yet been assigned, and null means that the value is blank.  To verify that they are equal, try using the strict equality operator.

One way that this error may occur in a real example is to try to use the DOM element in JavaScript before loading the element. 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 DOM elements are created. The JS code is interpreted from top to bottom according to the HTML format, so if there is a tag before the DOM element, then the JS code in 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 example, we can solve the problem by adding an event listener, which will notify us when the page is ready. Once triggered  addEventListener, 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

Script errors will occur when uncaught JavaScript errors cross domain boundaries in violation of cross-origin policies. For example, if you host your JavaScript code on a CDN, any uncaught errors (errors that bubble into the window.onerror handler, rather than errors that are caught in the try-catch) will be reported as " Script error" instead of containing useful information. This is a browser security measure designed to prevent the transfer of data across domains, otherwise the domain will not be able to communicate.

To get the real error message, do the following.

Send Access-Control-Allow-Origin header

Set the  Access-Control-Allow-Origin header to  * indicate that the resource can be accessed correctly from any domain. You may need to  * replace your domain: for example, Access-Control-Allow-Origin:www.example.com. However, it is more complicated to deal with multiple domains. If you use a CDN, there may be caching problems, which may not be worth the effort.

Here are some examples of how to set this header in various environments:

Apache

In the folder where JavaScript files will be provided, create a .htaccess file with the following content  :

Header add Access-Control-Allow-Origin "*"

Nginx

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

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

HAProxy

Add the following to the asset backend that provides JavaScript files:

rspadd Access-Control-Allow-Origin:\ *

Set crossorigin="anonymous" on the script tag

In your HTML source code, for Access-Control-Allow-Origin each script you set a header, set it  on the script tag crossorigin="anonymous". Before adding crossorigin attributes to the script tag  , make sure to verify that the header has been sent for the script file. In Firefox, if there are  crossorigin attributes but no  Access-Control-Allow-Origin headers, the script will not be executed.

5. TypeError: Object doesn’t support property

This is an error that occurs in IE. When you call the undefined method, you can test this in the IE developer console.

This is equivalent to the error "TypeError:'undefined' is not a function" in Chrome. Yes, for the same logical error, different browsers may have different error messages.

This is a common problem of IE in web applications that use the JavaScript namespace. In this case, 99.9% of the problem is that IE cannot bind methods in the current namespace to  this keywords.

For example, if your JS namespace  Rollbar uses  isAwesome methods. Generally, if you are in a  Rollbar namespace, you can call isAwesome methods using the following syntax  :

this.isAwesome();

Chrome, Firefox and Opera will be happy to accept this syntax. On the other hand, IE will not. Therefore, when using JS namespaces, the safest way is to use the actual namespace as a prefix.

Rollbar.isAwesome();

6. TypeError: ‘undefined’ is not a function

This is an error that occurs in Chrome, when you call undefined function. You can test this in the Chrome Developer Console and Mozilla Firefox Developer Console.

As JavaScript coding techniques and design patterns have become more and more complex over the years, the scope of self-referencing in callbacks and closures has also increased correspondingly, which is also a fairly common source of one or another confusion.

Consider the following sample code snippet:

function clearBoard(){
  alert("Cleared");
}
document.addEventListener("click", function(){
  this.clearBoard(); // 这个 "this" 是什么?
});

If you execute the above code and then click on the page, it will result in the following error "Uncaught TypeError: this.clearBoard not a function". The reason is that the anonymous function being executed in the context of the document, which  clearBoard is  window defined.

The traditional solution that is compatible with old browsers is to simply save a reference to it in a variable, and then the closure can inherit this variable. E.g:

var self = this;
document.addEventListener("click", function(){
  self.clearBoard();
});

In addition, in newer browsers, you can use the  bind() method to pass the correct reference:

document.addEventListener("click",this.clearBoard.bind(this));

7. Uncaught RangeError: Maximum call stack

This is an error that occurs in the Chrome browser in several situations, one is to call a recursive function that does not terminate. You can test this in the Chrome Developer Console.

This can also happen if you pass a value to a function that is out of range. Many functions only accept numbers in a certain range of input values, for example, Number.toExponential(digits) and  Number.toFixed(digits) accept numbers between 0 and 20, and Number.toFixed(digits) accept numbers between 1 and 21.

var a = newArray(4294967295);  //OK
var b = newArray(-1); //range error

var num = 2.555555;
document.writeln(num.toExponential(4));  //OK
document.writeln(num.toExponential(-2)); //range error!

num = 2.9999;
document.writeln(num.toFixed(2));   //OK
document.writeln(num.toFixed(25));  //range error!

num = 2.3456;
document.writeln(num.toPrecision(1));   //OK
document.writeln(num.toPrecision(22));  //range error!

8. TypeError: Cannot read property ‘length’

This is an error that occurs in the Chrome browser, because the length property of the undefined variable is read, and you can test it in the Chrome Developer Console.

Normally, you can find the defined length on the array, but if the array is not initialized or the variable name is hidden in other contexts, you may encounter this error. Let us understand this error with the following example.

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

When you declare a function with parameters, these parameters become local parameters. This means that even if you have  testArray a variable named, parameters with the same name in the function will still be treated as local parameters.

You can solve the problem in two ways:

Delete the parameters in the function declaration statement (it turns out that you want to access those variables declared outside the function, so you don't need to use parameters for the function)

var testArray = ["Test"];

/* 前置条件:在函数外部定义testArray */
function testFunction(/* No params */) {
   for (var i = 0; i < testArray.length; i++) {
     console.log(testArray[i]);
   }
}

testFunction()

Call the function and pass the array we declared to it.

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

When we try to access an undefined variable, it always returns  undefinedand we cannot get or set any  undefined properties. In this case, the application will raise "Uncaught TypeError: Cannot set property".

For example, in the Chrome browser:

If the  test object does not exist, the error will raise "Uncaught TypeError: Cannot set property".

10. ReferenceError: event is not defined

undefined This error will be raised when you try to access a variable that is out of the current scope. You can test it very easily in the Chrome browser.

If you receive this error when using the event handling system, please make sure you use the passed event object as a parameter. Older browsers such as IE will provide global variable events, while Chrome will automatically attach event variables to the handler. Firefox will not add it automatically. Libraries such as jQuery try to standardize this behavior, however, it is better to use the method passed to the event handler function.

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

to sum up

It turns out that many of them are null or undefined errors. If you use strict compiler options, a static type checking system like Typescript can help you avoid using them. It can warn you if a type is expected but not yet defined

study Exchange

  • Follow the public account [Frontend Universe], get good article recommendations every day

  • Add WeChat, join the group to communicate


"Watching and forwarding" is the greatest support

Guess you like

Origin blog.csdn.net/liuyan19891230/article/details/107873173