编辑:用他自己的话说: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
?这样做的一般原因是什么?
提前致谢。
答案 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
:这就是为什么可能容易出错。