[英] 基于上千个项目统计出的 JavaScript 十大 Error 及解决方案

时间:2021-1-8 作者:admin

{
this.setState({items: res.data});
});
}

render() {
return (

    {this.state.items.map(item =>

  • {item.name}
  • )}

);
}
}

There are two important things realize here:

1.  A component’s state (e.g. `this.state`) begins life as `null`.
2.  When you fetch data asynchronously, the component will render at least once before the data is loaded – regardless of whether it’s fetched in the constructor, `componentWillMount` or `componentDidMount`. When Quiz first renders, `this.state.items` is undefined. This, in turn, means `ItemList` gets items as undefined, and _you_ get an error – "Uncaught TypeError: Cannot read property ‘map’ of undefined" in the console.

This is easy to fix. The simplest way: Initialize state with reasonable default values 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 (

    {this.state.items.map(item =>

  • {item.name}
  • )}

);
}
}

The exact code in your app might be different, but we hope we’ve given you enough of a clue to either fix or avoid this problem in your app. If not, keep reading because we’ll cover more examples for related errors below.

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

This is an error that occurs in Safari when you read a property or call a method on an undefined object. You can test this very easily in the Safari Developer Console. This is essentially the same as the above error for Chrome, but Safari uses a different error message.

![Screenshot of TypeError: ‘undefined’ is not an object (evaluating](https://example.com/c74669934876033c2d1821a4f4e8d390)

## 3\. TypeError: null is not an object (evaluating

This is an error that occurs in Safari when you read a property or call a method on a null object. You can test this very easily in the Safari Developer Console.

![Screenshot of TypeError: null is not an object (evaluating](https://example.com/babdf89ffac45f24a124472e804c22d6)

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 been assigned, while null means the value is blank. To verify they are not equal, try using the strict equality operator:

![Screenshot of TypeError: null is not an object (evaluating](https://example.com/3edcfbb64aff879d45ceaef9e2d883c7)

One way this error might occur in a real world example is if you try using a DOM element in your JavaScript before the element is loaded. That’s because the DOM API returns null for object references that are blank.

Any JS code that executes and deals with DOM elements should execute after the DOM elements have been created. JS code is interpreted from top to down as laid out in the HTML. So, if there is a tag before the DOM elements, the JS code within script tag will execute as the browser parses the HTML page. You will get this error if the DOM elements have not been created before loading the script.

In this example, we can resolve the issue by adding an event listener that will notify us when the page is ready. Once the `addEventListener` is fired, the `init()` method can make use of the DOM elements.
## 4\. (unknown): Script error

The Script error occurs when an uncaught JavaScript error crosses domain boundaries in violation of the cross-origin policy. For example, if you host your JavaScript code on a CDN, any uncaught errors (errors that bubble up to the window.onerror handler, instead of being caught in try-catch) will get reported as simply "Script error" instead of containing useful information. This is a browser security measure intended to prevent passing data across domains that otherwise wouldn’t be allowed to communicate.

To get the real error messages, do the following:

**1\. Send the Access-Control-Allow-Origin header**

Setting the `Access-Control-Allow-Origin` header to * signifies that the resource can be accessed properly from any domain. You can replace * with your domain if necessary: for example, `Access-Control-Allow-Origin: www.example.com`. However, handling multiple domains gets tricky, and may not be worth the effort if you’re using a CDN due to caching issues that may arise. See more [here](https://link.funteas.com?target=http%3A%2F%2Fstackoverflow.com%2Fquestions%2F1653308%2Faccess-control-allow-origin-multiple-origin-domains).

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

_Apache_

In the folders where your JavaScript files will be served from, create an `.htaccess` file with the following contents:

Header add Access-Control-Allow-Origin “*”

_Nginx_

Add the add_header directive to the location block that serves your JavaScript files:

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

_HAProxy_

Add the following to your asset backend where JavaScript files are served from:

rspadd Access-Control-Allow-Origin:\ *

**2\. Set crossorigin="anonymous" on the script tag**

In your HTML source, for each of the scripts that you’ve set the `Access-Control-Allow-Origin` header for, set `crossorigin="anonymous"` on the SCRIPT tag. Make sure you verify that the header is being sent for the script file before adding the `crossorigin` property on the script tag. In Firefox, if the `crossorigin` attribute is present but the `Access-Control-Allow-Origin` header is not, the script won’t be executed.

## 5\. TypeError: Object doesn’t support property

This is an error that occurs in IE when you call an undefined method. You can test this in the IE Developer Console.

![Screenshot of TypeError: Object doesn’t support property](https://example.com/57a1ed05210347c6343cb5cff2b40619)

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

This is a common problem for IE in web applications that employ JavaScript namespacing. When this is the case, the problem 99.9% of the time is IE’s inability to bind methods within the current namespace to the `this` keyword. For example, if you have the JS namespace `Rollbar` with the method `isAwesome.` Normally, if you are within the `Rollbar` namespace you can invoke the `isAwesome` method with the following syntax:

this.isAwesome();

Chrome, Firefox and Opera will happily accept this syntax. IE, on the other hand, will not. Thus, the safest bet when using JS namespacing is to always prefix with the actual namespace.

Rollbar.isAwesome();

## 6\. TypeError: ‘undefined’ is not a function

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

![Screenshot of undefined is not a function](https://example.com/75bab6a16fd7d190264ce5334c3f57ba)

As JavaScript coding techniques and design patterns have become increasingly sophisticated over the years, there’s been a corresponding increase in the proliferation of self-referencing scopes within callbacks and closures, which are a fairly common source of this/that confusion.

Consider this example code snippet:

function testFunction() {
this.clearLocalStorage();
this.timer = setTimeout(function() {
this.clearBoard(); // what is “this”?
}, 0);
};

Executing the above code results in the following error: "Uncaught TypeError: undefined is not a function." The reason you get the above error is that when you invoke `setTimeout()`, you are actually invoking `window.setTimeout()`. As a result, an anonymous function being passed to `setTimeout()` is being defined in the context of the window object, which has no `clearBoard()` method.

A traditional, old-browser-compliant solution is to simply save your reference to `this` in a variable that can then be inherited by the closure. For example:

function testFunction () {
this.clearLocalStorage();
var self = this; // save reference to ‘this’, while it’s still this!
this.timer = setTimeout(function(){
self.clearBoard();
}, 0);
};

Alternatively, in the newer browsers, you can use the `bind()` method to pass the proper 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 right ‘this’!
};

## 7\. Uncaught RangeError: Maximum call stack

This is an error that occurs in Chrome under a couple of circumstances. One is when you call a recursive function that does not terminate. You can test this in the Chrome Developer Console.

![Screenshot of Uncaught RangeError: Maximum call stack](https://example.com/375385b4d2f3823b20357c9ba8eb8bb4)

It may also happen if you pass a value to a function that is out of range. Many functions accept only a specific range of numbers for their input values. For example, `Number.toExponential(digits)` and N`umber.toFixed(digits)` accept digits from 0 to 20, and `Number.toPrecision(digits)` accepts digits from 1 to 21.

var a = new Array(4294967295); //OK
var b = new Array(-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!

This is an error that occurs in Chrome because of reading length property for an undefined variable. You can test this in the Chrome Developer Console.

![Screenshot of TypeError: Cannot read property ‘length’](https://example.com/50c640476d1fc4d2050428588f9d3d6b)

You normally find length defined on an array, but you might run into this error if the array is not initialized or if the variable name is hidden in another context. Let’s 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 ones. This means that even if you have variables with names testArray, parameters with the same names within a function will still be treated as local.

You have two ways to resolve your issue:

  1. Remove parameters in the function declaration statement (it turns out you want to access those variables that are declared outside of the function, so you don’t need parameters for your function):

    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. Invoke the function passing it the array that we declared:

    “`
    var testArray = [“Test”];

    function testFunction(testArray) {
    for (var i = 0; i

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。