以下条件语句在未定义值时抛出异常:
if (!(e = e[f])) {
e[f] = {};
}
虽然以下内联条件不会抛出任何异常:
e = e[f] ? e[f] : e[f] = {};
这是包含条件的函数,它负责从window对象开始动态创建对象:
function t(a, c) {
var s = a.split('.'),
e = window;
// works only in IE
!(s[0] in e) && e.execScript && e.execScript('var '+ s[0]);
for (var f; s.length && (f = s.shift()); ) {
if (!s.length && void 0 !== c) {
e[f] = c;
}else {
e = e[f] ? e[f] : e[f] = {};
}
}
}
调用此函数的示例:
t('s.d');
此调用应创建一个新对象:window.s.d
有没有人知道发生了什么?
答案 0 :(得分:2)
if (!(e = e[f])) {
e[f] = {};
}
您将e
(已设置为window
对象)设置为其.s
属性(即t('s.d')
)。此属性未定义,并且使用!
“注意”此属性将返回true,从而有效地使语句通过。在下一行e
仍未定义,当你执行
e[ f ] = {};
它转换为:
undefined[ f ] = {};
这是造成错误的原因。
e = e[f] ? e[f] : e[f] = {};
这被解析为:
e = (e[f]) ? e[f] : e[f] = {};
和不为
(e = e[f]) ? e[f] : e[f] = {};
如果在后一种情况下解析它,则会得到与条件情况相同的错误,因为第一个操作数(e[f]
)将返回undefined,转到三元运算符的错误情况({{ 1}})。这也将转换为导致错误的e[f] = {}
。
答案 1 :(得分:1)
打破它:
e = e[f]
,这是一项任务。
e
不存在, undefined
将被分配e[f]
。
!(e = e[f])
为true
。
此声明为true
,因为e
不包含名为f
的属性。
if (!(e = e[f])) { ... }
,然后满足条件。
if( ... ){ e[f] = {}; }
。
此时e
保留值undefined
。这会转换为undefined[f] = {}
,因此会出错。