This article is my collection of the 10 most frequent errors in JavaScript. We will tell you what causes these errors and how to prevent them from happening. Friends in need can refer to it
In order to give back to our developer community, we checked the database of thousands of projects and found the 10 most frequent errors in JavaScript. We'll tell you what causes these errors and how to prevent them from happening. If you can avoid falling into these "traps", you will become a better developer.
Data is king. We collected and analyzed the top 10 most frequent JavaScript errors. Rollbar collects all errors for each project and summarizes the number of times each error occurred. We do this by grouping errors based on “fingerprints” (an algorithm used by rollbar, see: https://rollbar.com/docs/grouping-algorithm/). Basically, if the second error is just a duplicate of the first error, we group both errors into the same group. This will give the user a good overview, rather than an overwhelming dump like what you see in the log file.
We focus on the bugs most likely to impact you and your users. To do this, we ranked the errors by studying project sets from various companies. If we only looked at the total number of times each error occurred, the errors produced by a high-volume project might overwhelm other errors, resulting in a data set of errors that would not be relevant to most readers.
Here are the top 10 JavaScript errors:
We have shortened each error description for easier 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 are a JavaScript developer, you may have seen this error more times than you dare to admit ( LOL…). This error occurs in Chrome when you read a property of an undefined object or call its method. You can easily test (try it out) in the Chrome Developer Console.
There are many reasons why this happens, but a common one is improper initialization of state when rendering UI components.
Let’s look at an example of what happens in a real application: we choose 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> ); } }
There are two important things to achieve here:
The component's state (e.g. this.state) starts from undefined.
When data is obtained asynchronously, whether it is obtained in the constructor componentWillMount or componentDidMount, the component will be rendered at least once before the data is loaded. When Quiz is first rendered, this.state.items is not Defined. This in turn means that the ItemList defines items as undefined and an error appears in the console - "Uncaught TypeError: Cannot read property 'map' of undefined".
This is easily solved. The simplest way: initialize the state in the constructor with sensible default values.
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> ); } }
The specific code in your application may be different, but we hope we have given you enough clues to solve or avoid this problem in your application. If you haven't yet, keep reading as we'll cover more examples of related errors below.
2. 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 this in the Safari Developer Console. This is essentially the same Chrome error mentioned in #1, but Safari uses a different error message.
3. TypeError: null is not an object
This is when reading properties or calling on an empty object in Safari An error occurred during the method. You can easily test this 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 a variable that has not been assigned, while null means the value is empty. To verify that they are not equal, try using the strict equality operator ===:
In a real world example, one scenario where this error can occur is : If you try to use the element in JavaScript before the element is loaded. Because the DOM API returns null for a blank object reference.
任何执行和处理 DOM 元素的 JS 代码都应该在创建 DOM 元素之后执行。 JS 代码按照 HTML 中的规定从上到下进行解释。 所以,如果 DOM 元素之前有一个标签,脚本标签内的 JS 代码将在浏览器解析 HTML 页面时执行。 如果在加载脚本之前尚未创建 DOM 元素,则会出现此错误。
在这个例子中,我们可以通过添加一个事件监听器来解决这个问题,这个监听器会在页面准备好的时候通知我们。 一旦 addEventListener被触发,init() 方法就可以使用 DOM 元素。
<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
当未捕获的 JavaScript 错误(通过window.onerror处理程序引发的错误,而不是捕获在try-catch中)被浏览器的跨域策略限制时,会产生这类的脚本错误。 例如,如果您将您的 JavaScript 代码托管在 CDN 上,则任何未被捕获的错误将被报告为“脚本错误” 而不是包含有用的堆栈信息。这是一种浏览器安全措施,旨在防止跨域传递数据,否则将不允许进行通信。
要获得真正的错误消息,请执行以下操作:
1. 发送 ‘Access-Control-Allow-Origin' 头部
将 Access-Control-Allow-Origin 标头设置为 * 表示可以从任何域正确访问资源。 如有必要,您可以将域替换为您的域:例如,Access-Control-Allow-Origin:www.example.com。 但是,处理多个域会变得棘手,如果你使用 CDN,可能由此产生更多的缓存问题会让你感觉到这种努力并不值得。 在这里看到更多。
这里有一些关于如何在各种环境中设置这个头文件的例子:
Apache
在 JavaScript 文件所在的文件夹中,使用以下内容创建一个 .htaccess 文件:
Header add Access-Control-Allow-Origin "*"
Nginx
将 add_header 指令添加到提供 JavaScript 文件的位置块中:
location ~ ^/assets/ { add_header Access-Control-Allow-Origin *; }
HAProxy
将以下内容添加到您为 JavaScript 文件提供资源服务的后端:
rspadd Access-Control-Allow-Origin:\ *
2. 在