Javascript“单一var模式”的缺点

时间:2011-12-20 20:56:50

标签: javascript design-patterns variable-assignment declaration variable-declaration

在Stefanov的JS Design Patterns一书中,他写道“你使用一个var语句并声明用逗号分隔的多个变量”,然后给出一个“single var”模式的例子,如下所示:

function func() {
    var a = 1,
        b = 2,
        sum = a + b,
        myobject = {},
        i,
        j;
斯特凡诺夫还写道:

  • “最好在声明变量时使用初始值初始化变量。”
  • “您也可以在声明时做一些实际工作,例如前面代码中sum = a + b的情况。”

现在我有一些代码如下,用单个var模式声明相同数量的变量,但做了更多“声明时的实际工作”:

var html = '{purchaseQty}<br>FR:&nbsp; {fromLoc}'
    ,tpl = new Ext.XTemplate(html)
    ,srcReqLoc = record.get('SRC_REQUEST_LOC').trim()
    ,srcSupLoc = record.get('SRC_SUP_LOC').trim()
    ,fromLoc = srcReqLoc ? srcReqLoc : srcSupLoc
    ,tplCfg = {
        purchaseQty: purchaseQty
        ,fromLoc: fromLoc
    };

做太多“宣布时的实际工作”有什么缺点? BTW我不认为这是Javascript single var pattern. Am I overloading it?的完全重复,因为我问的是一般的缺点,而不仅仅是我的代码可能出错。

我认为我可以看到一般的缺点是无法检查错误,例如在我的示例中我在从record.get返回的字符串上调用trim(),但是如果返回undefined,那么“可以”对未定义对象的调用方法“(或者它是什么;)将被抛出。任何人都可以想到其他什么吗?

3 个答案:

答案 0 :(得分:6)

我个人支持道格拉斯·克罗克福德(虽然我很欣赏那些不支持这一点的人),在函数顶部声明变量最有意义,因为JavaScript没有块范围。

来自JSLint site

  

在具有块范围的语言中,通常建议使用   变量应在首次使用的站点声明。但是因为JavaScript   没有块范围,声明所有函数是明智的   函数顶部的变量。建议单一   每个函数使用var语句。

唯一的缺点是,对于来自基于C或C的背景的人来说,您的代码可读性较差。

我很担心我在这里听起来像是一个Crockford粉丝,但是我recommend this talk on coding style为什么有时你的大脑应该通过代码结构(取决于语言)统治你的心脏。

答案 1 :(得分:5)

将所有变量声明在范围的顶部,即在函数的开头或全局代码的开头处是有意义的。我同意这一点。

至于在申报时提供初始值,我将其视为更多指南。一般来说,一个好的计划,当然适用于简单的值,但有时直到一些更复杂的计算之后才知道初始值 - 在这种情况下我不会提供永远不会得到的默认值仅仅是为了提供一些价值而使用。有时候它太乱了。

此外,我不会在声明时给循环索引变量一个初始值 - 对我来说,在循环开始时分配值要清楚得多。

正如您已经指出的那样,如果您需要处理异常等等,您也需要稍后在函数中执行此操作。

只是使用一些常识:如果你有很多变量,你可能会发现你的var语句有点不可读,那么你可以将一些初始化移到函数的后面。

对我来说,你的示例代码没问题,但如果你需要添加更多内容,它会有点难以阅读,因为在密集块中有那么多代码我不能轻易地选择变量名,但是 - 这显然是一个品味问题 - 你可以添加一些空白:

var html       = '{purchaseQty}<br>FR:&nbsp; {fromLoc}'
    ,tpl       = new Ext.XTemplate(html)

    ,srcReqLoc = record.get('SRC_REQUEST_LOC').trim()
    ,srcSupLoc = record.get('SRC_SUP_LOC').trim()    
    ,fromLoc   = srcReqLoc ? srcReqLoc : srcSupLoc

    ,tplCfg    = {
        purchaseQty: purchaseQty
        ,fromLoc: fromLoc
    };

(将=符号对齐,或将相关变量与空行或两者组合。)

答案 2 :(得分:1)

由于这已经很老了,不再完全相关,所以指出那些从es6世界来到这里的人我们现在已经有了块区域范围。

Hoisting无论如何都将所有var声明的变量放在函数作用域的顶部,但有时您会在编码时意识到变量仅在某个块中使用 - 在这种情况下let是首选 - 或者甚至是变量赢了&# 39; t改变参考,在这种情况下,const是最好的主意。