未定义的类型在JS中表现不同

Moa*_*han 2 javascript

我只是尝试这个JS代码 -

if(a){
    console.log("a IS DEFINED")
} else {
    console.log("a IS UNDEFINED")
}
Run Code Online (Sandbox Code Playgroud)

我收到错误 -

ReferenceError: a is not defined
Run Code Online (Sandbox Code Playgroud)

但是当我添加var a它打印a IS UNDEFINED

var a;
if(a){
    console.log("a IS DEFINED")
} else {
    console.log("a IS UNDEFINED")
}

// prints a IS UNDEFINED
Run Code Online (Sandbox Code Playgroud)

为什么它在两种情况下a都表现不同undefined

T.J*_*der 5

你的困惑是完全可以理解的:它是"未定义"这个词的两种不同用法.

这里有一个之间的差未定义的标识符,undefined.

当你这样做

if (a)
Run Code Online (Sandbox Code Playgroud)

...你正试图获取标识符的值a.如果你还没有定义的标识符在所有的,这是一个ReferenceError.JavaScript引擎完全不知道a它的意图.

相比之下,这:

var a;
Run Code Online (Sandbox Code Playgroud)

定义标识符(作为变量)并为其赋予初始值undefined.那么当你这样做的时候

if (a)
Run Code Online (Sandbox Code Playgroud)

... JavaScript引擎知道你在说什么:它转到变量a并获得它的价值.

如果由于某种原因您需要知道是否定义了标识符并且您不想捕获错误,那么您可以获取未定义标识符的类型:

if (typeof a === "undefined")
Run Code Online (Sandbox Code Playgroud)

即使a完全未定义,这也可以(没有错误).但是,它没有区分这两件事(未定义的标识符和带有undefined值的已定义标识符).


现在,好像这不够混乱,在"松散模式"中,JavaScript有一个非常奇怪的行为,我称之为隐式全局的恐怖:如果你分配一个未定义的标识符(而不是试图读取它的值),而不是给予a ReferenceError,它创建一个新的全局变量.值得庆幸的是,我们现在拥有ES5的"严格模式",这使得它始终应该是错误.:-)