引用错误是范围解析失败错误。在 TypeError 中,作用域解析成功,但我们尝试执行
对变量的非法操作是不允许的。
以下示例将清楚地说明这两种类型的错误。
function foo(a){
console.log(a+b);//ReferenceError b is not defined
b=a;
}
foo(2);
执行上述函数会导致 TypeError,因为在编译器到达 console.log(a+b) 语句时,未定义 b,
注意 b 没有用 var 关键字声明。
现在考虑下面的函数,
function foo(a){
console.log(a+b);
var b=a;
}
foo(2);//NaN
上述函数执行时,编译器会提升变量b,在函数作用域内,编译后的函数如下所示
function foo(a){
var b;//--> b has a value of undefined at this point
console.log(a+b);
b=a;
}
foo(2);//NaN
当引擎执行 console.log(a+b) 时,此时 a 的值为 2 而 b 的值为 undefined 因此其日志南。
正如下面的表达式计算为 NaN
2 + undefined;// evaluates to NaN
现在来到 TypeError,考虑下面的代码块,像往常一样,我们将使用函数 foo。
function foo(a){
console.log(a+b.toString()); //TypeError Cannot read property 'toString' of undefined
var b = a;
}
foo(2);
按照上述逻辑,在变量 b 被提升后,编译器将函数转换为如下代码所示
function foo(a){
var b ;// b has a value of undefined at this point
console.log(a+b.toString()); //TypeError is thrown
b= a;
}
foo(2);
在函数的范围内,变量b 被提升,因此在console.log(a+b.toString()) 行之前有一个未定义的值。在这一行中,我们尝试将此时未定义的 b 转换为字符串,这样做,我们尝试进行非法操作,因此抛出 TypeError。变量 b 的范围查找成功,但我们执行了非法操作。因此抛出了 TypeError。