检查不存在的变量时控制流模式

Control flow pattern when checking for nonexistent variables

本文关键字:控制流 模式 变量 不存在 检查      更新时间:2023-09-26

我看到了以下模式,并尝试将其调整为我自己的用途:

var request = window.ActiveXObject ?
  new ActiveXObject('Microsoft.XMLHTTP') :
  new XMLHttpRequest;

简化:

var request = window.ActiveXObject ?
  "is ActiveX" : "not ActiveX";
document.write(request + "<br>");
// I get not ActiveX (Chrome)

现在当我尝试:

var notX = "x"; 
  var j = x ? "has x" : "no x";
  document.write(j + "<br>");
  // console error: x is not defined

http://jsfiddle.net/4mn8n/1/

不输出任何内容。是什么让window.ActiveXObject与程序继续document.write但在x的情况下没有x不同?

-- 更重要的是

我可以使用什么强大的模式来替换上述内容?

变量和属性之间有很大的区别(即使变量始终是某个对象的属性;有时该对象没有名称,您无法直接访问它,例如调用函数时使用的变量绑定对象(。当您执行以下操作时:

if (thingy.x) {
    // ...
}

。您正在检查属性。如果该属性不存在,则不是错误,只是您返回的值undefined

相反,如果您这样做:

if (x) {
    // ...
}

。您正在检查一个名为 x变量。如果x根本不存在,则是一个错误(特别是ReferenceError(,因为符号x是完全未定义的(而不是值为 undefined 的属性(。

当您处理全局变量时,这会变得有点模糊,因为全局变量是全局对象的属性,在浏览器中window。因此,如果您有:

var x;

。在全局范围内,if (x)将起作用,if (window.x)也是如此,因为xwindow(全局对象(的属性。但是有一个很大的区别,因为如果未定义xif (x)会抛出错误,但if (window.x)会是假的(因为表达式window.x会导致undefined(。

全局作用域是唯一发生这种情况的作用域,除非您使用 with 语句(出于 Crockford 在这里讨论的原因,我建议避免这样做(。(我并不总是同意克罗克福德的观点,事实上我可能会说这只是50%的事情,但他对with有很好的看法。

您可以可靠地typeof与任何引用(甚至是未定义的引用(一起使用,因此:

if (typeof x !== "undefined") {
}

。即使x完全未定义也能正常工作,因此这通常是检查是否存在某些内容的最佳方法。

当您仅按原样使用未定义的变量来检查它时,这是一个错误。原始代码没有错误,因为它将其作为window对象的属性进行访问;获取未定义的属性,而不是错误,会导致 JavaScript 中的undefined

要检查变量,可以改用typeof

var j = typeof x !== 'undefined' ? "has x" : "no x";