当前位置: 首页 > 科技观察

1000多个项目的十大JavaScript错误

时间:2023-03-12 07:50:47 科技观察

< titlesplit >每个错误都被截断以提高可读性,让我们更深入地研究每个问题以确定导致它们的原因以及如何避免它们。1.UncaughtTypeError:Cannotreadproperty如果你是JavaScript开发者,你可能见过这个错误。当您在未定义的对象上读取属性或调用方法时,这会在Chrome中发生。您可以在Chrome开发者控制台中轻松测试它。发生这种情况的原因有很多,但一个常见的原因是渲染UI组件时状态初始化不正确。让我们看一个例子,说明这在实际应用程序中是如何发生的。我们将选择React,但同样的不正确初始化原则也适用于Angular、Vue或任何其他框架。classQuizextendsComponent{componentWillMount(){axios.get('/thedata').then(res=>{this.setState({items:res.data});});}render(){return(

    {this.state.items.map(item=>{item.name})}
);}}这里有两件重要的事情要实现:组件状态(比如this.state)以undefined开头。当你异步获取数据时,无论数据是在构造函数componentWillMount还是componentDidMount中获取的,组件都会在数据加载之前至少渲染一次。当测验首次呈现时,this.state.items是未定义的。这反过来意味着ItemList将获得未定义的项目,并且您将在控制台中收到错误-“UncaughtTypeError:无法读取未定义的属性‘map’”。这很容易修复,最简单的方法:在构造函数中使用合理的默认值初始化状态。classQuizextendsComponent{//Addthis:constructor(props){super(props);this.state={items:[]//默认值};}componentWillMount(){axios.get('/thedata').then(res=>{this.setState({items:res.data});});}render(){return(
    {this.state.items.map(item=>>{item.name})}
);}}您的应用程序中的实际代码可能会有所不同,但我希望已经为您提供了足够的线索,以便您通过编程来修复或避免此问题。如果没有,请继续阅读,因为我将在下面介绍更多相关错误的示例。2.TypeError:'undefined'isnotanobject(evaluating)这是在Safari中读取未定义对象的属性或调用方法时出现的错误,你可以在SafariDeveloperConsole中很方便地测试这个。这基本上是一样的Chrome的错误同上,但是Safari使用了不同的错误信息。3.TypeError:nullisnotanobject(evaluatingThisisanerrorthathappensinSafariwhenreadingapropertyorcallingamethodonanullobject,youcanVeryeasy在Safari开发者控制台进行测试,有趣的是,在JavaScript中,null和undefined是不一样的,这就是为什么我们会看到两条不同的错误信息,undefined通常是一个还没有被赋值的变量,null表示值为空白。要验证它们是否相等,请尝试使用严格相等运算符。在实际示例中可能发生此错误的一种方式是在加载元素之前尝试在JavaScript中使用DOM元素,这是因为DOMAPI返回null一个空白对象重新参考。任何执行和处理DOM元素的JS代码都应该在DOM元素创建之后执行。JS代码是按照HTML格式从上到下进行解释的,所以如果DOM元素之前有标签,浏览器解析HTML页面时就会执行script标签里面的JS代码。如果在加载脚本之前尚未创建DOM元素,则会发生此错误。在这个例子中,我们可以通过添加一个事件侦听器来解决这个问题,该事件侦听器将在页面准备好时通知我们。一旦触发了addEventListener,init()方法就可以使用DOM元素。
4.(unknown):当未捕获的JavaScript错误违反跨源策略并跨越域边界时,将发生脚本错误脚本错误。例如,如果您将JavaScript代码托管在CDN上,任何未捕获的错误(冒泡到window.onerror处理程序中的错误,而不是在try-catch中捕获的错误)将被报告为“脚本错误”,而不是包括有用的信息.这是一种浏览器安全措施,旨在防止数据跨域传递,否则将无法进行通信。要获得真正的错误消息,请执行以下操作。(1)发送Access-Control-Allow-Originheader将Access-Control-Allow-Originheader设置为*表示可以从任何域正确访问该资源。如果需要,您可以将*替换为您的域:例如,Access-Control-Allow-Origin:www.example.com。但是,处理多个域很复杂,如果使用CDN可能会导致缓存问题,那么可能不值得为此付出努力。以下是如何在各种环境中设置此标头的一些示例:(2)Apache在将提供JavaScript文件的文件夹中,创建一个包含以下内容的.htaccess文件:HeaderaddAccess-Control-Allow-Origin"*"(3)Nginx在提供JavaScript文件的location块中添加add_header指令:location~^/assets/{add_headerAccess-Control-Allow-Origin*;}(4)HAProxy在提供JavaScript文件的asset端添加如下内容:rspaddAccess-Control-Allow-Origin:\*(5)在您的HTML源代码中的脚本标签上设置crossorigin="anonymous",对于您设置Access-Control-Allow-Origin标头的每个脚本,设置crossorigin="anonymous"脚本标签。在脚本标签上添加crossorigin属性之前,请确保您已验证正在为脚本文件发送标头。在Firefox中,如果存在crossorigin属性,但没有Access-Control-Allow-Origin标头,则不会执行脚本。5.TypeError:Objectdoesn'tsupportproperty这是IE中出现的错误,调用未定义的方法时,可以在IE开发者控制台中测试。这相当于Chrome中的错误“TypeError:'undefined'isnotafunction”。是的,对于同一个逻辑错误,不同的浏览器可能会有不同的错误信息。这是IE在采用JavaScript命名空间的Web应用程序中的一个常见问题,在这种情况下,99.9%的问题是IE无法将当前命名空间中的方法绑定到this关键字。例如,如果您的JS命名空间Rollbar使用isAwesome方法。通常,如果您在Rollbar命名空间中,则可以使用以下语法调用isAwesome方法:this.isAwesome();Chrome、Firefox和Opera会很乐意接受这种语法。另一方面,IE没有。因此,在使用JS命名空间时,最安全的做法是在它们前面加上实际的命名空间。Rollbar.isAwesome();6.TypeError:'undefined'isnotafunction这是Chrome调用未定义函数时出现的错误。您可以在Chrome开发者控制台和MozillaFirefox开发者控制台中对此进行测试。随着JavaScript编码技术和设计模式多年来变得越来越复杂,回调和闭包中的自引用范围也相应增加,这是一种相当普遍的混淆来源。考虑以下示例代码片段:functionclearBoard(){alert("Cleared");}document.addEventListener("click",function(){this.clearBoard();//这个“this”是什么?});如果执行上面的代码并单击页面,将导致以下错误“UncaughtTypeError:this.clearBoardnotafunction”。原因是正在执行的匿名函数是在文档的上下文中,而clearBoard是在window中定义的。传统的、旧的浏览器兼容的解决方案是简单地在一个变量中保留对它的引用,然后闭包可以继承它。例如:varself=this;document.addEventListener("click",function(){self.clearBoard();});此外,在较新的浏览器中,您可以使用bind()方法传递正确的引用:document。addEventListener("点击",this.clearBoard.bind(this));7.UncaughtRangeError:Maximumcallstack这是Chrome浏览器在几种情况下都会出现的错误,一种是调用了一个没有终止的递归函数。您可以在Chrome开发者控制台中对此进行测试。如果您将值传递给超出范围的函数,也会发生这种情况。许多函数只接受特定范围的数字作为输入值,例如,Number.toExponential(digits)和Number.toFixed(digits)接受0到20之间的数字,而Number.toFixed(digits)接受1到21之间的数字.vara=newArray(4294967295);//OKvarb=newArray(-1);//rangeerrorvarnum=2.555555;document.writeln(num.toExponential(4));//OKdocument.writeln(num.toExponential(-2));//rangeerror!num=2.9999;document.writeln(num.toFixed(2));//OKdocument.writeln(num.toFixed(25));//rangeerror!num=2.3456;document.writeln(num.toPrecision(1));//OKdocument.writeln(num.toPrecision(22));//范围错误!8.TypeError:Cannotreadproperty'length'这是Chrome浏览器的错误,因为未定义变量的长度是读取属性,可以在Chrome开发者控制台测试。通常,您可以在数组上找到定义的长度,但如果数组未初始化或变量名称对其他上下文隐藏,您可能会遇到此错误。让我们通过以下示例来理解此错误。vartestArray=["Test"];functiontestFunction(testArray){for(vari=0;i