2023年11月27日发(作者:)
10种最常见的Javascript错误(频率最⾼)
为了回馈我们的开发者社区,我们查看了数千个项⽬的数据库,发现了 JavaScript 中频度最⾼的 10 种错误。我们会告诉你什么原因导致了这些错误,以及如
何防⽌这些错误发⽣。如果你能够避免落⼊这些 “陷阱”,你将会成为⼀个更好的开发者。
我们专注于最有可能影响您和您的⽤户的错误。为此,我们通过研究各种不同公司的项⽬集来对于错误进⾏排列。如果我们只查看每个错误发⽣的总次数,那
么客户量⼤的的项⽬产⽣的错误可能会压倒其他错误,导致实际收集到的是与⼤多数读者⽆关的错误数据集。
以下是 JavaScript 错误 Top 10:
为了便于阅读,我们将每个错误描述都缩短了。接下来,让我们深⼊到每⼀个错误,来确定什么会导致它,以及如何避免创建它。
1. Uncaught TypeError: Cannot read property
如果你是⼀个 JavaScript 开发⼈员,可能你看到这个错误的次数⽐你敢承认的要多(LOL…)。当你读取⼀个未定义的对象的属性或调⽤其⽅法时,这个错误
会在 Chrome 中出现。 您可以很容易的在 Chrome 开发者控制台中进⾏测试(尝试)。
发⽣这种情况的原因很多,但常见的⼀种是在渲染 UI 组件时对于状态的初始化操作不当。
我们来看⼀个在真实应⽤程序中发⽣的例⼦:我们选择 React,但该情况也同样适⽤于 Angular、Vue 或任何其他框架。
class Quiz extends Component {
componentWillMount() {
('/thedata').then(res => {
te({items: });
});
}
render() {
return (
{(item =>
)}
);
}
}
这⾥有两件重要的事情要实现:
组件的状态(例如 )从 undefined 开始。
当异步获取数据时,不管它是在构造函数componentWillMount还是componentDidMount中获取的,组件在数据加载之前⾄少会呈现⼀次,当 Quiz 第⼀次呈现
时, 是未定义的。 这⼜意味着 ItemList 将 items 定义为 undefined,并且在控制台中出现错误 - “Uncaught TypeError: Cannot read property
‘map' of undefined”。
这很容易解决。最简单的⽅法:在构造函数中⽤合理的默认值来初始化 state。
class Quiz extends Component {
// Added this:
constructor(props) {
super(props);
// Assign state itself, and a default value for items
= {
items: []
};
}
componentWillMount() {
('/thedata').then(res => {
te({items: });
});
}
render() {
return (
{(item =>
)}
);
}
}
在你的应⽤程序中的具体代码可能是不同的,但我们希望我们已经给你⾜够的线索,以解决或避免在你的应⽤程序中出现的这个问题。如果还没有,请继续阅
读,因为我们将在下⾯覆盖更多相关错误的⽰例。
2. TypeError: ‘undefined' is not an object
这是在 Safari 中读取属性或调⽤未定义对象上的⽅法时发⽣的错误。您可以在 Safari Developer Console 中轻松测试。这与 1 中提到的 Chrome 的错误基本相
同,但 Safari 使⽤了不同的错误消息提⽰语。
3. TypeError: null is not an object
这是在 Safari 中读取属性或调⽤空对象上的⽅法时发⽣的错误。 您可以在 Safari Developer Console 中轻松测试。
有趣的是,在 JavaScript 中,null 和 undefined 是不⼀样的,这就是为什么我们看到两个不同的错误信息。undefined 通常是⼀个尚未分配的变量,⽽ null 表
⽰该值为空。 要验证它们不相等,请尝试使⽤严格的相等运算符 ===:
在现实世界的例⼦中,这种错误可能发⽣的⼀种场景是:如果在加载元素之前尝试在 JavaScript 中使⽤元素。 因为 DOM API 对于空⽩的对象引⽤返回值为
null。
任何执⾏和处理 DOM 元素的 JS 代码都应该在创建 DOM 元素之后执⾏。 JS 代码按照 HTML 中的规定从上到下进⾏解释。 所以,如果 DOM 元素之前有⼀
个标签,脚本标签内的 JS 代码将在浏览器解析 HTML 页⾯时执⾏。 如果在加载脚本之前尚未创建 DOM 元素,则会出现此错误。
在这个例⼦中,我们可以通过添加⼀个事件监听器来解决这个问题,这个监听器会在页⾯准备好的时候通知我们。 ⼀旦 addEventListener被触发,init() ⽅法
就可以使⽤ DOM 元素。
function init() {
var myButton = mentById("myButton");
var myTextfield = mentById("myTextfield");
k = function() {
var userName = ;
}
}
ntListener('readystatechange', function() {
if (tate === "complete") {
init();
}
});
4. (unknown): Script error
当未捕获的 JavaScript 错误(通过r处理程序引发的错误,⽽不是捕获在try-catch中)被浏览器的跨域策略限制时,会产⽣这类的脚本错误。 例
如,如果您将您的 JavaScript 代码托管在 CDN 上,则任何未被捕获的错误将被报告为“脚本错误” ⽽不是包含有⽤的堆栈信息。这是⼀种浏览器安全措施,旨
在防⽌跨域传递数据,否则将不允许进⾏通信。
要获得真正的错误消息,请执⾏以下操作:
1. 发送 ‘Access-Control-Allow-Origin' 头部
将 Access-Control-Allow-Origin 标头设置为 * 表⽰可以从任何域正确访问资源。 如有必要,您可以将域替换为您的域:例如,Access-Control-Allow-
Origin:。 但是,处理多个域会变得棘⼿,如果你使⽤ CDN,可能由此产⽣更多的缓存问题会让你感觉到这种努⼒并不值得。 在这⾥看到
更多。
这⾥有⼀些关于如何在各种环境中设置这个头⽂件的例⼦:
Apache
在 JavaScript ⽂件所在的⽂件夹中,使⽤以下内容创建⼀个 .htaccess ⽂件:
Header add Access-Control-Allow-Origin "*"
Nginx
将 add_header 指令添加到提供 JavaScript ⽂件的位置块中:
location ~ ^/assets/ {
add_header Access-
Control-Allow-Origin *;}
location ~ ^/assets/ {
add_header Access-Control-Allow-Origin *;
}
HAProxy
将以下内容添加到您为 JavaScript ⽂件提供资源服务的后端:
rspadd Access-Control-
Allow-Origin: *
rspadd Access-Control-Allow-Origin: *
2. 在
