为什么明确将变量定义为undefined?

时间:2013-10-23 14:19:33

标签: javascript functional-programming

编辑:用他自己的话说:https://twitter.com/fogus/status/393058344413302784

我正在阅读Michael Fogus的“功能JavaScript”,并在第5章开头看到了这个列表:

function dispatch(/* funs */) {
    var funs = _.toArray(arguments);
    var size = funs.length;

    return function(target /*, args */) {
        var ret = undefined; // <----------------------------------- ??
        var args = _.rest(arguments);

        for (var funIndex = 0; funIndex < size; funIndex++) {
            var fun = funs[funIndex];
            ret = fun.apply(fun, construct(target, args));

            if (existy(ret)) return ret;
        }

        return ret;
     };
}

如果这不是错误,为什么他明确将ret定义为undefined?这样做的一般原因是什么?

提前致谢。

3 个答案:

答案 0 :(得分:2)

你的问题的简短回答是让事情更明确。我不能保证为什么作者定义var ret = undefined;因为我不是作者。但是,我可以解释为什么在你教授某些东西时要明确这一点是个好主意。特别是当你教别人如何编码时。

我最喜欢的文章之一是Bret Victor在Learnable Programming上的着名博客文章(除此之外:你必须阅读它 - 我坚持认为)。在这篇博文中,Bret描述了人们如何比抽象概念更好地理解具体例子。因此,通过明确表示,对于没有JavaScript经验的人来说,理解程序中发生的事情会更容易。

每个自称为JavaScript的程序员都必须知道声明一个变量但不定义它会导致它变为undefined(如果你考虑它就很明显)。因此,无论作者是写var ret = undefined;还是仅var ret;,都不会有任何区别。然而,前者更具体,更容易被新手理解。

但应注意,undefined不是JavaScript中的保留字。因此,您可以创建一个名为undefined的变量,它很可能不是undefined。在上述代码的上下文中,undefined实际上可能不是undefined。我们不确定,因为我们无法看到dispatch的词汇环境。然而,很可能它必须是undefined

考虑到上述问题,将ret声明为var ret = void 0;会更不明确且更明确。 JavaScript中的void运算符采用表达式并计算为undefined。因此void expression始终评估为undefined。但是在给定的上下文中,简单地使用每个理智的JavaScript程序员所做的var ret;就不那么容易混淆和不那么暧昧了。

当然,这只是我对作者决定辩护的解释。要获得更明确的答案,您需要自己询问作者。

答案 1 :(得分:1)

有人可能会这样做,只是为了让读者更清楚价值尚未定义,或者他明确希望价值为undefined。也就是说,他将值定义为undefined

但这样做没有句法上的理由; var foo;var foo = undefined;如果它们位于函数的开头,则执行相同的操作,并且在其他任何位置使用后者都可能会丢弃现有变量的值。

答案 2 :(得分:0)

在这种特定情况下,我看不出技术原因,这可能只是他的习惯或做法。当然,他只能声明ret如下:

var ret;

在那种特定情况下,因为变量是本地的,就足够了。此外,它不会将变量的初始值用于任何事物(在循环中它只是分配它)。

但是,在更复杂的环境中,将变量显式设置为undefined,可能是一种很好的做法。因为var没有声明一个块范围变量,如果你有一个巨大的模块或正文函数 - 或者你在一个团队中工作,或者你将不同的脚本组合在一起然后在网上发布它们 - 它可能是您重复使用相同的变量名称两次,可能在两个不同的范围内。在这种情况下,如果您没有明确设置该值,则将重用之前设置的值。说清楚:

var ret = 10;
/* doing something with ret */

/* in the same scope, some lines above: */

if (someCondition) {
   var ret;
   console.log(ret); // 10, not `undefined`
}

这种情况正在发生,因为hoisting:变量声明被移到顶部,只剩下赋值。因为在if块中没有赋值,并且变量已经声明,所以声明将被简单地删除。

请注意,在开头没有var ret = 10的相同代码会导致undefined:这就是为什么可能容易出错。