我在每个页面和其中一个页面上运行UI组件,还有一个与之关联的额外功能。 UI组件有一个名为MyValue
的布尔值,额外的功能有一个名为ExtraObject
的对象,其中一个属性是一个名为ExtraBool
的布尔值。
我想测试MyValue是否为真且如果ExtraObject.ExtraBool为false,则仅在ExtraObject存在时进行测试。这样,如果我在没有ExtraObject的页面上,则没有错误。
我试过了:
if (MyValue === true &&
(typeof ExtraObject === undefined || ExtraObject.ExtraBool === false)) {...}
我该如何重写?
目前,我不断收到“ExtraObject is not defined error”。
感谢。
答案 0 :(得分:2)
应该是:
typeof ExtraObject === "undefined"
typeof
将表达式的类型作为字符串返回,因此您需要将名称"undefined"
与结果进行比较。
在我看来,你的情况有点过于明确。我会选择更短的东西:
if (MyValue && !(ExtraObject && ExtraObject.ExtraBool)) {...}
如果您正在使用自己的GUI代码进行通信,则可以假设类型符合预期。 JavaScript中的类型检查相当麻烦,因此如果您知道要处理的是什么,则可能不太明确。 (但这不适用于用户输入。永远不要相信用户输入。)
答案 1 :(得分:1)
逻辑不太正确:
if (MyValue && ExtraObject && !ExtraObject.ExtraBool) { ... }
我猜测null
将是一个值ExtraObject
不应该有的值;也就是说,我认为你的条件确实更好地表明它应该是对象的引用。
因此,当MyValue
是“真实的”时,我写的条件将成立,ExtraObject
是对真实对象的引用,并且该对象上的属性ExtraBool
是“falsy”。
有时需要对布尔常量进行显式比较,但在我看来这是代码味道。 (当然,检查真实性/虚假性也是危险的......)
编辑如果您的要求是MyValue
为真时表达式为真且 ExtraObject
不是对象的引用< em>或它的ExtraBool
属性是真的,然后我写了:
if (MyValue && (!ExtraObject || !ExtraObject.ExtraBool)) { ... }
哪个“更好”取决于个人偏好和经验。
答案 2 :(得分:1)
真相表时间!
A是MyValue
*
B是window.ExtraObject
**
C是ExtraObject.ExtraBool
A B C | O
------+--
0 0 0 | 0
0 0 1 | 0
0 1 0 | n/a***
0 1 1 | 0
1 0 0 | 1
1 0 1 | n/a***
1 1 0 | 1
1 1 1 | 0
我们用这些值发现的是,生成O
的最简单的等式是:
A && !C
所以你的代码应该是:
if (MyValue && !ExtraObject.ExtraBool) {}
但是,当然,如果未定义ExtraObject
,您提到不想遇到问题:
var extraBool = window.ExtraObject ? ExtraObject.ExtraBool : false;
if (MyValue && !extraBool) {}
另一种撰写extraBool
的方法是:
var extraBool = window.ExtraObject && ExtraObject.ExtraBool;
然后你可以内联这个:
if (MyValue && !(window.ExtraObject && ExtraObject.ExtraBool)) {}
撰写!(a && b)
的另一种方法是!a || !b
,这意味着:
if (MyValue && (!window.ExtraObject || !ExtraObject.ExtraBool)) {}
也是正确的。
*可能是MyValue===true
,具体取决于您需要的严格程度
**或typeof ExtraObject !== 'undefined'
***实际上不可能ExtraObject
未定义并访问ExtraObject.ExtraBool
子>
答案 3 :(得分:-1)
if ((MyValue === true) && (typeof ExtraObject === undefined || ExtraObject.ExtraBool === false)) {}