JavaScript 调试常见报错以及原因

  在程序开发中难免会遇到一些错误,在成千上万的代码中去寻找错误很明显相当于大海捞针,为此,每种计算机编程语言都要它独特的一套错误处理与调试机制。当然,JavaScript也不例外。但是,接触过javascript的人都知道,在调试js的过程中有时候真想砸电脑。因为在调试的过程中,控制台给出的错误非常难以理解,其次给出的行号不总有帮助。虽然很多时候都要靠经验去判断,但是控制台给出的错误提示也并不是一点用都没有。因为它会给你提供一些信息帮助你去判断和寻找错误的来源。那这些有用的信息是什么?前面已经说了,每种计算机编程语言都要它独特的一套错误处理与调试机制,每种错误都有对应的错误类型,而当错误发生时,就会抛出相应类型的错误对象。JavaScript同样如此,ECMA-262 定义了下列 7 种错误类型:

  1. Error 错误
  2. EvalError 全局错误
  3. RangeError 引用错误
  4. ReferenceError 参数错误
  5. SyntaxError 语法错误
  6. TypeError 类型错误
  7. URIError  编码错误

其中, Error 是基类型,其他错误类型都继承自该类型。因此,所有错误类型共享了一组相同的属性(错误对象中的方法全是默认的对象方法) 。 Error 类型的错误很少见,如果有也是浏览器抛出的,这个基类型的主要目的是供开发人员抛出自定义错误。
EvalError 类型的错误会在使用 eval() 函数而发生异常时被抛出。ECMA-262 中对这个错误有如下描述: “如果以非直接调用的方式使用 eval 属性的值(换句话说,没有明确地将其名称作为一个Identifier ,即用作 CallExpression 中的 MemberExpression ) ,或者为 eval 属性赋值。 ”简单地说,如果没有把 eval() 当成函数调用,就会抛出错误,例如:

new eval(); //抛出 EvalError

eval = foo; //抛出 EvalError

在实践中,浏览器不一定会在应该抛出错误时就抛出 EvalError 。例如,Firefox 4+和 IE8 对第一种情况会抛出 TypeError ,而第二种情况会成功执行,不发生错误。有鉴于此,加上在实际开发中极少会这样使用 eval() ,所以遇到这种错误类型的可能性极小。其他类型错误在接下来会详细说明。

 

错误类型:

  TypeError类型错误)对象用来表示值的类型非预期类型时发生的错误

错误原因:

  当传入函数的操作数参数的类型并非操作符或函数所预期的类型时,将抛出一个 TypeError 类型错误。

(一)

错误信息:

TypeError: undefined is not a function (Firefox)
Uncaught TypeError: undefined is not a function (Chrome)

错误分析:

  Uncaught TypeError: 这部分信息通常不是很有用。Uncaught 表示错误没有被 catch 语句捕获,TypeError 是错误的名字。

  undefined is not a function: 这部分信息,你必须逐字阅读。比如这里表示代码尝试使用 undefined ,把它当做一个函数。

错误实例:

/*
*  当尝试调用一个像方法的值时,这个值并不是一个方法
*/
var foo = undefined;
foo();   //Uncaught TypeError: foo is not a function

/*
*  当尝试调用一个对象的方法时,输错了名字,也会触发这个错误提示
*/

var x = document.getElementByID('foo');  //Uncaught TypeError: document.getElementByID is not a function

(二)

错误信息:

TypeError: foo is not a function (Firefox)
Uncaught TypeError: Cannot read property 'foo' of null (Chrome)

错误分析:

  Uncaught TypeError: 这部分信息通常不是很有用。Uncaught 表示错误没有被 catch 语句捕获,TypeError 是错误的名字。

  undefined is not a function: 这部分信息,你必须逐字阅读。比如这里表示代码尝试使用 undefined ,把它当做一个函数。

错误实例:

/*
*  尝试读取 null 或者 undefined ,把它当成了对象
*/
var someVal = null;
console.log(someVal.foo);

 

错误类型:

  ReferenceError(引用错误) 对象表明一个不存在的变量被引用。

错误原因:

  当你尝试引用一个未被定义的变量时,将会抛出一个 ReferenceError引用错误

错误信息:

ReferenceError: invalid assignment left-hand side (Firefox)
Uncaught ReferenceError: Invalid left-hand side in assignment (Chrome)

错误实例:

/*
*  尝试给不能赋值的东西赋值,引起错误
*  “left-hand side in assignment” 提及了等号左手边的部分,因为左手边包含不能赋值的东西 */ function doSomething(){}; if(doSomething() = 'somevalue'){}; /* * 当尝试调用一个对象的方法时,输错了名字,也会触发这个错误提示 */ var x = document.getElementByID('foo'); //Uncaught TypeError: document.getElementByID is not a function

 

错误类型:

  RangeError

错误信息:

RangeError: invalid array length (Firefox)
RangeError: Invalid array length (Chrome)
RangeError: Invalid array buffer length (Chrome)

错误原因:

  试图传递一个number参数给一个范围内不包含该number的函数时则会引发RangeError。当传递一个不合法的length值作为Array 构造器的参数创建数组,或者传递错误值到数值计算方法(Number.toExponential()Number.toFixed()Number.toPrecision()),会出现RangeError

错误实例:

/*
*  Array 和 ArrayBuffer 的 length(长度) 属性被定义为一个32位无符号整形(unsigned 32-bit integer)的值,所以它只能存储 0 - 232-1 之间的数。
*  当创建一个长度为负数或者长度大于等于232  Array 或者 ArrayBuffer 时,或者当设置 Array.length 属性为负数或者长度大于等于232 的时候就会触发这个错误
*/
new
Array(Math.pow(2, 40)) new Array(-1) new ArrayBuffer(Math.pow(2, 32)) new ArrayBuffer(-1) let a = []; a.length = a.length - 1; // 将 length 属性的值设置为 -1 let b = new Array(Math.pow(2, 32) - 1); b.length = b.length + 1; // 将 length 属性的值设置为 2^32

 

错误类型:

  SyntaxError

错误原因:

  SyntaxError 对象代表尝试解析语法上不合法的代码的错误。当Javascript语言解析代码时,Javascript引擎发现了不符合语法规范的tokens或token顺序时抛出SyntaxError。可能是丢失运算符或者转义字符等。

错误实例

/* 
*  因为没有使用 ”+“ 操作符来连接字符串,JavaScript 认为 log 函数的参数的值只是 “PI: ”,在这种情况下,它应该用一个右括号作为结束。 */
console.log("PI: " Math.PI); //Uncaught SyntaxError: missing ) after argument list

/*
*  一个字符串字面量少了结尾的引号
*/
var a='sd; //Uncaught SyntaxError: Invalid or unexpected token

如何解决:

  [ ] { } ( ) 这几个符号不配对常常导致出错。检查所有的圆括号和方括号是否配对。行号指出的不仅是问题字符。

  Unexpected / 跟正则表达式有关。此时行号通常是正确的。

  Unexpected ; 对象或者数组字面量里面有个;通常引起这个错误,或者函数调用的参数列表里有个分号。此时的行号通常也是正确的。

posted @ 2017-03-28 23:19  李某龙  阅读(...)  评论(...编辑  收藏