未声明的变量(即不存在的变量)没有类型 - 因此它的类型是未定义的。我相信测试某些东西是否未定义的普遍接受的方法是
typeof var === 'undefined'
而不是
var === undefined
因为如果变量不存在,您将无法访问它。如果您确定变量应该存在,后一种情况可能更有用,因为两者之间的区别在于未声明的变量在第一种情况下将返回 false,但在第二种情况下会导致错误。
如果您使用第二个变体,请确保使用三重等号运算符;(更常见的)双等号运算符执行类型强制,因此null == undefined为真而null === undefined为假。有时您可能想要第一种行为,但通常您会想要第二种行为,尤其是当您针对 undefined 进行测试时,因此识别差异很重要。(这是第一种情况的另一个好处,因为不可能犯这种微妙的错误)。
是的,变量的值可以是 undefined,您可以明确地为它们赋值。分配undefined给变量虽然可能会令人困惑,因为它有点自相矛盾(您已将变量定义为未定义)并且无法将该变量与不存在的变量或未初始化的变量区分开来。如果要表示变量当前没有值,或者要完全“取消声明”该变量,请使用 null,请使用delete {varname}. 将 undefined 赋值给一个变量不会删除该变量的声明;如果您迭代它们,它仍然会出现在其拥有对象的属性列表中,所以我想不出任何对您有益的情况。
编辑:为了回应评论,当用 === (或 ==)比较值时,必须推迟变量以获得其当前值才能进行比较。由于该变量不存在,因此取消引用失败(目前没有真正的惊喜)。虽然您可能期望 typeof 运算符以类似的方式工作(获取当前值,查看它的类型是什么),但它特别适用于未定义的变量。“简短版本”(如Mozilla 参考所用)只是“typeof 运算符返回一个字符串,指示未计算的操作数的类型”。
从ECMAScript 规范中提取的长版本是未定义变量的特殊情况:
11.4.3 typeof UnaryExpression的计算如下:
- 评估UnaryExpression(根据 10.1.4,如果变量未声明,则返回“一个类型 Reference 的值,其基对象为null,其属性名称为标识符”)。
- 如果 Type(Result(1)) 不是 Reference,则转到第 4 步。(It is a Reference)
- 如果 GetBase(Result(1)) 为null,则返回“未定义”。(这是匹配未定义变量的特殊情况)
至于你对第一个问题的评论,“你如何对不存在的东西进行分类”——很简单!只需将所有概念分为确实存在的事物(例如松鼠、岩石)和不存在的事物(独角兽、曲速引擎)。这就是 undefined 的意思;不管它在英语中的语义如何,它的 Javascript 含义是该变量尚未声明或填充,因此虽然“名为 foo 的变量”的概念是有效的,但不存在具有该名称的变量具有实际值。