2

以下条件语句在未定义值时引发异常:

if (!(e = e[f])) {
    e[f] = {};
}  

而以下内联条件不会引发任何异常:

e = e[f] ? e[f] : e[f] = {};

这是包含条件的函数,它负责从窗口对象开始动态创建对象:

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

有没有人知道发生了什么?

4

2 回答 2

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,进入三元运算符 ( e[f] = {}) 的错误情况。这也将转换为undefined[f] = {}导致错误的原因。

于 2012-12-09T17:10:04.473 回答
1

分解它:

  1. e = e[f],这是一个任务。

    eundefined如果e[f]不存在将被分配。

  2. !(e = e[f])true

    该语句是true因为e不包含名为f.

  3. if (!(e = e[f])) { ... },则满足条件。

  4. if( ... ){ e[f] = {}; }.

    此时e持有价值undefined。这转换为undefined[f] = {},因此错误。

于 2012-12-09T17:12:09.013 回答