黄子涵

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 运算符。

posted @ 2022-05-28 09:34  黄子涵  阅读(131)  评论(0编辑  收藏  举报