5.5 对变量是否存在的校验
如果试图读取没有被声明的变量,则会引起 ReferenceError 异常,这是一种错误,必须对代码进行修正。避免 ReferenceError 异常的一种方法:
var hzh1 = 1;
var hzh1 = hzh1 || 7;
var hzh2;
var hzh2 = hzh2 || 2;
console.log("分别输出hzh1和hzh2的值:");
console.log("hzh1 = " + hzh1);
console.log("hzh2 = " + hzh2);var hzh1 = 1;
var hzh1 = hzh1 || 7;
console.log("输出hzh1的值:");
console.log("hzh1 = " + hzh1);
[Running] node "e:\HMV\JavaScript\JavaScript.js"
分别输出hzh1和hzh2的值:
hzh1 = 1
hzh2 = 2
[Done] exited with code=0 in 0.212 seconds
该代码利用了对已经声明的变量再次声明不会产生副作用的特性。像下面这样,分成两行并使用不同的变量,作用是一样的。
// 也可以分开两行
var hzh3;
var hzh4 = hzh3 || 4;
console.log("输出hzh4的值:");
console.log("hzh4 = " + hzh4);
[Running] node "e:\HMV\JavaScript\JavaScript.js"
输出hzh4的值:
hzh4 = 4
[Done] exited with code=0 in 0.278 seconds
准确地说,这一代码并没有判断变量 hzh3 是否已经被声明。例如在该例中,如果变量 hzh3 的值是 0 或者是 "(空字符),它在被转换为布尔型之后值就会为假,这时,代码中的变量 hzh4 则会被赋值为 4。
// 也可以分开两行
var hzh3 = 0;
var hzh4 = hzh3 || 4;
console.log("输出hzh4的值:");
console.log("hzh4 = " + hzh4);
[Running] node "e:\HMV\JavaScript\JavaScript.js"
输出hzh4的值:
hzh4 = 4
[Done] exited with code=0 in 0.197 seconds
// 也可以分开两行
var hzh3 = "";
var hzh4 = hzh3 || 4;
console.log("输出hzh4的值:");
console.log("hzh4 = " + hzh4);
[Running] node "e:\HMV\JavaScript\JavaScript.js"
输出hzh4的值:
hzh4 = 4
[Done] exited with code=0 in 0.172 seconds
接下来的代码可能有些冗长,它直接判断变量 hzh5 的值是否是 undefined 值,由此判断出变量 a 是否已声明,或者是否在声明后值为 undefined。
var hzh5;
var hzh6 = (hzh5 !== undefined) ? hzh5 : 6;
console.log("输出hzh6的值:");
console.log("hzh6 = " + hzh6);
[Running] node "e:\HMV\JavaScript\JavaScript.js"
输出hzh6的值:
hzh6 = 6
[Done] exited with code=0 in 0.193 seconds
var hzh5 = 5;
var hzh6 = (hzh5 !== undefined) ? hzh5 : 6;
console.log("输出hzh6的值:");
console.log("hzh6 = " + hzh6);
[Running] node "e:\HMV\JavaScript\JavaScript.js"
输出hzh6的值:
hzh6 = 5
[Done] exited with code=0 in 0.174 seconds
虽说对同一变量再次声明不会有副作用,但每次都要写一遍 var a 也有些麻烦。为了避免这一问题,可以通过 typeof 运算来判断是否为 undefined 值。
请看下面的例子。这个例子利用了在 JavaScript(ECMAScript) 中没有块级作用域的特性。
var hzh7 = 7;
if(typeof hzh7 !== 'undefined') {
var hzh8 = hzh7;
}else {
var hzh8 = 8;
}
console.log("输出hzh8的值:");
console.log("hzh8 = " + hzh8);
[Running] node "e:\HMV\JavaScript\JavaScript.js"
输出hzh8的值:
hzh8 = 7
[Done] exited with code=0 in 0.282 seconds
在以上这些代码中,无法区分变量 hzh7 是还没声明,还是已经声明但值为 undefined。先不论是否有必要对此加以区分,最后再介绍一种能够区分这两种情况的方法。
在读取未声明变量的值时会引起 ReferenceRrror 异常,所以不可以读取这一变量的值,但是可以仅对这一名称是否存在进行确认。为此需要使用 in 运算。
可以在最外层代码中,像下面这样来判断在全局对象中是否存在属性 a,也就是说,可以用来检测全局变量 a 是否存在。
var hzh9 = 9;
if('hzh9' in this) {
var hzh10 = hzh9;
}else {
var hzh10 = 10;
}
console.log("输出hzh10的值:");
console.log("hzh10 = " + hzh10);
[Running] node "e:\HMV\JavaScript\JavaScript.js"
输出hzh10的值:
hzh10 = 10
[Done] exited with code=0 in 0.63 seconds
【评】这个实验结果和书上说的不一样,标记一下。
if('hzh9' in this) {
var hzh10 = hzh9;
}else {
var hzh10 = 10;
}
console.log("输出hzh10的值:");
console.log("hzh10 = " + hzh10);
[Running] node "e:\HMV\JavaScript\JavaScript.js"
输出hzh10的值:
hzh10 = 10
[Done] exited with code=0 in 0.192 seconds
对属性是否存在的检验
变量与属性实质上是一样的。不过,如果变量或属性本身不存在,处理方式则会有所不同。请看下面的例
子:
console.log(hzh1); // 访问未声明的变量会导致 ReferenceError 异常
[Running] node "e:\HMV\JavaScript\JavaScript.js"
e:\HMV\JavaScript\JavaScript.js:1
console.log(hzh1); // 访问未声明的变量会导致 ReferenceError 异常
^
ReferenceError: hzh1 is not defined
at Object.<anonymous> (e:\HMV\JavaScript\JavaScript.js:1:13)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
at internal/main/run_main_module.js:17:47
[Done] exited with code=1 in 0.199 seconds
console.log(this.hzh); // 访问不存在的属性并不会引起错误
[Running] node "e:\HMV\JavaScript\JavaScript.js"
undefined
[Done] exited with code=0 in 0.181 seconds
var hzh = {};
console.log(hzh.x); // 读取不存在的属性仅会返回undefined,并不会引起错误
[Running] node "e:\HMV\JavaScript\JavaScript.js"
undefined
[Done] exited with code=0 in 0.199 seconds
读取不存在的属性仅会返回 undefined 值,而不会引起错误。但是如果对 undefined 值进行属性访问的话,则会像下面这样产生 TpyeError 异常。
console.log(hzh.x.y);
[Running] node "e:\HMV\JavaScript\JavaScript.js"
e:\HMV\JavaScript\JavaScript.js:1
console.log(hzh.x.y);
^
ReferenceError: hzh is not defined
at Object.<anonymous> (e:\HMV\JavaScript\JavaScript.js:1:13)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
at internal/main/run_main_module.js:17:47
[Done] exited with code=1 in 0.171 seconds
为了避免产生 TypeError 异常,一般会使用下面的方法。
obj.x && Object.x.y
但如果是为了检测对象内是否存在某一属性,还请使用 in 运算符。